diff --git a/changes/4081-samuelcolvin.md b/changes/4081-samuelcolvin.md new file mode 100644 index 0000000..53fd4f5 --- /dev/null +++ b/changes/4081-samuelcolvin.md @@ -0,0 +1 @@ +Speedup `__isinstancecheck__` on pydantic models when the type is not a model, may also avoid memory "leaks". diff --git a/pydantic/main.py b/pydantic/main.py index 7afcafc..0c20d9e 100644 --- a/pydantic/main.py +++ b/pydantic/main.py @@ -295,6 +295,14 @@ class ModelMetaclass(ABCMeta): return cls + def __instancecheck__(self, instance: Any) -> bool: + """ + Avoid calling ABC _abc_subclasscheck unless we're pretty sure. + + See #3829 and python/cpython#92810 + """ + return hasattr(instance, '__fields__') and super().__instancecheck__(instance) + object_setattr = object.__setattr__ diff --git a/tests/test_edge_cases.py b/tests/test_edge_cases.py index 5da6225..b7083d0 100644 --- a/tests/test_edge_cases.py +++ b/tests/test_edge_cases.py @@ -1932,3 +1932,17 @@ def test_int_subclass(): m = MyModel(my_int=IntSubclass(123)) assert m.my_int.__class__ == IntSubclass + + +def test_model_issubclass(): + assert not issubclass(int, BaseModel) + + class MyModel(BaseModel): + x: int + + assert issubclass(MyModel, BaseModel) + + class Custom: + __fields__ = True + + assert not issubclass(Custom, BaseModel)