Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-multidict for openSUSE:Factory checked in at 2022-12-08 16:50:06 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-multidict (Old) and /work/SRC/openSUSE:Factory/.python-multidict.new.1835 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-multidict" Thu Dec 8 16:50:06 2022 rev:18 rq:1041242 version:6.0.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-multidict/python-multidict.changes 2022-02-26 17:02:20.543538376 +0100 +++ /work/SRC/openSUSE:Factory/.python-multidict.new.1835/python-multidict.changes 2022-12-08 16:50:12.791184518 +0100 @@ -1,0 +2,7 @@ +Wed Dec 7 19:54:19 UTC 2022 - Yogalakshmi Arunachalam <yarunacha...@suse.com> + +- Update to 6.0.3: + * Features + Declared the official support for Python 3.11 â by @mlegner. (#872) + +------------------------------------------------------------------- Old: ---- multidict-6.0.2.tar.gz New: ---- multidict-6.0.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-multidict.spec ++++++ --- /var/tmp/diff_new_pack.0ME08P/_old 2022-12-08 16:50:13.275186994 +0100 +++ /var/tmp/diff_new_pack.0ME08P/_new 2022-12-08 16:50:13.279187015 +0100 @@ -20,7 +20,7 @@ %define skip_python2 1 %define skip_python36 1 Name: python-multidict -Version: 6.0.2 +Version: 6.0.3 Release: 0 Summary: Multidict implementation License: Apache-2.0 ++++++ multidict-6.0.2.tar.gz -> multidict-6.0.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multidict-6.0.2/CHANGES.rst new/multidict-6.0.3/CHANGES.rst --- old/multidict-6.0.2/CHANGES.rst 2022-01-24 16:59:28.000000000 +0100 +++ new/multidict-6.0.3/CHANGES.rst 2022-12-03 03:30:31.000000000 +0100 @@ -14,6 +14,15 @@ .. towncrier release notes start +6.0.3 (2022-12-03) +================== + +Features +-------- + +- Declared the official support for Python 3.11 â by :user:`mlegner`. (:issue:`872`) + + 6.0.2 (2022-01-24) ================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multidict-6.0.2/Makefile new/multidict-6.0.3/Makefile --- old/multidict-6.0.2/Makefile 2022-01-24 16:59:28.000000000 +0100 +++ new/multidict-6.0.3/Makefile 2022-12-03 03:30:31.000000000 +0100 @@ -40,8 +40,7 @@ fi mypy: - mypy --show-error-codes multidict tests - mypy --show-error-codes tests/test_mypy.py --strict + mypy lint: flake8 black-check mypy isort-check check_changes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multidict-6.0.2/PKG-INFO new/multidict-6.0.3/PKG-INFO --- old/multidict-6.0.2/PKG-INFO 2022-01-24 16:59:30.462962400 +0100 +++ new/multidict-6.0.3/PKG-INFO 2022-12-03 03:30:33.947507600 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: multidict -Version: 6.0.2 +Version: 6.0.3 Summary: multidict implementation Home-page: https://github.com/aio-libs/multidict Author: Andrew Svetlov @@ -12,7 +12,6 @@ Project-URL: Docs: RTD, https://multidict.readthedocs.io Project-URL: GitHub: issues, https://github.com/aio-libs/multidict/issues Project-URL: GitHub: repo, https://github.com/aio-libs/multidict -Platform: UNKNOWN Classifier: License :: OSI Approved :: Apache Software License Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python @@ -21,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 Classifier: Development Status :: 5 - Production/Stable Requires-Python: >=3.7 License-File: LICENSE @@ -54,7 +54,7 @@ :alt: Chat on Gitter Multidict is dict-like collection of *key-value pairs* where key -might be occurred more than once in the container. +might occur more than once in the container. Introduction ------------ @@ -75,12 +75,12 @@ implement the ``collections.abc.Mapping`` interface. Regular mutable (``MultiDict`` and ``CIMultiDict``) classes -implement ``collections.abc.MutableMapping`` and allows to change +implement ``collections.abc.MutableMapping`` and allows them to change their own content. *Case insensitive* (``CIMultiDict`` and -``CIMultiDictProxy``) ones assume the *keys* are case +``CIMultiDictProxy``) assume the *keys* are case insensitive, e.g.:: >>> dct = CIMultiDict(key='val') @@ -91,7 +91,7 @@ *Keys* should be ``str`` or ``istr`` instances. -The library has optional C Extensions for sake of speed. +The library has optional C Extensions for speed. License @@ -109,18 +109,18 @@ The library is Python 3 only! PyPI contains binary wheels for Linux, Windows and MacOS. If you want to install -``multidict`` on another operation system (or *Alpine Linux* inside a Docker) the -Tarball will be used to compile the library from sources. It requires C compiler and -Python headers installed. +``multidict`` on another operating system (or *Alpine Linux* inside a Docker) the +tarball will be used to compile the library from source. It requires a C compiler and +Python headers to be installed. -To skip the compilation please use `MULTIDICT_NO_EXTENSIONS` environment variable, +To skip the compilation, please use the `MULTIDICT_NO_EXTENSIONS` environment variable, e.g.: .. code-block:: bash $ MULTIDICT_NO_EXTENSIONS=1 pip install multidict -Please note, Pure Python (uncompiled) version is about 20-50 times slower depending on +Please note, the pure Python (uncompiled) version is about 20-50 times slower depending on the usage scenario!!! @@ -128,4 +128,3 @@ Changelog --------- See `RTD page <http://multidict.readthedocs.org/en/latest/changes.html>`_. - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multidict-6.0.2/README.rst new/multidict-6.0.3/README.rst --- old/multidict-6.0.2/README.rst 2022-01-24 16:59:28.000000000 +0100 +++ new/multidict-6.0.3/README.rst 2022-12-03 03:30:31.000000000 +0100 @@ -27,7 +27,7 @@ :alt: Chat on Gitter Multidict is dict-like collection of *key-value pairs* where key -might be occurred more than once in the container. +might occur more than once in the container. Introduction ------------ @@ -48,12 +48,12 @@ implement the ``collections.abc.Mapping`` interface. Regular mutable (``MultiDict`` and ``CIMultiDict``) classes -implement ``collections.abc.MutableMapping`` and allows to change +implement ``collections.abc.MutableMapping`` and allows them to change their own content. *Case insensitive* (``CIMultiDict`` and -``CIMultiDictProxy``) ones assume the *keys* are case +``CIMultiDictProxy``) assume the *keys* are case insensitive, e.g.:: >>> dct = CIMultiDict(key='val') @@ -64,7 +64,7 @@ *Keys* should be ``str`` or ``istr`` instances. -The library has optional C Extensions for sake of speed. +The library has optional C Extensions for speed. License @@ -82,18 +82,18 @@ The library is Python 3 only! PyPI contains binary wheels for Linux, Windows and MacOS. If you want to install -``multidict`` on another operation system (or *Alpine Linux* inside a Docker) the -Tarball will be used to compile the library from sources. It requires C compiler and -Python headers installed. +``multidict`` on another operating system (or *Alpine Linux* inside a Docker) the +tarball will be used to compile the library from source. It requires a C compiler and +Python headers to be installed. -To skip the compilation please use `MULTIDICT_NO_EXTENSIONS` environment variable, +To skip the compilation, please use the `MULTIDICT_NO_EXTENSIONS` environment variable, e.g.: .. code-block:: bash $ MULTIDICT_NO_EXTENSIONS=1 pip install multidict -Please note, Pure Python (uncompiled) version is about 20-50 times slower depending on +Please note, the pure Python (uncompiled) version is about 20-50 times slower depending on the usage scenario!!! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multidict-6.0.2/docs/conf.py new/multidict-6.0.3/docs/conf.py --- old/multidict-6.0.2/docs/conf.py 2022-01-24 16:59:28.000000000 +0100 +++ new/multidict-6.0.3/docs/conf.py 2022-12-03 03:30:31.000000000 +0100 @@ -81,8 +81,15 @@ master_doc = "index" # General information about the project. -org = "aio-libs" -project = "multidict" + +github_url = "https://github.com" +github_repo_org = "aio-libs" +github_repo_name = "multidict" +github_repo_slug = f"{github_repo_org}/{github_repo_name}" +github_repo_url = f"{github_url}/{github_repo_slug}" +github_sponsors_url = f"{github_url}/sponsors" + +project = github_repo_name copyright = "2016â{end_year}, Andrew Svetlov".format( end_year=datetime.date.today().year ) @@ -138,6 +145,17 @@ # keep_warnings = False +# -- Extension configuration ------------------------------------------------- + +# -- Options for extlinks extension --------------------------------------- +extlinks = { + "issue": (f"{github_repo_url}/issues/%s", "#%s"), + "pr": (f"{github_repo_url}/pull/%s", "PR #%s"), + "commit": (f"{github_repo_url}/commit/%s", "%s"), + "gh": (f"{github_url}/%s", "GitHub: %s"), + "user": (f"{github_sponsors_url}/%s", "@%s"), +} + # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for @@ -150,8 +168,8 @@ html_theme_options = { # 'logo': 'aiohttp-icon-128x128.png', "description": project, - "github_user": org, - "github_repo": project, + "github_user": github_repo_org, + "github_repo": github_repo_name, "github_button": True, "github_type": "star", "github_banner": True, @@ -322,10 +340,3 @@ # If true, do not generate a @detailmenu in the "Top" node's menu. # texinfo_no_detailmenu = False - -github_repo_url = f"https://github.com/{org}/{project}" - -extlinks = { - "issue": (f"{github_repo_url}/issues/%s", "#"), - "pr": (f"{github_repo_url}/pull/%s", "PR #"), -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multidict-6.0.2/multidict/__init__.py new/multidict-6.0.3/multidict/__init__.py --- old/multidict-6.0.2/multidict/__init__.py 2022-01-24 16:59:28.000000000 +0100 +++ new/multidict-6.0.3/multidict/__init__.py 2022-12-03 03:30:31.000000000 +0100 @@ -20,7 +20,7 @@ "getversion", ) -__version__ = "6.0.2" +__version__ = "6.0.3" try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multidict-6.0.2/multidict/__init__.pyi new/multidict-6.0.3/multidict/__init__.pyi --- old/multidict-6.0.2/multidict/__init__.pyi 2022-01-24 16:59:28.000000000 +0100 +++ new/multidict-6.0.3/multidict/__init__.pyi 2022-12-03 03:30:31.000000000 +0100 @@ -1,23 +1,12 @@ import abc -from typing import ( - Dict, - Generic, - Iterable, - Iterator, - List, - Mapping, - MutableMapping, - Tuple, - TypeVar, - Union, - overload, -) +from collections.abc import Iterable, Iterator, Mapping, MutableMapping +from typing import Generic, TypeAlias, TypeVar, overload class istr(str): ... upstr = istr -_S = Union[str, istr] +_S: TypeAlias = str | istr _T = TypeVar("_T") @@ -28,21 +17,20 @@ class MultiMapping(Mapping[_S, _T_co]): @overload @abc.abstractmethod - def getall(self, key: _S) -> List[_T_co]: ... + def getall(self, key: _S) -> list[_T_co]: ... @overload @abc.abstractmethod - def getall(self, key: _S, default: _D) -> Union[List[_T_co], _D]: ... + def getall(self, key: _S, default: _D) -> list[_T_co] | _D: ... @overload @abc.abstractmethod def getone(self, key: _S) -> _T_co: ... @overload @abc.abstractmethod - def getone(self, key: _S, default: _D) -> Union[_T_co, _D]: ... + def getone(self, key: _S, default: _D) -> _T_co | _D: ... -_Arg = Union[Mapping[str, _T], Mapping[istr, _T], - Dict[str, _T], Dict[istr, _T], - MultiMapping[_T], - Iterable[Tuple[str, _T]], Iterable[Tuple[istr, _T]]] +_Arg: TypeAlias = (Mapping[str, _T] | Mapping[istr, _T] | dict[str, _T] + | dict[istr, _T] | MultiMapping[_T] + | Iterable[tuple[str, _T]] | Iterable[tuple[istr, _T]]) class MutableMultiMapping(MultiMapping[_T], MutableMapping[_S, _T], Generic[_T]): @abc.abstractmethod @@ -54,13 +42,13 @@ def popone(self, key: _S) -> _T: ... @overload @abc.abstractmethod - def popone(self, key: _S, default: _D) -> Union[_T, _D]: ... + def popone(self, key: _S, default: _D) -> _T | _D: ... @overload @abc.abstractmethod - def popall(self, key: _S) -> List[_T]: ... + def popall(self, key: _S) -> list[_T]: ... @overload @abc.abstractmethod - def popall(self, key: _S, default: _D) -> Union[List[_T], _D]: ... + def popall(self, key: _S, default: _D) -> list[_T] | _D: ... class MultiDict(MutableMultiMapping[_T], Generic[_T]): def __init__(self, arg: _Arg[_T] = ..., **kwargs: _T) -> None: ... @@ -71,23 +59,23 @@ def __iter__(self) -> Iterator[_S]: ... def __len__(self) -> int: ... @overload - def getall(self, key: _S) -> List[_T]: ... + def getall(self, key: _S) -> list[_T]: ... @overload - def getall(self, key: _S, default: _D) -> Union[List[_T], _D]: ... + def getall(self, key: _S, default: _D) -> list[_T] | _D: ... @overload def getone(self, key: _S) -> _T: ... @overload - def getone(self, key: _S, default: _D) -> Union[_T, _D]: ... + def getone(self, key: _S, default: _D) -> _T | _D: ... def add(self, key: _S, value: _T) -> None: ... def extend(self, arg: _Arg[_T] = ..., **kwargs: _T) -> None: ... @overload def popone(self, key: _S) -> _T: ... @overload - def popone(self, key: _S, default: _D) -> Union[_T, _D]: ... + def popone(self, key: _S, default: _D) -> _T | _D: ... @overload - def popall(self, key: _S) -> List[_T]: ... + def popall(self, key: _S) -> list[_T]: ... @overload - def popall(self, key: _S, default: _D) -> Union[List[_T], _D]: ... + def popall(self, key: _S, default: _D) -> list[_T] | _D: ... class CIMultiDict(MutableMultiMapping[_T], Generic[_T]): def __init__(self, arg: _Arg[_T] = ..., **kwargs: _T) -> None: ... @@ -98,58 +86,58 @@ def __iter__(self) -> Iterator[_S]: ... def __len__(self) -> int: ... @overload - def getall(self, key: _S) -> List[_T]: ... + def getall(self, key: _S) -> list[_T]: ... @overload - def getall(self, key: _S, default: _D) -> Union[List[_T], _D]: ... + def getall(self, key: _S, default: _D) -> list[_T] | _D: ... @overload def getone(self, key: _S) -> _T: ... @overload - def getone(self, key: _S, default: _D) -> Union[_T, _D]: ... + def getone(self, key: _S, default: _D) -> _T | _D: ... def add(self, key: _S, value: _T) -> None: ... def extend(self, arg: _Arg[_T] = ..., **kwargs: _T) -> None: ... @overload def popone(self, key: _S) -> _T: ... @overload - def popone(self, key: _S, default: _D) -> Union[_T, _D]: ... + def popone(self, key: _S, default: _D) -> _T | _D: ... @overload - def popall(self, key: _S) -> List[_T]: ... + def popall(self, key: _S) -> list[_T]: ... @overload - def popall(self, key: _S, default: _D) -> Union[List[_T], _D]: ... + def popall(self, key: _S, default: _D) -> list[_T] | _D: ... class MultiDictProxy(MultiMapping[_T], Generic[_T]): def __init__( - self, arg: Union[MultiMapping[_T], MutableMultiMapping[_T]] + self, arg: MultiMapping[_T] | MutableMultiMapping[_T] ) -> None: ... def copy(self) -> MultiDict[_T]: ... def __getitem__(self, k: _S) -> _T: ... def __iter__(self) -> Iterator[_S]: ... def __len__(self) -> int: ... @overload - def getall(self, key: _S) -> List[_T]: ... + def getall(self, key: _S) -> list[_T]: ... @overload - def getall(self, key: _S, default: _D) -> Union[List[_T], _D]: ... + def getall(self, key: _S, default: _D) -> list[_T] | _D: ... @overload def getone(self, key: _S) -> _T: ... @overload - def getone(self, key: _S, default: _D) -> Union[_T, _D]: ... + def getone(self, key: _S, default: _D) -> _T | _D: ... class CIMultiDictProxy(MultiMapping[_T], Generic[_T]): def __init__( - self, arg: Union[MultiMapping[_T], MutableMultiMapping[_T]] + self, arg: MultiMapping[_T] | MutableMultiMapping[_T] ) -> None: ... def __getitem__(self, k: _S) -> _T: ... def __iter__(self) -> Iterator[_S]: ... def __len__(self) -> int: ... @overload - def getall(self, key: _S) -> List[_T]: ... + def getall(self, key: _S) -> list[_T]: ... @overload - def getall(self, key: _S, default: _D) -> Union[List[_T], _D]: ... + def getall(self, key: _S, default: _D) -> list[_T] | _D: ... @overload def getone(self, key: _S) -> _T: ... @overload - def getone(self, key: _S, default: _D) -> Union[_T, _D]: ... + def getone(self, key: _S, default: _D) -> _T | _D: ... def copy(self) -> CIMultiDict[_T]: ... def getversion( - md: Union[MultiDict[_T], CIMultiDict[_T], MultiDictProxy[_T], CIMultiDictProxy[_T]] + md: MultiDict[_T] | CIMultiDict[_T] | MultiDictProxy[_T] | CIMultiDictProxy[_T] ) -> int: ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multidict-6.0.2/multidict/_multidict_py.py new/multidict-6.0.3/multidict/_multidict_py.py --- old/multidict-6.0.2/multidict/_multidict_py.py 2022-01-24 16:59:28.000000000 +0100 +++ new/multidict-6.0.3/multidict/_multidict_py.py 2022-12-03 03:30:31.000000000 +0100 @@ -67,7 +67,10 @@ raise KeyError("Key not found: %r" % key) def getone(self, key, default=_marker): - """Get first value matching the key.""" + """Get first value matching the key. + + Raises KeyError if the key is not found and no default is provided. + """ identity = self._title(key) for i, k, v in self._impl._items: if i == identity: @@ -82,7 +85,10 @@ return self.getone(key) def get(self, key, default=None): - """Get first value matching the key.""" + """Get first value matching the key. + + If the key is not found, returns the default (or None if no default is provided) + """ return self.getone(key, default) def __iter__(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multidict-6.0.2/multidict.egg-info/PKG-INFO new/multidict-6.0.3/multidict.egg-info/PKG-INFO --- old/multidict-6.0.2/multidict.egg-info/PKG-INFO 2022-01-24 16:59:30.000000000 +0100 +++ new/multidict-6.0.3/multidict.egg-info/PKG-INFO 2022-12-03 03:30:33.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: multidict -Version: 6.0.2 +Version: 6.0.3 Summary: multidict implementation Home-page: https://github.com/aio-libs/multidict Author: Andrew Svetlov @@ -12,7 +12,6 @@ Project-URL: Docs: RTD, https://multidict.readthedocs.io Project-URL: GitHub: issues, https://github.com/aio-libs/multidict/issues Project-URL: GitHub: repo, https://github.com/aio-libs/multidict -Platform: UNKNOWN Classifier: License :: OSI Approved :: Apache Software License Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python @@ -21,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 Classifier: Development Status :: 5 - Production/Stable Requires-Python: >=3.7 License-File: LICENSE @@ -54,7 +54,7 @@ :alt: Chat on Gitter Multidict is dict-like collection of *key-value pairs* where key -might be occurred more than once in the container. +might occur more than once in the container. Introduction ------------ @@ -75,12 +75,12 @@ implement the ``collections.abc.Mapping`` interface. Regular mutable (``MultiDict`` and ``CIMultiDict``) classes -implement ``collections.abc.MutableMapping`` and allows to change +implement ``collections.abc.MutableMapping`` and allows them to change their own content. *Case insensitive* (``CIMultiDict`` and -``CIMultiDictProxy``) ones assume the *keys* are case +``CIMultiDictProxy``) assume the *keys* are case insensitive, e.g.:: >>> dct = CIMultiDict(key='val') @@ -91,7 +91,7 @@ *Keys* should be ``str`` or ``istr`` instances. -The library has optional C Extensions for sake of speed. +The library has optional C Extensions for speed. License @@ -109,18 +109,18 @@ The library is Python 3 only! PyPI contains binary wheels for Linux, Windows and MacOS. If you want to install -``multidict`` on another operation system (or *Alpine Linux* inside a Docker) the -Tarball will be used to compile the library from sources. It requires C compiler and -Python headers installed. +``multidict`` on another operating system (or *Alpine Linux* inside a Docker) the +tarball will be used to compile the library from source. It requires a C compiler and +Python headers to be installed. -To skip the compilation please use `MULTIDICT_NO_EXTENSIONS` environment variable, +To skip the compilation, please use the `MULTIDICT_NO_EXTENSIONS` environment variable, e.g.: .. code-block:: bash $ MULTIDICT_NO_EXTENSIONS=1 pip install multidict -Please note, Pure Python (uncompiled) version is about 20-50 times slower depending on +Please note, the pure Python (uncompiled) version is about 20-50 times slower depending on the usage scenario!!! @@ -128,4 +128,3 @@ Changelog --------- See `RTD page <http://multidict.readthedocs.org/en/latest/changes.html>`_. - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multidict-6.0.2/multidict.egg-info/SOURCES.txt new/multidict-6.0.3/multidict.egg-info/SOURCES.txt --- old/multidict-6.0.2/multidict.egg-info/SOURCES.txt 2022-01-24 16:59:30.000000000 +0100 +++ new/multidict-6.0.3/multidict.egg-info/SOURCES.txt 2022-12-03 03:30:33.000000000 +0100 @@ -32,6 +32,7 @@ multidict/_multilib/iter.h multidict/_multilib/pair_list.h multidict/_multilib/views.h +tests/__init__.py tests/cimultidict.pickle.0 tests/cimultidict.pickle.1 tests/cimultidict.pickle.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multidict-6.0.2/pyproject.toml new/multidict-6.0.3/pyproject.toml --- old/multidict-6.0.2/pyproject.toml 2022-01-24 16:59:28.000000000 +0100 +++ new/multidict-6.0.3/pyproject.toml 2022-12-03 03:30:31.000000000 +0100 @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=40", "wheel"] +requires = ["setuptools >= 40"] [tool.towncrier] @@ -14,4 +14,4 @@ test-requires = "-r requirements/ci.txt" test-command = "pytest {project}/tests" # don't build PyPy wheels, install from source instead -skip = "pp*" \ No newline at end of file +skip = "pp*" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multidict-6.0.2/setup.py new/multidict-6.0.3/setup.py --- old/multidict-6.0.2/setup.py 2022-01-24 16:59:28.000000000 +0100 +++ new/multidict-6.0.3/setup.py 2022-12-03 03:30:31.000000000 +0100 @@ -65,6 +65,7 @@ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Development Status :: 5 - Production/Stable", ], author="Andrew Svetlov", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multidict-6.0.2/tests/test_multidict.py new/multidict-6.0.3/tests/test_multidict.py --- old/multidict-6.0.2/tests/test_multidict.py 2022-01-24 16:59:28.000000000 +0100 +++ new/multidict-6.0.3/tests/test_multidict.py 2022-12-03 03:30:31.000000000 +0100 @@ -5,13 +5,32 @@ from collections import deque from collections.abc import Mapping from functools import reduce +from typing import ( + Any, + Callable, + Dict, + Iterable, + Iterator, + List, + Mapping, + Set, + Tuple, + Type, + TypeVar, + Union, +) import pytest import multidict +from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy + +_MultiDictClasses = Union[Type[MultiDict[str]], Type[CIMultiDict[str]]] -def chained_callable(module, callables): +def chained_callable( + module: object, callables: Union[str, Iterable[str]] +) -> Callable[..., Any]: """ Returns callable that will get and call all given objects in module in exact order. If `names` is a single object's name function will return @@ -22,28 +41,32 @@ callables = (callables,) if isinstance(callables, str) else callables _callable, *rest = (getattr(module, name) for name in callables) - def chained_call(*args, **kwargs): + def chained_call(*args: object, **kwargs: object) -> Any: return reduce(lambda res, c: c(res), rest, _callable(*args, **kwargs)) - return chained_call if len(rest) > 0 else _callable + return chained_call if len(rest) > 0 else _callable # type: ignore[no-any-return] @pytest.fixture(scope="function") -def cls(request, _multidict): +def cls(request: Any, _multidict: Any) -> Any: return chained_callable(_multidict, request.param) -dict_cls = proxy_cls = cls +@pytest.fixture(scope="function") +def classes(request: Any, _multidict: Any) -> Any: + return tuple(chained_callable(_multidict, n) for n in request.param) @pytest.mark.parametrize("cls", ["MultiDict", "CIMultiDict"], indirect=True) -def test_exposed_names(cls): +def test_exposed_names( + cls: Union[Type[MultiDict[object]], Type[CIMultiDict[object]]] +) -> None: name = cls.__name__ while name.startswith("_"): name = name[1:] - assert name in multidict.__all__ + assert name in multidict.__all__ # type: ignore[attr-defined] @pytest.mark.parametrize( @@ -51,18 +74,28 @@ [("MultiDict", str), (("MultiDict", "MultiDictProxy"), str)], indirect=["cls"], ) -def test__iter__types(cls, key_cls): +def test__iter__types( + cls: Type[MultiDict[Union[str, int]]], key_cls: Type[object] +) -> None: d = cls([("key", "one"), ("key2", "two"), ("key", 3)]) for i in d: assert type(i) is key_cls, (type(i), key_cls) +_ClsPair = TypeVar( + "_ClsPair", + Tuple[Type[MultiDict[str]], Type[MultiDictProxy[str]]], + Tuple[Type[CIMultiDict[str]], Type[CIMultiDictProxy[str]]], +) + + @pytest.mark.parametrize( - "dict_cls, proxy_cls", + "classes", [("MultiDict", "MultiDictProxy"), ("CIMultiDict", "CIMultiDictProxy")], indirect=True, ) -def test_proxy_copy(dict_cls, proxy_cls): +def test_proxy_copy(classes: _ClsPair) -> None: + dict_cls, proxy_cls = classes d1 = dict_cls(key="value", a="b") p1 = proxy_cls(d1) @@ -76,26 +109,31 @@ ["MultiDict", "CIMultiDict", "MultiDictProxy", "CIMultiDictProxy"], indirect=True, ) -def test_subclassing(cls): - class MyClass(cls): +def test_subclassing(cls: Any) -> None: + class MyClass(cls): # type: ignore[valid-type,misc] pass class BaseMultiDictTest: - def test_instantiate__empty(self, cls): + def test_instantiate__empty(self, cls: _MultiDictClasses) -> None: d = cls() - assert d == {} + empty: Mapping[str, str] = {} + assert d == empty assert len(d) == 0 assert list(d.keys()) == [] assert list(d.values()) == [] assert list(d.items()) == [] - assert cls() != list() + assert cls() != list() # type: ignore[comparison-overlap] with pytest.raises(TypeError, match=r"(2 given)"): - cls(("key1", "value1"), ("key2", "value2")) + cls(("key1", "value1"), ("key2", "value2")) # type: ignore[arg-type,call-arg] # noqa: E501 @pytest.mark.parametrize("arg0", [[("key", "value1")], {"key": "value1"}]) - def test_instantiate__from_arg0(self, cls, arg0): + def test_instantiate__from_arg0( + self, + cls: _MultiDictClasses, + arg0: Union[List[Tuple[str, str]], Dict[str, str]], + ) -> None: d = cls(arg0) assert d == {"key": "value1"} @@ -104,7 +142,7 @@ assert list(d.values()) == ["value1"] assert list(d.items()) == [("key", "value1")] - def test_instantiate__with_kwargs(self, cls): + def test_instantiate__with_kwargs(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")], key2="value2") assert d == {"key": "value1", "key2": "value2"} @@ -113,7 +151,9 @@ assert sorted(d.values()) == ["value1", "value2"] assert sorted(d.items()) == [("key", "value1"), ("key2", "value2")] - def test_instantiate__from_generator(self, cls): + def test_instantiate__from_generator( + self, cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]] + ) -> None: d = cls((str(i), i) for i in range(2)) assert d == {"0": 0, "1": 1} @@ -122,16 +162,19 @@ assert sorted(d.values()) == [0, 1] assert sorted(d.items()) == [("0", 0), ("1", 1)] - def test_instantiate__from_list_of_lists(self, cls): - d = cls([["key", "value1"]]) + def test_instantiate__from_list_of_lists(self, cls: _MultiDictClasses) -> None: + # Should work at runtime, but won't type check. + d = cls([["key", "value1"]]) # type: ignore[list-item] assert d == {"key": "value1"} - def test_instantiate__from_list_of_custom_pairs(self, cls): + def test_instantiate__from_list_of_custom_pairs( + self, cls: _MultiDictClasses + ) -> None: class Pair: - def __len__(self): + def __len__(self) -> int: return 2 - def __getitem__(self, pos): + def __getitem__(self, pos: int) -> str: if pos == 0: return "key" elif pos == 1: @@ -139,10 +182,11 @@ else: raise IndexError - d = cls([Pair()]) + # Works at runtime, but won't type check. + d = cls([Pair()]) # type: ignore[list-item] assert d == {"key": "value1"} - def test_getone(self, cls): + def test_getone(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")], key="value2") assert d.getone("key") == "value1" @@ -158,12 +202,15 @@ def test__iter__( self, - cls, - ): + cls: Union[Type[MultiDict[Union[str, int]]], Type[CIMultiDict[Union[str, int]]]] + ) -> None: d = cls([("key", "one"), ("key2", "two"), ("key", 3)]) assert list(d) == ["key", "key2", "key"] - def test_keys__contains(self, cls): + def test_keys__contains( + self, + cls: Union[Type[MultiDict[Union[str, int]]], Type[CIMultiDict[Union[str, int]]]] + ) -> None: d = cls([("key", "one"), ("key2", "two"), ("key", 3)]) assert list(d.keys()) == ["key", "key2", "key"] @@ -173,7 +220,10 @@ assert "foo" not in d.keys() - def test_values__contains(self, cls): + def test_values__contains( + self, + cls: Union[Type[MultiDict[Union[str, int]]], Type[CIMultiDict[Union[str, int]]]] + ) -> None: d = cls([("key", "one"), ("key", "two"), ("key", 3)]) assert list(d.values()) == ["one", "two", 3] @@ -184,7 +234,10 @@ assert "foo" not in d.values() - def test_items__contains(self, cls): + def test_items__contains( + self, + cls: Union[Type[MultiDict[Union[str, int]]], Type[CIMultiDict[Union[str, int]]]] + ) -> None: d = cls([("key", "one"), ("key", "two"), ("key", 3)]) assert list(d.items()) == [("key", "one"), ("key", "two"), ("key", 3)] @@ -195,72 +248,74 @@ assert ("foo", "bar") not in d.items() - def test_cannot_create_from_unaccepted(self, cls): + def test_cannot_create_from_unaccepted(self, cls: _MultiDictClasses) -> None: with pytest.raises(TypeError): - cls([(1, 2, 3)]) + cls([(1, 2, 3)]) # type: ignore[list-item] - def test_keys_is_set_less(self, cls): + def test_keys_is_set_less(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")]) assert d.keys() < {"key", "key2"} - def test_keys_is_set_less_equal(self, cls): + def test_keys_is_set_less_equal(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")]) assert d.keys() <= {"key"} - def test_keys_is_set_equal(self, cls): + def test_keys_is_set_equal(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")]) assert d.keys() == {"key"} - def test_keys_is_set_greater(self, cls): + def test_keys_is_set_greater(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")]) assert {"key", "key2"} > d.keys() - def test_keys_is_set_greater_equal(self, cls): + def test_keys_is_set_greater_equal(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")]) assert {"key"} >= d.keys() - def test_keys_is_set_not_equal(self, cls): + def test_keys_is_set_not_equal(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")]) assert d.keys() != {"key2"} - def test_eq(self, cls): + def test_eq(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")]) assert {"key": "value1"} == d - def test_eq2(self, cls): + def test_eq2(self, cls: _MultiDictClasses) -> None: d1 = cls([("key", "value1")]) d2 = cls([("key2", "value1")]) assert d1 != d2 - def test_eq3(self, cls): + def test_eq3(self, cls: _MultiDictClasses) -> None: d1 = cls([("key", "value1")]) d2 = cls() assert d1 != d2 - def test_eq_other_mapping_contains_more_keys(self, cls): + def test_eq_other_mapping_contains_more_keys(self, cls: _MultiDictClasses) -> None: d1 = cls(foo="bar") d2 = dict(foo="bar", bar="baz") assert d1 != d2 - def test_eq_bad_mapping_len(self, cls): - class BadMapping(Mapping): - def __getitem__(self, key): + def test_eq_bad_mapping_len( + self, cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]] + ) -> None: + class BadMapping(Mapping[str, int]): + def __getitem__(self, key: str) -> int: return 1 - def __iter__(self): + def __iter__(self) -> Iterator[str]: yield "a" - def __len__(self): + def __len__(self) -> int: # type: ignore[return] 1 / 0 d1 = cls(a=1) @@ -268,15 +323,18 @@ with pytest.raises(ZeroDivisionError): d1 == d2 - def test_eq_bad_mapping_getitem(self, cls): - class BadMapping(Mapping): - def __getitem__(self, key): + def test_eq_bad_mapping_getitem( + self, + cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]] + ) -> None: + class BadMapping(Mapping[str, int]): + def __getitem__(self, key: str) -> int: # type: ignore[return] 1 / 0 - def __iter__(self): + def __iter__(self) -> Iterator[str]: yield "a" - def __len__(self): + def __len__(self) -> int: return 1 d1 = cls(a=1) @@ -284,58 +342,60 @@ with pytest.raises(ZeroDivisionError): d1 == d2 - def test_ne(self, cls): + def test_ne(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")]) assert d != {"key": "another_value"} - def test_and(self, cls): + def test_and(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")]) assert {"key"} == d.keys() & {"key", "key2"} - def test_and2(self, cls): + def test_and2(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")]) assert {"key"} == {"key", "key2"} & d.keys() - def test_or(self, cls): + def test_or(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")]) assert {"key", "key2"} == d.keys() | {"key2"} - def test_or2(self, cls): + def test_or2(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1")]) assert {"key", "key2"} == {"key2"} | d.keys() - def test_sub(self, cls): + def test_sub(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1"), ("key2", "value2")]) assert {"key"} == d.keys() - {"key2"} - def test_sub2(self, cls): + def test_sub2(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1"), ("key2", "value2")]) assert {"key3"} == {"key", "key2", "key3"} - d.keys() - def test_xor(self, cls): + def test_xor(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1"), ("key2", "value2")]) assert {"key", "key3"} == d.keys() ^ {"key2", "key3"} - def test_xor2(self, cls): + def test_xor2(self, cls: _MultiDictClasses) -> None: d = cls([("key", "value1"), ("key2", "value2")]) assert {"key", "key3"} == {"key2", "key3"} ^ d.keys() @pytest.mark.parametrize("_set, expected", [({"key2"}, True), ({"key"}, False)]) - def test_isdisjoint(self, cls, _set, expected): + def test_isdisjoint( + self, cls: _MultiDictClasses, _set: Set[str], expected: bool + ) -> None: d = cls([("key", "value1")]) assert d.keys().isdisjoint(_set) == expected - def test_repr_issue_410(self, cls): + def test_repr_issue_410(self, cls: _MultiDictClasses) -> None: d = cls() try: @@ -350,7 +410,12 @@ "op", [operator.or_, operator.and_, operator.sub, operator.xor] ) @pytest.mark.parametrize("other", [{"other"}]) - def test_op_issue_410(self, cls, op, other): + def test_op_issue_410( + self, + cls: _MultiDictClasses, + op: Callable[[object, object], object], + other: Set[str], + ) -> None: d = cls([("key", "value")]) try: @@ -361,10 +426,10 @@ assert sys.exc_info()[1] == e - def test_weakref(self, cls): + def test_weakref(self, cls: _MultiDictClasses) -> None: called = False - def cb(wr): + def cb(wr: object) -> None: nonlocal called called = True @@ -375,34 +440,52 @@ assert called del wr - def test_iter_length_hint_keys(self, cls): + def test_iter_length_hint_keys( + self, + cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]] + ) -> None: md = cls(a=1, b=2) it = iter(md.keys()) - assert it.__length_hint__() == 2 + assert it.__length_hint__() == 2 # type: ignore[attr-defined] - def test_iter_length_hint_items(self, cls): + def test_iter_length_hint_items( + self, + cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]] + ) -> None: md = cls(a=1, b=2) it = iter(md.items()) - assert it.__length_hint__() == 2 + assert it.__length_hint__() == 2 # type: ignore[attr-defined] - def test_iter_length_hint_values(self, cls): + def test_iter_length_hint_values( + self, + cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]] + ) -> None: md = cls(a=1, b=2) it = iter(md.values()) - assert it.__length_hint__() == 2 + assert it.__length_hint__() == 2 # type: ignore[attr-defined] - def test_ctor_list_arg_and_kwds(self, cls): + def test_ctor_list_arg_and_kwds( + self, + cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]] + ) -> None: arg = [("a", 1)] obj = cls(arg, b=2) assert list(obj.items()) == [("a", 1), ("b", 2)] assert arg == [("a", 1)] - def test_ctor_tuple_arg_and_kwds(self, cls): + def test_ctor_tuple_arg_and_kwds( + self, + cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]] + ) -> None: arg = (("a", 1),) obj = cls(arg, b=2) assert list(obj.items()) == [("a", 1), ("b", 2)] assert arg == (("a", 1),) - def test_ctor_deque_arg_and_kwds(self, cls): + def test_ctor_deque_arg_and_kwds( + self, + cls: Union[Type[MultiDict[int]], Type[CIMultiDict[int]]] + ) -> None: arg = deque([("a", 1)]) obj = cls(arg, b=2) assert list(obj.items()) == [("a", 1), ("b", 2)] @@ -411,10 +494,10 @@ class TestMultiDict(BaseMultiDictTest): @pytest.fixture(params=["MultiDict", ("MultiDict", "MultiDictProxy")]) - def cls(self, request, _multidict): + def cls(self, request: Any, _multidict: Any) -> Any: return chained_callable(_multidict, request.param) - def test__repr__(self, cls): + def test__repr__(self, cls: Type[MultiDict[str]]) -> None: d = cls() _cls = type(d) @@ -424,7 +507,7 @@ assert str(d) == "<%s('key': 'one', 'key': 'two')>" % _cls.__name__ - def test_getall(self, cls): + def test_getall(self, cls: Type[MultiDict[str]]) -> None: d = cls([("key", "value1")], key="value2") assert d != {"key": "value1"} @@ -438,36 +521,38 @@ default = object() assert d.getall("some_key", default) is default - def test_preserve_stable_ordering(self, cls): + def test_preserve_stable_ordering( + self, cls: Type[MultiDict[Union[str, int]]] + ) -> None: d = cls([("a", 1), ("b", "2"), ("a", 3)]) s = "&".join("{}={}".format(k, v) for k, v in d.items()) assert s == "a=1&b=2&a=3" - def test_get(self, cls): + def test_get(self, cls: Type[MultiDict[int]]) -> None: d = cls([("a", 1), ("a", 2)]) assert d["a"] == 1 - def test_items__repr__(self, cls): + def test_items__repr__(self, cls: Type[MultiDict[str]]) -> None: d = cls([("key", "value1")], key="value2") expected = "_ItemsView('key': 'value1', 'key': 'value2')" assert repr(d.items()) == expected - def test_keys__repr__(self, cls): + def test_keys__repr__(self, cls: Type[MultiDict[str]]) -> None: d = cls([("key", "value1")], key="value2") assert repr(d.keys()) == "_KeysView('key', 'key')" - def test_values__repr__(self, cls): + def test_values__repr__(self, cls: Type[MultiDict[str]]) -> None: d = cls([("key", "value1")], key="value2") assert repr(d.values()) == "_ValuesView('value1', 'value2')" class TestCIMultiDict(BaseMultiDictTest): @pytest.fixture(params=["CIMultiDict", ("CIMultiDict", "CIMultiDictProxy")]) - def cls(self, request, _multidict): + def cls(self, request: Any, _multidict: Any) -> Any: return chained_callable(_multidict, request.param) - def test_basics(self, cls): + def test_basics(self, cls: Type[CIMultiDict[str]]) -> None: d = cls([("KEY", "value1")], KEY="value2") assert d.getone("key") == "value1" @@ -481,7 +566,7 @@ with pytest.raises(KeyError, match="key2"): d.getone("key2") - def test_getall(self, cls): + def test_getall(self, cls: Type[CIMultiDict[str]]) -> None: d = cls([("KEY", "value1")], KEY="value2") assert not d == {"KEY": "value1"} @@ -492,26 +577,26 @@ with pytest.raises(KeyError, match="some_key"): d.getall("some_key") - def test_get(self, cls): + def test_get(self, cls: Type[CIMultiDict[int]]) -> None: d = cls([("A", 1), ("a", 2)]) assert 1 == d["a"] - def test__repr__(self, cls): + def test__repr__(self, cls: Type[CIMultiDict[str]]) -> None: d = cls([("KEY", "value1")], key="value2") _cls = type(d) expected = "<%s('KEY': 'value1', 'key': 'value2')>" % _cls.__name__ assert str(d) == expected - def test_items__repr__(self, cls): + def test_items__repr__(self, cls: Type[CIMultiDict[str]]) -> None: d = cls([("KEY", "value1")], key="value2") expected = "_ItemsView('KEY': 'value1', 'key': 'value2')" assert repr(d.items()) == expected - def test_keys__repr__(self, cls): + def test_keys__repr__(self, cls: Type[CIMultiDict[str]]) -> None: d = cls([("KEY", "value1")], key="value2") assert repr(d.keys()) == "_KeysView('KEY', 'key')" - def test_values__repr__(self, cls): + def test_values__repr__(self, cls: Type[CIMultiDict[str]]) -> None: d = cls([("KEY", "value1")], key="value2") assert repr(d.values()) == "_ValuesView('value1', 'value2')"