summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2021-03-16 15:03:22 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2021-03-16 15:14:00 -0400
commitd386552d11ea697463211c1499b2bee2f5548be7 (patch)
treef07f03c7bd96bb2573605acc720b0425e5dc0a6c /lib/sqlalchemy
parentc949312bc1a1980da016918d9c4b002b68062fca (diff)
downloadsqlalchemy-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.py17
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):