summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ext
diff options
context:
space:
mode:
authorNils Philippsen <nils@tiptoe.de>2023-02-28 16:04:54 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2023-03-04 11:09:57 -0500
commit80b7c608835f1be5418d8ed567664654e8b583e3 (patch)
treecb130762a03034df733954dedf2aa68f9196f88b /lib/sqlalchemy/ext
parentda70478eb2eafe9c76b836217371e029c3c820e3 (diff)
downloadsqlalchemy-80b7c608835f1be5418d8ed567664654e8b583e3.tar.gz
restore old *args approach for MutableDict.pop()
The typing change in ba0e508141206efc55cdab91df21c1 changed the semantics of pop() and possibly setdefault() in order to try working at runtime with a two-argument signature. however the implementation for this in cpython likely uses a strict `*args` approach where the lack of the second parameter is explicit, rather than matching to a constant. Restore the old implementation inside of a "not TYPE_CHECKING" block while keeping the type annotated forms intact for typing only. Fixed regression caused by typing added to ``sqlalchemy.ext.mutable`` for :ticket:`8667`, where the semantics of the ``.pop()`` method changed such that the method was non-working. Pull request courtesy Nils Philippsen. Fixes: #9380 Closes: #9381 Co-authored-by: Mike Bayer <mike_mp@zzzcomputing.com> Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/9381 Pull-request-sha: fd903ce1b949d2af26ceb6c2159ad84aab007f3d Change-Id: I213e52f51a795801aacf05307e38cc8c89b54e12
Diffstat (limited to 'lib/sqlalchemy/ext')
-rw-r--r--lib/sqlalchemy/ext/mutable.py65
1 files changed, 35 insertions, 30 deletions
diff --git a/lib/sqlalchemy/ext/mutable.py b/lib/sqlalchemy/ext/mutable.py
index 07f357bd6..940d62b0a 100644
--- a/lib/sqlalchemy/ext/mutable.py
+++ b/lib/sqlalchemy/ext/mutable.py
@@ -369,6 +369,7 @@ from typing import Optional
from typing import overload
from typing import Set
from typing import Tuple
+from typing import TYPE_CHECKING
from typing import TypeVar
from typing import Union
import weakref
@@ -781,27 +782,25 @@ class MutableDict(Mutable, Dict[_KT, _VT]):
super().__setitem__(key, value)
self.changed()
- def _exists(self, value: _T | None) -> TypeGuard[_T]:
- return value is not None
+ if TYPE_CHECKING:
- def _is_none(self, value: _T | None) -> TypeGuard[None]:
- return value is None
+ @overload
+ def setdefault(self, key: _KT) -> _VT | None:
+ ...
- @overload
- def setdefault(self, key: _KT) -> _VT | None:
- ...
+ @overload
+ def setdefault(self, key: _KT, value: _VT) -> _VT:
+ ...
- @overload
- def setdefault(self, key: _KT, value: _VT) -> _VT:
- ...
+ def setdefault(self, key: _KT, value: _VT | None = None) -> _VT | None:
+ ...
- def setdefault(self, key: _KT, value: _VT | None = None) -> _VT | None:
- if self._exists(value):
- result = super().setdefault(key, value)
- else:
- result = super().setdefault(key) # type: ignore[call-arg]
- self.changed()
- return result
+ else:
+
+ def setdefault(self, *arg): # noqa: F811
+ result = super().setdefault(*arg)
+ self.changed()
+ return result
def __delitem__(self, key: _KT) -> None:
"""Detect dictionary del events and emit change events."""
@@ -812,21 +811,27 @@ class MutableDict(Mutable, Dict[_KT, _VT]):
super().update(*a, **kw)
self.changed()
- @overload
- def pop(self, __key: _KT) -> _VT:
- ...
+ if TYPE_CHECKING:
- @overload
- def pop(self, __key: _KT, __default: _VT | _T) -> _VT | _T:
- ...
+ @overload
+ def pop(self, __key: _KT) -> _VT:
+ ...
- def pop(self, __key: _KT, __default: _VT | _T | None = None) -> _VT | _T:
- if self._exists(__default):
- result = super().pop(__key, __default)
- else:
- result = super().pop(__key)
- self.changed()
- return result
+ @overload
+ def pop(self, __key: _KT, __default: _VT | _T) -> _VT | _T:
+ ...
+
+ def pop(
+ self, __key: _KT, __default: _VT | _T | None = None
+ ) -> _VT | _T:
+ ...
+
+ else:
+
+ def pop(self, *arg): # noqa: F811
+ result = super().pop(*arg)
+ self.changed()
+ return result
def popitem(self) -> Tuple[_KT, _VT]:
result = super().popitem()