Merge pull request #10396 from pytest-dev/pylib-hax
vendor py.path and py.error
This commit is contained in:
commit
ffe49ac17c
|
@ -66,7 +66,7 @@ jobs:
|
||||||
- name: "windows-py37-pluggy"
|
- name: "windows-py37-pluggy"
|
||||||
python: "3.7"
|
python: "3.7"
|
||||||
os: windows-latest
|
os: windows-latest
|
||||||
tox_env: "py37-pluggymain-xdist"
|
tox_env: "py37-pluggymain-pylib-xdist"
|
||||||
- name: "windows-py38"
|
- name: "windows-py38"
|
||||||
python: "3.8"
|
python: "3.8"
|
||||||
os: windows-latest
|
os: windows-latest
|
||||||
|
@ -93,7 +93,7 @@ jobs:
|
||||||
- name: "ubuntu-py37-pluggy"
|
- name: "ubuntu-py37-pluggy"
|
||||||
python: "3.7"
|
python: "3.7"
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
tox_env: "py37-pluggymain-xdist"
|
tox_env: "py37-pluggymain-pylib-xdist"
|
||||||
- name: "ubuntu-py37-freeze"
|
- name: "ubuntu-py37-freeze"
|
||||||
python: "3.7"
|
python: "3.7"
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
|
|
|
@ -65,7 +65,6 @@ repos:
|
||||||
args: []
|
args: []
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
- iniconfig>=1.1.0
|
- iniconfig>=1.1.0
|
||||||
- py>=1.8.2
|
|
||||||
- attrs>=19.2.0
|
- attrs>=19.2.0
|
||||||
- packaging
|
- packaging
|
||||||
- tomli
|
- tomli
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
pytest no longer depends on the ``py`` library. ``pytest`` provides a vendored copy of ``py.error`` and ``py.path`` modules but will use the ``py`` library if it is installed. If you need other ``py.*`` modules, continue to install the deprecated ``py`` library separately, otherwise it can usually be removed as a dependency.
|
|
@ -36,16 +36,17 @@ packages =
|
||||||
_pytest
|
_pytest
|
||||||
_pytest._code
|
_pytest._code
|
||||||
_pytest._io
|
_pytest._io
|
||||||
|
_pytest._py
|
||||||
_pytest.assertion
|
_pytest.assertion
|
||||||
_pytest.config
|
_pytest.config
|
||||||
_pytest.mark
|
_pytest.mark
|
||||||
pytest
|
pytest
|
||||||
|
py_modules = py
|
||||||
install_requires =
|
install_requires =
|
||||||
attrs>=19.2.0
|
attrs>=19.2.0
|
||||||
iniconfig
|
iniconfig
|
||||||
packaging
|
packaging
|
||||||
pluggy>=0.12,<2.0
|
pluggy>=0.12,<2.0
|
||||||
py>=1.8.2
|
|
||||||
colorama;sys_platform=="win32"
|
colorama;sys_platform=="win32"
|
||||||
exceptiongroup>=1.0.0rc8;python_version<"3.11"
|
exceptiongroup>=1.0.0rc8;python_version<"3.11"
|
||||||
importlib-metadata>=0.12;python_version<"3.8"
|
importlib-metadata>=0.12;python_version<"3.8"
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
"""create errno-specific classes for IO or os calls."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import errno
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from typing import Callable
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from typing_extensions import ParamSpec
|
||||||
|
|
||||||
|
P = ParamSpec("P")
|
||||||
|
|
||||||
|
R = TypeVar("R")
|
||||||
|
|
||||||
|
|
||||||
|
class Error(EnvironmentError):
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return "{}.{} {!r}: {} ".format(
|
||||||
|
self.__class__.__module__,
|
||||||
|
self.__class__.__name__,
|
||||||
|
self.__class__.__doc__,
|
||||||
|
" ".join(map(str, self.args)),
|
||||||
|
# repr(self.args)
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
s = "[{}]: {}".format(
|
||||||
|
self.__class__.__doc__,
|
||||||
|
" ".join(map(str, self.args)),
|
||||||
|
)
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
_winerrnomap = {
|
||||||
|
2: errno.ENOENT,
|
||||||
|
3: errno.ENOENT,
|
||||||
|
17: errno.EEXIST,
|
||||||
|
18: errno.EXDEV,
|
||||||
|
13: errno.EBUSY, # empty cd drive, but ENOMEDIUM seems unavailiable
|
||||||
|
22: errno.ENOTDIR,
|
||||||
|
20: errno.ENOTDIR,
|
||||||
|
267: errno.ENOTDIR,
|
||||||
|
5: errno.EACCES, # anything better?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorMaker:
|
||||||
|
"""lazily provides Exception classes for each possible POSIX errno
|
||||||
|
(as defined per the 'errno' module). All such instances
|
||||||
|
subclass EnvironmentError.
|
||||||
|
"""
|
||||||
|
|
||||||
|
_errno2class: dict[int, type[Error]] = {}
|
||||||
|
|
||||||
|
def __getattr__(self, name: str) -> type[Error]:
|
||||||
|
if name[0] == "_":
|
||||||
|
raise AttributeError(name)
|
||||||
|
eno = getattr(errno, name)
|
||||||
|
cls = self._geterrnoclass(eno)
|
||||||
|
setattr(self, name, cls)
|
||||||
|
return cls
|
||||||
|
|
||||||
|
def _geterrnoclass(self, eno: int) -> type[Error]:
|
||||||
|
try:
|
||||||
|
return self._errno2class[eno]
|
||||||
|
except KeyError:
|
||||||
|
clsname = errno.errorcode.get(eno, "UnknownErrno%d" % (eno,))
|
||||||
|
errorcls = type(
|
||||||
|
clsname,
|
||||||
|
(Error,),
|
||||||
|
{"__module__": "py.error", "__doc__": os.strerror(eno)},
|
||||||
|
)
|
||||||
|
self._errno2class[eno] = errorcls
|
||||||
|
return errorcls
|
||||||
|
|
||||||
|
def checked_call(
|
||||||
|
self, func: Callable[P, R], *args: P.args, **kwargs: P.kwargs
|
||||||
|
) -> R:
|
||||||
|
"""Call a function and raise an errno-exception if applicable."""
|
||||||
|
__tracebackhide__ = True
|
||||||
|
try:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
except Error:
|
||||||
|
raise
|
||||||
|
except OSError as value:
|
||||||
|
if not hasattr(value, "errno"):
|
||||||
|
raise
|
||||||
|
errno = value.errno
|
||||||
|
if sys.platform == "win32":
|
||||||
|
try:
|
||||||
|
cls = self._geterrnoclass(_winerrnomap[errno])
|
||||||
|
except KeyError:
|
||||||
|
raise value
|
||||||
|
else:
|
||||||
|
# we are not on Windows, or we got a proper OSError
|
||||||
|
cls = self._geterrnoclass(errno)
|
||||||
|
|
||||||
|
raise cls(f"{func.__name__}{args!r}")
|
||||||
|
|
||||||
|
|
||||||
|
_error_maker = ErrorMaker()
|
||||||
|
checked_call = _error_maker.checked_call
|
||||||
|
|
||||||
|
|
||||||
|
def __getattr__(attr: str) -> type[Error]:
|
||||||
|
return getattr(_error_maker, attr) # type: ignore[no-any-return]
|
File diff suppressed because it is too large
Load Diff
|
@ -18,6 +18,7 @@ from typing import TypeVar
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
|
|
||||||
import py
|
import py
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
# shim for pylib going away
|
||||||
|
# if pylib is installed this file will get skipped
|
||||||
|
# (`py/__init__.py` has higher precedence)
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import _pytest._py.error as error
|
||||||
|
import _pytest._py.path as path
|
||||||
|
|
||||||
|
sys.modules["py.error"] = error
|
||||||
|
sys.modules["py.path"] = path
|
File diff suppressed because it is too large
Load Diff
|
@ -91,6 +91,12 @@ class TestImportPath:
|
||||||
yield path
|
yield path
|
||||||
assert path.joinpath("samplefile").exists()
|
assert path.joinpath("samplefile").exists()
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def preserve_sys(self):
|
||||||
|
with unittest.mock.patch.dict(sys.modules):
|
||||||
|
with unittest.mock.patch.object(sys, "path", list(sys.path)):
|
||||||
|
yield
|
||||||
|
|
||||||
def setuptestfs(self, path: Path) -> None:
|
def setuptestfs(self, path: Path) -> None:
|
||||||
# print "setting up test fs for", repr(path)
|
# print "setting up test fs for", repr(path)
|
||||||
samplefile = path / "samplefile"
|
samplefile = path / "samplefile"
|
||||||
|
|
3
tox.ini
3
tox.ini
|
@ -10,7 +10,7 @@ envlist =
|
||||||
py310
|
py310
|
||||||
py311
|
py311
|
||||||
pypy3
|
pypy3
|
||||||
py37-{pexpect,xdist,unittestextras,numpy,pluggymain}
|
py37-{pexpect,xdist,unittestextras,numpy,pluggymain,pylib}
|
||||||
doctesting
|
doctesting
|
||||||
plugins
|
plugins
|
||||||
py37-freeze
|
py37-freeze
|
||||||
|
@ -54,6 +54,7 @@ deps =
|
||||||
numpy: numpy>=1.19.4
|
numpy: numpy>=1.19.4
|
||||||
pexpect: pexpect>=4.8.0
|
pexpect: pexpect>=4.8.0
|
||||||
pluggymain: pluggy @ git+https://github.com/pytest-dev/pluggy.git
|
pluggymain: pluggy @ git+https://github.com/pytest-dev/pluggy.git
|
||||||
|
pylib: py>=1.8.2
|
||||||
unittestextras: twisted
|
unittestextras: twisted
|
||||||
unittestextras: asynctest
|
unittestextras: asynctest
|
||||||
xdist: pytest-xdist>=2.1.0
|
xdist: pytest-xdist>=2.1.0
|
||||||
|
|
Loading…
Reference in New Issue