New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid __dict__ and __weakref__ attributes in AnyUrl and _BaseAddress subclasses #2890
Conversation
…subclasses When inheriting from a class with `__slots__`, [child subclasses will get a `__dict__` and `__weakref__` unless they also define `__slots__`](https://docs.python.org/3/reference/datamodel.html#notes-on-using-slots). ```python from pydantic import AnyUrl, AnyHttpUrl class AnyOtherHttpUrl(AnyUrl): allowed_schemes = {'http', 'https'} __slots__ = () print(set(dir(AnyHttpUrl)) - set(dir(AnyUrl))) #> {'__weakref__', '__dict__'} print(set(dir(AnyOtherHttpUrl)) - set(dir(AnyUrl))) #> set() ```
Hi @nuno-andre |
Hi @PrettyWood! One of the from pydantic import AnyUrl, AnyHttpUrl
from pympler.asizeof import asizeof
class AnyOtherHttpUrl(AnyUrl):
allowed_schemes = {'http', 'https'}
__slots__ = ()
a = AnyUrl.__new__(AnyHttpUrl, 'https://example.com')
print(asizeof(a))
#> 224
b = AnyUrl.__new__(AnyOtherHttpUrl, 'https://example.com')
print(asizeof(b))
#> 120 from pydantic import BaseModel
class A(BaseModel):
url: AnyHttpUrl
class B(BaseModel):
url: AnyOtherHttpUrl
a = A(url='https://example.com')
print(asizeof(a))
#> 808
b = B(url='https://example.com')
print(asizeof(b))
#> 704 I think this is a pretty straightforward and valuable optimization and also makes a more consistent type model. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good to me, I can't see how this will break anyone's code. But I'm sure we'll have someone shouting at us about breaking code in a few weeks from some weird usage.
Let the shouting begin... 😃 We had a breaking change as we were reading the slots to be able to clone a RedisDsn and add in a password that was stored in a secret. We worked around by hard-coding the property names, but is there a better way of doing that? For reference:
|
I don't know if this would be a frequent use case, but something like copy on BaseModel would be nice:
|
Change Summary
Add an empty
__slots__
declaration toAnyUrl
and_BaseAddress
subclasses to avoid the creation of__dict__
and__weakreef__
attributes. When inheriting from a class with__slots__
, child subclasses will get a__dict__
and__weakref__
unless they also define__slots__
.Related issue number
None.
Checklist
changes/<pull request or issue id>-<github username>.md
file added describing change(see changes/README.md for details)