diff options
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r-- | lib/sqlalchemy/engine/base.py | 4 | ||||
-rw-r--r-- | lib/sqlalchemy/interfaces.py | 363 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/__init__.py | 3 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/attributes.py | 23 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/deprecated_interfaces.py | 572 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/descriptor_props.py | 15 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/interfaces.py | 12 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 54 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/properties.py | 15 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/relationships.py | 16 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/session.py | 20 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/strategies.py | 3 | ||||
-rw-r--r-- | lib/sqlalchemy/pool/base.py | 35 |
13 files changed, 6 insertions, 1129 deletions
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index a0a2680ca..27da8c295 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -14,7 +14,6 @@ from .interfaces import ExceptionContext from .util import _distill_params from .. import exc from .. import inspection -from .. import interfaces from .. import log from .. import util from ..sql import schema @@ -1910,7 +1909,6 @@ class Engine(Connectable, log.Identified): url, logging_name=None, echo=None, - proxy=None, execution_options=None, hide_parameters=False, ): @@ -1922,8 +1920,6 @@ class Engine(Connectable, log.Identified): self.echo = echo self.hide_parameters = hide_parameters log.instance_logger(self, echoflag=echo) - if proxy: - interfaces.ConnectionProxy._adapt_listener(self, proxy) if execution_options: self.update_execution_options(**execution_options) diff --git a/lib/sqlalchemy/interfaces.py b/lib/sqlalchemy/interfaces.py deleted file mode 100644 index 374199143..000000000 --- a/lib/sqlalchemy/interfaces.py +++ /dev/null @@ -1,363 +0,0 @@ -# sqlalchemy/interfaces.py -# Copyright (C) 2007-2019 the SQLAlchemy authors and contributors -# <see AUTHORS file> -# Copyright (C) 2007 Jason Kirtland jek@discorporate.us -# -# This module is part of SQLAlchemy and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - -"""Deprecated core event interfaces. - - -.. deprecated:: 0.7 - As of SQLAlchemy 0.7, the new event system described in - :ref:`event_toplevel` replaces the extension/proxy/listener system, - providing a consistent interface to all events without the need for - subclassing. - -""" - -from . import event -from . import util - - -class PoolListener(object): - """Hooks into the lifecycle of connections in a :class:`.Pool`. - - .. deprecated:: 0.7 - - :class:`.PoolListener` is deprecated and will be removed in a future - release. Please refer to :func:`.event.listen` in conjunction with - the :class:`.PoolEvents` listener interface. - - Usage:: - - class MyListener(PoolListener): - def connect(self, dbapi_con, con_record): - '''perform connect operations''' - # etc. - - # create a new pool with a listener - p = QueuePool(..., listeners=[MyListener()]) - - # add a listener after the fact - p.add_listener(MyListener()) - - # usage with create_engine() - e = create_engine("url://", listeners=[MyListener()]) - - All of the standard connection :class:`~sqlalchemy.pool.Pool` types can - accept event listeners for key connection lifecycle events: - creation, pool check-out and check-in. There are no events fired - when a connection closes. - - For any given DB-API connection, there will be one ``connect`` - event, `n` number of ``checkout`` events, and either `n` or `n - 1` - ``checkin`` events. (If a ``Connection`` is detached from its - pool via the ``detach()`` method, it won't be checked back in.) - - These are low-level events for low-level objects: raw Python - DB-API connections, without the conveniences of the SQLAlchemy - ``Connection`` wrapper, ``Dialect`` services or ``ClauseElement`` - execution. If you execute SQL through the connection, explicitly - closing all cursors and other resources is recommended. - - Events also receive a ``_ConnectionRecord``, a long-lived internal - ``Pool`` object that basically represents a "slot" in the - connection pool. ``_ConnectionRecord`` objects have one public - attribute of note: ``info``, a dictionary whose contents are - scoped to the lifetime of the DB-API connection managed by the - record. You can use this shared storage area however you like. - - There is no need to subclass ``PoolListener`` to handle events. - Any class that implements one or more of these methods can be used - as a pool listener. The ``Pool`` will inspect the methods - provided by a listener object and add the listener to one or more - internal event queues based on its capabilities. In terms of - efficiency and function call overhead, you're much better off only - providing implementations for the hooks you'll be using. - - """ - - @classmethod - def _adapt_listener(cls, self, listener): - """Adapt a :class:`.PoolListener` to individual - :class:`event.Dispatch` events. - - """ - - methods = ["connect", "first_connect", "checkout", "checkin"] - listener = util.as_interface(listener, methods=methods) - - for meth in methods: - me_meth = getattr(PoolListener, meth) - ls_meth = getattr(listener, meth, None) - - if ls_meth is not None and not util.methods_equivalent( - me_meth, ls_meth - ): - util.warn_deprecated( - "PoolListener.%s is deprecated. The " - "PoolListener class will be removed in a future " - "release. Please transition to the @event interface, " - "using @event.listens_for(Engine, '%s')." % (meth, meth) - ) - - if hasattr(listener, "connect"): - event.listen(self, "connect", listener.connect) - if hasattr(listener, "first_connect"): - event.listen(self, "first_connect", listener.first_connect) - if hasattr(listener, "checkout"): - event.listen(self, "checkout", listener.checkout) - if hasattr(listener, "checkin"): - event.listen(self, "checkin", listener.checkin) - - def connect(self, dbapi_con, con_record): - """Called once for each new DB-API connection or Pool's ``creator()``. - - dbapi_con - A newly connected raw DB-API connection (not a SQLAlchemy - ``Connection`` wrapper). - - con_record - The ``_ConnectionRecord`` that persistently manages the connection - - """ - - def first_connect(self, dbapi_con, con_record): - """Called exactly once for the first DB-API connection. - - dbapi_con - A newly connected raw DB-API connection (not a SQLAlchemy - ``Connection`` wrapper). - - con_record - The ``_ConnectionRecord`` that persistently manages the connection - - """ - - def checkout(self, dbapi_con, con_record, con_proxy): - """Called when a connection is retrieved from the Pool. - - dbapi_con - A raw DB-API connection - - con_record - The ``_ConnectionRecord`` that persistently manages the connection - - con_proxy - The ``_ConnectionFairy`` which manages the connection for the span of - the current checkout. - - If you raise an ``exc.DisconnectionError``, the current - connection will be disposed and a fresh connection retrieved. - Processing of all checkout listeners will abort and restart - using the new connection. - """ - - def checkin(self, dbapi_con, con_record): - """Called when a connection returns to the pool. - - Note that the connection may be closed, and may be None if the - connection has been invalidated. ``checkin`` will not be called - for detached connections. (They do not return to the pool.) - - dbapi_con - A raw DB-API connection - - con_record - The ``_ConnectionRecord`` that persistently manages the connection - - """ - - -class ConnectionProxy(object): - """Allows interception of statement execution by Connections. - - .. deprecated:: 0.7 - - :class:`.ConnectionProxy` is deprecated and will be removed in a future - release. Please refer to :func:`.event.listen` in conjunction with - the :class:`.ConnectionEvents` listener interface. - - Either or both of the ``execute()`` and ``cursor_execute()`` - may be implemented to intercept compiled statement and - cursor level executions, e.g.:: - - class MyProxy(ConnectionProxy): - def execute(self, conn, execute, clauseelement, - *multiparams, **params): - print "compiled statement:", clauseelement - return execute(clauseelement, *multiparams, **params) - - def cursor_execute(self, execute, cursor, statement, - parameters, context, executemany): - print "raw statement:", statement - return execute(cursor, statement, parameters, context) - - The ``execute`` argument is a function that will fulfill the default - execution behavior for the operation. The signature illustrated - in the example should be used. - - The proxy is installed into an :class:`~sqlalchemy.engine.Engine` via - the ``proxy`` argument:: - - e = create_engine('someurl://', proxy=MyProxy()) - - """ - - @classmethod - def _adapt_listener(cls, self, listener): - - methods = [ - "execute", - "cursor_execute", - "begin", - "rollback", - "commit", - "savepoint", - "rollback_savepoint", - "release_savepoint", - "begin_twophase", - "prepare_twophase", - "rollback_twophase", - "commit_twophase", - ] - for meth in methods: - me_meth = getattr(ConnectionProxy, meth) - ls_meth = getattr(listener, meth) - - if not util.methods_equivalent(me_meth, ls_meth): - util.warn_deprecated( - "ConnectionProxy.%s is deprecated. The " - "ConnectionProxy class will be removed in a future " - "release. Please transition to the @event interface, " - "using @event.listens_for(Engine, '%s')." % (meth, meth) - ) - - def adapt_execute(conn, clauseelement, multiparams, params): - def execute_wrapper(clauseelement, *multiparams, **params): - return clauseelement, multiparams, params - - return listener.execute( - conn, execute_wrapper, clauseelement, *multiparams, **params - ) - - event.listen(self, "before_execute", adapt_execute) - - def adapt_cursor_execute( - conn, cursor, statement, parameters, context, executemany - ): - def execute_wrapper(cursor, statement, parameters, context): - return statement, parameters - - return listener.cursor_execute( - execute_wrapper, - cursor, - statement, - parameters, - context, - executemany, - ) - - event.listen(self, "before_cursor_execute", adapt_cursor_execute) - - def do_nothing_callback(*arg, **kw): - pass - - def adapt_listener(fn): - def go(conn, *arg, **kw): - fn(conn, do_nothing_callback, *arg, **kw) - - return util.update_wrapper(go, fn) - - event.listen(self, "begin", adapt_listener(listener.begin)) - event.listen(self, "rollback", adapt_listener(listener.rollback)) - event.listen(self, "commit", adapt_listener(listener.commit)) - event.listen(self, "savepoint", adapt_listener(listener.savepoint)) - event.listen( - self, - "rollback_savepoint", - adapt_listener(listener.rollback_savepoint), - ) - event.listen( - self, - "release_savepoint", - adapt_listener(listener.release_savepoint), - ) - event.listen( - self, "begin_twophase", adapt_listener(listener.begin_twophase) - ) - event.listen( - self, "prepare_twophase", adapt_listener(listener.prepare_twophase) - ) - event.listen( - self, - "rollback_twophase", - adapt_listener(listener.rollback_twophase), - ) - event.listen( - self, "commit_twophase", adapt_listener(listener.commit_twophase) - ) - - def execute(self, conn, execute, clauseelement, *multiparams, **params): - """Intercept high level execute() events.""" - - return execute(clauseelement, *multiparams, **params) - - def cursor_execute( - self, execute, cursor, statement, parameters, context, executemany - ): - """Intercept low-level cursor execute() events.""" - - return execute(cursor, statement, parameters, context) - - def begin(self, conn, begin): - """Intercept begin() events.""" - - return begin() - - def rollback(self, conn, rollback): - """Intercept rollback() events.""" - - return rollback() - - def commit(self, conn, commit): - """Intercept commit() events.""" - - return commit() - - def savepoint(self, conn, savepoint, name=None): - """Intercept savepoint() events.""" - - return savepoint(name=name) - - def rollback_savepoint(self, conn, rollback_savepoint, name, context): - """Intercept rollback_savepoint() events.""" - - return rollback_savepoint(name, context) - - def release_savepoint(self, conn, release_savepoint, name, context): - """Intercept release_savepoint() events.""" - - return release_savepoint(name, context) - - def begin_twophase(self, conn, begin_twophase, xid): - """Intercept begin_twophase() events.""" - - return begin_twophase(xid) - - def prepare_twophase(self, conn, prepare_twophase, xid): - """Intercept prepare_twophase() events.""" - - return prepare_twophase(xid) - - def rollback_twophase(self, conn, rollback_twophase, xid, is_prepared): - """Intercept rollback_twophase() events.""" - - return rollback_twophase(xid, is_prepared) - - def commit_twophase(self, conn, commit_twophase, xid, is_prepared): - """Intercept commit_twophase() events.""" - - return commit_twophase(xid, is_prepared) diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py index a596d1408..8bd68b417 100644 --- a/lib/sqlalchemy/orm/__init__.py +++ b/lib/sqlalchemy/orm/__init__.py @@ -16,9 +16,6 @@ documentation for an overview of how this module is used. from . import exc # noqa from . import mapper as mapperlib # noqa from . import strategy_options -from .deprecated_interfaces import AttributeExtension # noqa -from .deprecated_interfaces import MapperExtension # noqa -from .deprecated_interfaces import SessionExtension # noqa from .descriptor_props import ComparableProperty # noqa from .descriptor_props import CompositeProperty # noqa from .descriptor_props import SynonymProperty # noqa diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 117dd4cea..1466f5f47 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -465,7 +465,6 @@ class AttributeImpl(object): callable_, dispatch, trackparent=False, - extension=None, compare_function=None, active_history=False, parent_token=None, @@ -490,19 +489,6 @@ class AttributeImpl(object): if True, attempt to track if an instance has a parent attached to it via this attribute. - :param extension: - a single or list of AttributeExtension object(s) which will - receive set/delete/append/remove/etc. events. - The event package is now used. - - .. deprecated:: 1.3 - - The :paramref:`.AttributeImpl.extension` parameter is deprecated - and will be removed in a future release, corresponding to the - "extension" parameter on the :class:`.MapperProprty` classes - like :func:`.column_property` and :func:`.relationship` The - events system is now used. - :param compare_function: a function that compares two values which are normally assignable to this attribute. @@ -545,13 +531,6 @@ class AttributeImpl(object): else: self.accepts_scalar_loader = self.default_accepts_scalar_loader - # TODO: pass in the manager here - # instead of doing a lookup - attr = manager_of_class(class_)[key] - - for ext in util.to_list(extension or []): - ext._adapt_listener(attr, ext) - if active_history: self.dispatch._active_history = True @@ -1075,7 +1054,6 @@ class CollectionAttributeImpl(AttributeImpl): dispatch, typecallable=None, trackparent=False, - extension=None, copy_function=None, compare_function=None, **kwargs @@ -1086,7 +1064,6 @@ class CollectionAttributeImpl(AttributeImpl): callable_, dispatch, trackparent=trackparent, - extension=extension, compare_function=compare_function, **kwargs ) diff --git a/lib/sqlalchemy/orm/deprecated_interfaces.py b/lib/sqlalchemy/orm/deprecated_interfaces.py deleted file mode 100644 index 4069b43a5..000000000 --- a/lib/sqlalchemy/orm/deprecated_interfaces.py +++ /dev/null @@ -1,572 +0,0 @@ -# orm/deprecated_interfaces.py -# Copyright (C) 2005-2019 the SQLAlchemy authors and contributors -# <see AUTHORS file> -# -# This module is part of SQLAlchemy and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - -from .interfaces import EXT_CONTINUE -from .. import event -from .. import util - - -@util.langhelpers.dependency_for("sqlalchemy.orm.interfaces") -class MapperExtension(object): - """Base implementation for :class:`.Mapper` event hooks. - - .. deprecated:: 0.7 - - :class:`.MapperExtension` is deprecated and will be removed in a future - release. Please refer to :func:`.event.listen` in conjunction with - the :class:`.MapperEvents` listener interface. - - New extension classes subclass :class:`.MapperExtension` and are specified - using the ``extension`` mapper() argument, which is a single - :class:`.MapperExtension` or a list of such:: - - from sqlalchemy.orm.interfaces import MapperExtension - - class MyExtension(MapperExtension): - def before_insert(self, mapper, connection, instance): - print "instance %s before insert !" % instance - - m = mapper(User, users_table, extension=MyExtension()) - - A single mapper can maintain a chain of ``MapperExtension`` - objects. When a particular mapping event occurs, the - corresponding method on each ``MapperExtension`` is invoked - serially, and each method has the ability to halt the chain - from proceeding further:: - - m = mapper(User, users_table, extension=[ext1, ext2, ext3]) - - Each ``MapperExtension`` method returns the symbol - EXT_CONTINUE by default. This symbol generally means "move - to the next ``MapperExtension`` for processing". For methods - that return objects like translated rows or new object - instances, EXT_CONTINUE means the result of the method - should be ignored. In some cases it's required for a - default mapper activity to be performed, such as adding a - new instance to a result list. - - The symbol EXT_STOP has significance within a chain - of ``MapperExtension`` objects that the chain will be stopped - when this symbol is returned. Like EXT_CONTINUE, it also - has additional significance in some cases that a default - mapper activity will not be performed. - - """ - - @classmethod - def _adapt_instrument_class(cls, self, listener): - cls._adapt_listener_methods(self, listener, ("instrument_class",)) - - @classmethod - def _adapt_listener(cls, self, listener): - cls._adapt_listener_methods( - self, - listener, - ( - "init_instance", - "init_failed", - "reconstruct_instance", - "before_insert", - "after_insert", - "before_update", - "after_update", - "before_delete", - "after_delete", - ), - ) - - @classmethod - def _adapt_listener_methods(cls, self, listener, methods): - - for meth in methods: - me_meth = getattr(MapperExtension, meth) - ls_meth = getattr(listener, meth) - - if not util.methods_equivalent(me_meth, ls_meth): - util.warn_deprecated( - "MapperExtension.%s is deprecated. The " - "MapperExtension class will be removed in a future " - "release. Please transition to the @event interface, " - "using @event.listens_for(mapped_class, '%s')." - % (meth, meth) - ) - - if meth == "reconstruct_instance": - - def go(ls_meth): - def reconstruct(instance, ctx): - ls_meth(self, instance) - - return reconstruct - - event.listen( - self.class_manager, - "load", - go(ls_meth), - raw=False, - propagate=True, - ) - elif meth == "init_instance": - - def go(ls_meth): - def init_instance(instance, args, kwargs): - ls_meth( - self, - self.class_, - self.class_manager.original_init, - instance, - args, - kwargs, - ) - - return init_instance - - event.listen( - self.class_manager, - "init", - go(ls_meth), - raw=False, - propagate=True, - ) - elif meth == "init_failed": - - def go(ls_meth): - def init_failed(instance, args, kwargs): - util.warn_exception( - ls_meth, - self, - self.class_, - self.class_manager.original_init, - instance, - args, - kwargs, - ) - - return init_failed - - event.listen( - self.class_manager, - "init_failure", - go(ls_meth), - raw=False, - propagate=True, - ) - else: - event.listen( - self, - "%s" % meth, - ls_meth, - raw=False, - retval=True, - propagate=True, - ) - - def instrument_class(self, mapper, class_): - """Receive a class when the mapper is first constructed, and has - applied instrumentation to the mapped class. - - The return value is only significant within the ``MapperExtension`` - chain; the parent mapper's behavior isn't modified by this method. - - """ - return EXT_CONTINUE - - def init_instance(self, mapper, class_, oldinit, instance, args, kwargs): - """Receive an instance when its constructor is called. - - This method is only called during a userland construction of - an object. It is not called when an object is loaded from the - database. - - The return value is only significant within the ``MapperExtension`` - chain; the parent mapper's behavior isn't modified by this method. - - """ - return EXT_CONTINUE - - def init_failed(self, mapper, class_, oldinit, instance, args, kwargs): - """Receive an instance when its constructor has been called, - and raised an exception. - - This method is only called during a userland construction of - an object. It is not called when an object is loaded from the - database. - - The return value is only significant within the ``MapperExtension`` - chain; the parent mapper's behavior isn't modified by this method. - - """ - return EXT_CONTINUE - - def reconstruct_instance(self, mapper, instance): - """Receive an object instance after it has been created via - ``__new__``, and after initial attribute population has - occurred. - - This typically occurs when the instance is created based on - incoming result rows, and is only called once for that - instance's lifetime. - - Note that during a result-row load, this method is called upon - the first row received for this instance. Note that some - attributes and collections may or may not be loaded or even - initialized, depending on what's present in the result rows. - - The return value is only significant within the ``MapperExtension`` - chain; the parent mapper's behavior isn't modified by this method. - - """ - return EXT_CONTINUE - - def before_insert(self, mapper, connection, instance): - """Receive an object instance before that instance is inserted - into its table. - - This is a good place to set up primary key values and such - that aren't handled otherwise. - - Column-based attributes can be modified within this method - which will result in the new value being inserted. However - *no* changes to the overall flush plan can be made, and - manipulation of the ``Session`` will not have the desired effect. - To manipulate the ``Session`` within an extension, use - ``SessionExtension``. - - The return value is only significant within the ``MapperExtension`` - chain; the parent mapper's behavior isn't modified by this method. - - """ - - return EXT_CONTINUE - - def after_insert(self, mapper, connection, instance): - """Receive an object instance after that instance is inserted. - - The return value is only significant within the ``MapperExtension`` - chain; the parent mapper's behavior isn't modified by this method. - - """ - - return EXT_CONTINUE - - def before_update(self, mapper, connection, instance): - """Receive an object instance before that instance is updated. - - Note that this method is called for all instances that are marked as - "dirty", even those which have no net changes to their column-based - attributes. An object is marked as dirty when any of its column-based - attributes have a "set attribute" operation called or when any of its - collections are modified. If, at update time, no column-based - attributes have any net changes, no UPDATE statement will be issued. - This means that an instance being sent to before_update is *not* a - guarantee that an UPDATE statement will be issued (although you can - affect the outcome here). - - To detect if the column-based attributes on the object have net - changes, and will therefore generate an UPDATE statement, use - ``object_session(instance).is_modified(instance, - include_collections=False)``. - - Column-based attributes can be modified within this method - which will result in the new value being updated. However - *no* changes to the overall flush plan can be made, and - manipulation of the ``Session`` will not have the desired effect. - To manipulate the ``Session`` within an extension, use - ``SessionExtension``. - - The return value is only significant within the ``MapperExtension`` - chain; the parent mapper's behavior isn't modified by this method. - - """ - - return EXT_CONTINUE - - def after_update(self, mapper, connection, instance): - """Receive an object instance after that instance is updated. - - The return value is only significant within the ``MapperExtension`` - chain; the parent mapper's behavior isn't modified by this method. - - """ - - return EXT_CONTINUE - - def before_delete(self, mapper, connection, instance): - """Receive an object instance before that instance is deleted. - - Note that *no* changes to the overall flush plan can be made - here; and manipulation of the ``Session`` will not have the - desired effect. To manipulate the ``Session`` within an - extension, use ``SessionExtension``. - - The return value is only significant within the ``MapperExtension`` - chain; the parent mapper's behavior isn't modified by this method. - - """ - - return EXT_CONTINUE - - def after_delete(self, mapper, connection, instance): - """Receive an object instance after that instance is deleted. - - The return value is only significant within the ``MapperExtension`` - chain; the parent mapper's behavior isn't modified by this method. - - """ - - return EXT_CONTINUE - - -@util.langhelpers.dependency_for("sqlalchemy.orm.interfaces") -class SessionExtension(object): - - """Base implementation for :class:`.Session` event hooks. - - .. deprecated:: 0.7 - - :class:`.SessionExtension` is deprecated and will be removed in a future - release. Please refer to :func:`.event.listen` in conjunction with - the :class:`.SessionEvents` listener interface. - - Subclasses may be installed into a :class:`.Session` (or - :class:`.sessionmaker`) using the ``extension`` keyword - argument:: - - from sqlalchemy.orm.interfaces import SessionExtension - - class MySessionExtension(SessionExtension): - def before_commit(self, session): - print "before commit!" - - Session = sessionmaker(extension=MySessionExtension()) - - The same :class:`.SessionExtension` instance can be used - with any number of sessions. - - """ - - @classmethod - def _adapt_listener(cls, self, listener): - for meth in [ - "before_commit", - "after_commit", - "after_rollback", - "before_flush", - "after_flush", - "after_flush_postexec", - "after_begin", - "after_attach", - "after_bulk_update", - "after_bulk_delete", - ]: - me_meth = getattr(SessionExtension, meth) - ls_meth = getattr(listener, meth) - - if not util.methods_equivalent(me_meth, ls_meth): - util.warn_deprecated( - "SessionExtension.%s is deprecated. The " - "SessionExtension class will be removed in a future " - "release. Please transition to the @event interface, " - "using @event.listens_for(Session, '%s')." % (meth, meth) - ) - - event.listen(self, meth, getattr(listener, meth)) - - def before_commit(self, session): - """Execute right before commit is called. - - Note that this may not be per-flush if a longer running - transaction is ongoing.""" - - def after_commit(self, session): - """Execute after a commit has occurred. - - Note that this may not be per-flush if a longer running - transaction is ongoing.""" - - def after_rollback(self, session): - """Execute after a rollback has occurred. - - Note that this may not be per-flush if a longer running - transaction is ongoing.""" - - def before_flush(self, session, flush_context, instances): - """Execute before flush process has started. - - `instances` is an optional list of objects which were passed to - the ``flush()`` method. """ - - def after_flush(self, session, flush_context): - """Execute after flush has completed, but before commit has been - called. - - Note that the session's state is still in pre-flush, i.e. 'new', - 'dirty', and 'deleted' lists still show pre-flush state as well - as the history settings on instance attributes.""" - - def after_flush_postexec(self, session, flush_context): - """Execute after flush has completed, and after the post-exec - state occurs. - - This will be when the 'new', 'dirty', and 'deleted' lists are in - their final state. An actual commit() may or may not have - occurred, depending on whether or not the flush started its own - transaction or participated in a larger transaction. """ - - def after_begin(self, session, transaction, connection): - """Execute after a transaction is begun on a connection - - `transaction` is the SessionTransaction. This method is called - after an engine level transaction is begun on a connection. """ - - def after_attach(self, session, instance): - """Execute after an instance is attached to a session. - - This is called after an add, delete or merge. """ - - def after_bulk_update(self, session, query, query_context, result): - """Execute after a bulk update operation to the session. - - This is called after a session.query(...).update() - - `query` is the query object that this update operation was - called on. `query_context` was the query context object. - `result` is the result object returned from the bulk operation. - """ - - def after_bulk_delete(self, session, query, query_context, result): - """Execute after a bulk delete operation to the session. - - This is called after a session.query(...).delete() - - `query` is the query object that this delete operation was - called on. `query_context` was the query context object. - `result` is the result object returned from the bulk operation. - """ - - -@util.langhelpers.dependency_for("sqlalchemy.orm.interfaces") -class AttributeExtension(object): - """Base implementation for :class:`.AttributeImpl` event hooks, events - that fire upon attribute mutations in user code. - - .. deprecated:: 0.7 - - :class:`.AttributeExtension` is deprecated and will be removed in a - future release. Please refer to :func:`.event.listen` in conjunction - with the :class:`.AttributeEvents` listener interface. - - :class:`.AttributeExtension` is used to listen for set, - remove, and append events on individual mapped attributes. - It is established on an individual mapped attribute using - the `extension` argument, available on - :func:`.column_property`, :func:`.relationship`, and - others:: - - from sqlalchemy.orm.interfaces import AttributeExtension - from sqlalchemy.orm import mapper, relationship, column_property - - class MyAttrExt(AttributeExtension): - def append(self, state, value, initiator): - print "append event !" - return value - - def set(self, state, value, oldvalue, initiator): - print "set event !" - return value - - mapper(SomeClass, sometable, properties={ - 'foo':column_property(sometable.c.foo, extension=MyAttrExt()), - 'bar':relationship(Bar, extension=MyAttrExt()) - }) - - Note that the :class:`.AttributeExtension` methods - :meth:`~.AttributeExtension.append` and - :meth:`~.AttributeExtension.set` need to return the - ``value`` parameter. The returned value is used as the - effective value, and allows the extension to change what is - ultimately persisted. - - AttributeExtension is assembled within the descriptors associated - with a mapped class. - - """ - - active_history = True - """indicates that the set() method would like to receive the 'old' value, - even if it means firing lazy callables. - - Note that ``active_history`` can also be set directly via - :func:`.column_property` and :func:`.relationship`. - - """ - - @classmethod - def _adapt_listener(cls, self, listener): - for meth in ["append", "remove", "set"]: - me_meth = getattr(AttributeExtension, meth) - ls_meth = getattr(listener, meth) - - if not util.methods_equivalent(me_meth, ls_meth): - util.warn_deprecated( - "AttributeExtension.%s is deprecated. The " - "AttributeExtension class will be removed in a future " - "release. Please transition to the @event interface, " - "using @event.listens_for(Class.attribute, '%s')." - % (meth, meth) - ) - - event.listen( - self, - "append", - listener.append, - active_history=listener.active_history, - raw=True, - retval=True, - ) - event.listen( - self, - "remove", - listener.remove, - active_history=listener.active_history, - raw=True, - retval=True, - ) - event.listen( - self, - "set", - listener.set, - active_history=listener.active_history, - raw=True, - retval=True, - ) - - def append(self, state, value, initiator): - """Receive a collection append event. - - The returned value will be used as the actual value to be - appended. - - """ - return value - - def remove(self, state, value, initiator): - """Receive a remove event. - - No return value is defined. - - """ - pass - - def set(self, state, value, oldvalue, initiator): - """Receive a set event. - - The returned value will be used as the actual value to be - set. - - """ - return value diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py index 075638fed..dd482bf06 100644 --- a/lib/sqlalchemy/orm/descriptor_props.py +++ b/lib/sqlalchemy/orm/descriptor_props.py @@ -97,15 +97,6 @@ class CompositeProperty(DescriptorProperty): """ - @util.deprecated_params( - extension=( - "0.7", - ":class:`.AttributeExtension` is deprecated in favor of the " - ":class:`.AttributeEvents` listener interface. The " - ":paramref:`.composite.extension` parameter will be " - "removed in a future release.", - ) - ) def __init__(self, class_, *attrs, **kwargs): r"""Return a composite column-based property for use with a Mapper. @@ -148,12 +139,6 @@ class CompositeProperty(DescriptorProperty): :param info: Optional data dictionary which will be populated into the :attr:`.MapperProperty.info` attribute of this object. - :param extension: - an :class:`.AttributeExtension` instance, - or list of extensions, which will be prepended to the list of - attribute listeners for the resulting descriptor placed on the - class. - """ super(CompositeProperty, self).__init__() diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index d6bdfb924..09d1858b9 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -9,11 +9,9 @@ Contains various base classes used throughout the ORM. -Defines some key base classes prominent within the internals, -as well as the now-deprecated ORM extension classes. +Defines some key base classes prominent within the internals. -Other than the deprecated extensions, this module and the -classes within are mostly private, though some attributes +This module and the classes within are mostly private, though some attributes are exposed when inspecting mappings. """ @@ -40,11 +38,7 @@ from .. import util from ..sql import operators -# imported later -MapperExtension = SessionExtension = AttributeExtension = None - __all__ = ( - "AttributeExtension", "EXT_CONTINUE", "EXT_STOP", "EXT_SKIP", @@ -53,11 +47,9 @@ __all__ = ( "MANYTOONE", "NOT_EXTENSION", "LoaderStrategy", - "MapperExtension", "MapperOption", "MapperProperty", "PropComparator", - "SessionExtension", "StrategizedProperty", ) diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index e8b215653..0d8d454eb 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -108,13 +108,6 @@ class Mapper(InspectionAttr): _dispose_called = False @util.deprecated_params( - extension=( - "0.7", - ":class:`.MapperExtension` is deprecated in favor of the " - ":class:`.MapperEvents` listener interface. The " - ":paramref:`.mapper.extension` parameter will be " - "removed in a future release.", - ), order_by=( "1.1", "The :paramref:`.mapper.order_by` parameter " @@ -141,7 +134,6 @@ class Mapper(InspectionAttr): inherits=None, inherit_condition=None, inherit_foreign_keys=None, - extension=None, order_by=False, always_refresh=False, version_id_col=None, @@ -295,10 +287,6 @@ class Mapper(InspectionAttr): See :ref:`include_exclude_cols` for an example. - :param extension: A :class:`.MapperExtension` instance or - list of :class:`.MapperExtension` instances which will be applied - to all operations by this :class:`.Mapper`. - :param include_properties: An inclusive list or set of string column names to map. @@ -673,7 +661,6 @@ class Mapper(InspectionAttr): self._memoized_values = {} self._compiled_cache_size = _compiled_cache_size self._reconstructor = None - self._deprecated_extensions = util.to_list(extension or []) self.allow_partial_pks = allow_partial_pks if self.inherits and not self.concrete: @@ -715,9 +702,7 @@ class Mapper(InspectionAttr): try: self.dispatch._events._new_mapper_instance(class_, self) self._configure_inheritance() - self._configure_legacy_instrument_class() self._configure_class_instrumentation() - self._configure_listeners() self._configure_properties() self._configure_polymorphic_setter() self._configure_pks() @@ -1012,6 +997,9 @@ class Mapper(InspectionAttr): "Class '%s' does not inherit from '%s'" % (self.class_.__name__, self.inherits.class_.__name__) ) + + self.dispatch._update(self.inherits.dispatch) + if self.non_primary != self.inherits.non_primary: np = not self.non_primary and "primary" or "non-primary" raise sa_exc.ArgumentError( @@ -1206,42 +1194,6 @@ class Mapper(InspectionAttr): self.polymorphic_on = polymorphic_on self._configure_polymorphic_setter(True) - def _configure_legacy_instrument_class(self): - - if self.inherits: - self.dispatch._update(self.inherits.dispatch) - super_extensions = set( - chain( - *[ - m._deprecated_extensions - for m in self.inherits.iterate_to_root() - ] - ) - ) - else: - super_extensions = set() - - for ext in self._deprecated_extensions: - if ext not in super_extensions: - ext._adapt_instrument_class(self, ext) - - def _configure_listeners(self): - if self.inherits: - super_extensions = set( - chain( - *[ - m._deprecated_extensions - for m in self.inherits.iterate_to_root() - ] - ) - ) - else: - super_extensions = set() - - for ext in self._deprecated_extensions: - if ext not in super_extensions: - ext._adapt_listener(self, ext) - def _configure_class_instrumentation(self): """If this mapper is to be a primary mapper (i.e. the non_primary flag is not set), associate this Mapper with the diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index f804d6eed..f8bf06926 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -44,7 +44,6 @@ class ColumnProperty(StrategizedProperty): "instrument", "comparator_factory", "descriptor", - "extension", "active_history", "expire_on_flush", "info", @@ -56,15 +55,6 @@ class ColumnProperty(StrategizedProperty): "_deferred_column_loader", ) - @util.deprecated_params( - extension=( - "0.7", - ":class:`.AttributeExtension` is deprecated in favor of the " - ":class:`.AttributeEvents` listener interface. The " - ":paramref:`.column_property.extension` parameter will be " - "removed in a future release.", - ) - ) def __init__(self, *columns, **kwargs): r"""Provide a column-level property for use with a Mapper. @@ -125,10 +115,6 @@ class ColumnProperty(StrategizedProperty): :param info: Optional data dictionary which will be populated into the :attr:`.MapperProperty.info` attribute of this object. - :param extension: - an :class:`.AttributeExtension` instance, or list of extensions, - which will be prepended to the list of attribute listeners for the - resulting descriptor placed on the class. """ super(ColumnProperty, self).__init__() @@ -148,7 +134,6 @@ class ColumnProperty(StrategizedProperty): "comparator_factory", self.__class__.Comparator ) self.descriptor = kwargs.pop("descriptor", None) - self.extension = kwargs.pop("extension", None) self.active_history = kwargs.pop("active_history", False) self.expire_on_flush = kwargs.pop("expire_on_flush", True) diff --git a/lib/sqlalchemy/orm/relationships.py b/lib/sqlalchemy/orm/relationships.py index 731947cba..a8013f36d 100644 --- a/lib/sqlalchemy/orm/relationships.py +++ b/lib/sqlalchemy/orm/relationships.py @@ -107,15 +107,6 @@ class RelationshipProperty(StrategizedProperty): _dependency_processor = None - @util.deprecated_params( - extension=( - "0.7", - ":class:`.AttributeExtension` is deprecated in favor of the " - ":class:`.AttributeEvents` listener interface. The " - ":paramref:`.relationship.extension` parameter will be " - "removed in a future release.", - ) - ) def __init__( self, argument, @@ -129,7 +120,6 @@ class RelationshipProperty(StrategizedProperty): back_populates=None, post_update=False, cascade=False, - extension=None, viewonly=False, lazy="select", collection_class=None, @@ -415,11 +405,6 @@ class RelationshipProperty(StrategizedProperty): :param doc: docstring which will be applied to the resulting descriptor. - :param extension: - an :class:`.AttributeExtension` instance, or list of extensions, - which will be prepended to the list of attribute listeners for - the resulting descriptor placed on the class. - :param foreign_keys: a list of columns which are to be used as "foreign key" @@ -865,7 +850,6 @@ class RelationshipProperty(StrategizedProperty): self.join_depth = join_depth self.omit_join = omit_join self.local_remote_pairs = _local_remote_pairs - self.extension = extension self.bake_queries = bake_queries self.load_on_pending = load_on_pending self.comparator_factory = ( diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 3aa392ecf..5cf31da0f 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -25,7 +25,6 @@ from .base import instance_str from .base import object_mapper from .base import object_state from .base import state_str -from .deprecated_interfaces import SessionExtension from .unitofwork import UOWTransaction from .. import engine from .. import exc as sa_exc @@ -37,7 +36,7 @@ from ..sql import roles from ..sql import util as sql_util -__all__ = ["Session", "SessionTransaction", "SessionExtension", "sessionmaker"] +__all__ = ["Session", "SessionTransaction", "sessionmaker"] _sessions = weakref.WeakValueDictionary() """Weak-referencing dictionary of :class:`.Session` objects. @@ -660,13 +659,6 @@ class Session(_SessionClassMethods): "The :paramref:`.Session._enable_transaction_accounting` " "parameter is deprecated and will be removed in a future release.", ), - extension=( - "0.7", - ":class:`.SessionExtension` is deprecated in favor of the " - ":class:`.SessionEvents` listener interface. The " - ":paramref:`.Session.extension` parameter will be " - "removed in a future release.", - ), ) def __init__( self, @@ -678,7 +670,6 @@ class Session(_SessionClassMethods): twophase=False, weak_identity_map=None, binds=None, - extension=None, enable_baked_queries=True, info=None, query_cls=None, @@ -789,11 +780,6 @@ class Session(_SessionClassMethods): so that all attribute/object access subsequent to a completed transaction will load from the most recent database state. - :param extension: An optional - :class:`~.SessionExtension` instance, or a list - of such instances, which will receive pre- and post- commit and - flush events, as well as a post-rollback event. - :param info: optional dictionary of arbitrary data to be associated with this :class:`.Session`. Is available via the :attr:`.Session.info` attribute. Note the dictionary is copied at @@ -850,10 +836,6 @@ class Session(_SessionClassMethods): if info: self.info.update(info) - if extension: - for ext in util.to_list(extension): - SessionExtension._adapt_listener(self, ext) - if binds is not None: for key, bind in binds.items(): self._add_bind(key, bind) diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index f82973b39..f82fc2c57 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -51,8 +51,6 @@ def _register_attribute( **kw ): - attribute_ext = list(util.to_list(prop.extension, default=[])) - listen_hooks = [] uselist = useobject and prop.uselist @@ -105,7 +103,6 @@ def _register_attribute( uselist=uselist, compare_function=compare_function, useobject=useobject, - extension=attribute_ext, trackparent=useobject and ( prop.single_parent diff --git a/lib/sqlalchemy/pool/base.py b/lib/sqlalchemy/pool/base.py index c45f836db..db1197eec 100644 --- a/lib/sqlalchemy/pool/base.py +++ b/lib/sqlalchemy/pool/base.py @@ -16,7 +16,6 @@ import weakref from .. import event from .. import exc -from .. import interfaces from .. import log from .. import util from ..util import threading @@ -60,15 +59,6 @@ class Pool(log.Identified): _dialect = _ConnDialect() - @util.deprecated_params( - listeners=( - "0.7", - ":class:`.PoolListener` is deprecated in favor of the " - ":class:`.PoolEvents` listener interface. The " - ":paramref:`.Pool.listeners` parameter will be removed in a " - "future release.", - ) - ) def __init__( self, creator, @@ -76,7 +66,6 @@ class Pool(log.Identified): echo=None, logging_name=None, reset_on_return=True, - listeners=None, events=None, dialect=None, pre_ping=False, @@ -155,11 +144,6 @@ class Pool(log.Identified): can be assigned via :func:`.create_engine` before dialect-level listeners are applied. - :param listeners: A list of :class:`.PoolListener`-like objects or - dictionaries of callables that receive events when DB-API - connections are created, checked out and checked in to the - pool. - :param dialect: a :class:`.Dialect` that will handle the job of calling rollback(), close(), or commit() on DBAPI connections. If omitted, a built-in "stub" dialect is used. Applications that @@ -211,9 +195,6 @@ class Pool(log.Identified): if events: for fn, target in events: event.listen(self, target, fn) - if listeners: - for l in listeners: - self.add_listener(l) @property def _creator(self): @@ -260,22 +241,6 @@ class Pool(log.Identified): "Exception closing connection %r", connection, exc_info=True ) - @util.deprecated( - "0.7", - "The :meth:`.Pool.add_listener` method is deprecated and " - "will be removed in a future release. Please use the " - ":class:`.PoolEvents` listener interface.", - ) - def add_listener(self, listener): - """Add a :class:`.PoolListener`-like object to this pool. - - ``listener`` may be an object that implements some or all of - PoolListener, or a dictionary of callables containing implementations - of some or all of the named methods in PoolListener. - - """ - interfaces.PoolListener._adapt_listener(self, listener) - def _create_connection(self): """Called by subclasses to create a new ConnectionRecord.""" |