mirror of https://github.com/pypa/pip
Drop support for soon-EOL Python 3.6
This commit is contained in:
parent
d81c65ace1
commit
0252c04a16
|
@ -102,11 +102,10 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
os: [Ubuntu, MacOS]
|
os: [Ubuntu, MacOS]
|
||||||
python:
|
python:
|
||||||
- 3.6
|
|
||||||
- 3.7
|
- 3.7
|
||||||
- 3.8
|
- 3.8
|
||||||
- 3.9
|
- 3.9
|
||||||
- "3.10.0-alpha - 3.10"
|
- "3.10"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
@ -151,12 +150,11 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
os: [Windows]
|
os: [Windows]
|
||||||
python:
|
python:
|
||||||
- 3.6
|
- 3.7
|
||||||
# Commented out, since Windows tests are expensively slow.
|
# Commented out, since Windows tests are expensively slow.
|
||||||
# - 3.7
|
|
||||||
# - 3.8
|
# - 3.8
|
||||||
- 3.9
|
- 3.9
|
||||||
- "3.10.0-alpha - 3.10"
|
- "3.10"
|
||||||
group: [1, 2]
|
group: [1, 2]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
|
@ -18,17 +18,17 @@ Supported interpreters
|
||||||
|
|
||||||
pip support a variety of Python interpreters:
|
pip support a variety of Python interpreters:
|
||||||
|
|
||||||
- CPython 3.6
|
|
||||||
- CPython 3.7
|
- CPython 3.7
|
||||||
- CPython 3.8
|
- CPython 3.8
|
||||||
- CPython 3.9
|
- CPython 3.9
|
||||||
|
- CPython 3.10
|
||||||
- Latest PyPy3
|
- Latest PyPy3
|
||||||
|
|
||||||
on different operating systems:
|
on different operating systems:
|
||||||
|
|
||||||
- Linux
|
- Linux
|
||||||
- Windows
|
- Windows
|
||||||
- MacOS
|
- macOS
|
||||||
|
|
||||||
and on different architectures:
|
and on different architectures:
|
||||||
|
|
||||||
|
@ -77,9 +77,9 @@ Developer tasks
|
||||||
======== =============== ================ ================== =============
|
======== =============== ================ ================== =============
|
||||||
OS docs lint vendoring packaging
|
OS docs lint vendoring packaging
|
||||||
======== =============== ================ ================== =============
|
======== =============== ================ ================== =============
|
||||||
Linux Github Github Github Github
|
Linux GitHub GitHub GitHub GitHub
|
||||||
Windows Github Github Github Github
|
Windows GitHub GitHub GitHub GitHub
|
||||||
MacOS Github Github Github Github
|
macOS GitHub GitHub GitHub GitHub
|
||||||
======== =============== ================ ================== =============
|
======== =============== ================ ================== =============
|
||||||
|
|
||||||
Actual testing
|
Actual testing
|
||||||
|
@ -88,28 +88,26 @@ Actual testing
|
||||||
+------------------------------+---------------+-----------------+
|
+------------------------------+---------------+-----------------+
|
||||||
| **interpreter** | **unit** | **integration** |
|
| **interpreter** | **unit** | **integration** |
|
||||||
+-----------+----------+-------+---------------+-----------------+
|
+-----------+----------+-------+---------------+-----------------+
|
||||||
| | | CP3.6 | | |
|
|
||||||
| | +-------+---------------+-----------------+
|
|
||||||
| | x86 | CP3.7 | | |
|
| | x86 | CP3.7 | | |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | CP3.8 | | |
|
| | | CP3.8 | | |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | CP3.9 | | |
|
| | | CP3.9 | | |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
|
| | | CP3.10| | |
|
||||||
|
| | +-------+---------------+-----------------+
|
||||||
| | | PyPy3 | | |
|
| | | PyPy3 | | |
|
||||||
| Windows +----------+-------+---------------+-----------------+
|
| Windows +----------+-------+---------------+-----------------+
|
||||||
| | | CP3.6 | Github | Github |
|
| | x64 | CP3.7 | GitHub | GitHub |
|
||||||
| | +-------+---------------+-----------------+
|
|
||||||
| | x64 | CP3.7 | | |
|
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | CP3.8 | | |
|
| | | CP3.8 | | |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | CP3.9 | Github | Github |
|
| | | CP3.9 | GitHub | GitHub |
|
||||||
|
| | +-------+---------------+-----------------+
|
||||||
|
| | | CP3.10| GitHub | GitHub |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | PyPy3 | | |
|
| | | PyPy3 | | |
|
||||||
+-----------+----------+-------+---------------+-----------------+
|
+-----------+----------+-------+---------------+-----------------+
|
||||||
| | | CP3.6 | | |
|
|
||||||
| | +-------+---------------+-----------------+
|
|
||||||
| | x86 | CP3.7 | | |
|
| | x86 | CP3.7 | | |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | CP3.8 | | |
|
| | | CP3.8 | | |
|
||||||
|
@ -118,33 +116,33 @@ Actual testing
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | PyPy3 | | |
|
| | | PyPy3 | | |
|
||||||
| Linux +----------+-------+---------------+-----------------+
|
| Linux +----------+-------+---------------+-----------------+
|
||||||
| | | CP3.6 | Github | Github |
|
| | x64 | CP3.7 | GitHub | GitHub |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | x64 | CP3.7 | Github | Github |
|
| | | CP3.8 | GitHub | GitHub |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | CP3.8 | Github | Github |
|
| | | CP3.9 | GitHub | GitHub |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | CP3.9 | Github | Github |
|
| | | CP3.10| GitHub | GitHub |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | PyPy3 | | |
|
| | | PyPy3 | | |
|
||||||
+-----------+----------+-------+---------------+-----------------+
|
+-----------+----------+-------+---------------+-----------------+
|
||||||
| | | CP3.6 | | |
|
|
||||||
| | +-------+---------------+-----------------+
|
|
||||||
| | x86 | CP3.7 | | |
|
| | x86 | CP3.7 | | |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | CP3.8 | | |
|
| | | CP3.8 | | |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | CP3.9 | | |
|
| | | CP3.9 | | |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
|
| | | CP3.10| | |
|
||||||
|
| | +-------+---------------+-----------------+
|
||||||
| | | PyPy3 | | |
|
| | | PyPy3 | | |
|
||||||
| MacOS +----------+-------+---------------+-----------------+
|
| macOS +----------+-------+---------------+-----------------+
|
||||||
| | | CP3.6 | Github | Github |
|
| | x64 | CP3.7 | GitHub | GitHub |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | x64 | CP3.7 | Github | Github |
|
| | | CP3.8 | GitHub | GitHub |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | CP3.8 | Github | Github |
|
| | | CP3.9 | GitHub | GitHub |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | CP3.9 | Github | Github |
|
| | | CP3.10| GitHub | GitHub |
|
||||||
| | +-------+---------------+-----------------+
|
| | +-------+---------------+-----------------+
|
||||||
| | | PyPy3 | | |
|
| | | PyPy3 | | |
|
||||||
+-----------+----------+-------+---------------+-----------------+
|
+-----------+----------+-------+---------------+-----------------+
|
||||||
|
|
|
@ -70,15 +70,15 @@ To run tests:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ tox -e py36 -- -n auto
|
$ tox -e py310 -- -n auto
|
||||||
|
|
||||||
To run tests without parallelization, run:
|
To run tests without parallelization, run:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ tox -e py36
|
$ tox -e py310
|
||||||
|
|
||||||
The example above runs tests against Python 3.6. You can also use other
|
The example above runs tests against Python 3.10. You can also use other
|
||||||
versions like ``py39`` and ``pypy3``.
|
versions like ``py39`` and ``pypy3``.
|
||||||
|
|
||||||
``tox`` has been configured to forward any additional arguments it is given to
|
``tox`` has been configured to forward any additional arguments it is given to
|
||||||
|
@ -88,11 +88,11 @@ can select tests using the various ways that pytest provides:
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ # Using file name
|
$ # Using file name
|
||||||
$ tox -e py36 -- tests/functional/test_install.py
|
$ tox -e py310 -- tests/functional/test_install.py
|
||||||
$ # Using markers
|
$ # Using markers
|
||||||
$ tox -e py36 -- -m unit
|
$ tox -e py310 -- -m unit
|
||||||
$ # Using keywords
|
$ # Using keywords
|
||||||
$ tox -e py36 -- -k "install and not wheel"
|
$ tox -e py310 -- -k "install and not wheel"
|
||||||
|
|
||||||
Running pip's entire test suite requires supported version control tools
|
Running pip's entire test suite requires supported version control tools
|
||||||
(subversion, bazaar, git, and mercurial) to be installed. If you are missing
|
(subversion, bazaar, git, and mercurial) to be installed. If you are missing
|
||||||
|
@ -101,8 +101,8 @@ explicitly tell pytest to skip those tests:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ tox -e py36 -- -k "not svn"
|
$ tox -e py310 -- -k "not svn"
|
||||||
$ tox -e py36 -- -k "not (svn or git)"
|
$ tox -e py310 -- -k "not (svn or git)"
|
||||||
|
|
||||||
|
|
||||||
Running Linters
|
Running Linters
|
||||||
|
|
|
@ -75,7 +75,7 @@ $ pip install --upgrade pip
|
||||||
The current version of pip works on:
|
The current version of pip works on:
|
||||||
|
|
||||||
- Windows, Linux and MacOS.
|
- Windows, Linux and MacOS.
|
||||||
- CPython 3.6, 3.7, 3.8, 3.9, 3.10 and latest PyPy3.
|
- CPython 3.7, 3.8, 3.9, 3.10 and latest PyPy3.
|
||||||
|
|
||||||
pip is tested to work on the latest patch version of the Python interpreter,
|
pip is tested to work on the latest patch version of the Python interpreter,
|
||||||
for each of the minor versions listed above. Previous patch versions are
|
for each of the minor versions listed above. Previous patch versions are
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Drop support for Python 3.6.
|
|
@ -69,7 +69,7 @@ def should_update_common_wheels() -> bool:
|
||||||
# completely to nox for all our automation. Contributors should prefer using
|
# completely to nox for all our automation. Contributors should prefer using
|
||||||
# `tox -e ...` until this note is removed.
|
# `tox -e ...` until this note is removed.
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10", "pypy3"])
|
@nox.session(python=["3.7", "3.8", "3.9", "3.10", "pypy3"])
|
||||||
def test(session: nox.Session) -> None:
|
def test(session: nox.Session) -> None:
|
||||||
# Get the common wheels.
|
# Get the common wheels.
|
||||||
if should_update_common_wheels():
|
if should_update_common_wheels():
|
||||||
|
|
3
setup.py
3
setup.py
|
@ -37,7 +37,6 @@ setup(
|
||||||
"Programming Language :: Python",
|
"Programming Language :: Python",
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"Programming Language :: Python :: 3 :: Only",
|
"Programming Language :: Python :: 3 :: Only",
|
||||||
"Programming Language :: Python :: 3.6",
|
|
||||||
"Programming Language :: Python :: 3.7",
|
"Programming Language :: Python :: 3.7",
|
||||||
"Programming Language :: Python :: 3.8",
|
"Programming Language :: Python :: 3.8",
|
||||||
"Programming Language :: Python :: 3.9",
|
"Programming Language :: Python :: 3.9",
|
||||||
|
@ -81,5 +80,5 @@ setup(
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
python_requires=">=3.6",
|
python_requires=">=3.7",
|
||||||
)
|
)
|
||||||
|
|
|
@ -197,14 +197,7 @@ class BuildEnvironment:
|
||||||
if not requirements:
|
if not requirements:
|
||||||
return
|
return
|
||||||
with contextlib.ExitStack() as ctx:
|
with contextlib.ExitStack() as ctx:
|
||||||
# TODO: Remove this block when dropping 3.6 support. Python 3.6
|
pip_runnable = ctx.enter_context(_create_standalone_pip())
|
||||||
# lacks importlib.resources and pep517 has issues loading files in
|
|
||||||
# a zip, so we fallback to the "old" method by adding the current
|
|
||||||
# pip directory to the child process's sys.path.
|
|
||||||
if sys.version_info < (3, 7):
|
|
||||||
pip_runnable = os.path.dirname(pip_location)
|
|
||||||
else:
|
|
||||||
pip_runnable = ctx.enter_context(_create_standalone_pip())
|
|
||||||
self._install_requirements(
|
self._install_requirements(
|
||||||
pip_runnable,
|
pip_runnable,
|
||||||
finder,
|
finder,
|
||||||
|
|
|
@ -16,7 +16,6 @@ from pip._internal.models.selection_prefs import SelectionPreferences
|
||||||
from pip._internal.network.session import PipSession
|
from pip._internal.network.session import PipSession
|
||||||
from pip._internal.utils.compat import stdlib_pkgs
|
from pip._internal.utils.compat import stdlib_pkgs
|
||||||
from pip._internal.utils.misc import tabulate, write_output
|
from pip._internal.utils.misc import tabulate, write_output
|
||||||
from pip._internal.utils.parallel import map_multithread
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from pip._internal.metadata.base import DistributionVersion
|
from pip._internal.metadata.base import DistributionVersion
|
||||||
|
@ -254,7 +253,7 @@ class ListCommand(IndexGroupCommand):
|
||||||
dist.latest_filetype = typ
|
dist.latest_filetype = typ
|
||||||
return dist
|
return dist
|
||||||
|
|
||||||
for dist in map_multithread(latest_info, packages):
|
for dist in map(latest_info, packages):
|
||||||
if dist is not None:
|
if dist is not None:
|
||||||
yield dist
|
yield dist
|
||||||
|
|
||||||
|
|
|
@ -1,103 +0,0 @@
|
||||||
"""Convenient parallelization of higher order functions.
|
|
||||||
|
|
||||||
This module provides two helper functions, with appropriate fallbacks on
|
|
||||||
Python 2 and on systems lacking support for synchronization mechanisms:
|
|
||||||
|
|
||||||
- map_multiprocess
|
|
||||||
- map_multithread
|
|
||||||
|
|
||||||
These helpers work like Python 3's map, with two differences:
|
|
||||||
|
|
||||||
- They don't guarantee the order of processing of
|
|
||||||
the elements of the iterable.
|
|
||||||
- The underlying process/thread pools chop the iterable into
|
|
||||||
a number of chunks, so that for very long iterables using
|
|
||||||
a large value for chunksize can make the job complete much faster
|
|
||||||
than using the default value of 1.
|
|
||||||
"""
|
|
||||||
|
|
||||||
__all__ = ["map_multiprocess", "map_multithread"]
|
|
||||||
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from multiprocessing import Pool as ProcessPool
|
|
||||||
from multiprocessing import pool
|
|
||||||
from multiprocessing.dummy import Pool as ThreadPool
|
|
||||||
from typing import Callable, Iterable, Iterator, TypeVar, Union
|
|
||||||
|
|
||||||
from pip._vendor.requests.adapters import DEFAULT_POOLSIZE
|
|
||||||
|
|
||||||
Pool = Union[pool.Pool, pool.ThreadPool]
|
|
||||||
S = TypeVar("S")
|
|
||||||
T = TypeVar("T")
|
|
||||||
|
|
||||||
# On platforms without sem_open, multiprocessing[.dummy] Pool
|
|
||||||
# cannot be created.
|
|
||||||
try:
|
|
||||||
import multiprocessing.synchronize # noqa
|
|
||||||
except ImportError:
|
|
||||||
LACK_SEM_OPEN = True
|
|
||||||
else:
|
|
||||||
LACK_SEM_OPEN = False
|
|
||||||
|
|
||||||
# Incredibly large timeout to work around bpo-8296 on Python 2.
|
|
||||||
TIMEOUT = 2000000
|
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def closing(pool: Pool) -> Iterator[Pool]:
|
|
||||||
"""Return a context manager making sure the pool closes properly."""
|
|
||||||
try:
|
|
||||||
yield pool
|
|
||||||
finally:
|
|
||||||
# For Pool.imap*, close and join are needed
|
|
||||||
# for the returned iterator to begin yielding.
|
|
||||||
pool.close()
|
|
||||||
pool.join()
|
|
||||||
pool.terminate()
|
|
||||||
|
|
||||||
|
|
||||||
def _map_fallback(
|
|
||||||
func: Callable[[S], T], iterable: Iterable[S], chunksize: int = 1
|
|
||||||
) -> Iterator[T]:
|
|
||||||
"""Make an iterator applying func to each element in iterable.
|
|
||||||
|
|
||||||
This function is the sequential fallback either on Python 2
|
|
||||||
where Pool.imap* doesn't react to KeyboardInterrupt
|
|
||||||
or when sem_open is unavailable.
|
|
||||||
"""
|
|
||||||
return map(func, iterable)
|
|
||||||
|
|
||||||
|
|
||||||
def _map_multiprocess(
|
|
||||||
func: Callable[[S], T], iterable: Iterable[S], chunksize: int = 1
|
|
||||||
) -> Iterator[T]:
|
|
||||||
"""Chop iterable into chunks and submit them to a process pool.
|
|
||||||
|
|
||||||
For very long iterables using a large value for chunksize can make
|
|
||||||
the job complete much faster than using the default value of 1.
|
|
||||||
|
|
||||||
Return an unordered iterator of the results.
|
|
||||||
"""
|
|
||||||
with closing(ProcessPool()) as pool:
|
|
||||||
return pool.imap_unordered(func, iterable, chunksize)
|
|
||||||
|
|
||||||
|
|
||||||
def _map_multithread(
|
|
||||||
func: Callable[[S], T], iterable: Iterable[S], chunksize: int = 1
|
|
||||||
) -> Iterator[T]:
|
|
||||||
"""Chop iterable into chunks and submit them to a thread pool.
|
|
||||||
|
|
||||||
For very long iterables using a large value for chunksize can make
|
|
||||||
the job complete much faster than using the default value of 1.
|
|
||||||
|
|
||||||
Return an unordered iterator of the results.
|
|
||||||
"""
|
|
||||||
with closing(ThreadPool(DEFAULT_POOLSIZE)) as pool:
|
|
||||||
return pool.imap_unordered(func, iterable, chunksize)
|
|
||||||
|
|
||||||
|
|
||||||
if LACK_SEM_OPEN:
|
|
||||||
map_multiprocess = map_multithread = _map_fallback
|
|
||||||
else:
|
|
||||||
map_multiprocess = _map_multiprocess
|
|
||||||
map_multithread = _map_multithread
|
|
|
@ -1,73 +0,0 @@
|
||||||
"""Test multiprocessing/multithreading higher-order functions."""
|
|
||||||
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from importlib import import_module
|
|
||||||
from math import factorial
|
|
||||||
from sys import modules
|
|
||||||
from typing import Any, Iterator
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
DUNDER_IMPORT = "builtins.__import__"
|
|
||||||
FUNC, ITERABLE = factorial, range(42)
|
|
||||||
MAPS = "map_multiprocess", "map_multithread"
|
|
||||||
_import = __import__
|
|
||||||
|
|
||||||
|
|
||||||
def unload_parallel() -> None:
|
|
||||||
try:
|
|
||||||
del modules["pip._internal.utils.parallel"]
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def tmp_import_parallel() -> Iterator[Any]:
|
|
||||||
unload_parallel()
|
|
||||||
try:
|
|
||||||
yield import_module("pip._internal.utils.parallel")
|
|
||||||
finally:
|
|
||||||
unload_parallel()
|
|
||||||
|
|
||||||
|
|
||||||
def lack_sem_open(name: str, *args: Any, **kwargs: Any) -> Any:
|
|
||||||
"""Raise ImportError on import of multiprocessing.synchronize."""
|
|
||||||
if name.endswith("synchronize"):
|
|
||||||
raise ImportError
|
|
||||||
return _import(name, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def have_sem_open(name: str, *args: Any, **kwargs: Any) -> Any:
|
|
||||||
"""Make sure multiprocessing.synchronize import is successful."""
|
|
||||||
# We don't care about the return value
|
|
||||||
# since we don't use the pool with this import.
|
|
||||||
if name.endswith("synchronize"):
|
|
||||||
return None
|
|
||||||
return _import(name, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("name", MAPS)
|
|
||||||
def test_lack_sem_open(name: str, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
||||||
"""Test fallback when sem_open is not available.
|
|
||||||
|
|
||||||
If so, multiprocessing[.dummy].Pool will fail to be created and
|
|
||||||
map_async should fallback to map.
|
|
||||||
"""
|
|
||||||
monkeypatch.setattr(DUNDER_IMPORT, lack_sem_open)
|
|
||||||
with tmp_import_parallel() as parallel:
|
|
||||||
assert getattr(parallel, name) is parallel._map_fallback
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("name", MAPS)
|
|
||||||
def test_have_sem_open(name: str, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
||||||
"""Test fallback when sem_open is available."""
|
|
||||||
monkeypatch.setattr(DUNDER_IMPORT, have_sem_open)
|
|
||||||
with tmp_import_parallel() as parallel:
|
|
||||||
assert getattr(parallel, name) is getattr(parallel, f"_{name}")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("name", MAPS)
|
|
||||||
def test_map(name: str) -> None:
|
|
||||||
"""Test correctness of result of asynchronous maps."""
|
|
||||||
map_async = getattr(import_module("pip._internal.utils.parallel"), name)
|
|
||||||
assert set(map_async(FUNC, ITERABLE)) == set(map(FUNC, ITERABLE))
|
|
2
tox.ini
2
tox.ini
|
@ -2,7 +2,7 @@
|
||||||
minversion = 3.4.0
|
minversion = 3.4.0
|
||||||
envlist =
|
envlist =
|
||||||
docs, packaging, lint, vendoring,
|
docs, packaging, lint, vendoring,
|
||||||
py36, py37, py38, py39, py310, pypy3
|
py37, py38, py39, py310, pypy3
|
||||||
|
|
||||||
[helpers]
|
[helpers]
|
||||||
# Wrapper for calls to pip that make sure the version being used is the
|
# Wrapper for calls to pip that make sure the version being used is the
|
||||||
|
|
Loading…
Reference in New Issue