python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
17.88k stars 2.74k forks source link

CRASH SQLAlchemy relationship with any arguments #17033

Closed Buczek05 closed 3 months ago

Buczek05 commented 3 months ago

Crash Report

mypy ./ --show-traceback                                                                                                                                                                                                                                                
./mwl_cost/core/db/invoice.py:28: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 1.10.0+dev.a18a0db0c77e71050aaf31a53ad1fba8c663fd1a
Traceback (most recent call last):
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/bin/mypy", line 8, in <module>
    sys.exit(console_entry())
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/__main__.py", line 15, in console_entry
    main()
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/main.py", line 100, in main
    res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/main.py", line 182, in run_build
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/build.py", line 192, in build
    result = _build(
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/build.py", line 266, in _build
    graph = dispatch(sources, manager, stdout)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/build.py", line 2942, in dispatch
    process_graph(graph, manager)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/build.py", line 3340, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/build.py", line 3435, in process_stale_scc
    mypy.semanal_main.semantic_analysis_for_scc(graph, scc, manager.errors)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/semanal_main.py", line 93, in semantic_analysis_for_scc
    process_top_levels(graph, scc, patches)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/semanal_main.py", line 220, in process_top_levels
    deferred, incomplete, progress = semantic_analyze_target(
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/semanal_main.py", line 349, in semantic_analyze_target
    analyzer.refresh_partial(
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/semanal.py", line 599, in refresh_partial
    self.refresh_top_level(node)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/semanal.py", line 610, in refresh_top_level
    self.accept(d)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/semanal.py", line 6695, in accept
    node.accept(self)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/nodes.py", line 1142, in accept
    return visitor.visit_class_def(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/semanal.py", line 1621, in visit_class_def
    self.analyze_class(defn)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/semanal.py", line 1706, in analyze_class
    self.analyze_class_body_common(defn)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/semanal.py", line 1740, in analyze_class_body_common
    self.apply_class_plugin_hooks(defn)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/mypy/semanal.py", line 1825, in apply_class_plugin_hooks
    hook(ClassDefContext(defn, base_expr, self))
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/sqlalchemy/ext/mypy/plugin.py", line 277, in _base_cls_hook
    decl_class.scan_declarative_assignments_and_apply_types(ctx.cls, ctx.api)
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/sqlalchemy/ext/mypy/decl_class.py", line 97, in scan_declarative_assignments_and_apply_types
    _scan_declarative_assignment_stmt(
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/sqlalchemy/ext/mypy/decl_class.py", line 458, in _scan_declarative_assignment_stmt
    python_type_for_type = infer.infer_type_from_right_hand_nameexpr(
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/sqlalchemy/ext/mypy/infer.py", line 59, in infer_type_from_right_hand_nameexpr
    python_type_for_type = _infer_type_from_relationship(
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/bukowski/Library/Caches/pypoetry/virtualenvs/mwl-cost-Ajo0IwpA-py3.12/lib/python3.12/site-packages/sqlalchemy/ext/mypy/infer.py", line 111, in _infer_type_from_relationship
    target_cls_arg = stmt.rvalue.args[0]
                     ~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range
./mwl_cost/core/db/invoice.py:28: : note: use --pdb to drop into pdb

Traceback

(Insert traceback and other messages from mypy here -- use `--show-traceback`.)

To Reproduce

exchange_table: Mapped[Optional["ExchangeTable"]] = relationship()
when using sqlalchemy relationship with any arguments

Your Environment

[tool.poetry.dependencies]
python = "^3.12"
loguru = "^0.7.2"
fastapi = "^0.109.2"
boto3 = "^1.34.43"
tomli = "^2.0.1"
pydantic = "^2.6.1"
pydantic-settings = "^2.1.0"
httpx = "^0.26.0"
uvicorn = "^0.27.1"
sqlalchemy = "^2.0.27"
alembic = "^1.13.1"
psycopg2-binary = "^2.9.9"
psycopg2 = "^2.9.9"
pytz = "^2024.1"
asyncpg = "^0.29.0"
pandas = "^2.2.1"
openpyxl = "^3.1.2"
xlrd = "^2.0.1"
numpy = "^1.26.4"
aio-pika = "^9.4.0"
celery = "^5.3.6"

[tool.poetry.group.dev.dependencies]
pytest = "^8.0.0"
mypy = "^1.8.0"
ruff = "^0.2.1"
coverage = "^7.4.1"
tox = "^4.12.1"
pytest-asyncio = "^0.23.5"
sqlalchemy-utils = "^0.41.1"
factory-boy = "^3.3.0"
pytest-mock = "^3.12.0"
types-requests = "^2.31.0.20240218"
requests = "^2.31.0"
pandas-stubs = "^2.2.0.240218"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.mypy]
python_version = "3.12"
disallow_untyped_defs = true
show_error_codes = true
no_implicit_optional = true
warn_return_any = true
warn_unused_ignores = true
warn_unused_configs = true
plugins = ["sqlalchemy.ext.mypy.plugin"]

[[tool.mypy.overrides]]
module = [
    "boto3",
    "sqlalchemy_utils",
    "async_factory_boy.*",
    "factory.*",
    "pytz",
    "botocore.exceptions",
    "kombu.*",
    "celery.*",
]
ignore_missing_imports = true

[[tool.mypy.overrides]]
module = "mwl_cost.migrations.versions.*"
ignore_errors = true

[tool.ruff]
lint.select = ["E", "F", "UP", "B", "SIM", "I"]
lint.ignore = ["UP007", "B008"]
line-length = 120
target-version = "py312"

[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401", "F403", "E402"]

[tool.pytest.ini_options]
filterwarnings = [
    "ignore::DeprecationWarning:openpyxl.*:",
    "ignore::DeprecationWarning:botocore.*:",
    "ignore::DeprecationWarning:aio_pika.*:",
    "ignore::DeprecationWarning:pytest_asyncio.plugin:",
]
AlexWaygood commented 3 months ago

Thanks! It looks from the traceback like this is a bug in the sqlalchemy mypy plugin, so this should probably be reported over at their repo unfortunately.