sqlalchemy-stubs icon indicating copy to clipboard operation
sqlalchemy-stubs copied to clipboard

Support collection_class in relationship()

Open NargiT opened this issue 6 years ago • 7 comments

I do not know if #82 will fix the issue but I have the following problem with mypy. I use typing in order to simplify coding.

repositories: Set['Repository'] = relationship('Repository', back_populates="installation", uselist=True, collection_class=set)

This is the error I get when running mypy with sqlalchemy-stubs

error: Incompatible types in assignment (expression has type "RelationshipProperty[Iterable[Repository]]", variable has type "Set['Repository']")

I also tried with InstrumentedSet which is the instance returned by relationship in my case. but no success. The code works btw, so it's really mypy that is not able to understand.

Do you think it's the scope of sqlalchemy-stubs ?

Information

python 3.6
sqlalchemy 1.3.8 Database Abstraction Library
sqlalchemy-stubs 0.2 SQLAlchemy stubs and mypy plugin
├── mypy >=0.660
│   ├── mypy-extensions >=0.4.0,<0.5.0 
│   ├── typed-ast >=1.4.0,<1.5.0 
│   └── typing-extensions >=3.7.4 
│       └── typing >=3.7.4 
└── typing-extensions >=3.6.5
    └── typing >=3.7.4

NargiT avatar Sep 13 '19 08:09 NargiT

The code works btw, so it's really mypy that is not able to understand.

x: int = 'no way' also works at runtime so not really an explanation. Have tried adding a precise annotation to that line? For example:

repositories: RelationshipProperty[Set['Repository']] = relationship('Repository', back_populates="installation", uselist=True, collection_class=set)

That one should work I hope, otherwise it is a bug in sqlalchemy-stubs.

ilevkivskyi avatar Sep 13 '19 12:09 ilevkivskyi

I will try tomorrow with your suggestion. but I am afraid that it will not behave correctly for intellisense

NargiT avatar Sep 17 '19 19:09 NargiT

The code

repositories: RelationshipProperty[Set['Repository']] = relationship('Repository', back_populates="installation", uselist=True, collection_class=set)

The error

error: Incompatible types in assignment (expression has type "RelationshipProperty[Iterable[Repository]]", variable has type "RelationshipProperty[Set[Repository]]")

NargiT avatar Sep 20 '19 06:09 NargiT

OK, the latter error can be fixed by adding support for collection_class. On one hand this doesn't look like high priority (there is a simple workaround like adding correct annotation plus a # type: ignore), but on other hand this should not be hard to fix.

ilevkivskyi avatar Sep 24 '19 20:09 ilevkivskyi

may you give more information about the "correct annotation" ?

NargiT avatar Sep 26 '19 04:09 NargiT

repositories: RelationshipProperty[Set['Repository']] = relationship('Repository', back_populates="installation", uselist=True, collection_class=set)  # type: ignore

ilevkivskyi avatar Sep 26 '19 10:09 ilevkivskyi

thx I finally had the time to try this, and I have a funny case again.

the annotation # type: ignore is line sensitive

this does not work

repositories: Set['Repository'] = relationship('Repository', back_populates="installation", uselist=True, collection_class=set,
                                                   cascade="all, delete-orphan") # type: ignore

error

src/models.py:30: error: Incompatible types in assignment (expression has type "RelationshipProperty[Iterable[Repository]]", variable has type "Set[Repository]")

this works

repositories: Set['Repository'] = relationship('Repository', back_populates="installation", uselist=True, collection_class=set,  # type: ignore
                                                   cascade="all, delete-orphan")

looks like the annotation has to be on the same line instead of the instruction. Is this wanted behaviour ?

NargiT avatar Oct 07 '19 06:10 NargiT