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.

using @declared_attr does not recognize method as a classmethod unless one writes @classmethod explicitly (hence the workaround)

See original GitHub issue

Describe the bug

Further typing refinement is required for sqlalchemy.orm.has_inherited_table as PyCharm currently complains when it’s used both directly inside the DeclarativeBase class and in Mixin classes (as the 2.0 docs suggest).

To Reproduce

from typing import Optional
from sqlalchemy.orm import DeclarativeBase, declared_attr, has_inherited_table

# Scenario 1: Directly within a DeclarativeBase class
class Base(DeclarativeBase):
    @declared_attr.directive
    def __tablename__(cls) -> Optional[str]:
        if has_inherited_table(cls):  # <- PyCharm Warning: Expected type 'Type[_O]', got 'Base' instead
            return None
        return cls.__name__.lower()

# Scenario 2: Within a Mixin class (directly from the 2.0 docs)
class Tablename:
    @declared_attr.directive
    def __tablename__(cls):
        if has_inherited_table(cls):  # <- PyCharm Warning: Expected type 'Type[_O]', got 'Tablename' instead
            return None
        return cls.__name__.lower()

Error

N/A - Non-runtime issue

Versions

  • OS: Microsoft Windows [Version 10.0.19043.2130]
  • Python: 3.7.8 (tags/v3.7.8:4b47a5b6ba, Jun 28 2020, 08:53:46) [MSC v.1916 64 bit (AMD64)] on win32
  • SQLAlchemy: 2.0.0b3
  • Database: N/A, but PostgreSQL 14
  • DBAPI (eg: psycopg, cx_oracle, mysqlclient): psycopg

Additional context

I prefer to have the logic inside the Base(DeclarativeBase) class, so the logic is applied conditionally to all mapped tables without needing a Mixin for this specific functionality.

Issue Analytics

  • State:open
  • Created 10 months ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
zzzeekcommented, Dec 1, 2022

sure but that’s not correct. there’s any number of functions one could invoke that accept a class as its argument which would all have this problem.

0reactions
caffeinatedMikecommented, Dec 1, 2022

True, I see what you mean. I know it’s not a concrete solution, but in the case of has_inherited_table it seems to be resolved by updating the the signature to def has_inherited_table(cls: Type[Union[_O, _OO]]) -> bool:.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Can't add attributes to classmethods - Stack Overflow
Now if you try to add an attribute to your method, do not write it as @classmethod def cfn(cls, *args): print(cls, *args) cfn.val...
Read more >
Issue #349 · pallets-eco/flask-sqlalchemy - GitHub
It runs at import time and ends up accessing all attributes on the model classes. My base model class has a class-level property...
Read more >
staticmethod / @classmethod (beginner + advanced) anthony ...
today I walk through what the `staticmethod` and ` classmethod ` decorators do -- I also show roughly how to implement them as...
Read more >
Declarative API — SQLAlchemy 1.3 Documentation
Given a class, return True if any of the classes it inherits from has a mapped table, otherwise return False. This is used...
Read more >
Class Attributes and Class Methods in Python OOP | Medium
In order to make this method a class method, the decorator @classmethod should be used, without this decorator, the method will be a...
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