main commit
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-10-16 16:30:25 +09:00
parent 91c7e04474
commit 537e7b363f
1146 changed files with 45926 additions and 77196 deletions

View File

@@ -1,5 +1,5 @@
# orm/collections.py
# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
# Copyright (C) 2005-2023 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
@@ -21,8 +21,6 @@ provided. One is a bundle of generic decorators that map function arguments
and return values to events::
from sqlalchemy.orm.collections import collection
class MyClass:
# ...
@@ -34,6 +32,7 @@ and return values to events::
def pop(self):
return self.data.pop()
The second approach is a bundle of targeted decorators that wrap appropriate
append and remove notifiers around the mutation methods present in the
standard Python ``list``, ``set`` and ``dict`` interfaces. These could be
@@ -74,11 +73,10 @@ generally not needed. Odds are, the extension method will delegate to a
method that's already instrumented. For example::
class QueueIsh(list):
def push(self, item):
self.append(item)
def shift(self):
return self.pop(0)
def push(self, item):
self.append(item)
def shift(self):
return self.pop(0)
There's no need to decorate these methods. ``append`` and ``pop`` are already
instrumented as part of the ``list`` interface. Decorating them would fire
@@ -150,12 +148,10 @@ __all__ = [
"keyfunc_mapping",
"column_keyed_dict",
"attribute_keyed_dict",
"KeyFuncDict",
# old names in < 2.0
"mapped_collection",
"column_mapped_collection",
"attribute_mapped_collection",
"column_keyed_dict",
"attribute_keyed_dict",
"MappedCollection",
"KeyFuncDict",
]
__instrumentation_mutex = threading.Lock()
@@ -171,7 +167,8 @@ _FN = TypeVar("_FN", bound="Callable[..., Any]")
class _CollectionConverterProtocol(Protocol):
def __call__(self, collection: _COL) -> _COL: ...
def __call__(self, collection: _COL) -> _COL:
...
class _AdaptedCollectionProtocol(Protocol):
@@ -197,10 +194,9 @@ class collection:
The recipe decorators all require parens, even those that take no
arguments::
@collection.adds("entity")
@collection.adds('entity')
def insert(self, position, entity): ...
@collection.removes_return()
def popitem(self): ...
@@ -220,13 +216,11 @@ class collection:
@collection.appender
def add(self, append): ...
# or, equivalently
@collection.appender
@collection.adds(1)
def add(self, append): ...
# for mapping type, an 'append' may kick out a previous value
# that occupies that slot. consider d['a'] = 'foo'- any previous
# value in d['a'] is discarded.
@@ -266,11 +260,10 @@ class collection:
@collection.remover
def zap(self, entity): ...
# or, equivalently
@collection.remover
@collection.removes_return()
def zap(self): ...
def zap(self, ): ...
If the value to remove is not present in the collection, you may
raise an exception or return None to ignore the error.
@@ -359,7 +352,7 @@ class collection:
return fn
@staticmethod
def adds(arg: int) -> Callable[[_FN], _FN]:
def adds(arg):
"""Mark the method as adding an entity to the collection.
Adds "add to collection" handling to the method. The decorator
@@ -370,8 +363,7 @@ class collection:
@collection.adds(1)
def push(self, item): ...
@collection.adds("entity")
@collection.adds('entity')
def do_stuff(self, thing, entity=None): ...
"""
@@ -556,9 +548,9 @@ class CollectionAdapter:
self.empty
), "This collection adapter is not in the 'empty' state"
self.empty = False
self.owner_state.dict[self._key] = (
self.owner_state._empty_collections.pop(self._key)
)
self.owner_state.dict[
self._key
] = self.owner_state._empty_collections.pop(self._key)
def _refuse_empty(self) -> NoReturn:
raise sa_exc.InvalidRequestError(
@@ -1562,14 +1554,14 @@ class InstrumentedDict(Dict[_KT, _VT]):
"""An instrumented version of the built-in dict."""
__canned_instrumentation: util.immutabledict[Any, _CollectionFactoryType] = (
util.immutabledict(
{
list: InstrumentedList,
set: InstrumentedSet,
dict: InstrumentedDict,
}
)
__canned_instrumentation: util.immutabledict[
Any, _CollectionFactoryType
] = util.immutabledict(
{
list: InstrumentedList,
set: InstrumentedSet,
dict: InstrumentedDict,
}
)
__interfaces: util.immutabledict[