Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# multidict documentation build configuration file, created by
# sphinx-quickstart on Wed Mar 5 12:35:35 2014.
Expand Down Expand Up @@ -382,7 +381,7 @@ def _replace_missing_aiohttp_hdrs_reference(
env: BuildEnvironment,
node: pending_xref,
contnode: literal,
) -> "reference | None":
) -> reference | None:
if (node.get("refdomain"), node.get("reftype")) != ("py", "mod"):
return None

Expand Down
16 changes: 8 additions & 8 deletions multidict/_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@
@overload
def getall(self, key: str) -> list[_V_co]: ...
@overload
def getall(self, key: str, default: _T) -> Union[list[_V_co], _T]: ...
def getall(self, key: str, default: _T) -> list[_V_co] | _T: ...

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
Comment thread
bdraco marked this conversation as resolved.
Dismissed
@abc.abstractmethod
def getall(self, key: str, default: _T = ...) -> Union[list[_V_co], _T]:
def getall(self, key: str, default: _T = ...) -> list[_V_co] | _T:
"""Return all values for key."""

@overload
def getone(self, key: str) -> _V_co: ...
@overload
def getone(self, key: str, default: _T) -> Union[_V_co, _T]: ...
def getone(self, key: str, default: _T) -> _V_co | _T: ...

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
Comment thread
bdraco marked this conversation as resolved.
Dismissed
@abc.abstractmethod
def getone(self, key: str, default: _T = ...) -> Union[_V_co, _T]:
def getone(self, key: str, default: _T = ...) -> _V_co | _T:
"""Return first value for key."""


Expand All @@ -59,15 +59,15 @@
@overload
def popone(self, key: str) -> _V: ...
@overload
def popone(self, key: str, default: _T) -> Union[_V, _T]: ...
def popone(self, key: str, default: _T) -> _V | _T: ...

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
Comment thread
bdraco marked this conversation as resolved.
Dismissed
@abc.abstractmethod
def popone(self, key: str, default: _T = ...) -> Union[_V, _T]:
def popone(self, key: str, default: _T = ...) -> _V | _T:
"""Remove specified key and return the corresponding value."""

@overload
def popall(self, key: str) -> list[_V]: ...
@overload
def popall(self, key: str, default: _T) -> Union[list[_V], _T]: ...
def popall(self, key: str, default: _T) -> list[_V] | _T: ...

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
Comment thread
bdraco marked this conversation as resolved.
Dismissed
@abc.abstractmethod
def popall(self, key: str, default: _T = ...) -> Union[list[_V], _T]:
def popall(self, key: str, default: _T = ...) -> list[_V] | _T:
"""Remove all occurrences of key and return the list of corresponding values."""
100 changes: 43 additions & 57 deletions multidict/_multidict_py.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"""Case insensitive str."""

__is_istr__ = True
__istr_identity__: Optional[str] = None
__istr_identity__: str | None = None


_V = TypeVar("_V")
Expand Down Expand Up @@ -109,9 +109,7 @@
body = ", ".join(lst)
return f"<{self.__class__.__name__}({body})>"

def _parse_item(
self, arg: Union[tuple[str, _V], _T]
) -> Optional[tuple[int, str, str, _V]]:
def _parse_item(self, arg: tuple[str, _V] | _T) -> tuple[int, str, str, _V] | None:
if not isinstance(arg, tuple):
return None
if len(arg) != 2:
Expand Down Expand Up @@ -167,14 +165,14 @@
break
return ret

def __or__(self, other: Iterable[_T]) -> set[Union[tuple[str, _V], _T]]:
ret: set[Union[tuple[str, _V], _T]] = set(self)
def __or__(self, other: Iterable[_T]) -> set[tuple[str, _V] | _T]:
ret: set[tuple[str, _V] | _T] = set(self)
try:
it = iter(other)
except TypeError:
return NotImplemented
for arg in it:
item: Optional[tuple[int, str, str, _V]] = self._parse_item(arg)
item: tuple[int, str, str, _V] | None = self._parse_item(arg)
if item is None:
ret.add(arg)
continue
Expand All @@ -186,9 +184,9 @@
ret.add(arg)
return ret

def __ror__(self, other: Iterable[_T]) -> set[Union[tuple[str, _V], _T]]:
def __ror__(self, other: Iterable[_T]) -> set[tuple[str, _V] | _T]:
try:
ret: set[Union[tuple[str, _V], _T]] = set(other)
ret: set[tuple[str, _V] | _T] = set(other)
except TypeError:
return NotImplemented
tmp = self._tmp_set(ret)
Expand All @@ -198,8 +196,8 @@
ret.add((e.key, e.value))
return ret

def __sub__(self, other: Iterable[_T]) -> set[Union[tuple[str, _V], _T]]:
ret: set[Union[tuple[str, _V], _T]] = set()
def __sub__(self, other: Iterable[_T]) -> set[tuple[str, _V] | _T]:
ret: set[tuple[str, _V] | _T] = set()
try:
it = iter(other)
except TypeError:
Expand Down Expand Up @@ -232,12 +230,12 @@
ret.add(arg)
return ret

def __xor__(self, other: Iterable[_T]) -> set[Union[tuple[str, _V], _T]]:
def __xor__(self, other: Iterable[_T]) -> set[tuple[str, _V] | _T]:
try:
rgt = set(other)
except TypeError:
return NotImplemented
ret: set[Union[tuple[str, _V], _T]] = self - rgt
ret: set[tuple[str, _V] | _T] = self - rgt
ret |= rgt - self
return ret

Expand Down Expand Up @@ -338,8 +336,8 @@
ret.add(key)
return cast(set[_T], ret)

def __or__(self, other: Iterable[_T]) -> set[Union[str, _T]]:
ret: set[Union[str, _T]] = set(self)
def __or__(self, other: Iterable[_T]) -> set[str | _T]:
ret: set[str | _T] = set(self)
try:
it = iter(other)
except TypeError:
Expand All @@ -352,9 +350,9 @@
ret.add(key)
return ret

def __ror__(self, other: Iterable[_T]) -> set[Union[str, _T]]:
def __ror__(self, other: Iterable[_T]) -> set[str | _T]:
try:
ret: set[Union[str, _T]] = set(other)
ret: set[str | _T] = set(other)
except TypeError:
return NotImplemented

Expand Down Expand Up @@ -399,12 +397,12 @@
ret.discard(key) # type: ignore[arg-type]
return ret

def __xor__(self, other: Iterable[_T]) -> set[Union[str, _T]]:
def __xor__(self, other: Iterable[_T]) -> set[str | _T]:
try:
rgt = set(other)
except TypeError:
return NotImplemented
ret: set[Union[str, _T]] = self - rgt # type: ignore[assignment]
ret: set[str | _T] = self - rgt # type: ignore[assignment]
ret |= rgt - self
return ret

Expand Down Expand Up @@ -482,7 +480,7 @@
usable: int

indices: array # type: ignore[type-arg] # TODO(PY312): array[int]
entries: list[Optional[_Entry[_V]]]
entries: list[_Entry[_V] | None]

@functools.cached_property
def nslots(self) -> int:
Expand All @@ -502,7 +500,7 @@
)

@classmethod
def new(cls, log2_size: int, entries: list[Optional[_Entry[_V]]]) -> Self:
def new(cls, log2_size: int, entries: list[_Entry[_V] | None]) -> Self:
size = 1 << log2_size
usable = (size << 1) // 3
if log2_size < 10:
Expand Down Expand Up @@ -647,12 +645,10 @@
self._used = md._used

@overload
def getall(self, key: str) -> list[_V]: ...

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
@overload
def getall(self, key: str, default: _T) -> Union[list[_V], _T]: ...
def getall(
self, key: str, default: Union[_T, _SENTINEL] = sentinel
) -> Union[list[_V], _T]:
def getall(self, key: str, default: _T) -> list[_V] | _T: ...
Comment thread
bdraco marked this conversation as resolved.
Dismissed
def getall(self, key: str, default: _T | _SENTINEL = sentinel) -> list[_V] | _T:
"""Return a list of all values matching the key."""
identity = self._identity(key)
hash_ = hash(identity)
Expand All @@ -674,12 +670,10 @@
raise KeyError("Key not found: %r" % key)

@overload
def getone(self, key: str) -> _V: ...

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
@overload
def getone(self, key: str, default: _T) -> Union[_V, _T]: ...
def getone(
self, key: str, default: Union[_T, _SENTINEL] = sentinel
) -> Union[_V, _T]:
def getone(self, key: str, default: _T) -> _V | _T: ...
Comment thread
bdraco marked this conversation as resolved.
Dismissed
def getone(self, key: str, default: _T | _SENTINEL = sentinel) -> _V | _T:
"""Get first value matching the key.

Raises KeyError if the key is not found and no default is provided.
Expand All @@ -697,12 +691,12 @@

def __getitem__(self, key: str) -> _V:
return self.getone(key)

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
@overload
def get(self, key: str, /) -> Union[_V, None]: ...
def get(self, key: str, /) -> _V | None: ...

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
Comment thread
bdraco marked this conversation as resolved.
Dismissed
Comment thread
bdraco marked this conversation as resolved.
Dismissed
@overload
def get(self, key: str, /, default: _T) -> Union[_V, _T]: ...
def get(self, key: str, default: Union[_T, None] = None) -> Union[_V, _T, None]:
def get(self, key: str, /, default: _T) -> _V | _T: ...
def get(self, key: str, default: _T | None = None) -> _V | _T | None:
"""Get first value matching the key.

If the key is not found, returns the default (or None if no default is provided)
Expand Down Expand Up @@ -799,7 +793,7 @@
self,
arg: MDArg[_V],
kwargs: Mapping[str, _V],
) -> Iterator[Union[int, _Entry[_V]]]:
) -> Iterator[int | _Entry[_V]]:
identity_func = self._identity
if arg:
if isinstance(arg, MultiDictProxy):
Expand Down Expand Up @@ -904,12 +898,12 @@
self._incr_version()

@overload
def setdefault(

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
self: "MultiDict[Union[_T, None]]", key: str, default: None = None
) -> Union[_T, None]: ...
self: "MultiDict[_T | None]", key: str, default: None = None
) -> _T | None: ...
Comment thread
bdraco marked this conversation as resolved.
Dismissed
@overload
def setdefault(self, key: str, default: _V) -> _V: ...
def setdefault(self, key: str, default: Union[_V, None] = None) -> Union[_V, None]: # type: ignore[misc]
def setdefault(self, key: str, default: _V | None = None) -> _V | None: # type: ignore[misc]
"""Return value for key, set value to default if key is not present."""
identity = self._identity(key)
hash_ = hash(identity)
Expand All @@ -920,12 +914,10 @@
return default

@overload
def popone(self, key: str) -> _V: ...

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
@overload
def popone(self, key: str, default: _T) -> Union[_V, _T]: ...
def popone(
self, key: str, default: Union[_T, _SENTINEL] = sentinel
) -> Union[_V, _T]:
def popone(self, key: str, default: _T) -> _V | _T: ...
def popone(self, key: str, default: _T | _SENTINEL = sentinel) -> _V | _T:
"""Remove specified key and return the corresponding value.

If key is not found, d is returned if given, otherwise
Expand All @@ -950,12 +942,10 @@
pop = popone

@overload
def popall(self, key: str) -> list[_V]: ...

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
@overload
def popall(self, key: str, default: _T) -> Union[list[_V], _T]: ...
def popall(
self, key: str, default: Union[_T, _SENTINEL] = sentinel
) -> Union[list[_V], _T]:
def popall(self, key: str, default: _T) -> list[_V] | _T: ...
Comment thread
bdraco marked this conversation as resolved.
Dismissed
def popall(self, key: str, default: _T | _SENTINEL = sentinel) -> list[_V] | _T:
"""Remove all occurrences of key and return the list of corresponding
values.

Expand Down Expand Up @@ -1153,12 +1143,10 @@
raise TypeError(f"can't pickle {self.__class__.__name__} objects")

@overload
def getall(self, key: str) -> list[_V]: ...

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
@overload
def getall(self, key: str, default: _T) -> Union[list[_V], _T]: ...
def getall(
self, key: str, default: Union[_T, _SENTINEL] = sentinel
) -> Union[list[_V], _T]:
def getall(self, key: str, default: _T) -> list[_V] | _T: ...
Comment thread
bdraco marked this conversation as resolved.
Dismissed
def getall(self, key: str, default: _T | _SENTINEL = sentinel) -> list[_V] | _T:
"""Return a list of all values matching the key."""
if default is not sentinel:
return self._md.getall(key, default)
Expand All @@ -1166,12 +1154,10 @@
return self._md.getall(key)

@overload
def getone(self, key: str) -> _V: ...

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
@overload
def getone(self, key: str, default: _T) -> Union[_V, _T]: ...
def getone(
self, key: str, default: Union[_T, _SENTINEL] = sentinel
) -> Union[_V, _T]:
def getone(self, key: str, default: _T) -> _V | _T: ...
Comment thread
bdraco marked this conversation as resolved.
Dismissed
def getone(self, key: str, default: _T | _SENTINEL = sentinel) -> _V | _T:
"""Get first value matching the key.

Raises KeyError if the key is not found and no default is provided.
Expand All @@ -1185,12 +1171,12 @@

def __getitem__(self, key: str) -> _V:
return self.getone(key)

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
@overload
def get(self, key: str, /) -> Union[_V, None]: ...
def get(self, key: str, /) -> _V | None: ...

Check notice

Code scanning / CodeQL

Statement has no effect Note

This statement has no effect.
Comment thread
bdraco marked this conversation as resolved.
Dismissed
Comment thread
bdraco marked this conversation as resolved.
Dismissed
@overload
def get(self, key: str, /, default: _T) -> Union[_V, _T]: ...
def get(self, key: str, default: Union[_T, None] = None) -> Union[_V, _T, None]:
def get(self, key: str, /, default: _T) -> _V | _T: ...
def get(self, key: str, default: _T | None = None) -> _V | _T | None:
"""Get first value matching the key.

If the key is not found, returns the default (or None if no default is provided)
Expand Down Expand Up @@ -1234,7 +1220,7 @@
class CIMultiDictProxy(_CIMixin, MultiDictProxy[_V]):
"""Read-only proxy for CIMultiDict instance."""

def __init__(self, arg: Union[MultiDict[_V], MultiDictProxy[_V]]):
def __init__(self, arg: MultiDict[_V] | MultiDictProxy[_V]):
if not isinstance(arg, (CIMultiDict, CIMultiDictProxy)):
raise TypeError(
"ctor requires CIMultiDict or CIMultiDictProxy instance"
Expand All @@ -1248,7 +1234,7 @@
return CIMultiDict(self._md)


def getversion(md: Union[MultiDict[object], MultiDictProxy[object]]) -> int:
def getversion(md: MultiDict[object] | MultiDictProxy[object]) -> int:
if isinstance(md, MultiDictProxy):
md = md._md
elif not isinstance(md, MultiDict):
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ build-backend = "setuptools.build_meta"
[tool.ruff]
target-version = "py310"

[tool.ruff.lint]
select = ["UP"]

[tool.cibuildwheel]
test-requires = "-r requirements/pytest.txt"
test-command = 'pytest -m "not leaks" --no-cov {project}/tests'
Expand Down
Loading
Loading