question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

mypy plugin: infer relationship information for models specified as strings

See original GitHub issue

Is your feature request related to a problem? Please describe.

Currently the mypy plugin can infer types/information for a relationship when the model parameter is an actual class value, but cannot do so when it is a string:

from sqlalchemy import Column, Integer, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import as_declarative
from typing import List, Optional

@as_declarative()
class Base:
    pass

class Foo(Base):
    id = Column(Integer(), primary_key=True)
    bars = relationship("Bar", back_populates="foo", uselist=True)
    # error, must be: bars: List["Bar"] = relationship("Bar", back_populates="foo", uselist=True)

class Bar(Base):
    id = Column(Integer(), primary_key=True)
    foo_id: Optional[int] = Column(ForeignKey(Foo.id))
    foo = relationship(Foo, back_populates="bars", uselist=False)

# successful inference:
reveal_type(Bar().foo) # Union[test2.Foo, None]

Describe the solution you’d like

In https://github.com/sqlalchemy/sqlalchemy/discussions/6372, we discussed that string parameters could be handled via doing a name lookup in the current module, similar to the plugin in https://github.com/dropbox/sqlalchemy-stubs. This requires the other model name being imported (potentially in an if TYPE_CHECKING: block), but that’s okay: doing the explicit type annotation also requires the name being in scope for mypy.

(This approach could potentially be used for Column(ForeignKey("Abc.def"), ...) too, but it was mentioned in #6372 that doing the .def lookup might be hard.)

Describe alternatives you’ve considered

The current situation of annotating the type explicitly is a little suboptimal, as the plugin doesn’t validate, that, for instance, the collection types are correct. Another option would to have the righthand side be partially inferred, e.g. list[_] and then do a type join between LHS and RHS; if the LHS annotation is list[Bar], then the join will be successful, but if it’s very wrong (e.g. just Bar), then the join(Bar, list[_]) will not be possible an error can be reported.

Additional context N/A

Have a nice day! you too 😄

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
CaselITcommented, Jun 17, 2022

I guess we can close as will not fix since v2 will not use the plugin

0reactions
zzzeekcommented, Jun 18, 2022

it’s all in 2.0 now, docs are not up yet save for the quickstart at https://docs.sqlalchemy.org/en/20/orm/quickstart.html where you can see relationship() works in the most minimal way possible, inferring the class from the string annotation.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Mypy / Pep-484 Support for ORM Mappings
The primary purpose of the Mypy plugin is to intercept and alter the static definition of SQLAlchemy declarative mappings so that they match...
Read more >
How can I disable the bundled SQLAlchemy stubs? · Issue #837
My code is incompatible with the SQLAlchemy stubs bundled in the latest version of Pylance. Is there a way to disable these via...
Read more >
Mypy Documentation - Read the Docs
Mypy has a powerful and easy-to-use type system, supporting features such as type inference, generics, callable types, tuple types, union types ...
Read more >
Type inference and type annotations - Mypy documentation
For most variables, if you do not explicitly specify its type, mypy will infer the correct type based on what is initially assigned...
Read more >
SqlAlchemy Mypy undefined definition error - Stack Overflow
Our solution, which isn't particularly elegant, but gets the job done, is to allow using string literals in annotations.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found