Mike Bayer avatar Mike Bayer committed 49a89c8

removed setup_instance() from the public API
of ClassManager, and made it a private method on
_ClassInstrumentationAdapter. ClassManager's approach
handles the default task with fewer function calls which chops off
a few hundred calls from the pertinent profile tests.

Comments (0)

Files changed (5)

lib/sqlalchemy/orm/attributes.py

         self.manager = manager
         self.obj = weakref.ref(obj, self._cleanup)
         self.dict = obj.__dict__
-        self.committed_state = {}
         self.modified = False
         self.callables = {}
+        self.expired = False
+        self.committed_state = {}
+        self.pending = {}
         self.parents = {}
-        self.pending = {}
-        self.expired = False
-
+        
     def detach(self):
         if self.session_id:
             del self.session_id
     def get_impl(self, key):
         return self.manager.get_impl(key)
 
-    def get_inst(self, key):
-        return self.manager.get_inst(key)
-
     def get_pending(self, key):
         if key not in self.pending:
             self.pending[key] = PendingCollection()
     def __call__(self):
         """__call__ allows the InstanceState to act as a deferred
         callable for loading expired attributes, which is also
-        serializable.
+        serializable (picklable).
 
         """
         unmodified = self.unmodified
         if a value was not populated in state.dict.
 
         """
+        
         self.committed_state = {}
         self.pending = {}
-
+        
         # unexpire attributes which have loaded
         if self.expired_attributes:
             for key in self.expired_attributes.intersection(self.dict):
     def get_impl(self, key):
         return self[key].impl
 
-    get_inst = dict.__getitem__
-
     @property
     def attributes(self):
         return self.itervalues()
 
     @classmethod
     def deferred_scalar_loader(cls, state, keys):
-        """TODO"""
+        """Apply a scalar loader to the given state.
+        
+        Unimplemented by default, is patched
+        by the mapper.
+        
+        """
 
     ## InstanceState management
 
     def new_instance(self, state=None):
         instance = self.class_.__new__(self.class_)
-        self.setup_instance(instance, state)
+        setattr(instance, self.STATE_ATTR, state or self.instance_state_factory(instance, self))
         return instance
 
-    def setup_instance(self, instance, with_state=None):
-        """Register an InstanceState with an instance."""
-        if self.has_state(instance):
-            state = self.state_of(instance)
-            if with_state:
-                assert state is with_state
+    def _new_state_if_none(self, instance):
+        """Install a default InstanceState if none is present.
+
+        A private convenience method used by the __init__ decorator.
+        
+        """
+        if hasattr(instance, self.STATE_ATTR):
+            return False
+        else:
+            state = self.instance_state_factory(instance, self)
+            setattr(instance, self.STATE_ATTR, state)
             return state
-        if with_state is None:
-            with_state = self.instance_state_factory(instance, self)
-        self.install_state(instance, with_state)
-        return with_state
-
-    def install_state(self, instance, state):
-        setattr(instance, self.STATE_ATTR, state)
-
-    def has_state(self, instance):
-        """True if an InstanceState is installed on the instance."""
-        return bool(getattr(instance, self.STATE_ATTR, False))
-
+    
     def state_of(self, instance):
-        """Retrieve the InstanceState of an instance.
-
-        May raise KeyError or AttributeError if no state is available.
-        """
         return getattr(instance, self.STATE_ATTR)
-
+        
     def state_getter(self):
         """Return a (instance) -> InstanceState callable.
 
         AttributeError if no InstanceState could be found for the
         instance.
         """
+
         return attrgetter(self.STATE_ATTR)
-
-    def _new_state_if_none(self, instance):
-        """Install a default InstanceState if none is present.
-
-        A private convenience method used by the __init__ decorator.
-        """
-        if self.has_state(instance):
-            return False
-        else:
-            return self.setup_instance(instance)
-
+    
+    def has_state(self, instance):
+        return hasattr(instance, self.STATE_ATTR)
+        
     def has_parent(self, state, key, optimistic=False):
         """TODO"""
         return self.get_impl(key).hasparent(state, optimistic=optimistic)
         else:
             return ClassManager.initialize_collection(self, key, state, factory)
 
-    def setup_instance(self, instance, state=None):
+    def new_instance(self, state=None):
+        instance = self.class_.__new__(self.class_)
+        self._setup_instance(instance, state)
+        return instance
+
+    def _new_state_if_none(self, instance):
+        """Install a default InstanceState if none is present.
+
+        A private convenience method used by the __init__ decorator.
+        """
+        if self.has_state(instance):
+            return False
+        else:
+            return self._setup_instance(instance)
+
+    def _setup_instance(self, instance, state=None):
         self._adapted.initialize_instance_dict(self.class_, instance)
-        state = ClassManager.setup_instance(self, instance, with_state=state)
+        
+        if state is None:
+            state = self.instance_state_factory(instance, self)
+            
+        # the given instance is assumed to have no state
+        self._adapted.install_state(self.class_, instance, state)
         state.dict = self._adapted.get_instance_dict(self.class_, instance)
         return state
 
-    def install_state(self, instance, state):
-        self._adapted.install_state(self.class_, instance, state)
-
     def state_of(self, instance):
         if hasattr(self._adapted, 'state_of'):
             return self._adapted.state_of(self.class_, instance)

lib/sqlalchemy/orm/properties.py

                 self.prop._create_joins(dest_polymorphic=True, dest_selectable=to_selectable, source_selectable=source_selectable)
 
             for k in kwargs:
-                crit = self.prop.mapper.class_manager.get_inst(k) == kwargs[k]
+                crit = self.prop.mapper.class_manager[k] == kwargs[k]
                 if criterion is None:
                     criterion = crit
                 else:

test/orm/extendedattr.py

         attributes.register_attribute(Foo, "name", uselist=False, useobject=False)
         attributes.register_attribute(Foo, "bars", uselist=True, trackparent=True, useobject=True)
 
-        assert Foo.name == attributes.manager_of_class(Foo).get_inst('name')
-        assert Foo.bars == attributes.manager_of_class(Foo).get_inst('bars')
+        assert Foo.name == attributes.manager_of_class(Foo)['name']
+        assert Foo.bars == attributes.manager_of_class(Foo)['bars']
 
     def test_alternate_finders(self):
         """Ensure the generic finder front-end deals with edge cases."""

test/profiling/zoomark_orm.py

     def test_profile_1_create_tables(self):
         self.test_baseline_1_create_tables()
 
-    @profiling.function_call_count(13636, {'2.4':12478})
+    @profiling.function_call_count(12925, {'2.4':12478})
     def test_profile_1a_populate(self):
         self.test_baseline_1a_populate()
 

test/testlib/profiling.py

                     stats.print_stats(limit)
                 else:
                     stats.print_stats()
+                #stats.print_callers()
             os.unlink(filename)
             return result
         return _function_named(profiled, fn.__name__)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.