You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					417 lines
				
				14 KiB
			
		
		
			
		
	
	
					417 lines
				
				14 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								"""Extensible class instrumentation.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The :mod:`sqlalchemy.ext.instrumentation` package provides for alternate
							 | 
						||
| 
								 | 
							
								systems of class instrumentation within the ORM.  Class instrumentation
							 | 
						||
| 
								 | 
							
								refers to how the ORM places attributes on the class which maintain
							 | 
						||
| 
								 | 
							
								data and track changes to that data, as well as event hooks installed
							 | 
						||
| 
								 | 
							
								on the class.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.. note::
							 | 
						||
| 
								 | 
							
								    The extension package is provided for the benefit of integration
							 | 
						||
| 
								 | 
							
								    with other object management packages, which already perform
							 | 
						||
| 
								 | 
							
								    their own instrumentation.  It is not intended for general use.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								For examples of how the instrumentation extension is used,
							 | 
						||
| 
								 | 
							
								see the example :ref:`examples_instrumentation`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								"""
							 | 
						||
| 
								 | 
							
								import weakref
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								from .. import util
							 | 
						||
| 
								 | 
							
								from ..orm import attributes
							 | 
						||
| 
								 | 
							
								from ..orm import base as orm_base
							 | 
						||
| 
								 | 
							
								from ..orm import collections
							 | 
						||
| 
								 | 
							
								from ..orm import exc as orm_exc
							 | 
						||
| 
								 | 
							
								from ..orm import instrumentation as orm_instrumentation
							 | 
						||
| 
								 | 
							
								from ..orm.instrumentation import _default_dict_getter
							 | 
						||
| 
								 | 
							
								from ..orm.instrumentation import _default_manager_getter
							 | 
						||
| 
								 | 
							
								from ..orm.instrumentation import _default_state_getter
							 | 
						||
| 
								 | 
							
								from ..orm.instrumentation import ClassManager
							 | 
						||
| 
								 | 
							
								from ..orm.instrumentation import InstrumentationFactory
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								INSTRUMENTATION_MANAGER = "__sa_instrumentation_manager__"
							 | 
						||
| 
								 | 
							
								"""Attribute, elects custom instrumentation when present on a mapped class.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Allows a class to specify a slightly or wildly different technique for
							 | 
						||
| 
								 | 
							
								tracking changes made to mapped attributes and collections.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Only one instrumentation implementation is allowed in a given object
							 | 
						||
| 
								 | 
							
								inheritance hierarchy.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The value of this attribute must be a callable and will be passed a class
							 | 
						||
| 
								 | 
							
								object.  The callable must return one of:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  - An instance of an :class:`.InstrumentationManager` or subclass
							 | 
						||
| 
								 | 
							
								  - An object implementing all or some of InstrumentationManager (TODO)
							 | 
						||
| 
								 | 
							
								  - A dictionary of callables, implementing all or some of the above (TODO)
							 | 
						||
| 
								 | 
							
								  - An instance of a :class:`.ClassManager` or subclass
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This attribute is consulted by SQLAlchemy instrumentation
							 | 
						||
| 
								 | 
							
								resolution, once the :mod:`sqlalchemy.ext.instrumentation` module
							 | 
						||
| 
								 | 
							
								has been imported.  If custom finders are installed in the global
							 | 
						||
| 
								 | 
							
								instrumentation_finders list, they may or may not choose to honor this
							 | 
						||
| 
								 | 
							
								attribute.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								"""
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def find_native_user_instrumentation_hook(cls):
							 | 
						||
| 
								 | 
							
								    """Find user-specified instrumentation management for a class."""
							 | 
						||
| 
								 | 
							
								    return getattr(cls, INSTRUMENTATION_MANAGER, None)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								instrumentation_finders = [find_native_user_instrumentation_hook]
							 | 
						||
