Skip to content

Add __get__ to the column and relationship to improve usage #172

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions sqlalchemy-stubs/orm/relationships.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ from typing import Any
from typing import Callable
from typing import MutableMapping
from typing import Optional
from typing import overload
from typing import Sequence
from typing import Tuple
from typing import Type
Expand All @@ -13,6 +14,7 @@ from typing_extensions import Literal

from . import _BackrefResult
from . import attributes as attributes
from .attributes import Mapped
from .base import state_str as state_str
from .interfaces import MANYTOMANY as MANYTOMANY
from .interfaces import MANYTOONE as MANYTOONE
Expand Down Expand Up @@ -188,6 +190,12 @@ class RelationshipProperty(StrategizedProperty[_T]):
def cascade(self) -> CascadeOptions: ...
@cascade.setter
def cascade(self, cascade: Sequence[str]) -> None: ...
# NOTE: his doesn't exist at runtime, it's used when not using the plugin
# makes the inferred type of class attrs Mapped, Any for instance ones
@overload
def __get__(self, instance: None, owner: Any) -> Mapped: ...
@overload
def __get__(self, instance: object, owner: Any) -> Any: ...

class JoinCondition:
parent_persist_selectable: Any = ...
Expand Down
7 changes: 7 additions & 0 deletions sqlalchemy-stubs/sql/schema.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ from .selectable import TableClause
from .. import util
from ..engine import Connection
from ..engine import Engine
from ..orm import Mapped
from ..util import langhelpers

RETAIN_SCHEMA: langhelpers._symbol
Expand Down Expand Up @@ -246,6 +247,12 @@ class Column(DialectKWArgs, SchemaItem, ColumnClause[_TE]):
def references(self, column: Column[Any]) -> bool: ...
def append_foreign_key(self, fk: ForeignKey) -> None: ...
def copy(self: _CO, **kw: Any) -> _CO: ...
# NOTE: his doesn't exist at runtime, it's used when not using the plugin
# makes the inferred type of orm class attrs Mapped, Any for instance ones
@overload
def __get__(self, instance: None, owner: Any) -> Mapped: ...
@overload
def __get__(self, instance: object, owner: Any) -> Any: ...

class ForeignKey(DialectKWArgs, SchemaItem):
__visit_name__: str = ...
Expand Down
42 changes: 42 additions & 0 deletions test/files/orm_columns.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from typing import List
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this gets tested with the plugin installed, so isnt really tested, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but the objective it to ensure that with the plugin nothing unsurprising happens.

I've looked at it in vscode and the types are inferred correctly

from typing import Optional

from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import ForeignKey
from sqlalchemy import Text
from sqlalchemy.orm import registry
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Mapped

reg: registry = registry()


@reg.mapped
class Model:
__tablename__ = "model"

id = Column(Integer, primary_key=True)
name = Column(Text)


@reg.mapped
class Other:
__tablename__ = "other"
id = Column(Integer, primary_key=True)
model_id = Column(Integer, ForeignKey("model.id"))

model = relationship(Model, uselist=False)


col_id: Column[Integer] = Model.id
col_name: Column[Text] = Model.name
other_id: Column[Integer] = Other.id
other_mid: Column[Integer] = Other.model_id
other_model: Mapped[Model] = Other.model

inst_id: Optional[int] = Model().id
inst_name: Optional[str] = Model().name
inst_other_id: Optional[int] = Other().id
inst_other_mid: Optional[int] = Other().model_id
inst_other_model: Optional[Model] = Other().model