Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
names.py336 linesDownload Raw Back to mypy
1# ext/mypy/names.py
2# Copyright (C) 2021-2026 the SQLAlchemy authors and contributors
3# <see AUTHORS file>
4#
5# This module is part of SQLAlchemy and is released under
6# the MIT License: https://www.opensource.org/licenses/mit-license.php
7
8from __future__ import annotations
9
10from typing import Dict
11from typing import List
12from typing import Optional
13from typing import Set
14from typing import Tuple
15from typing import Union
16
17from mypy.nodes import ARG_POS
18from mypy.nodes import CallExpr
19from mypy.nodes import ClassDef
20from mypy.nodes import Decorator
21from mypy.nodes import Expression
22from mypy.nodes import FuncDef
23from mypy.nodes import MemberExpr
24from mypy.nodes import NameExpr
25from mypy.nodes import OverloadedFuncDef
26from mypy.nodes import SymbolNode
27from mypy.nodes import TypeAlias
28from mypy.nodes import TypeInfo
29from mypy.plugin import SemanticAnalyzerPluginInterface
30from mypy.types import CallableType
31from mypy.types import get_proper_type
32from mypy.types import Instance
33from mypy.types import UnboundType
34
35from ... import util
36
37COLUMN: int = util.symbol("COLUMN")
38RELATIONSHIP: int = util.symbol("RELATIONSHIP")
39REGISTRY: int = util.symbol("REGISTRY")
40COLUMN_PROPERTY: int = util.symbol("COLUMN_PROPERTY")
41TYPEENGINE: int = util.symbol("TYPEENGNE")
42MAPPED: int = util.symbol("MAPPED")
43DECLARATIVE_BASE: int = util.symbol("DECLARATIVE_BASE")
44DECLARATIVE_META: int = util.symbol("DECLARATIVE_META")
45MAPPED_DECORATOR: int = util.symbol("MAPPED_DECORATOR")
46SYNONYM_PROPERTY: int = util.symbol("SYNONYM_PROPERTY")
47COMPOSITE_PROPERTY: int = util.symbol("COMPOSITE_PROPERTY")
48DECLARED_ATTR: int = util.symbol("DECLARED_ATTR")
49MAPPER_PROPERTY: int = util.symbol("MAPPER_PROPERTY")
50AS_DECLARATIVE: int = util.symbol("AS_DECLARATIVE")
51AS_DECLARATIVE_BASE: int = util.symbol("AS_DECLARATIVE_BASE")
52DECLARATIVE_MIXIN: int = util.symbol("DECLARATIVE_MIXIN")
53QUERY_EXPRESSION: int = util.symbol("QUERY_EXPRESSION")
54
55# names that must succeed with mypy.api.named_type
56NAMED_TYPE_BUILTINS_OBJECT = "builtins.object"
57NAMED_TYPE_BUILTINS_STR = "builtins.str"
58NAMED_TYPE_BUILTINS_LIST = "builtins.list"
59NAMED_TYPE_SQLA_MAPPED = "sqlalchemy.orm.base.Mapped"
60
61_RelFullNames = {
62    "sqlalchemy.orm.relationships.Relationship",
63    "sqlalchemy.orm.relationships.RelationshipProperty",
64    "sqlalchemy.orm.relationships._RelationshipDeclared",
65    "sqlalchemy.orm.Relationship",
66    "sqlalchemy.orm.RelationshipProperty",
67}
68
69_lookup: Dict[str, Tuple[int, Set[str]]] = {
70    "Column": (
71        COLUMN,
72        {
73            "sqlalchemy.sql.schema.Column",
74            "sqlalchemy.sql.Column",
75        },
76    ),
77    "Relationship": (RELATIONSHIP, _RelFullNames),
78    "RelationshipProperty": (RELATIONSHIP, _RelFullNames),
79    "_RelationshipDeclared": (RELATIONSHIP, _RelFullNames),
80    "registry": (
81        REGISTRY,
82        {
83            "sqlalchemy.orm.decl_api.registry",
84            "sqlalchemy.orm.registry",
85        },
86    ),
87    "ColumnProperty": (
88        COLUMN_PROPERTY,
89        {
90            "sqlalchemy.orm.properties.MappedSQLExpression",
91            "sqlalchemy.orm.MappedSQLExpression",
92            "sqlalchemy.orm.properties.ColumnProperty",
93            "sqlalchemy.orm.ColumnProperty",
94        },
95    ),
96    "MappedSQLExpression": (
97        COLUMN_PROPERTY,
98        {
99            "sqlalchemy.orm.properties.MappedSQLExpression",
100            "sqlalchemy.orm.MappedSQLExpression",
101            "sqlalchemy.orm.properties.ColumnProperty",
102            "sqlalchemy.orm.ColumnProperty",
103        },
104    ),
105    "Synonym": (
106        SYNONYM_PROPERTY,
107        {
108            "sqlalchemy.orm.descriptor_props.Synonym",
109            "sqlalchemy.orm.Synonym",
110            "sqlalchemy.orm.descriptor_props.SynonymProperty",
111            "sqlalchemy.orm.SynonymProperty",
112        },
113    ),
114    "SynonymProperty": (
115        SYNONYM_PROPERTY,
116        {
117            "sqlalchemy.orm.descriptor_props.Synonym",
118            "sqlalchemy.orm.Synonym",
119            "sqlalchemy.orm.descriptor_props.SynonymProperty",
120            "sqlalchemy.orm.SynonymProperty",
121        },
122    ),
123    "Composite": (
124        COMPOSITE_PROPERTY,
125        {
126            "sqlalchemy.orm.descriptor_props.Composite",
127            "sqlalchemy.orm.Composite",
128            "sqlalchemy.orm.descriptor_props.CompositeProperty",
129            "sqlalchemy.orm.CompositeProperty",
130        },
131    ),
132    "CompositeProperty": (
133        COMPOSITE_PROPERTY,
134        {
135            "sqlalchemy.orm.descriptor_props.Composite",
136            "sqlalchemy.orm.Composite",
137            "sqlalchemy.orm.descriptor_props.CompositeProperty",
138            "sqlalchemy.orm.CompositeProperty",
139        },
140    ),
141    "MapperProperty": (
142        MAPPER_PROPERTY,
143        {
144            "sqlalchemy.orm.interfaces.MapperProperty",
145            "sqlalchemy.orm.MapperProperty",
146        },
147    ),
148    "TypeEngine": (TYPEENGINE, {"sqlalchemy.sql.type_api.TypeEngine"}),
149    "Mapped": (MAPPED, {NAMED_TYPE_SQLA_MAPPED}),
150    "declarative_base": (
151        DECLARATIVE_BASE,
152        {
153            "sqlalchemy.ext.declarative.declarative_base",
154            "sqlalchemy.orm.declarative_base",
155            "sqlalchemy.orm.decl_api.declarative_base",
156        },
157    ),
158    "DeclarativeMeta": (
159        DECLARATIVE_META,
160        {
161            "sqlalchemy.ext.declarative.DeclarativeMeta",
162            "sqlalchemy.orm.DeclarativeMeta",
163            "sqlalchemy.orm.decl_api.DeclarativeMeta",
164        },
165    ),
166    "mapped": (
167        MAPPED_DECORATOR,
168        {
169            "sqlalchemy.orm.decl_api.registry.mapped",
170            "sqlalchemy.orm.registry.mapped",
171        },
172    ),
173    "as_declarative": (
174        AS_DECLARATIVE,
175        {
176            "sqlalchemy.ext.declarative.as_declarative",
177            "sqlalchemy.orm.decl_api.as_declarative",
178            "sqlalchemy.orm.as_declarative",
179        },
180    ),
181    "as_declarative_base": (
182        AS_DECLARATIVE_BASE,
183        {
184            "sqlalchemy.orm.decl_api.registry.as_declarative_base",
185            "sqlalchemy.orm.registry.as_declarative_base",
186        },
187    ),
188    "declared_attr": (
189        DECLARED_ATTR,
190        {
191            "sqlalchemy.orm.decl_api.declared_attr",
192            "sqlalchemy.orm.declared_attr",
193        },
194    ),
195    "declarative_mixin": (
196        DECLARATIVE_MIXIN,
197        {
198            "sqlalchemy.orm.decl_api.declarative_mixin",
199            "sqlalchemy.orm.declarative_mixin",
200        },
201    ),
202    "query_expression": (
203        QUERY_EXPRESSION,
204        {
205            "sqlalchemy.orm.query_expression",
206            "sqlalchemy.orm._orm_constructors.query_expression",
207        },
208    ),
209}
210
211
212def has_base_type_id(info: TypeInfo, type_id: int) -> bool:
213    for mr in info.mro:
214        check_type_id, fullnames = _lookup.get(mr.name, (None, None))
215        if check_type_id == type_id:
216            break
217    else:
218        return False
219
220    if fullnames is None:
221        return False
222
223    return mr.fullname in fullnames
224
225
226def mro_has_id(mro: List[TypeInfo], type_id: int) -> bool:
227    for mr in mro:
228        check_type_id, fullnames = _lookup.get(mr.name, (None, None))
229        if check_type_id == type_id:
230            break
231    else:
232        return False
233
234    if fullnames is None:
235        return False
236
237    return mr.fullname in fullnames
238
239
240def type_id_for_unbound_type(
241    type_: UnboundType, cls: ClassDef, api: SemanticAnalyzerPluginInterface
242) -> Optional[int]:
243    sym = api.lookup_qualified(type_.name, type_)
244    if sym is not None:
245        if isinstance(sym.node, TypeAlias):
246            target_type = get_proper_type(sym.node.target)
247            if isinstance(target_type, Instance):
248                return type_id_for_named_node(target_type.type)
249        elif isinstance(sym.node, TypeInfo):
250            return type_id_for_named_node(sym.node)
251
252    return None
253
254
255def type_id_for_callee(callee: Expression) -> Optional[int]:
256    if isinstance(callee, (MemberExpr, NameExpr)):
257        if isinstance(callee.node, Decorator) and isinstance(
258            callee.node.func, FuncDef
259        ):
260            if callee.node.func.type and isinstance(
261                callee.node.func.type, CallableType
262            ):
263                ret_type = get_proper_type(callee.node.func.type.ret_type)
264
265                if isinstance(ret_type, Instance):
266                    return type_id_for_fullname(ret_type.type.fullname)
267
268            return None
269
270        elif isinstance(callee.node, OverloadedFuncDef):
271            if (
272                callee.node.impl
273                and callee.node.impl.type
274                and isinstance(callee.node.impl.type, CallableType)
275            ):
276                ret_type = get_proper_type(callee.node.impl.type.ret_type)
277
278                if isinstance(ret_type, Instance):
279                    return type_id_for_fullname(ret_type.type.fullname)
280
281            return None
282        elif isinstance(callee.node, FuncDef):
283            if callee.node.type and isinstance(callee.node.type, CallableType):
284                ret_type = get_proper_type(callee.node.type.ret_type)
285
286                if isinstance(ret_type, Instance):
287                    return type_id_for_fullname(ret_type.type.fullname)
288
289            return None
290        elif isinstance(callee.node, TypeAlias):
291            target_type = get_proper_type(callee.node.target)
292            if isinstance(target_type, Instance):
293                return type_id_for_fullname(target_type.type.fullname)
294        elif isinstance(callee.node, TypeInfo):
295            return type_id_for_named_node(callee)
296    return None
297
298
299def type_id_for_named_node(
300    node: Union[NameExpr, MemberExpr, SymbolNode],
301) -> Optional[int]:
302    type_id, fullnames = _lookup.get(node.name, (None, None))
303
304    if type_id is None or fullnames is None:
305        return None
306    elif node.fullname in fullnames:
307        return type_id
308    else:
309        return None
310
311
312def type_id_for_fullname(fullname: str) -> Optional[int]:
313    tokens = fullname.split(".")
314    immediate = tokens[-1]
315
316    type_id, fullnames = _lookup.get(immediate, (None, None))
317
318    if type_id is None or fullnames is None:
319        return None
320    elif fullname in fullnames:
321        return type_id
322    else:
323        return None
324
325
326def expr_to_mapped_constructor(expr: Expression) -> CallExpr:
327    column_descriptor = NameExpr("__sa_Mapped")
328    column_descriptor.fullname = NAMED_TYPE_SQLA_MAPPED
329    member_expr = MemberExpr(column_descriptor, "_empty_constructor")
330    return CallExpr(
331        member_expr,
332        [expr],
333        [ARG_POS],
334        ["arg1"],
335    )
336 
codekingpro/portable-devtools · Team Ai