diff options
author | cyfraeviolae <cyfraeviolae> | 2024-04-03 03:17:55 -0400 |
---|---|---|
committer | cyfraeviolae <cyfraeviolae> | 2024-04-03 03:17:55 -0400 |
commit | 12cf076118570eebbff08c6b3090e0d4798447a1 (patch) | |
tree | 3ba25e17e3c3a5e82316558ba3864b955919ff72 /venv/lib/python3.11/site-packages/sqlalchemy/event | |
parent | c45662ff3923b34614ddcc8feb9195541166dcc5 (diff) |
no venv
Diffstat (limited to 'venv/lib/python3.11/site-packages/sqlalchemy/event')
12 files changed, 0 insertions, 1999 deletions
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/event/__init__.py b/venv/lib/python3.11/site-packages/sqlalchemy/event/__init__.py deleted file mode 100644 index 9b54f07..0000000 --- a/venv/lib/python3.11/site-packages/sqlalchemy/event/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# event/__init__.py -# Copyright (C) 2005-2024 the SQLAlchemy authors and contributors -# <see AUTHORS file> -# -# This module is part of SQLAlchemy and is released under -# the MIT License: https://www.opensource.org/licenses/mit-license.php - -from __future__ import annotations - -from .api import CANCEL as CANCEL -from .api import contains as contains -from .api import listen as listen -from .api import listens_for as listens_for -from .api import NO_RETVAL as NO_RETVAL -from .api import remove as remove -from .attr import _InstanceLevelDispatch as _InstanceLevelDispatch -from .attr import RefCollection as RefCollection -from .base import _Dispatch as _Dispatch -from .base import _DispatchCommon as _DispatchCommon -from .base import dispatcher as dispatcher -from .base import Events as Events -from .legacy import _legacy_signature as _legacy_signature -from .registry import _EventKey as _EventKey -from .registry import _ListenerFnType as _ListenerFnType -from .registry import EventTarget as EventTarget diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/__init__.cpython-311.pyc Binary files differdeleted file mode 100644 index cdacdf7..0000000 --- a/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/__init__.cpython-311.pyc +++ /dev/null diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/api.cpython-311.pyc b/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/api.cpython-311.pyc Binary files differdeleted file mode 100644 index 9495b80..0000000 --- a/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/api.cpython-311.pyc +++ /dev/null diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/attr.cpython-311.pyc b/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/attr.cpython-311.pyc Binary files differdeleted file mode 100644 index 264917e..0000000 --- a/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/attr.cpython-311.pyc +++ /dev/null diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/base.cpython-311.pyc b/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/base.cpython-311.pyc Binary files differdeleted file mode 100644 index d2dce27..0000000 --- a/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/base.cpython-311.pyc +++ /dev/null diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/legacy.cpython-311.pyc b/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/legacy.cpython-311.pyc Binary files differdeleted file mode 100644 index f6911d7..0000000 --- a/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/legacy.cpython-311.pyc +++ /dev/null diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/registry.cpython-311.pyc b/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/registry.cpython-311.pyc Binary files differdeleted file mode 100644 index 7bf4877..0000000 --- a/venv/lib/python3.11/site-packages/sqlalchemy/event/__pycache__/registry.cpython-311.pyc +++ /dev/null diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/event/api.py b/venv/lib/python3.11/site-packages/sqlalchemy/event/api.py deleted file mode 100644 index 4a39d10..0000000 --- a/venv/lib/python3.11/site-packages/sqlalchemy/event/api.py +++ /dev/null @@ -1,225 +0,0 @@ -# event/api.py -# Copyright (C) 2005-2024 the SQLAlchemy authors and contributors -# <see AUTHORS file> -# -# This module is part of SQLAlchemy and is released under -# the MIT License: https://www.opensource.org/licenses/mit-license.php - -"""Public API functions for the event system. - -""" -from __future__ import annotations - -from typing import Any -from typing import Callable - -from .base import _registrars -from .registry import _ET -from .registry import _EventKey -from .registry import _ListenerFnType -from .. import exc -from .. import util - - -CANCEL = util.symbol("CANCEL") -NO_RETVAL = util.symbol("NO_RETVAL") - - -def _event_key( - target: _ET, identifier: str, fn: _ListenerFnType -) -> _EventKey[_ET]: - for evt_cls in _registrars[identifier]: - tgt = evt_cls._accept_with(target, identifier) - if tgt is not None: - return _EventKey(target, identifier, fn, tgt) - else: - raise exc.InvalidRequestError( - "No such event '%s' for target '%s'" % (identifier, target) - ) - - -def listen( - target: Any, identifier: str, fn: Callable[..., Any], *args: Any, **kw: Any -) -> None: - """Register a listener function for the given target. - - The :func:`.listen` function is part of the primary interface for the - SQLAlchemy event system, documented at :ref:`event_toplevel`. - - e.g.:: - - from sqlalchemy import event - from sqlalchemy.schema import UniqueConstraint - - def unique_constraint_name(const, table): - const.name = "uq_%s_%s" % ( - table.name, - list(const.columns)[0].name - ) - event.listen( - UniqueConstraint, - "after_parent_attach", - unique_constraint_name) - - :param bool insert: The default behavior for event handlers is to append - the decorated user defined function to an internal list of registered - event listeners upon discovery. If a user registers a function with - ``insert=True``, SQLAlchemy will insert (prepend) the function to the - internal list upon discovery. This feature is not typically used or - recommended by the SQLAlchemy maintainers, but is provided to ensure - certain user defined functions can run before others, such as when - :ref:`Changing the sql_mode in MySQL <mysql_sql_mode>`. - - :param bool named: When using named argument passing, the names listed in - the function argument specification will be used as keys in the - dictionary. - See :ref:`event_named_argument_styles`. - - :param bool once: Private/Internal API usage. Deprecated. This parameter - would provide that an event function would run only once per given - target. It does not however imply automatic de-registration of the - listener function; associating an arbitrarily high number of listeners - without explicitly removing them will cause memory to grow unbounded even - if ``once=True`` is specified. - - :param bool propagate: The ``propagate`` kwarg is available when working - with ORM instrumentation and mapping events. - See :class:`_ormevent.MapperEvents` and - :meth:`_ormevent.MapperEvents.before_mapper_configured` for examples. - - :param bool retval: This flag applies only to specific event listeners, - each of which includes documentation explaining when it should be used. - By default, no listener ever requires a return value. - However, some listeners do support special behaviors for return values, - and include in their documentation that the ``retval=True`` flag is - necessary for a return value to be processed. - - Event listener suites that make use of :paramref:`_event.listen.retval` - include :class:`_events.ConnectionEvents` and - :class:`_ormevent.AttributeEvents`. - - .. note:: - - The :func:`.listen` function cannot be called at the same time - that the target event is being run. This has implications - for thread safety, and also means an event cannot be added - from inside the listener function for itself. The list of - events to be run are present inside of a mutable collection - that can't be changed during iteration. - - Event registration and removal is not intended to be a "high - velocity" operation; it is a configurational operation. For - systems that need to quickly associate and deassociate with - events at high scale, use a mutable structure that is handled - from inside of a single listener. - - .. seealso:: - - :func:`.listens_for` - - :func:`.remove` - - """ - - _event_key(target, identifier, fn).listen(*args, **kw) - - -def listens_for( - target: Any, identifier: str, *args: Any, **kw: Any -) -> Callable[[Callable[..., Any]], Callable[..., Any]]: - """Decorate a function as a listener for the given target + identifier. - - The :func:`.listens_for` decorator is part of the primary interface for the - SQLAlchemy event system, documented at :ref:`event_toplevel`. - - This function generally shares the same kwargs as :func:`.listens`. - - e.g.:: - - from sqlalchemy import event - from sqlalchemy.schema import UniqueConstraint - - @event.listens_for(UniqueConstraint, "after_parent_attach") - def unique_constraint_name(const, table): - const.name = "uq_%s_%s" % ( - table.name, - list(const.columns)[0].name - ) - - A given function can also be invoked for only the first invocation - of the event using the ``once`` argument:: - - @event.listens_for(Mapper, "before_configure", once=True) - def on_config(): - do_config() - - - .. warning:: The ``once`` argument does not imply automatic de-registration - of the listener function after it has been invoked a first time; a - listener entry will remain associated with the target object. - Associating an arbitrarily high number of listeners without explicitly - removing them will cause memory to grow unbounded even if ``once=True`` - is specified. - - .. seealso:: - - :func:`.listen` - general description of event listening - - """ - - def decorate(fn: Callable[..., Any]) -> Callable[..., Any]: - listen(target, identifier, fn, *args, **kw) - return fn - - return decorate - - -def remove(target: Any, identifier: str, fn: Callable[..., Any]) -> None: - """Remove an event listener. - - The arguments here should match exactly those which were sent to - :func:`.listen`; all the event registration which proceeded as a result - of this call will be reverted by calling :func:`.remove` with the same - arguments. - - e.g.:: - - # if a function was registered like this... - @event.listens_for(SomeMappedClass, "before_insert", propagate=True) - def my_listener_function(*arg): - pass - - # ... it's removed like this - event.remove(SomeMappedClass, "before_insert", my_listener_function) - - Above, the listener function associated with ``SomeMappedClass`` was also - propagated to subclasses of ``SomeMappedClass``; the :func:`.remove` - function will revert all of these operations. - - .. note:: - - The :func:`.remove` function cannot be called at the same time - that the target event is being run. This has implications - for thread safety, and also means an event cannot be removed - from inside the listener function for itself. The list of - events to be run are present inside of a mutable collection - that can't be changed during iteration. - - Event registration and removal is not intended to be a "high - velocity" operation; it is a configurational operation. For - systems that need to quickly associate and deassociate with - events at high scale, use a mutable structure that is handled - from inside of a single listener. - - .. seealso:: - - :func:`.listen` - - """ - _event_key(target, identifier, fn).remove() - - -def contains(target: Any, identifier: str, fn: Callable[..., Any]) -> bool: - """Return True if the given target/ident/fn is set up to listen.""" - - return _event_key(target, identifier, fn).contains() diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/event/attr.py b/venv/lib/python3.11/site-packages/sqlalchemy/event/attr.py deleted file mode 100644 index ef2b334..0000000 --- a/venv/lib/python3.11/site-packages/sqlalchemy/event/attr.py +++ /dev/null @@ -1,655 +0,0 @@ -# event/attr.py -# Copyright (C) 2005-2024 the SQLAlchemy authors and contributors -# <see AUTHORS file> -# -# This module is part of SQLAlchemy and is released under -# the MIT License: https://www.opensource.org/licenses/mit-license.php - -"""Attribute implementation for _Dispatch classes. - -The various listener targets for a particular event class are represented -as attributes, which refer to collections of listeners to be fired off. -These collections can exist at the class level as well as at the instance -level. An event is fired off using code like this:: - - some_object.dispatch.first_connect(arg1, arg2) - -Above, ``some_object.dispatch`` would be an instance of ``_Dispatch`` and -``first_connect`` is typically an instance of ``_ListenerCollection`` -if event listeners are present, or ``_EmptyListener`` if none are present. - -The attribute mechanics here spend effort trying to ensure listener functions -are available with a minimum of function call overhead, that unnecessary -objects aren't created (i.e. many empty per-instance listener collections), -as well as that everything is garbage collectable when owning references are -lost. Other features such as "propagation" of listener functions across -many ``_Dispatch`` instances, "joining" of multiple ``_Dispatch`` instances, -as well as support for subclass propagation (e.g. events assigned to -``Pool`` vs. ``QueuePool``) are all implemented here. - -""" -from __future__ import annotations - -import collections -from itertools import chain -import threading -from types import TracebackType -import typing -from typing import Any -from typing import cast -from typing import Collection -from typing import Deque -from typing import FrozenSet -from typing import Generic -from typing import Iterator -from typing import MutableMapping -from typing import MutableSequence -from typing import NoReturn -from typing import Optional -from typing import Sequence -from typing import Set -from typing import Tuple -from typing import Type -from typing import TypeVar -from typing import Union -import weakref - -from . import legacy -from . import registry -from .registry import _ET -from .registry import _EventKey -from .registry import _ListenerFnType -from .. import exc -from .. import util -from ..util.concurrency import AsyncAdaptedLock -from ..util.typing import Protocol - -_T = TypeVar("_T", bound=Any) - -if typing.TYPE_CHECKING: - from .base import _Dispatch - from .base import _DispatchCommon - from .base import _HasEventsDispatch - - -class RefCollection(util.MemoizedSlots, Generic[_ET]): - __slots__ = ("ref",) - - ref: weakref.ref[RefCollection[_ET]] - - def _memoized_attr_ref(self) -> weakref.ref[RefCollection[_ET]]: - return weakref.ref(self, registry._collection_gced) - - -class _empty_collection(Collection[_T]): - def append(self, element: _T) -> None: - pass - - def appendleft(self, element: _T) -> None: - pass - - def extend(self, other: Sequence[_T]) -> None: - pass - - def remove(self, element: _T) -> None: - pass - - def __contains__(self, element: Any) -> bool: - return False - - def __iter__(self) -> Iterator[_T]: - return iter([]) - - def clear(self) -> None: - pass - - def __len__(self) -> int: - return 0 - - -_ListenerFnSequenceType = Union[Deque[_T], _empty_collection[_T]] - - -class _ClsLevelDispatch(RefCollection[_ET]): - """Class-level events on :class:`._Dispatch` classes.""" - - __slots__ = ( - "clsname", - "name", - "arg_names", - "has_kw", - "legacy_signatures", - "_clslevel", - "__weakref__", - ) - - clsname: str - name: str - arg_names: Sequence[str] - has_kw: bool - legacy_signatures: MutableSequence[legacy._LegacySignatureType] - _clslevel: MutableMapping[ - Type[_ET], _ListenerFnSequenceType[_ListenerFnType] - ] - - def __init__( - self, - parent_dispatch_cls: Type[_HasEventsDispatch[_ET]], - fn: _ListenerFnType, - ): - self.name = fn.__name__ - self.clsname = parent_dispatch_cls.__name__ - argspec = util.inspect_getfullargspec(fn) - self.arg_names = argspec.args[1:] - self.has_kw = bool(argspec.varkw) - self.legacy_signatures = list( - reversed( - sorted( - getattr(fn, "_legacy_signatures", []), key=lambda s: s[0] - ) - ) - ) - fn.__doc__ = legacy._augment_fn_docs(self, parent_dispatch_cls, fn) - - self._clslevel = weakref.WeakKeyDictionary() - - def _adjust_fn_spec( - self, fn: _ListenerFnType, named: bool - ) -> _ListenerFnType: - if named: - fn = self._wrap_fn_for_kw(fn) - if self.legacy_signatures: - try: - argspec = util.get_callable_argspec(fn, no_self=True) - except TypeError: - pass - else: - fn = legacy._wrap_fn_for_legacy(self, fn, argspec) - return fn - - def _wrap_fn_for_kw(self, fn: _ListenerFnType) -> _ListenerFnType: - def wrap_kw(*args: Any, **kw: Any) -> Any: - argdict = dict(zip(self.arg_names, args)) - argdict.update(kw) - return fn(**argdict) - - return wrap_kw - - def _do_insert_or_append( - self, event_key: _EventKey[_ET], is_append: bool - ) -> None: - target = event_key.dispatch_target - assert isinstance( - target, type - ), "Class-level Event targets must be classes." - if not getattr(target, "_sa_propagate_class_events", True): - raise exc.InvalidRequestError( - f"Can't assign an event directly to the {target} class" - ) - - cls: Type[_ET] - - for cls in util.walk_subclasses(target): - if cls is not target and cls not in self._clslevel: - self.update_subclass(cls) - else: - if cls not in self._clslevel: - self.update_subclass(cls) - if is_append: - self._clslevel[cls].append(event_key._listen_fn) - else: - self._clslevel[cls].appendleft(event_key._listen_fn) - registry._stored_in_collection(event_key, self) - - def insert(self, event_key: _EventKey[_ET], propagate: bool) -> None: - self._do_insert_or_append(event_key, is_append=False) - - def append(self, event_key: _EventKey[_ET], propagate: bool) -> None: - self._do_insert_or_append(event_key, is_append=True) - - def update_subclass(self, target: Type[_ET]) -> None: - if target not in self._clslevel: - if getattr(target, "_sa_propagate_class_events", True): - self._clslevel[target] = collections.deque() - else: - self._clslevel[target] = _empty_collection() - - clslevel = self._clslevel[target] - cls: Type[_ET] - for cls in target.__mro__[1:]: - if cls in self._clslevel: - clslevel.extend( - [fn for fn in self._clslevel[cls] if fn not in clslevel] - ) - - def remove(self, event_key: _EventKey[_ET]) -> None: - target = event_key.dispatch_target - cls: Type[_ET] - for cls in util.walk_subclasses(target): - if cls in self._clslevel: - self._clslevel[cls].remove(event_key._listen_fn) - registry._removed_from_collection(event_key, self) - - def clear(self) -> None: - """Clear all class level listeners""" - - to_clear: Set[_ListenerFnType] = set() - for dispatcher in self._clslevel.values(): - to_clear.update(dispatcher) - dispatcher.clear() - registry._clear(self, to_clear) - - def for_modify(self, obj: _Dispatch[_ET]) -> _ClsLevelDispatch[_ET]: - """Return an event collection which can be modified. - - For _ClsLevelDispatch at the class level of - a dispatcher, this returns self. - - """ - return self - - -class _InstanceLevelDispatch(RefCollection[_ET], Collection[_ListenerFnType]): - __slots__ = () - - parent: _ClsLevelDispatch[_ET] - - def _adjust_fn_spec( - self, fn: _ListenerFnType, named: bool - ) -> _ListenerFnType: - return self.parent._adjust_fn_spec(fn, named) - - def __contains__(self, item: Any) -> bool: - raise NotImplementedError() - - def __len__(self) -> int: - raise NotImplementedError() - - def __iter__(self) -> Iterator[_ListenerFnType]: - raise NotImplementedError() - - def __bool__(self) -> bool: - raise NotImplementedError() - - def exec_once(self, *args: Any, **kw: Any) -> None: - raise NotImplementedError() - - def exec_once_unless_exception(self, *args: Any, **kw: Any) -> None: - raise NotImplementedError() - - def _exec_w_sync_on_first_run(self, *args: Any, **kw: Any) -> None: - raise NotImplementedError() - - def __call__(self, *args: Any, **kw: Any) -> None: - raise NotImplementedError() - - def insert(self, event_key: _EventKey[_ET], propagate: bool) -> None: - raise NotImplementedError() - - def append(self, event_key: _EventKey[_ET], propagate: bool) -> None: - raise NotImplementedError() - - def remove(self, event_key: _EventKey[_ET]) -> None: - raise NotImplementedError() - - def for_modify( - self, obj: _DispatchCommon[_ET] - ) -> _InstanceLevelDispatch[_ET]: - """Return an event collection which can be modified. - - For _ClsLevelDispatch at the class level of - a dispatcher, this returns self. - - """ - return self - - -class _EmptyListener(_InstanceLevelDispatch[_ET]): - """Serves as a proxy interface to the events - served by a _ClsLevelDispatch, when there are no - instance-level events present. - - Is replaced by _ListenerCollection when instance-level - events are added. - - """ - - __slots__ = "parent", "parent_listeners", "name" - - propagate: FrozenSet[_ListenerFnType] = frozenset() - listeners: Tuple[()] = () - parent: _ClsLevelDispatch[_ET] - parent_listeners: _ListenerFnSequenceType[_ListenerFnType] - name: str - - def __init__(self, parent: _ClsLevelDispatch[_ET], target_cls: Type[_ET]): - if target_cls not in parent._clslevel: - parent.update_subclass(target_cls) - self.parent = parent - self.parent_listeners = parent._clslevel[target_cls] - self.name = parent.name - - def for_modify( - self, obj: _DispatchCommon[_ET] - ) -> _ListenerCollection[_ET]: - """Return an event collection which can be modified. - - For _EmptyListener at the instance level of - a dispatcher, this generates a new - _ListenerCollection, applies it to the instance, - and returns it. - - """ - obj = cast("_Dispatch[_ET]", obj) - - assert obj._instance_cls is not None - result = _ListenerCollection(self.parent, obj._instance_cls) - if getattr(obj, self.name) is self: - setattr(obj, self.name, result) - else: - assert isinstance(getattr(obj, self.name), _JoinedListener) - return result - - def _needs_modify(self, *args: Any, **kw: Any) -> NoReturn: - raise NotImplementedError("need to call for_modify()") - - def exec_once(self, *args: Any, **kw: Any) -> NoReturn: - self._needs_modify(*args, **kw) - - def exec_once_unless_exception(self, *args: Any, **kw: Any) -> NoReturn: - self._needs_modify(*args, **kw) - - def insert(self, *args: Any, **kw: Any) -> NoReturn: - self._needs_modify(*args, **kw) - - def append(self, *args: Any, **kw: Any) -> NoReturn: - self._needs_modify(*args, **kw) - - def remove(self, *args: Any, **kw: Any) -> NoReturn: - self._needs_modify(*args, **kw) - - def clear(self, *args: Any, **kw: Any) -> NoReturn: - self._needs_modify(*args, **kw) - - def __call__(self, *args: Any, **kw: Any) -> None: - """Execute this event.""" - - for fn in self.parent_listeners: - fn(*args, **kw) - - def __contains__(self, item: Any) -> bool: - return item in self.parent_listeners - - def __len__(self) -> int: - return len(self.parent_listeners) - - def __iter__(self) -> Iterator[_ListenerFnType]: - return iter(self.parent_listeners) - - def __bool__(self) -> bool: - return bool(self.parent_listeners) - - -class _MutexProtocol(Protocol): - def __enter__(self) -> bool: ... - - def __exit__( - self, - exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType], - ) -> Optional[bool]: ... - - -class _CompoundListener(_InstanceLevelDispatch[_ET]): - __slots__ = ( - "_exec_once_mutex", - "_exec_once", - "_exec_w_sync_once", - "_is_asyncio", - ) - - _exec_once_mutex: _MutexProtocol - parent_listeners: Collection[_ListenerFnType] - listeners: Collection[_ListenerFnType] - _exec_once: bool - _exec_w_sync_once: bool - - def __init__(self, *arg: Any, **kw: Any): - super().__init__(*arg, **kw) - self._is_asyncio = False - - def _set_asyncio(self) -> None: - self._is_asyncio = True - - def _memoized_attr__exec_once_mutex(self) -> _MutexProtocol: - if self._is_asyncio: - return AsyncAdaptedLock() - else: - return threading.Lock() - - def _exec_once_impl( - self, retry_on_exception: bool, *args: Any, **kw: Any - ) -> None: - with self._exec_once_mutex: - if not self._exec_once: - try: - self(*args, **kw) - exception = False - except: - exception = True - raise - finally: - if not exception or not retry_on_exception: - self._exec_once = True - - def exec_once(self, *args: Any, **kw: Any) -> None: - """Execute this event, but only if it has not been - executed already for this collection.""" - - if not self._exec_once: - self._exec_once_impl(False, *args, **kw) - - def exec_once_unless_exception(self, *args: Any, **kw: Any) -> None: - """Execute this event, but only if it has not been - executed already for this collection, or was called - by a previous exec_once_unless_exception call and - raised an exception. - - If exec_once was already called, then this method will never run - the callable regardless of whether it raised or not. - - .. versionadded:: 1.3.8 - - """ - if not self._exec_once: - self._exec_once_impl(True, *args, **kw) - - def _exec_w_sync_on_first_run(self, *args: Any, **kw: Any) -> None: - """Execute this event, and use a mutex if it has not been - executed already for this collection, or was called - by a previous _exec_w_sync_on_first_run call and - raised an exception. - - If _exec_w_sync_on_first_run was already called and didn't raise an - exception, then a mutex is not used. - - .. versionadded:: 1.4.11 - - """ - if not self._exec_w_sync_once: - with self._exec_once_mutex: - try: - self(*args, **kw) - except: - raise - else: - self._exec_w_sync_once = True - else: - self(*args, **kw) - - def __call__(self, *args: Any, **kw: Any) -> None: - """Execute this event.""" - - for fn in self.parent_listeners: - fn(*args, **kw) - for fn in self.listeners: - fn(*args, **kw) - - def __contains__(self, item: Any) -> bool: - return item in self.parent_listeners or item in self.listeners - - def __len__(self) -> int: - return len(self.parent_listeners) + len(self.listeners) - - def __iter__(self) -> Iterator[_ListenerFnType]: - return chain(self.parent_listeners, self.listeners) - - def __bool__(self) -> bool: - return bool(self.listeners or self.parent_listeners) - - -class _ListenerCollection(_CompoundListener[_ET]): - """Instance-level attributes on instances of :class:`._Dispatch`. - - Represents a collection of listeners. - - As of 0.7.9, _ListenerCollection is only first - created via the _EmptyListener.for_modify() method. - - """ - - __slots__ = ( - "parent_listeners", - "parent", - "name", - "listeners", - "propagate", - "__weakref__", - ) - - parent_listeners: Collection[_ListenerFnType] - parent: _ClsLevelDispatch[_ET] - name: str - listeners: Deque[_ListenerFnType] - propagate: Set[_ListenerFnType] - - def __init__(self, parent: _ClsLevelDispatch[_ET], target_cls: Type[_ET]): - super().__init__() - if target_cls not in parent._clslevel: - parent.update_subclass(target_cls) - self._exec_once = False - self._exec_w_sync_once = False - self.parent_listeners = parent._clslevel[target_cls] - self.parent = parent - self.name = parent.name - self.listeners = collections.deque() - self.propagate = set() - - def for_modify( - self, obj: _DispatchCommon[_ET] - ) -> _ListenerCollection[_ET]: - """Return an event collection which can be modified. - - For _ListenerCollection at the instance level of - a dispatcher, this returns self. - - """ - return self - - def _update( - self, other: _ListenerCollection[_ET], only_propagate: bool = True - ) -> None: - """Populate from the listeners in another :class:`_Dispatch` - object.""" - existing_listeners = self.listeners - existing_listener_set = set(existing_listeners) - self.propagate.update(other.propagate) - other_listeners = [ - l - for l in other.listeners - if l not in existing_listener_set - and not only_propagate - or l in self.propagate - ] - - existing_listeners.extend(other_listeners) - - if other._is_asyncio: - self._set_asyncio() - - to_associate = other.propagate.union(other_listeners) - registry._stored_in_collection_multi(self, other, to_associate) - - def insert(self, event_key: _EventKey[_ET], propagate: bool) -> None: - if event_key.prepend_to_list(self, self.listeners): - if propagate: - self.propagate.add(event_key._listen_fn) - - def append(self, event_key: _EventKey[_ET], propagate: bool) -> None: - if event_key.append_to_list(self, self.listeners): - if propagate: - self.propagate.add(event_key._listen_fn) - - def remove(self, event_key: _EventKey[_ET]) -> None: - self.listeners.remove(event_key._listen_fn) - self.propagate.discard(event_key._listen_fn) - registry._removed_from_collection(event_key, self) - - def clear(self) -> None: - registry._clear(self, self.listeners) - self.propagate.clear() - self.listeners.clear() - - -class _JoinedListener(_CompoundListener[_ET]): - __slots__ = "parent_dispatch", "name", "local", "parent_listeners" - - parent_dispatch: _DispatchCommon[_ET] - name: str - local: _InstanceLevelDispatch[_ET] - parent_listeners: Collection[_ListenerFnType] - - def __init__( - self, - parent_dispatch: _DispatchCommon[_ET], - name: str, - local: _EmptyListener[_ET], - ): - self._exec_once = False - self.parent_dispatch = parent_dispatch - self.name = name - self.local = local - self.parent_listeners = self.local - - if not typing.TYPE_CHECKING: - # first error, I don't really understand: - # Signature of "listeners" incompatible with - # supertype "_CompoundListener" [override] - # the name / return type are exactly the same - # second error is getattr_isn't typed, the cast() here - # adds too much method overhead - @property - def listeners(self) -> Collection[_ListenerFnType]: - return getattr(self.parent_dispatch, self.name) - - def _adjust_fn_spec( - self, fn: _ListenerFnType, named: bool - ) -> _ListenerFnType: - return self.local._adjust_fn_spec(fn, named) - - def for_modify(self, obj: _DispatchCommon[_ET]) -> _JoinedListener[_ET]: - self.local = self.parent_listeners = self.local.for_modify(obj) - return self - - def insert(self, event_key: _EventKey[_ET], propagate: bool) -> None: - self.local.insert(event_key, propagate) - - def append(self, event_key: _EventKey[_ET], propagate: bool) -> None: - self.local.append(event_key, propagate) - - def remove(self, event_key: _EventKey[_ET]) -> None: - self.local.remove(event_key) - - def clear(self) -> None: - raise NotImplementedError() diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/event/base.py b/venv/lib/python3.11/site-packages/sqlalchemy/event/base.py deleted file mode 100644 index 1f52e2e..0000000 --- a/venv/lib/python3.11/site-packages/sqlalchemy/event/base.py +++ /dev/null @@ -1,462 +0,0 @@ -# event/base.py -# Copyright (C) 2005-2024 the SQLAlchemy authors and contributors -# <see AUTHORS file> -# -# This module is part of SQLAlchemy and is released under -# the MIT License: https://www.opensource.org/licenses/mit-license.php - -"""Base implementation classes. - -The public-facing ``Events`` serves as the base class for an event interface; -its public attributes represent different kinds of events. These attributes -are mirrored onto a ``_Dispatch`` class, which serves as a container for -collections of listener functions. These collections are represented both -at the class level of a particular ``_Dispatch`` class as well as within -instances of ``_Dispatch``. - -""" -from __future__ import annotations - -import typing -from typing import Any -from typing import cast -from typing import Dict -from typing import Generic -from typing import Iterator -from typing import List -from typing import Mapping -from typing import MutableMapping -from typing import Optional -from typing import overload -from typing import Tuple -from typing import Type -from typing import Union -import weakref - -from .attr import _ClsLevelDispatch -from .attr import _EmptyListener -from .attr import _InstanceLevelDispatch -from .attr import _JoinedListener -from .registry import _ET -from .registry import _EventKey -from .. import util -from ..util.typing import Literal - -_registrars: MutableMapping[str, List[Type[_HasEventsDispatch[Any]]]] = ( - util.defaultdict(list) -) - - -def _is_event_name(name: str) -> bool: - # _sa_event prefix is special to support internal-only event names. - # most event names are just plain method names that aren't - # underscored. - - return ( - not name.startswith("_") and name != "dispatch" - ) or name.startswith("_sa_event") - - -class _UnpickleDispatch: - """Serializable callable that re-generates an instance of - :class:`_Dispatch` given a particular :class:`.Events` subclass. - - """ - - def __call__(self, _instance_cls: Type[_ET]) -> _Dispatch[_ET]: - for cls in _instance_cls.__mro__: - if "dispatch" in cls.__dict__: - return cast( - "_Dispatch[_ET]", cls.__dict__["dispatch"].dispatch - )._for_class(_instance_cls) - else: - raise AttributeError("No class with a 'dispatch' member present.") - - -class _DispatchCommon(Generic[_ET]): - __slots__ = () - - _instance_cls: Optional[Type[_ET]] - - def _join(self, other: _DispatchCommon[_ET]) -> _JoinedDispatcher[_ET]: - raise NotImplementedError() - - def __getattr__(self, name: str) -> _InstanceLevelDispatch[_ET]: - raise NotImplementedError() - - @property - def _events(self) -> Type[_HasEventsDispatch[_ET]]: - raise NotImplementedError() - - -class _Dispatch(_DispatchCommon[_ET]): - """Mirror the event listening definitions of an Events class with - listener collections. - - Classes which define a "dispatch" member will return a - non-instantiated :class:`._Dispatch` subclass when the member - is accessed at the class level. When the "dispatch" member is - accessed at the instance level of its owner, an instance - of the :class:`._Dispatch` class is returned. - - A :class:`._Dispatch` class is generated for each :class:`.Events` - class defined, by the :meth:`._HasEventsDispatch._create_dispatcher_class` - method. The original :class:`.Events` classes remain untouched. - This decouples the construction of :class:`.Events` subclasses from - the implementation used by the event internals, and allows - inspecting tools like Sphinx to work in an unsurprising - way against the public API. - - """ - - # "active_history" is an ORM case we add here. ideally a better - # system would be in place for ad-hoc attributes. - __slots__ = "_parent", "_instance_cls", "__dict__", "_empty_listeners" - - _active_history: bool - - _empty_listener_reg: MutableMapping[ - Type[_ET], Dict[str, _EmptyListener[_ET]] - ] = weakref.WeakKeyDictionary() - - _empty_listeners: Dict[str, _EmptyListener[_ET]] - - _event_names: List[str] - - _instance_cls: Optional[Type[_ET]] - - _joined_dispatch_cls: Type[_JoinedDispatcher[_ET]] - - _events: Type[_HasEventsDispatch[_ET]] - """reference back to the Events class. - - Bidirectional against _HasEventsDispatch.dispatch - - """ - - def __init__( - self, - parent: Optional[_Dispatch[_ET]], - instance_cls: Optional[Type[_ET]] = None, - ): - self._parent = parent - self._instance_cls = instance_cls - - if instance_cls: - assert parent is not None - try: - self._empty_listeners = self._empty_listener_reg[instance_cls] - except KeyError: - self._empty_listeners = self._empty_listener_reg[ - instance_cls - ] = { - ls.name: _EmptyListener(ls, instance_cls) - for ls in parent._event_descriptors - } - else: - self._empty_listeners = {} - - def __getattr__(self, name: str) -> _InstanceLevelDispatch[_ET]: - # Assign EmptyListeners as attributes on demand - # to reduce startup time for new dispatch objects. - try: - ls = self._empty_listeners[name] - except KeyError: - raise AttributeError(name) - else: - setattr(self, ls.name, ls) - return ls - - @property - def _event_descriptors(self) -> Iterator[_ClsLevelDispatch[_ET]]: - for k in self._event_names: - # Yield _ClsLevelDispatch related - # to relevant event name. - yield getattr(self, k) - - def _listen(self, event_key: _EventKey[_ET], **kw: Any) -> None: - return self._events._listen(event_key, **kw) - - def _for_class(self, instance_cls: Type[_ET]) -> _Dispatch[_ET]: - return self.__class__(self, instance_cls) - - def _for_instance(self, instance: _ET) -> _Dispatch[_ET]: - instance_cls = instance.__class__ - return self._for_class(instance_cls) - - def _join(self, other: _DispatchCommon[_ET]) -> _JoinedDispatcher[_ET]: - """Create a 'join' of this :class:`._Dispatch` and another. - - This new dispatcher will dispatch events to both - :class:`._Dispatch` objects. - - """ - if "_joined_dispatch_cls" not in self.__class__.__dict__: - cls = type( - "Joined%s" % self.__class__.__name__, - (_JoinedDispatcher,), - {"__slots__": self._event_names}, - ) - self.__class__._joined_dispatch_cls = cls - return self._joined_dispatch_cls(self, other) - - def __reduce__(self) -> Union[str, Tuple[Any, ...]]: - return _UnpickleDispatch(), (self._instance_cls,) - - def _update( - self, other: _Dispatch[_ET], only_propagate: bool = True - ) -> None: - """Populate from the listeners in another :class:`_Dispatch` - object.""" - for ls in other._event_descriptors: - if isinstance(ls, _EmptyListener): - continue - getattr(self, ls.name).for_modify(self)._update( - ls, only_propagate=only_propagate - ) - - def _clear(self) -> None: - for ls in self._event_descriptors: - ls.for_modify(self).clear() - - -def _remove_dispatcher(cls: Type[_HasEventsDispatch[_ET]]) -> None: - for k in cls.dispatch._event_names: - _registrars[k].remove(cls) - if not _registrars[k]: - del _registrars[k] - - -class _HasEventsDispatch(Generic[_ET]): - _dispatch_target: Optional[Type[_ET]] - """class which will receive the .dispatch collection""" - - dispatch: _Dispatch[_ET] - """reference back to the _Dispatch class. - - Bidirectional against _Dispatch._events - - """ - - if typing.TYPE_CHECKING: - - def __getattr__(self, name: str) -> _InstanceLevelDispatch[_ET]: ... - - def __init_subclass__(cls) -> None: - """Intercept new Event subclasses and create associated _Dispatch - classes.""" - - cls._create_dispatcher_class(cls.__name__, cls.__bases__, cls.__dict__) - - @classmethod - def _accept_with( - cls, target: Union[_ET, Type[_ET]], identifier: str - ) -> Optional[Union[_ET, Type[_ET]]]: - raise NotImplementedError() - - @classmethod - def _listen( - cls, - event_key: _EventKey[_ET], - *, - propagate: bool = False, - insert: bool = False, - named: bool = False, - asyncio: bool = False, - ) -> None: - raise NotImplementedError() - - @staticmethod - def _set_dispatch( - klass: Type[_HasEventsDispatch[_ET]], - dispatch_cls: Type[_Dispatch[_ET]], - ) -> _Dispatch[_ET]: - # This allows an Events subclass to define additional utility - # methods made available to the target via - # "self.dispatch._events.<utilitymethod>" - # @staticmethod to allow easy "super" calls while in a metaclass - # constructor. - klass.dispatch = dispatch_cls(None) - dispatch_cls._events = klass - return klass.dispatch - - @classmethod - def _create_dispatcher_class( - cls, classname: str, bases: Tuple[type, ...], dict_: Mapping[str, Any] - ) -> None: - """Create a :class:`._Dispatch` class corresponding to an - :class:`.Events` class.""" - - # there's all kinds of ways to do this, - # i.e. make a Dispatch class that shares the '_listen' method - # of the Event class, this is the straight monkeypatch. - if hasattr(cls, "dispatch"): - dispatch_base = cls.dispatch.__class__ - else: - dispatch_base = _Dispatch - - event_names = [k for k in dict_ if _is_event_name(k)] - dispatch_cls = cast( - "Type[_Dispatch[_ET]]", - type( - "%sDispatch" % classname, - (dispatch_base,), - {"__slots__": event_names}, - ), - ) - - dispatch_cls._event_names = event_names - dispatch_inst = cls._set_dispatch(cls, dispatch_cls) - for k in dispatch_cls._event_names: - setattr(dispatch_inst, k, _ClsLevelDispatch(cls, dict_[k])) - _registrars[k].append(cls) - - for super_ in dispatch_cls.__bases__: - if issubclass(super_, _Dispatch) and super_ is not _Dispatch: - for ls in super_._events.dispatch._event_descriptors: - setattr(dispatch_inst, ls.name, ls) - dispatch_cls._event_names.append(ls.name) - - if getattr(cls, "_dispatch_target", None): - dispatch_target_cls = cls._dispatch_target - assert dispatch_target_cls is not None - if ( - hasattr(dispatch_target_cls, "__slots__") - and "_slots_dispatch" in dispatch_target_cls.__slots__ - ): - dispatch_target_cls.dispatch = slots_dispatcher(cls) - else: - dispatch_target_cls.dispatch = dispatcher(cls) - - -class Events(_HasEventsDispatch[_ET]): - """Define event listening functions for a particular target type.""" - - @classmethod - def _accept_with( - cls, target: Union[_ET, Type[_ET]], identifier: str - ) -> Optional[Union[_ET, Type[_ET]]]: - def dispatch_is(*types: Type[Any]) -> bool: - return all(isinstance(target.dispatch, t) for t in types) - - def dispatch_parent_is(t: Type[Any]) -> bool: - return isinstance( - cast("_JoinedDispatcher[_ET]", target.dispatch).parent, t - ) - - # Mapper, ClassManager, Session override this to - # also accept classes, scoped_sessions, sessionmakers, etc. - if hasattr(target, "dispatch"): - if ( - dispatch_is(cls.dispatch.__class__) - or dispatch_is(type, cls.dispatch.__class__) - or ( - dispatch_is(_JoinedDispatcher) - and dispatch_parent_is(cls.dispatch.__class__) - ) - ): - return target - - return None - - @classmethod - def _listen( - cls, - event_key: _EventKey[_ET], - *, - propagate: bool = False, - insert: bool = False, - named: bool = False, - asyncio: bool = False, - ) -> None: - event_key.base_listen( - propagate=propagate, insert=insert, named=named, asyncio=asyncio - ) - - @classmethod - def _remove(cls, event_key: _EventKey[_ET]) -> None: - event_key.remove() - - @classmethod - def _clear(cls) -> None: - cls.dispatch._clear() - - -class _JoinedDispatcher(_DispatchCommon[_ET]): - """Represent a connection between two _Dispatch objects.""" - - __slots__ = "local", "parent", "_instance_cls" - - local: _DispatchCommon[_ET] - parent: _DispatchCommon[_ET] - _instance_cls: Optional[Type[_ET]] - - def __init__( - self, local: _DispatchCommon[_ET], parent: _DispatchCommon[_ET] - ): - self.local = local - self.parent = parent - self._instance_cls = self.local._instance_cls - - def __getattr__(self, name: str) -> _JoinedListener[_ET]: - # Assign _JoinedListeners as attributes on demand - # to reduce startup time for new dispatch objects. - ls = getattr(self.local, name) - jl = _JoinedListener(self.parent, ls.name, ls) - setattr(self, ls.name, jl) - return jl - - def _listen(self, event_key: _EventKey[_ET], **kw: Any) -> None: - return self.parent._listen(event_key, **kw) - - @property - def _events(self) -> Type[_HasEventsDispatch[_ET]]: - return self.parent._events - - -class dispatcher(Generic[_ET]): - """Descriptor used by target classes to - deliver the _Dispatch class at the class level - and produce new _Dispatch instances for target - instances. - - """ - - def __init__(self, events: Type[_HasEventsDispatch[_ET]]): - self.dispatch = events.dispatch - self.events = events - - @overload - def __get__( - self, obj: Literal[None], cls: Type[Any] - ) -> Type[_Dispatch[_ET]]: ... - - @overload - def __get__(self, obj: Any, cls: Type[Any]) -> _DispatchCommon[_ET]: ... - - def __get__(self, obj: Any, cls: Type[Any]) -> Any: - if obj is None: - return self.dispatch - - disp = self.dispatch._for_instance(obj) - try: - obj.__dict__["dispatch"] = disp - except AttributeError as ae: - raise TypeError( - "target %r doesn't have __dict__, should it be " - "defining _slots_dispatch?" % (obj,) - ) from ae - return disp - - -class slots_dispatcher(dispatcher[_ET]): - def __get__(self, obj: Any, cls: Type[Any]) -> Any: - if obj is None: - return self.dispatch - - if hasattr(obj, "_slots_dispatch"): - return obj._slots_dispatch - - disp = self.dispatch._for_instance(obj) - obj._slots_dispatch = disp - return disp diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/event/legacy.py b/venv/lib/python3.11/site-packages/sqlalchemy/event/legacy.py deleted file mode 100644 index 57e561c..0000000 --- a/venv/lib/python3.11/site-packages/sqlalchemy/event/legacy.py +++ /dev/null @@ -1,246 +0,0 @@ -# event/legacy.py -# Copyright (C) 2005-2024 the SQLAlchemy authors and contributors -# <see AUTHORS file> -# -# This module is part of SQLAlchemy and is released under -# the MIT License: https://www.opensource.org/licenses/mit-license.php - -"""Routines to handle adaption of legacy call signatures, -generation of deprecation notes and docstrings. - -""" -from __future__ import annotations - -import typing -from typing import Any -from typing import Callable -from typing import List -from typing import Optional -from typing import Tuple -from typing import Type - -from .registry import _ET -from .registry import _ListenerFnType -from .. import util -from ..util.compat import FullArgSpec - -if typing.TYPE_CHECKING: - from .attr import _ClsLevelDispatch - from .base import _HasEventsDispatch - - -_LegacySignatureType = Tuple[str, List[str], Optional[Callable[..., Any]]] - - -def _legacy_signature( - since: str, - argnames: List[str], - converter: Optional[Callable[..., Any]] = None, -) -> Callable[[Callable[..., Any]], Callable[..., Any]]: - """legacy sig decorator - - - :param since: string version for deprecation warning - :param argnames: list of strings, which is *all* arguments that the legacy - version accepted, including arguments that are still there - :param converter: lambda that will accept tuple of this full arg signature - and return tuple of new arg signature. - - """ - - def leg(fn: Callable[..., Any]) -> Callable[..., Any]: - if not hasattr(fn, "_legacy_signatures"): - fn._legacy_signatures = [] # type: ignore[attr-defined] - fn._legacy_signatures.append((since, argnames, converter)) # type: ignore[attr-defined] # noqa: E501 - return fn - - return leg - - -def _wrap_fn_for_legacy( - dispatch_collection: _ClsLevelDispatch[_ET], - fn: _ListenerFnType, - argspec: FullArgSpec, -) -> _ListenerFnType: - for since, argnames, conv in dispatch_collection.legacy_signatures: - if argnames[-1] == "**kw": - has_kw = True - argnames = argnames[0:-1] - else: - has_kw = False - - if len(argnames) == len(argspec.args) and has_kw is bool( - argspec.varkw - ): - formatted_def = "def %s(%s%s)" % ( - dispatch_collection.name, - ", ".join(dispatch_collection.arg_names), - ", **kw" if has_kw else "", - ) - warning_txt = ( - 'The argument signature for the "%s.%s" event listener ' - "has changed as of version %s, and conversion for " - "the old argument signature will be removed in a " - 'future release. The new signature is "%s"' - % ( - dispatch_collection.clsname, - dispatch_collection.name, - since, - formatted_def, - ) - ) - - if conv is not None: - assert not has_kw - - def wrap_leg(*args: Any, **kw: Any) -> Any: - util.warn_deprecated(warning_txt, version=since) - assert conv is not None - return fn(*conv(*args)) - - else: - - def wrap_leg(*args: Any, **kw: Any) -> Any: - util.warn_deprecated(warning_txt, version=since) - argdict = dict(zip(dispatch_collection.arg_names, args)) - args_from_dict = [argdict[name] for name in argnames] - if has_kw: - return fn(*args_from_dict, **kw) - else: - return fn(*args_from_dict) - - return wrap_leg - else: - return fn - - -def _indent(text: str, indent: str) -> str: - return "\n".join(indent + line for line in text.split("\n")) - - -def _standard_listen_example( - dispatch_collection: _ClsLevelDispatch[_ET], - sample_target: Any, - fn: _ListenerFnType, -) -> str: - example_kw_arg = _indent( - "\n".join( - "%(arg)s = kw['%(arg)s']" % {"arg": arg} - for arg in dispatch_collection.arg_names[0:2] - ), - " ", - ) - if dispatch_collection.legacy_signatures: - current_since = max( - since - for since, args, conv in dispatch_collection.legacy_signatures - ) - else: - current_since = None - text = ( - "from sqlalchemy import event\n\n\n" - "@event.listens_for(%(sample_target)s, '%(event_name)s')\n" - "def receive_%(event_name)s(" - "%(named_event_arguments)s%(has_kw_arguments)s):\n" - " \"listen for the '%(event_name)s' event\"\n" - "\n # ... (event handling logic) ...\n" - ) - - text %= { - "current_since": ( - " (arguments as of %s)" % current_since if current_since else "" - ), - "event_name": fn.__name__, - "has_kw_arguments": ", **kw" if dispatch_collection.has_kw else "", - "named_event_arguments": ", ".join(dispatch_collection.arg_names), - "example_kw_arg": example_kw_arg, - "sample_target": sample_target, - } - return text - - -def _legacy_listen_examples( - dispatch_collection: _ClsLevelDispatch[_ET], - sample_target: str, - fn: _ListenerFnType, -) -> str: - text = "" - for since, args, conv in dispatch_collection.legacy_signatures: - text += ( - "\n# DEPRECATED calling style (pre-%(since)s, " - "will be removed in a future release)\n" - "@event.listens_for(%(sample_target)s, '%(event_name)s')\n" - "def receive_%(event_name)s(" - "%(named_event_arguments)s%(has_kw_arguments)s):\n" - " \"listen for the '%(event_name)s' event\"\n" - "\n # ... (event handling logic) ...\n" - % { - "since": since, - "event_name": fn.__name__, - "has_kw_arguments": ( - " **kw" if dispatch_collection.has_kw else "" - ), - "named_event_arguments": ", ".join(args), - "sample_target": sample_target, - } - ) - return text - - -def _version_signature_changes( - parent_dispatch_cls: Type[_HasEventsDispatch[_ET]], - dispatch_collection: _ClsLevelDispatch[_ET], -) -> str: - since, args, conv = dispatch_collection.legacy_signatures[0] - return ( - "\n.. versionchanged:: %(since)s\n" - " The :meth:`.%(clsname)s.%(event_name)s` event now accepts the \n" - " arguments %(named_event_arguments)s%(has_kw_arguments)s.\n" - " Support for listener functions which accept the previous \n" - ' argument signature(s) listed above as "deprecated" will be \n' - " removed in a future release." - % { - "since": since, - "clsname": parent_dispatch_cls.__name__, - "event_name": dispatch_collection.name, - "named_event_arguments": ", ".join( - ":paramref:`.%(clsname)s.%(event_name)s.%(param_name)s`" - % { - "clsname": parent_dispatch_cls.__name__, - "event_name": dispatch_collection.name, - "param_name": param_name, - } - for param_name in dispatch_collection.arg_names - ), - "has_kw_arguments": ", **kw" if dispatch_collection.has_kw else "", - } - ) - - -def _augment_fn_docs( - dispatch_collection: _ClsLevelDispatch[_ET], - parent_dispatch_cls: Type[_HasEventsDispatch[_ET]], - fn: _ListenerFnType, -) -> str: - header = ( - ".. container:: event_signatures\n\n" - " Example argument forms::\n" - "\n" - ) - - sample_target = getattr(parent_dispatch_cls, "_target_class_doc", "obj") - text = header + _indent( - _standard_listen_example(dispatch_collection, sample_target, fn), - " " * 8, - ) - if dispatch_collection.legacy_signatures: - text += _indent( - _legacy_listen_examples(dispatch_collection, sample_target, fn), - " " * 8, - ) - - text += _version_signature_changes( - parent_dispatch_cls, dispatch_collection - ) - - return util.inject_docstring_text(fn.__doc__, text, 1) diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/event/registry.py b/venv/lib/python3.11/site-packages/sqlalchemy/event/registry.py deleted file mode 100644 index 773620f..0000000 --- a/venv/lib/python3.11/site-packages/sqlalchemy/event/registry.py +++ /dev/null @@ -1,386 +0,0 @@ -# event/registry.py -# Copyright (C) 2005-2024 the SQLAlchemy authors and contributors -# <see AUTHORS file> -# -# This module is part of SQLAlchemy and is released under -# the MIT License: https://www.opensource.org/licenses/mit-license.php - -"""Provides managed registration services on behalf of :func:`.listen` -arguments. - -By "managed registration", we mean that event listening functions and -other objects can be added to various collections in such a way that their -membership in all those collections can be revoked at once, based on -an equivalent :class:`._EventKey`. - -""" -from __future__ import annotations - -import collections -import types -import typing -from typing import Any -from typing import Callable -from typing import cast -from typing import Deque -from typing import Dict -from typing import Generic -from typing import Iterable -from typing import Optional -from typing import Tuple -from typing import TypeVar -from typing import Union -import weakref - -from .. import exc -from .. import util - -if typing.TYPE_CHECKING: - from .attr import RefCollection - from .base import dispatcher - -_ListenerFnType = Callable[..., Any] -_ListenerFnKeyType = Union[int, Tuple[int, int]] -_EventKeyTupleType = Tuple[int, str, _ListenerFnKeyType] - - -_ET = TypeVar("_ET", bound="EventTarget") - - -class EventTarget: - """represents an event target, that is, something we can listen on - either with that target as a class or as an instance. - - Examples include: Connection, Mapper, Table, Session, - InstrumentedAttribute, Engine, Pool, Dialect. - - """ - - __slots__ = () - - dispatch: dispatcher[Any] - - -_RefCollectionToListenerType = Dict[ - "weakref.ref[RefCollection[Any]]", - "weakref.ref[_ListenerFnType]", -] - -_key_to_collection: Dict[_EventKeyTupleType, _RefCollectionToListenerType] = ( - collections.defaultdict(dict) -) -""" -Given an original listen() argument, can locate all -listener collections and the listener fn contained - -(target, identifier, fn) -> { - ref(listenercollection) -> ref(listener_fn) - ref(listenercollection) -> ref(listener_fn) - ref(listenercollection) -> ref(listener_fn) - } -""" - -_ListenerToEventKeyType = Dict[ - "weakref.ref[_ListenerFnType]", - _EventKeyTupleType, -] -_collection_to_key: Dict[ - weakref.ref[RefCollection[Any]], - _ListenerToEventKeyType, -] = collections.defaultdict(dict) -""" -Given a _ListenerCollection or _ClsLevelListener, can locate -all the original listen() arguments and the listener fn contained - -ref(listenercollection) -> { - ref(listener_fn) -> (target, identifier, fn), - ref(listener_fn) -> (target, identifier, fn), - ref(listener_fn) -> (target, identifier, fn), - } -""" - - -def _collection_gced(ref: weakref.ref[Any]) -> None: - # defaultdict, so can't get a KeyError - if not _collection_to_key or ref not in _collection_to_key: - return - - ref = cast("weakref.ref[RefCollection[EventTarget]]", ref) - - listener_to_key = _collection_to_key.pop(ref) - for key in listener_to_key.values(): - if key in _key_to_collection: - # defaultdict, so can't get a KeyError - dispatch_reg = _key_to_collection[key] - dispatch_reg.pop(ref) - if not dispatch_reg: - _key_to_collection.pop(key) - - -def _stored_in_collection( - event_key: _EventKey[_ET], owner: RefCollection[_ET] -) -> bool: - key = event_key._key - - dispatch_reg = _key_to_collection[key] - - owner_ref = owner.ref - listen_ref = weakref.ref(event_key._listen_fn) - - if owner_ref in dispatch_reg: - return False - - dispatch_reg[owner_ref] = listen_ref - - listener_to_key = _collection_to_key[owner_ref] - listener_to_key[listen_ref] = key - - return True - - -def _removed_from_collection( - event_key: _EventKey[_ET], owner: RefCollection[_ET] -) -> None: - key = event_key._key - - dispatch_reg = _key_to_collection[key] - - listen_ref = weakref.ref(event_key._listen_fn) - - owner_ref = owner.ref - dispatch_reg.pop(owner_ref, None) - if not dispatch_reg: - del _key_to_collection[key] - - if owner_ref in _collection_to_key: - listener_to_key = _collection_to_key[owner_ref] - listener_to_key.pop(listen_ref) - - -def _stored_in_collection_multi( - newowner: RefCollection[_ET], - oldowner: RefCollection[_ET], - elements: Iterable[_ListenerFnType], -) -> None: - if not elements: - return - - oldowner_ref = oldowner.ref - newowner_ref = newowner.ref - - old_listener_to_key = _collection_to_key[oldowner_ref] - new_listener_to_key = _collection_to_key[newowner_ref] - - for listen_fn in elements: - listen_ref = weakref.ref(listen_fn) - try: - key = old_listener_to_key[listen_ref] - except KeyError: - # can occur during interpreter shutdown. - # see #6740 - continue - - try: - dispatch_reg = _key_to_collection[key] - except KeyError: - continue - - if newowner_ref in dispatch_reg: - assert dispatch_reg[newowner_ref] == listen_ref - else: - dispatch_reg[newowner_ref] = listen_ref - - new_listener_to_key[listen_ref] = key - - -def _clear( - owner: RefCollection[_ET], - elements: Iterable[_ListenerFnType], -) -> None: - if not elements: - return - - owner_ref = owner.ref - listener_to_key = _collection_to_key[owner_ref] - for listen_fn in elements: - listen_ref = weakref.ref(listen_fn) - key = listener_to_key[listen_ref] - dispatch_reg = _key_to_collection[key] - dispatch_reg.pop(owner_ref, None) - - if not dispatch_reg: - del _key_to_collection[key] - - -class _EventKey(Generic[_ET]): - """Represent :func:`.listen` arguments.""" - - __slots__ = ( - "target", - "identifier", - "fn", - "fn_key", - "fn_wrap", - "dispatch_target", - ) - - target: _ET - identifier: str - fn: _ListenerFnType - fn_key: _ListenerFnKeyType - dispatch_target: Any - _fn_wrap: Optional[_ListenerFnType] - - def __init__( - self, - target: _ET, - identifier: str, - fn: _ListenerFnType, - dispatch_target: Any, - _fn_wrap: Optional[_ListenerFnType] = None, - ): - self.target = target - self.identifier = identifier - self.fn = fn - if isinstance(fn, types.MethodType): - self.fn_key = id(fn.__func__), id(fn.__self__) - else: - self.fn_key = id(fn) - self.fn_wrap = _fn_wrap - self.dispatch_target = dispatch_target - - @property - def _key(self) -> _EventKeyTupleType: - return (id(self.target), self.identifier, self.fn_key) - - def with_wrapper(self, fn_wrap: _ListenerFnType) -> _EventKey[_ET]: - if fn_wrap is self._listen_fn: - return self - else: - return _EventKey( - self.target, - self.identifier, - self.fn, - self.dispatch_target, - _fn_wrap=fn_wrap, - ) - - def with_dispatch_target(self, dispatch_target: Any) -> _EventKey[_ET]: - if dispatch_target is self.dispatch_target: - return self - else: - return _EventKey( - self.target, - self.identifier, - self.fn, - dispatch_target, - _fn_wrap=self.fn_wrap, - ) - - def listen(self, *args: Any, **kw: Any) -> None: - once = kw.pop("once", False) - once_unless_exception = kw.pop("_once_unless_exception", False) - named = kw.pop("named", False) - - target, identifier, fn = ( - self.dispatch_target, - self.identifier, - self._listen_fn, - ) - - dispatch_collection = getattr(target.dispatch, identifier) - - adjusted_fn = dispatch_collection._adjust_fn_spec(fn, named) - - self = self.with_wrapper(adjusted_fn) - - stub_function = getattr( - self.dispatch_target.dispatch._events, self.identifier - ) - if hasattr(stub_function, "_sa_warn"): - stub_function._sa_warn() - - if once or once_unless_exception: - self.with_wrapper( - util.only_once( - self._listen_fn, retry_on_exception=once_unless_exception - ) - ).listen(*args, **kw) - else: - self.dispatch_target.dispatch._listen(self, *args, **kw) - - def remove(self) -> None: - key = self._key - - if key not in _key_to_collection: - raise exc.InvalidRequestError( - "No listeners found for event %s / %r / %s " - % (self.target, self.identifier, self.fn) - ) - - dispatch_reg = _key_to_collection.pop(key) - - for collection_ref, listener_ref in dispatch_reg.items(): - collection = collection_ref() - listener_fn = listener_ref() - if collection is not None and listener_fn is not None: - collection.remove(self.with_wrapper(listener_fn)) - - def contains(self) -> bool: - """Return True if this event key is registered to listen.""" - return self._key in _key_to_collection - - def base_listen( - self, - propagate: bool = False, - insert: bool = False, - named: bool = False, - retval: Optional[bool] = None, - asyncio: bool = False, - ) -> None: - target, identifier = self.dispatch_target, self.identifier - - dispatch_collection = getattr(target.dispatch, identifier) - - for_modify = dispatch_collection.for_modify(target.dispatch) - if asyncio: - for_modify._set_asyncio() - - if insert: - for_modify.insert(self, propagate) - else: - for_modify.append(self, propagate) - - @property - def _listen_fn(self) -> _ListenerFnType: - return self.fn_wrap or self.fn - - def append_to_list( - self, - owner: RefCollection[_ET], - list_: Deque[_ListenerFnType], - ) -> bool: - if _stored_in_collection(self, owner): - list_.append(self._listen_fn) - return True - else: - return False - - def remove_from_list( - self, - owner: RefCollection[_ET], - list_: Deque[_ListenerFnType], - ) -> None: - _removed_from_collection(self, owner) - list_.remove(self._listen_fn) - - def prepend_to_list( - self, - owner: RefCollection[_ET], - list_: Deque[_ListenerFnType], - ) -> bool: - if _stored_in_collection(self, owner): - list_.appendleft(self._listen_fn) - return True - else: - return False |