| 
								 | 
							
								"""An extensible sequence of callables which return instrumentation
							 | 
						||
| 
								 | 
							
								implementations
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								When a class is registered, each callable will be passed a class object.
							 | 
						||
| 
								 | 
							
								If None is returned, the
							 | 
						||
| 
								 | 
							
								next finder in the sequence is consulted.  Otherwise the return must be an
							 | 
						||
| 
								 | 
							
								instrumentation factory that follows the same guidelines as
							 | 
						||
| 
								 | 
							
								sqlalchemy.ext.instrumentation.INSTRUMENTATION_MANAGER.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								By default, the only finder is find_native_user_instrumentation_hook, which
							 | 
						||
| 
								 | 
							
								searches for INSTRUMENTATION_MANAGER.  If all finders return None, standard
							 | 
						||
| 
								 | 
							
								ClassManager instrumentation is used.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								"""
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class ExtendedInstrumentationRegistry(InstrumentationFactory):
							 | 
						||
| 
								 | 
							
								    """Extends :class:`.InstrumentationFactory` with additional
							 | 
						||
| 
								 | 
							
								    bookkeeping, to accommodate multiple types of
							 | 
						||
| 
								 | 
							
								    class managers.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    _manager_finders = weakref.WeakKeyDictionary()
							 | 
						||
| 
								 | 
							
								    _state_finders = weakref.WeakKeyDictionary()
							 | 
						||
| 
								 | 
							
								    _dict_finders = weakref.WeakKeyDictionary()
							 | 
						||
| 
								 | 
							
								    _extended = False
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def _locate_extended_factory(self, class_):
							 | 
						||
| 
								 | 
							
								        for finder in instrumentation_finders:
							 | 
						||
| 
								 | 
							
								            factory = finder(class_)
							 | 
						||
| 
								 | 
							
								            if factory is not None:
							 | 
						||
| 
								 | 
							
								                manager = self._extended_class_manager(class_, factory)
							 | 
						||
| 
								 | 
							
								                return manager, factory
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            return None, None
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def _check_conflicts(self, class_, factory):
							 | 
						||
| 
								 | 
							
								        existing_factories = self._collect_management_factories_for(
							 | 
						||
| 
								 | 
							
								            class_
							 | 
						||
| 
								 | 
							
								        ).difference([factory])
							 | 
						||
| 
								 | 
							
								        if existing_factories:
							 | 
						||
| 
								 | 
							
								            raise TypeError(
							 | 
						||
| 
								 | 
							
								                "multiple instrumentation implementations specified "
							 | 
						||
| 
								 | 
							
								                "in %s inheritance hierarchy: %r"
							 | 
						||
| 
								 | 
							
								                % (class_.__name__, list(existing_factories))
							 | 
						||
| 
								 | 
							
								            )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def _extended_class_manager(self, class_, factory):
							 | 
						||
| 
								 | 
							
								        manager = factory(class_)
							 | 
						||
| 
								 | 
							
								        if not isinstance(manager, ClassManager):
							 | 
						||
| 
								 | 
							
								            manager = _ClassInstrumentationAdapter(class_, manager)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if factory != ClassManager and not self._extended:
							 | 
						||
| 
								 | 
							
								            # somebody invoked a custom ClassManager.
							 | 
						||
| 
								 | 
							
								            # reinstall global "getter" functions with the more
							 | 
						||
| 
								 | 
							
								            # expensive ones.
							 | 
						||
| 
								 | 
							
								            self._extended = True
							 | 
						||
| 
								 | 
							
								            _install_instrumented_lookups()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        self._manager_finders[class_] = manager.manager_getter()
							 | 
						||
| 
								 | 
							
								        self._state_finders[class_] = manager.state_getter()
							 | 
						||
| 
								 | 
							
								        self._dict_finders[class_] = manager.dict_getter()
							 | 
						||
| 
								 | 
							
								        return manager
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def _collect_management_factories_for(self, cls):
							 | 
						||
| 
								 | 
							
								        """Return a collection of factories in play or specified for a
							 | 
						||
| 
								 | 
							
								        hierarchy.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Traverses the entire inheritance graph of a cls and returns a
							 | 
						||
| 
								 | 
							
								        collection of instrumentation factories for those classes. Factories
							 | 
						||
| 
								 | 
							
								        are extracted from active ClassManagers, if available, otherwise
							 | 
						||
