Skip to content
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

Model descriptors as constructor kwargs are not supported #253

Open
erwinkinn opened this issue Feb 16, 2023 · 0 comments
Open

Model descriptors as constructor kwargs are not supported #253

erwinkinn opened this issue Feb 16, 2023 · 0 comments

Comments

@erwinkinn
Copy link

Hello, I've an interesting issue and a suggestion here.
Next example is OK at runtime. It's connected with how SQLAlchemy initializes models when creates them using setattr or smth similar. So whatever attribute is passed it will be set regardless of whether such a column exists or not.

class D:
    def __set_name__(self, _, name):
        self.attr = "_" + name

    def __get__(self, obj, _):
        return getattr(obj, self.attr)

    def __set__(self, obj, v):
        setattr(obj, self.attr, v)

class M(Model):
    _x = Column(Integer)
    x = D()

def test_(s: Session):
    m = M(x=42)   # <---- Unexpected keyword argument "x" for "M"  [call-arg] mypy(error)
    s.add(m)

As it's shown we have a private field and the descriptor to get its value having some kind of additional logic.
Thanks to sqlalchemy-stubs, mypy sees problem when it is passed to __init__ a keyword that is not a column at all.
However, in the example above x field is a descriptor and it will be initialized as expected at runtime. It mimics a valid parameter and an argument to initialize a model with. You can't spot the difference from the outside.
It seems possible to support such a kind of descriptor checking, am I right?
Could it be a use case for sqlalchemy-stubs?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant