forked from Alsan/Post_finder
venv
This commit is contained in:
@ -0,0 +1,317 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import collections.abc as cabc
|
||||
import typing as t
|
||||
from functools import update_wrapper
|
||||
from itertools import repeat
|
||||
|
||||
from .._internal import _missing
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
import typing_extensions as te
|
||||
|
||||
K = t.TypeVar("K")
|
||||
V = t.TypeVar("V")
|
||||
T = t.TypeVar("T")
|
||||
F = t.TypeVar("F", bound=cabc.Callable[..., t.Any])
|
||||
|
||||
|
||||
def _immutable_error(self: t.Any) -> t.NoReturn:
|
||||
raise TypeError(f"{type(self).__name__!r} objects are immutable")
|
||||
|
||||
|
||||
class ImmutableListMixin:
|
||||
"""Makes a :class:`list` immutable.
|
||||
|
||||
.. versionadded:: 0.5
|
||||
|
||||
:private:
|
||||
"""
|
||||
|
||||
_hash_cache: int | None = None
|
||||
|
||||
def __hash__(self) -> int:
|
||||
if self._hash_cache is not None:
|
||||
return self._hash_cache
|
||||
rv = self._hash_cache = hash(tuple(self)) # type: ignore[arg-type]
|
||||
return rv
|
||||
|
||||
def __reduce_ex__(self, protocol: t.SupportsIndex) -> t.Any:
|
||||
return type(self), (list(self),) # type: ignore[call-overload]
|
||||
|
||||
def __delitem__(self, key: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def __iadd__(self, other: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def __imul__(self, other: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def __setitem__(self, key: t.Any, value: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def append(self, item: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def remove(self, item: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def extend(self, iterable: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def insert(self, pos: t.Any, value: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def pop(self, index: t.Any = -1) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def reverse(self: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def sort(self, key: t.Any = None, reverse: t.Any = False) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
|
||||
class ImmutableDictMixin(t.Generic[K, V]):
|
||||
"""Makes a :class:`dict` immutable.
|
||||
|
||||
.. versionchanged:: 3.1
|
||||
Disallow ``|=`` operator.
|
||||
|
||||
.. versionadded:: 0.5
|
||||
|
||||
:private:
|
||||
"""
|
||||
|
||||
_hash_cache: int | None = None
|
||||
|
||||
@classmethod
|
||||
@t.overload
|
||||
def fromkeys(
|
||||
cls, keys: cabc.Iterable[K], value: None
|
||||
) -> ImmutableDictMixin[K, t.Any | None]: ...
|
||||
@classmethod
|
||||
@t.overload
|
||||
def fromkeys(cls, keys: cabc.Iterable[K], value: V) -> ImmutableDictMixin[K, V]: ...
|
||||
@classmethod
|
||||
def fromkeys(
|
||||
cls, keys: cabc.Iterable[K], value: V | None = None
|
||||
) -> ImmutableDictMixin[K, t.Any | None] | ImmutableDictMixin[K, V]:
|
||||
instance = super().__new__(cls)
|
||||
instance.__init__(zip(keys, repeat(value))) # type: ignore[misc]
|
||||
return instance
|
||||
|
||||
def __reduce_ex__(self, protocol: t.SupportsIndex) -> t.Any:
|
||||
return type(self), (dict(self),) # type: ignore[call-overload]
|
||||
|
||||
def _iter_hashitems(self) -> t.Iterable[t.Any]:
|
||||
return self.items() # type: ignore[attr-defined,no-any-return]
|
||||
|
||||
def __hash__(self) -> int:
|
||||
if self._hash_cache is not None:
|
||||
return self._hash_cache
|
||||
rv = self._hash_cache = hash(frozenset(self._iter_hashitems()))
|
||||
return rv
|
||||
|
||||
def setdefault(self, key: t.Any, default: t.Any = None) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def update(self, arg: t.Any, /, **kwargs: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def __ior__(self, other: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def pop(self, key: t.Any, default: t.Any = None) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def popitem(self) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def __setitem__(self, key: t.Any, value: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def __delitem__(self, key: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def clear(self) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
|
||||
class ImmutableMultiDictMixin(ImmutableDictMixin[K, V]):
|
||||
"""Makes a :class:`MultiDict` immutable.
|
||||
|
||||
.. versionadded:: 0.5
|
||||
|
||||
:private:
|
||||
"""
|
||||
|
||||
def __reduce_ex__(self, protocol: t.SupportsIndex) -> t.Any:
|
||||
return type(self), (list(self.items(multi=True)),) # type: ignore[attr-defined]
|
||||
|
||||
def _iter_hashitems(self) -> t.Iterable[t.Any]:
|
||||
return self.items(multi=True) # type: ignore[attr-defined,no-any-return]
|
||||
|
||||
def add(self, key: t.Any, value: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def popitemlist(self) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def poplist(self, key: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def setlist(self, key: t.Any, new_list: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def setlistdefault(self, key: t.Any, default_list: t.Any = None) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
|
||||
class ImmutableHeadersMixin:
|
||||
"""Makes a :class:`Headers` immutable. We do not mark them as
|
||||
hashable though since the only usecase for this datastructure
|
||||
in Werkzeug is a view on a mutable structure.
|
||||
|
||||
.. versionchanged:: 3.1
|
||||
Disallow ``|=`` operator.
|
||||
|
||||
.. versionadded:: 0.5
|
||||
|
||||
:private:
|
||||
"""
|
||||
|
||||
def __delitem__(self, key: t.Any, **kwargs: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def __setitem__(self, key: t.Any, value: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def set(self, key: t.Any, value: t.Any, /, **kwargs: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def setlist(self, key: t.Any, values: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def add(self, key: t.Any, value: t.Any, /, **kwargs: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def add_header(self, key: t.Any, value: t.Any, /, **kwargs: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def remove(self, key: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def extend(self, arg: t.Any, /, **kwargs: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def update(self, arg: t.Any, /, **kwargs: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def __ior__(self, other: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def insert(self, pos: t.Any, value: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def pop(self, key: t.Any = None, default: t.Any = _missing) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def popitem(self) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def setdefault(self, key: t.Any, default: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
def setlistdefault(self, key: t.Any, default: t.Any) -> t.NoReturn:
|
||||
_immutable_error(self)
|
||||
|
||||
|
||||
def _always_update(f: F) -> F:
|
||||
def wrapper(
|
||||
self: UpdateDictMixin[t.Any, t.Any], /, *args: t.Any, **kwargs: t.Any
|
||||
) -> t.Any:
|
||||
rv = f(self, *args, **kwargs)
|
||||
|
||||
if self.on_update is not None:
|
||||
self.on_update(self)
|
||||
|
||||
return rv
|
||||
|
||||
return update_wrapper(wrapper, f) # type: ignore[return-value]
|
||||
|
||||
|
||||
class UpdateDictMixin(dict[K, V]):
|
||||
"""Makes dicts call `self.on_update` on modifications.
|
||||
|
||||
.. versionchanged:: 3.1
|
||||
Implement ``|=`` operator.
|
||||
|
||||
.. versionadded:: 0.5
|
||||
|
||||
:private:
|
||||
"""
|
||||
|
||||
on_update: cabc.Callable[[te.Self], None] | None = None
|
||||
|
||||
def setdefault(self: te.Self, key: K, default: V | None = None) -> V:
|
||||
modified = key not in self
|
||||
rv = super().setdefault(key, default) # type: ignore[arg-type]
|
||||
if modified and self.on_update is not None:
|
||||
self.on_update(self)
|
||||
return rv
|
||||
|
||||
@t.overload
|
||||
def pop(self: te.Self, key: K) -> V: ...
|
||||
@t.overload
|
||||
def pop(self: te.Self, key: K, default: V) -> V: ...
|
||||
@t.overload
|
||||
def pop(self: te.Self, key: K, default: T) -> T: ...
|
||||
def pop(
|
||||
self: te.Self,
|
||||
key: K,
|
||||
default: V | T = _missing, # type: ignore[assignment]
|
||||
) -> V | T:
|
||||
modified = key in self
|
||||
if default is _missing:
|
||||
rv = super().pop(key)
|
||||
else:
|
||||
rv = super().pop(key, default) # type: ignore[arg-type]
|
||||
if modified and self.on_update is not None:
|
||||
self.on_update(self)
|
||||
return rv
|
||||
|
||||
@_always_update
|
||||
def __setitem__(self, key: K, value: V) -> None:
|
||||
super().__setitem__(key, value)
|
||||
|
||||
@_always_update
|
||||
def __delitem__(self, key: K) -> None:
|
||||
super().__delitem__(key)
|
||||
|
||||
@_always_update
|
||||
def clear(self) -> None:
|
||||
super().clear()
|
||||
|
||||
@_always_update
|
||||
def popitem(self) -> tuple[K, V]:
|
||||
return super().popitem()
|
||||
|
||||
@_always_update
|
||||
def update( # type: ignore[override]
|
||||
self,
|
||||
arg: cabc.Mapping[K, V] | cabc.Iterable[tuple[K, V]] | None = None,
|
||||
/,
|
||||
**kwargs: V,
|
||||
) -> None:
|
||||
if arg is None:
|
||||
super().update(**kwargs)
|
||||
else:
|
||||
super().update(arg, **kwargs)
|
||||
|
||||
@_always_update
|
||||
def __ior__( # type: ignore[override]
|
||||
self, other: cabc.Mapping[K, V] | cabc.Iterable[tuple[K, V]]
|
||||
) -> te.Self:
|
||||
return super().__ior__(other)
|
Reference in New Issue
Block a user