using @declared_attr does not recognize method as a classmethod unless one writes @classmethod explicitly (hence the workaround)
See original GitHub issueDescribe 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:
- Created 10 months ago
- Comments:5 (3 by maintainers)
Top 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 >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
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.
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 todef has_inherited_table(cls: Type[Union[_O, _OO]]) -> bool:
.