from . import attributes
from .. import util
-class IdentityMap(dict):
+class IdentityMap(object):
def __init__(self):
+ self._dict = {}
self._modified = set()
self._wr = weakref.ref(self)
def add(self, state):
raise NotImplementedError()
+ def _add_unpresent(self, state, key):
+ """optional inlined form of add() which can assume item isn't present
+ in the map"""
+ self.add(state)
+
def update(self, dict):
raise NotImplementedError("IdentityMap uses add() to insert data")
class WeakInstanceDict(IdentityMap):
- def __init__(self):
- IdentityMap.__init__(self)
def __getitem__(self, key):
- state = dict.__getitem__(self, key)
+ state = self._dict[key]
o = state.obj()
if o is None:
raise KeyError(key)
def __contains__(self, key):
try:
- if dict.__contains__(self, key):
- state = dict.__getitem__(self, key)
+ if key in self._dict:
+ state = self._dict[key]
o = state.obj()
else:
return False
return o is not None
def contains_state(self, state):
- return dict.get(self, state.key) is state
+ return state.key in self._dict and self._dict[state.key] is state
def replace(self, state):
- if dict.__contains__(self, state.key):
- existing = dict.__getitem__(self, state.key)
+ if state.key in self._dict:
+ existing = self._dict[state.key]
if existing is not state:
self._manage_removed_state(existing)
else:
return
- dict.__setitem__(self, state.key, state)
+ self._dict[state.key] = state
self._manage_incoming_state(state)
def add(self, state):
key = state.key
# inline of self.__contains__
- if dict.__contains__(self, key):
+ if key in self._dict:
try:
- existing_state = dict.__getitem__(self, key)
+ existing_state = self._dict[key]
if existing_state is not state:
o = existing_state.obj()
if o is not None:
return
except KeyError:
pass
- dict.__setitem__(self, key, state)
+ self._dict[key] = state
self._manage_incoming_state(state)
+ def _add_unpresent(self, state, key):
+ # inlined form of add() called by loading.py
+ self._dict[key] = state
+ state._instance_dict = self._wr
+
def get(self, key, default=None):
- state = dict.get(self, key, default)
- if state is default:
+ if key not in self._dict:
return default
+ state = self._dict[key]
o = state.obj()
if o is None:
return default
def all_states(self):
if util.py2k:
- return dict.values(self)
+ return self._dict.values()
else:
- return list(dict.values(self))
+ return list(self._dict.values())
def discard(self, state):
- st = dict.get(self, state.key, None)
- if st is state:
- dict.pop(self, state.key, None)
- self._manage_removed_state(state)
+ if state.key in self._dict:
+ st = self._dict[state.key]
+ if st is state:
+ self._dict.pop(state.key, None)
+ self._manage_removed_state(state)
def prune(self):
return 0
attributes.instance_state(self[state.key]) is state)
def replace(self, state):
- if dict.__contains__(self, state.key):
- existing = dict.__getitem__(self, state.key)
+ if state.key in self._dict:
+ existing = self._dict[state.key]
existing = attributes.instance_state(existing)
if existing is not state:
self._manage_removed_state(existing)
else:
return
- dict.__setitem__(self, state.key, state.obj())
+ self._dict[state.key] = state.obj()
self._manage_incoming_state(state)
def add(self, state):
if state.key in self:
- if attributes.instance_state(dict.__getitem__(self,
- state.key)) is not state:
+ if attributes.instance_state(self._dict[state.key]) is not state:
raise AssertionError('A conflicting state is already '
'present in the identity map for key %r'
% (state.key, ))
else:
- dict.__setitem__(self, state.key, state.obj())
+ self._dict[state.key] = state.obj()
self._manage_incoming_state(state)
+ def _add_unpresent(self, state, key):
+ # inlined form of add() called by loading.py
+ self._dict[key] = state.obj()
+ state._instance_dict = self._wr
+
def discard(self, state):
- obj = dict.get(self, state.key, None)
- if obj is not None:
+ if state.key in self._dict:
+ obj = self._dict[state.key]
st = attributes.instance_state(obj)
if st is state:
- dict.pop(self, state.key, None)
+ self._dict.pop(state.key, None)
self._manage_removed_state(state)
def prune(self):
keepers = weakref.WeakValueDictionary()
keepers.update(self)
- dict.clear(self)
- dict.update(self, keepers)
+ self._dict.clear()
+ self._dict.update(keepers)
self.modified = bool(dirty)
return ref_count - len(self)
context.progress.pop(context.refresh_state)
statelib.InstanceState._commit_all_states(
- list(context.progress.items()),
+ context.progress.items(),
session.identity_map
)
populate_existing = context.populate_existing or mapper.always_refresh
invoke_all_eagers = context.invoke_all_eagers
+ load_evt = mapper.class_manager.dispatch.load or None
+ refresh_evt = mapper.class_manager.dispatch.refresh or None
+
+ instance_state = attributes.instance_state
+ instance_dict = attributes.instance_dict
+
if mapper.allow_partial_pks:
is_not_primary_key = _none_set.issuperset
else:
instance = session_identity_map.get(identitykey)
if instance is not None:
- state = attributes.instance_state(instance)
- dict_ = attributes.instance_dict(instance)
+ state = instance_state(instance)
+ dict_ = instance_dict(instance)
isnew = state.runid != context.runid
currentload = not isnew
# when eager_defaults is True.
state = refresh_state
instance = state.obj()
- dict_ = attributes.instance_dict(instance)
+ dict_ = instance_dict(instance)
isnew = state.runid != context.runid
currentload = True
loaded_instance = False
else:
instance = mapper.class_manager.new_instance()
- dict_ = attributes.instance_dict(instance)
- state = attributes.instance_state(instance)
+ dict_ = instance_dict(instance)
+ state = instance_state(instance)
state.key = identitykey
# attach instance to session.
state.session_id = context.session.hash_key
- session_identity_map.add(state)
+ session_identity_map._add_unpresent(state, identitykey)
if currentload or populate_existing:
# state is being fully loaded, so populate.
else:
populate_state(state, dict_, row, isnew, only_load_props)
- if loaded_instance:
+ if loaded_instance and load_evt:
state.manager.dispatch.load(state, context)
- elif isnew:
+ elif isnew and refresh_evt:
state.manager.dispatch.refresh(state, context, only_load_props)
elif state in context.partials or state.unloaded or eager_populators: