Merge branch 'main' into add-type-ignore-for-attr-defined-errors

This commit is contained in:
WarrenTheRabbit 2023-08-24 10:26:42 +10:00 committed by GitHub
commit 7600243819
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 371 additions and 150 deletions

View File

@ -27,7 +27,7 @@ jobs:
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: with:
python-version: "3.8" python-version: "3.11"
cache: pip cache: pip
- name: requests-cache - name: requests-cache
uses: actions/cache@v3 uses: actions/cache@v3

View File

@ -5,7 +5,7 @@ repos:
- id: black - id: black
args: [--safe, --quiet] args: [--safe, --quiet]
- repo: https://github.com/asottile/blacken-docs - repo: https://github.com/asottile/blacken-docs
rev: 1.15.0 rev: 1.16.0
hooks: hooks:
- id: blacken-docs - id: blacken-docs
additional_dependencies: [black==23.7.0] additional_dependencies: [black==23.7.0]
@ -56,7 +56,7 @@ repos:
hooks: hooks:
- id: python-use-type-annotations - id: python-use-type-annotations
- repo: https://github.com/pre-commit/mirrors-mypy - repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.5.0 rev: v1.5.1
hooks: hooks:
- id: mypy - id: mypy
files: ^(src/|testing/) files: ^(src/|testing/)

View File

@ -0,0 +1,2 @@
Corrected the spelling of ``Config.ArgsSource.INVOCATION_DIR``.
The previous spelling ``INCOVATION_DIR`` remains as an alias.

View File

@ -0,0 +1 @@
Removes unhelpful error message from assertion rewrite mechanism when exceptions raised in __iter__ methods, and instead treats them as un-iterable.

View File

@ -34,7 +34,7 @@ a function/method call.
**Assert** is where we look at that resulting state and check if it looks how **Assert** is where we look at that resulting state and check if it looks how
we'd expect after the dust has settled. It's where we gather evidence to say the we'd expect after the dust has settled. It's where we gather evidence to say the
behavior does or does not aligns with what we expect. The ``assert`` in our test behavior does or does not align with what we expect. The ``assert`` in our test
is where we take that measurement/observation and apply our judgement to it. If is where we take that measurement/observation and apply our judgement to it. If
something should be green, we'd say ``assert thing == "green"``. something should be green, we'd say ``assert thing == "green"``.

File diff suppressed because it is too large Load Diff

View File

@ -1640,11 +1640,11 @@ passed multiple times. The expected format is ``name=value``. For example::
Additionally, ``pytest`` will attempt to intelligently identify and ignore a Additionally, ``pytest`` will attempt to intelligently identify and ignore a
virtualenv by the presence of an activation script. Any directory deemed to virtualenv by the presence of an activation script. Any directory deemed to
be the root of a virtual environment will not be considered during test be the root of a virtual environment will not be considered during test
collection unless ``collectinvirtualenv`` is given. Note also that collection unless ``--collect-in-virtualenv`` is given. Note also that
``norecursedirs`` takes precedence over ``collectinvirtualenv``; e.g. if ``norecursedirs`` takes precedence over ``--collect-in-virtualenv``; e.g. if
you intend to run tests in a virtualenv with a base directory that matches you intend to run tests in a virtualenv with a base directory that matches
``'.*'`` you *must* override ``norecursedirs`` in addition to using the ``'.*'`` you *must* override ``norecursedirs`` in addition to using the
``collectinvirtualenv`` flag. ``--collect-in-virtualenv`` flag.
.. confval:: python_classes .. confval:: python_classes

View File

@ -44,6 +44,7 @@ DEVELOPMENT_STATUS_CLASSIFIERS = (
) )
ADDITIONAL_PROJECTS = { # set of additional projects to consider as plugins ADDITIONAL_PROJECTS = { # set of additional projects to consider as plugins
"logassert", "logassert",
"nuts",
} }

View File

@ -132,7 +132,7 @@ def isiterable(obj: Any) -> bool:
try: try:
iter(obj) iter(obj)
return not istext(obj) return not istext(obj)
except TypeError: except Exception:
return False return False

View File

@ -953,7 +953,8 @@ class Config:
#: Command line arguments. #: Command line arguments.
ARGS = enum.auto() ARGS = enum.auto()
#: Invocation directory. #: Invocation directory.
INCOVATION_DIR = enum.auto() INVOCATION_DIR = enum.auto()
INCOVATION_DIR = INVOCATION_DIR # backwards compatibility alias
#: 'testpaths' configuration value. #: 'testpaths' configuration value.
TESTPATHS = enum.auto() TESTPATHS = enum.auto()
@ -1278,7 +1279,7 @@ class Config:
else: else:
result = [] result = []
if not result: if not result:
source = Config.ArgsSource.INCOVATION_DIR source = Config.ArgsSource.INVOCATION_DIR
result = [str(invocation_dir)] result = [str(invocation_dir)]
return result, source return result, source

View File

@ -829,7 +829,7 @@ class Pytester:
return self._makefile(ext, args, kwargs) return self._makefile(ext, args, kwargs)
def makeconftest(self, source: str) -> Path: def makeconftest(self, source: str) -> Path:
"""Write a contest.py file. """Write a conftest.py file.
:param source: The contents. :param source: The contents.
:returns: The conftest.py file. :returns: The conftest.py file.

View File

@ -1,5 +1,7 @@
# PYTHON_ARGCOMPLETE_OK # PYTHON_ARGCOMPLETE_OK
"""pytest: unit and functional testing with Python.""" """pytest: unit and functional testing with Python."""
from typing import TYPE_CHECKING
from _pytest import __version__ from _pytest import __version__
from _pytest import version_tuple from _pytest import version_tuple
from _pytest._code import ExceptionInfo from _pytest._code import ExceptionInfo
@ -165,6 +167,7 @@ __all__ = [
"yield_fixture", "yield_fixture",
] ]
if not TYPE_CHECKING:
def __getattr__(name: str) -> object: def __getattr__(name: str) -> object:
if name == "Instance": if name == "Instance":

View File

@ -272,7 +272,7 @@ def test_importing_instance_is_deprecated(pytester: Pytester) -> None:
pytest.PytestDeprecationWarning, pytest.PytestDeprecationWarning,
match=re.escape("The pytest.Instance collector type is deprecated"), match=re.escape("The pytest.Instance collector type is deprecated"),
): ):
pytest.Instance pytest.Instance # type:ignore[attr-defined]
with pytest.warns( with pytest.warns(
pytest.PytestDeprecationWarning, pytest.PytestDeprecationWarning,

View File

@ -685,6 +685,25 @@ class TestAssertionRewrite:
assert msg is not None assert msg is not None
assert "<MY42 object> < 0" in msg assert "<MY42 object> < 0" in msg
def test_assert_handling_raise_in__iter__(self, pytester: Pytester) -> None:
pytester.makepyfile(
"""\
class A:
def __iter__(self):
raise ValueError()
def __eq__(self, o: object) -> bool:
return self is o
def __repr__(self):
return "<A object>"
assert A() == A()
"""
)
result = pytester.runpytest()
result.stdout.fnmatch_lines(["*E*assert <A object> == <A object>"])
def test_formatchar(self) -> None: def test_formatchar(self) -> None:
def f() -> None: def f() -> None:
assert "%test" == "test" # type: ignore[comparison-overlap] assert "%test" == "test" # type: ignore[comparison-overlap]

View File

@ -507,6 +507,24 @@ class TestParseIni:
result = pytester.runpytest("--foo=1") result = pytester.runpytest("--foo=1")
result.stdout.fnmatch_lines("* no tests ran in *") result.stdout.fnmatch_lines("* no tests ran in *")
def test_args_source_args(self, pytester: Pytester):
config = pytester.parseconfig("--", "test_filename.py")
assert config.args_source == Config.ArgsSource.ARGS
def test_args_source_invocation_dir(self, pytester: Pytester):
config = pytester.parseconfig()
assert config.args_source == Config.ArgsSource.INVOCATION_DIR
def test_args_source_testpaths(self, pytester: Pytester):
pytester.makeini(
"""
[pytest]
testpaths=*
"""
)
config = pytester.parseconfig()
assert config.args_source == Config.ArgsSource.TESTPATHS
class TestConfigCmdlineParsing: class TestConfigCmdlineParsing:
def test_parsing_again_fails(self, pytester: Pytester) -> None: def test_parsing_again_fails(self, pytester: Pytester) -> None: