summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/orm')
-rw-r--r--lib/sqlalchemy/orm/attributes.py97
-rw-r--r--lib/sqlalchemy/orm/base.py3
-rw-r--r--lib/sqlalchemy/orm/interfaces.py4
-rw-r--r--lib/sqlalchemy/orm/properties.py1
4 files changed, 68 insertions, 37 deletions
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py
index 2b4c3ec75..e9c8c511a 100644
--- a/lib/sqlalchemy/orm/attributes.py
+++ b/lib/sqlalchemy/orm/attributes.py
@@ -345,18 +345,16 @@ class Event(object):
.. versionadded:: 0.9.0
- """
-
- impl = None
- """The :class:`.AttributeImpl` which is the current event initiator.
- """
+ :var impl: The :class:`.AttributeImpl` which is the current event
+ initiator.
- op = None
- """The symbol :attr:`.OP_APPEND`, :attr:`.OP_REMOVE` or :attr:`.OP_REPLACE`,
- indicating the source operation.
+ :var op: The symbol :attr:`.OP_APPEND`, :attr:`.OP_REMOVE` or
+ :attr:`.OP_REPLACE`, indicating the source operation.
"""
+ __slots__ = 'impl', 'op', 'parent_token'
+
def __init__(self, attribute_impl, op):
self.impl = attribute_impl
self.op = op
@@ -455,6 +453,11 @@ class AttributeImpl(object):
self.expire_missing = expire_missing
+ __slots__ = (
+ 'class_', 'key', 'callable_', 'dispatch', 'trackparent',
+ 'parent_token', 'send_modified_events', 'is_equal', 'expire_missing'
+ )
+
def __str__(self):
return "%s.%s" % (self.class_.__name__, self.key)
@@ -654,6 +657,23 @@ class ScalarAttributeImpl(AttributeImpl):
supports_population = True
collection = False
+ __slots__ = '_replace_token', '_append_token', '_remove_token'
+
+ def __init__(self, *arg, **kw):
+ super(ScalarAttributeImpl, self).__init__(*arg, **kw)
+ self._replace_token = self._append_token = None
+ self._remove_token = None
+
+ def _init_append_token(self):
+ self._replace_token = self._append_token = Event(self, OP_REPLACE)
+ return self._replace_token
+
+ _init_append_or_replace_token = _init_append_token
+
+ def _init_remove_token(self):
+ self._remove_token = Event(self, OP_REMOVE)
+ return self._remove_token
+
def delete(self, state, dict_):
# TODO: catch key errors, convert to attributeerror?
@@ -692,27 +712,18 @@ class ScalarAttributeImpl(AttributeImpl):
state._modified_event(dict_, self, old)
dict_[self.key] = value
- @util.memoized_property
- def _replace_token(self):
- return Event(self, OP_REPLACE)
-
- @util.memoized_property
- def _append_token(self):
- return Event(self, OP_REPLACE)
-
- @util.memoized_property
- def _remove_token(self):
- return Event(self, OP_REMOVE)
-
def fire_replace_event(self, state, dict_, value, previous, initiator):
for fn in self.dispatch.set:
value = fn(
- state, value, previous, initiator or self._replace_token)
+ state, value, previous,
+ initiator or self._replace_token or
+ self._init_append_or_replace_token())
return value
def fire_remove_event(self, state, dict_, value, initiator):
for fn in self.dispatch.remove:
- fn(state, value, initiator or self._remove_token)
+ fn(state, value,
+ initiator or self._remove_token or self._init_remove_token())
@property
def type(self):
@@ -732,9 +743,13 @@ class ScalarObjectAttributeImpl(ScalarAttributeImpl):
supports_population = True
collection = False
+ __slots__ = ()
+
def delete(self, state, dict_):
old = self.get(state, dict_)
- self.fire_remove_event(state, dict_, old, self._remove_token)
+ self.fire_remove_event(
+ state, dict_, old,
+ self._remove_token or self._init_remove_token())
del dict_[self.key]
def get_history(self, state, dict_, passive=PASSIVE_OFF):
@@ -807,7 +822,8 @@ class ScalarObjectAttributeImpl(ScalarAttributeImpl):
self.sethasparent(instance_state(value), state, False)
for fn in self.dispatch.remove:
- fn(state, value, initiator or self._remove_token)
+ fn(state, value, initiator or
+ self._remove_token or self._init_remove_token())
state._modified_event(dict_, self, value)
@@ -819,7 +835,8 @@ class ScalarObjectAttributeImpl(ScalarAttributeImpl):
for fn in self.dispatch.set:
value = fn(
- state, value, previous, initiator or self._replace_token)
+ state, value, previous, initiator or
+ self._replace_token or self._init_append_or_replace_token())
state._modified_event(dict_, self, previous)
@@ -846,6 +863,8 @@ class CollectionAttributeImpl(AttributeImpl):
supports_population = True
collection = True
+ __slots__ = 'copy', 'collection_factory', '_append_token', '_remove_token'
+
def __init__(self, class_, key, callable_, dispatch,
typecallable=None, trackparent=False, extension=None,
copy_function=None, compare_function=None, **kwargs):
@@ -862,6 +881,8 @@ class CollectionAttributeImpl(AttributeImpl):
copy_function = self.__copy
self.copy = copy_function
self.collection_factory = typecallable
+ self._append_token = None
+ self._remove_token = None
if getattr(self.collection_factory, "_sa_linker", None):
@@ -873,6 +894,14 @@ class CollectionAttributeImpl(AttributeImpl):
def unlink(target, collection, collection_adapter):
collection._sa_linker(None)
+ def _init_append_token(self):
+ self._append_token = Event(self, OP_APPEND)
+ return self._append_token
+
+ def _init_remove_token(self):
+ self._remove_token = Event(self, OP_REMOVE)
+ return self._remove_token
+
def __copy(self, item):
return [y for y in collections.collection_adapter(item)]
@@ -915,17 +944,11 @@ class CollectionAttributeImpl(AttributeImpl):
return [(instance_state(o), o) for o in current]
- @util.memoized_property
- def _append_token(self):
- return Event(self, OP_APPEND)
-
- @util.memoized_property
- def _remove_token(self):
- return Event(self, OP_REMOVE)
-
def fire_append_event(self, state, dict_, value, initiator):
for fn in self.dispatch.append:
- value = fn(state, value, initiator or self._append_token)
+ value = fn(
+ state, value,
+ initiator or self._append_token or self._init_append_token())
state._modified_event(dict_, self, NEVER_SET, True)
@@ -942,7 +965,8 @@ class CollectionAttributeImpl(AttributeImpl):
self.sethasparent(instance_state(value), state, False)
for fn in self.dispatch.remove:
- fn(state, value, initiator or self._remove_token)
+ fn(state, value,
+ initiator or self._remove_token or self._init_remove_token())
state._modified_event(dict_, self, NEVER_SET, True)
@@ -1134,7 +1158,8 @@ def backref_listeners(attribute, key, uselist):
impl.pop(old_state,
old_dict,
state.obj(),
- parent_impl._append_token,
+ parent_impl._append_token or
+ parent_impl._init_append_token(),
passive=PASSIVE_NO_FETCH)
if child is not None:
diff --git a/lib/sqlalchemy/orm/base.py b/lib/sqlalchemy/orm/base.py
index 3390ceec4..afeeba322 100644
--- a/lib/sqlalchemy/orm/base.py
+++ b/lib/sqlalchemy/orm/base.py
@@ -438,6 +438,8 @@ class InspectionAttr(object):
"""
+ __slots__ = ()
+
is_selectable = False
"""Return True if this object is an instance of :class:`.Selectable`."""
@@ -520,3 +522,4 @@ class _MappedAttribute(object):
attributes.
"""
+ __slots__ = ()
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py
index ad2452c1b..bff73258c 100644
--- a/lib/sqlalchemy/orm/interfaces.py
+++ b/lib/sqlalchemy/orm/interfaces.py
@@ -303,6 +303,8 @@ class PropComparator(operators.ColumnOperators):
"""
+ __slots__ = 'prop', 'property', '_parentmapper', '_adapt_to_entity'
+
def __init__(self, prop, parentmapper, adapt_to_entity=None):
self.prop = self.property = prop
self._parentmapper = parentmapper
@@ -331,7 +333,7 @@ class PropComparator(operators.ColumnOperators):
else:
return self._adapt_to_entity._adapt_element
- @util.memoized_property
+ @property
def info(self):
return self.property.info
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py
index 62ea93fb3..291fabdd0 100644
--- a/lib/sqlalchemy/orm/properties.py
+++ b/lib/sqlalchemy/orm/properties.py
@@ -224,6 +224,7 @@ class ColumnProperty(StrategizedProperty):
:attr:`.TypeEngine.comparator_factory`
"""
+
@util.memoized_instancemethod
def __clause_element__(self):
if self.adapter: