diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-03-16 15:03:22 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-03-16 15:14:00 -0400 |
| commit | d386552d11ea697463211c1499b2bee2f5548be7 (patch) | |
| tree | f07f03c7bd96bb2573605acc720b0425e5dc0a6c /lib/sqlalchemy | |
| parent | c949312bc1a1980da016918d9c4b002b68062fca (diff) | |
| download | sqlalchemy-d386552d11ea697463211c1499b2bee2f5548be7.tar.gz | |
Early-assign Base.registry to a private name
Fixed bug where user-mapped classes that contained an attribute named
"registry" would cause conflicts with the new registry-based mapping system
when using :class:`.DeclarativeMeta`. While the attribute remains
something that can be set explicitly on a declarative base to be
consumed by the metaclass, once located it is placed under a private
class variable so it does not conflict with future subclasses that use
the same name for other purposes.
Fixes: #6054
Change-Id: I1f2e04b0d74c493e7e90eadead4e861d8960a794
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/orm/decl_api.py | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/lib/sqlalchemy/orm/decl_api.py b/lib/sqlalchemy/orm/decl_api.py index 1166d307e..0266c973a 100644 --- a/lib/sqlalchemy/orm/decl_api.py +++ b/lib/sqlalchemy/orm/decl_api.py @@ -25,6 +25,7 @@ from .decl_base import _DeferredMapperConfig from .decl_base import _del_attribute from .decl_base import _mapper from .descriptor_props import SynonymProperty as _orm_synonym +from .. import exc from .. import inspection from .. import util from ..sql.schema import MetaData @@ -56,8 +57,22 @@ def has_inherited_table(cls): class DeclarativeMeta(type): def __init__(cls, classname, bases, dict_, **kw): + # early-consume registry from the initial declarative base, + # assign privately to not conflict with subclass attributes named + # "registry" + reg = getattr(cls, "_sa_registry", None) + if reg is None: + reg = dict_.get("registry", None) + if not isinstance(reg, registry): + raise exc.InvalidRequestError( + "Declarative base class has no 'registry' attribute, " + "or registry is not a sqlalchemy.orm.registry() object" + ) + else: + cls._sa_registry = reg + if not cls.__dict__.get("__abstract__", False): - _as_declarative(cls.registry, cls, cls.__dict__) + _as_declarative(reg, cls, dict_) type.__init__(cls, classname, bases, dict_) def __setattr__(cls, key, value): |