| 
								 | 
							
								        instrumentation_finders is consulted.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        """
							 | 
						||
| 
								 | 
							
								        hierarchy = util.class_hierarchy(cls)
							 | 
						||
| 
								 | 
							
								        factories = set()
							 | 
						||
| 
								 | 
							
								        for member in hierarchy:
							 | 
						||
| 
								 | 
							
								            manager = self.manager_of_class(member)
							 | 
						||
| 
								 | 
							
								            if manager is not None:
							 | 
						||
| 
								 | 
							
								                factories.add(manager.factory)
							 | 
						||
| 
								 | 
							
								            else:
							 | 
						||
| 
								 | 
							
								                for finder in instrumentation_finders:
							 | 
						||
| 
								 | 
							
								                    factory = finder(member)
							 | 
						||
| 
								 | 
							
								                    if factory is not None:
							 | 
						||
| 
								 | 
							
								                        break
							 | 
						||
| 
								 | 
							
								                else:
							 | 
						||
| 
								 | 
							
								                    factory = None
							 | 
						||
| 
								 | 
							
								                factories.add(factory)
							 | 
						||
| 
								 | 
							
								        factories.discard(None)
							 | 
						||
| 
								 | 
							
								        return factories
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def unregister(self, class_):
							 | 
						||
| 
								 | 
							
								        super(ExtendedInstrumentationRegistry, self).unregister(class_)
							 | 
						||
| 
								 | 
							
								        if class_ in self._manager_finders:
							 | 
						||
| 
								 | 
							
								            del self._manager_finders[class_]
							 | 
						||
| 
								 | 
							
								            del self._state_finders[class_]
							 | 
						||
| 
								 | 
							
								            del self._dict_finders[class_]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def manager_of_class(self, cls):
							 | 
						||
| 
								 | 
							
								        if cls is None:
							 | 
						||
| 
								 | 
							
								            return None
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            finder = self._manager_finders.get(cls, _default_manager_getter)
							 | 
						||
| 
								 | 
							
								        except TypeError:
							 | 
						||
| 
								 | 
							
								            # due to weakref lookup on invalid object
							 | 
						||
| 
								 | 
							
								            return None
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            return finder(cls)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def state_of(self, instance):
							 | 
						||
| 
								 | 
							
								        if instance is None:
							 | 
						||
| 
								 | 
							
								            raise AttributeError("None has no persistent state.")
							 | 
						||
| 
								 | 
							
								        return self._state_finders.get(
							 | 
						||
| 
								 | 
							
								            instance.__class__, _default_state_getter
							 | 
						||
| 
								 | 
							
								        )(instance)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def dict_of(self, instance):
							 | 
						||
| 
								 | 
							
								        if instance is None:
							 | 
						||
| 
								 | 
							
								            raise AttributeError("None has no persistent state.")
							 | 
						||
| 
								 | 
							
								        return self._dict_finders.get(
							 | 
						||
| 
								 | 
							
								            instance.__class__, _default_dict_getter
							 | 
						||
| 
								 | 
							
								        )(instance)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								orm_instrumentation._instrumentation_factory = (
							 | 
						||
| 
								 | 
							
								    _instrumentation_factory
							 | 
						||
| 
								 | 
							
								) = ExtendedInstrumentationRegistry()
							 | 
						||
| 
								 | 
							
								orm_instrumentation.instrumentation_finders = instrumentation_finders
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class InstrumentationManager(object):
							 | 
						||
| 
								 | 
							
								    """User-defined class instrumentation extension.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    :class:`.InstrumentationManager` can be subclassed in order
							 | 
						||
| 
								 | 
							
								    to change
							 | 
						||
| 
								 | 
							
								    how class instrumentation proceeds. This class exists for
							 | 
						||
| 
								 | 
							
								    the purposes of integration with other object management
							 | 
						||
| 
								 | 
							
								    frameworks which would like to entirely modify the
							 | 
						||
| 
								 | 
							
								    instrumentation methodology of the ORM, and is not intended
							 | 
						||
| 
								 | 
							
								    for regular usage.  For interception of class instrumentation
							 | 
						||
| 
								 | 
							
								    events, see :class:`.InstrumentationEvents`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    The API for this class should be considered as semi-stable,
							 | 
						||
| 
								 | 
							
								    and may change slightly with new releases.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # r4361 added a mandatory (cls) constructor to this interface.
							 | 
						||
| 
								 | 
							
								    # given that, perhaps class_ should be dropped from all of these
							 | 
						||
| 
								 | 
							
								    # signatures.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __init__(self, class_):
							 | 
						||
| 
								 | 
							
								        pass
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def manage(self, class_, manager):
							 | 
						||
| 
								 | 
							
								        setattr(class_, "_default_class_manager", manager)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def unregister(self, class_, manager):
							 | 
						||
| 
								 | 
							
								        delattr(class_, "_default_class_manager")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def manager_getter(self, class_):
							 | 
						||
| 
								 | 
							
								        def get(cls):
							 | 
						||
| 
								 | 
							
								            return cls._default_class_manager
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return get
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def instrument_attribute(self, class_, key, inst):
							 | 
						||
| 
								 | 
							
								        pass
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def post_configure_attribute(self, class_, key, inst):
							 | 
						||
| 
								 | 
							
								        pass
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def install_descriptor(self, class_, key, inst):
							 | 
						||
| 
								 | 
							
								        setattr(class_, key, inst)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def uninstall_descriptor(self, class_, key):
							 | 
						||
| 
								 | 
							
								        delattr(class_, key)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def install_member(self, class_, key, implementation):
							 | 
						||
| 
								 | 
							
								        setattr(class_, key, implementation)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def uninstall_member(self, class_, key):
							 | 
						||
| 
								 | 
							
								        delattr(class_, key)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def instrument_collection_class(self, class_, key, collection_class):
							 | 
						||
| 
								 | 
							
								        return collections.prepare_instrumentation(collection_class)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def get_instance_dict(self, class_, instance):
							 | 
						||
| 
								 | 
							
								        return instance.__dict__
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def initialize_instance_dict(self, class_, instance):
							 | 
						||
| 
								 | 
							
								        pass
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def install_state(self, class_, instance, state):
							 | 
						||
| 
								 | 
							
								        setattr(instance, "_default_state", state)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def remove_state(self, class_, instance):
							 | 
						||
| 
								 | 
							
								        delattr(instance, "_default_state")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def state_getter(self, class_):
							 | 
						||
| 
								 | 
							
								        return lambda instance: getattr(instance, "_default_state")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def dict_getter(self, class_):
							 | 
						||
| 
								 | 
							
								        return lambda inst: self.get_instance_dict(class_, inst)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class _ClassInstrumentationAdapter(ClassManager):
							 | 
						||
| 
								 | 
							
								    """Adapts a user-defined InstrumentationManager to a ClassManager."""
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __init__(self, class_, override):
							 | 
						||
| 
								 | 
							
								        self._adapted = override
							 | 
						||
| 
								 | 
							
								        self._get_state = self._adapted.state_getter(class_)
							 | 
						||
| 
								 | 
							
								        self._get_dict = self._adapted.dict_getter(class_)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ClassManager.__init__(self, class_)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def manage(self):
							 | 
						||
| 
								 | 
							
								        self._adapted.manage(self.class_, self)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def unregister(self):
							 | 
						||
| 
								 | 
							
								        self._adapted.unregister(self.class_, self)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def manager_getter(self):
							 | 
						||
| 
								 | 
							
								        return self._adapted.manager_getter(self.class_)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def instrument_attribute(self, key, inst, propagated=False):
							 | 
						||
| 
								 | 
							
								        ClassManager.instrument_attribute(self, key, inst, propagated)
							 | 
						||
| 
								 | 
							
								        if not propagated:
							 | 
						||
| 
								 | 
							
								            self._adapted.instrument_attribute(self.class_, key, inst)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def post_configure_attribute(self, key):
							 | 
						||
| 
								 | 
							
								        super(_ClassInstrumentationAdapter, self).post_configure_attribute(key)
							 | 
						||
| 
								 | 
							
								        self._adapted.post_configure_attribute(self.class_, key, self[key])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def install_descriptor(self, key, inst):
							 | 
						||
| 
								 | 
							
								        self._adapted.install_descriptor(self.class_, key, inst)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def uninstall_descriptor(self, key):
							 | 
						||
| 
								 | 
							
								        self._adapted.uninstall_descriptor(self.class_, key)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def install_member(self, key, implementation):
							 | 
						||
| 
								 | 
							
								        self._adapted.install_member(self.class_, key, implementation)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def uninstall_member(self, key):
							 | 
						||
| 
								 | 
							
								        self._adapted.uninstall_member(self.class_, key)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def instrument_collection_class(self, key, collection_class):
							 | 
						||
| 
								 | 
							
								        return self._adapted.instrument_collection_class(
							 | 
						||
| 
								 | 
							
								            self.class_, key, collection_class
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def initialize_collection(self, key, state, factory):
							 | 
						||
| 
								 | 
							
								        delegate = getattr(self._adapted, "initialize_collection", None)
							 | 
						||
| 
								 | 
							
								        if delegate:
							 | 
						||
| 
								 | 
							
								            return delegate(key, state, factory)
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            return ClassManager.initialize_collection(
							 | 
						||
| 
								 | 
							
								                self, key, state, factory
							 | 
						||
| 
								 | 
							
								            )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    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)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if state is None:
							 | 
						||
| 
								 | 
							
								            state = self._state_constructor(instance, self)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # the given instance is assumed to have no state
							 | 
						||
| 
								 | 
							
								        self._adapted.install_state(self.class_, instance, state)
							 | 
						||
| 
								 | 
							
								        return state
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def teardown_instance(self, instance):
							 | 
						||
| 
								 | 
							
								        self._adapted.remove_state(self.class_, instance)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def has_state(self, instance):
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            self._get_state(instance)
							 | 
						||
| 
								 | 
							
								        except orm_exc.NO_STATE:
							 | 
						||
| 
								 | 
							
								            return False
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            return True
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def state_getter(self):
							 | 
						||
| 
								 | 
							
								        return self._get_state
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def dict_getter(self):
							 | 
						||
| 
								 | 
							
								        return self._get_dict
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def _install_instrumented_lookups():
							 | 
						||
| 
								 | 
							
								    """Replace global class/object management functions
							 | 
						||
| 
								 | 
							
								    with ExtendedInstrumentationRegistry implementations, which
							 | 
						||
| 
								 | 
							
								    allow multiple types of class managers to be present,
							 | 
						||
| 
								 | 
							
								    at the cost of performance.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    This function is called only by ExtendedInstrumentationRegistry
							 | 
						||
| 
								 | 
							
								    and unit tests specific to this behavior.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    The _reinstall_default_lookups() function can be called
							 | 
						||
| 
								 | 
							
								    after this one to re-establish the default functions.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								    _install_lookups(
							 | 
						||
| 
								 | 
							
								        dict(
							 | 
						||
| 
								 | 
							
								            instance_state=_instrumentation_factory.state_of,
							 | 
						||
| 
								 | 
							
								            instance_dict=_instrumentation_factory.dict_of,
							 | 
						||
| 
								 | 
							
								            manager_of_class=_instrumentation_factory.manager_of_class,
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def _reinstall_default_lookups():
							 | 
						||
| 
								 | 
							
								    """Restore simplified lookups."""
							 | 
						||
| 
								 | 
							
								    _install_lookups(
							 | 
						||
| 
								 | 
							
								        dict(
							 | 
						||
| 
								 | 
							
								            instance_state=_default_state_getter,
							 | 
						||
| 
								 | 
							
								            instance_dict=_default_dict_getter,
							 | 
						||
| 
								 | 
							
								            manager_of_class=_default_manager_getter,
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								    _instrumentation_factory._extended = False
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def _install_lookups(lookups):
							 | 
						||
| 
								 | 
							
								    global instance_state, instance_dict, manager_of_class
							 | 
						||
| 
								 | 
							
								    instance_state = lookups["instance_state"]
							 | 
						||
| 
								 | 
							
								    instance_dict = lookups["instance_dict"]
							 | 
						||
| 
								 | 
							
								    manager_of_class = lookups["manager_of_class"]
							 | 
						||
| 
								 | 
							
								    orm_base.instance_state = (
							 | 
						||
| 
								 | 
							
								        attributes.instance_state
							 | 
						||
| 
								 | 
							
								    ) = orm_instrumentation.instance_state = instance_state
							 | 
						||
| 
								 | 
							
								    orm_base.instance_dict = (
							 | 
						||
| 
								 | 
							
								        attributes.instance_dict
							 | 
						||
| 
								 | 
							
								    ) = orm_instrumentation.instance_dict = instance_dict
							 | 
						||
| 
								 | 
							
								    orm_base.manager_of_class = (
							 | 
						||
| 
								 | 
							
								        attributes.manager_of_class
							 | 
						||
| 
								 | 
							
								    ) = orm_instrumentation.manager_of_class = manager_of_class
							 |