Merge pull request #5752 from bluetech/typing-py350-fix

Fix TypeError when importing pytest on Python 3.5.0 and 3.5.1
This commit is contained in:
Anthony Sottile 2019-08-20 08:04:58 -07:00 committed by GitHub
commit daff9066c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 34 additions and 24 deletions

View File

@ -26,7 +26,7 @@ repos:
hooks: hooks:
- id: flake8 - id: flake8
language_version: python3 language_version: python3
additional_dependencies: [flake8-typing-imports] additional_dependencies: [flake8-typing-imports==1.3.0]
- repo: https://github.com/asottile/reorder_python_imports - repo: https://github.com/asottile/reorder_python_imports
rev: v1.4.0 rev: v1.4.0
hooks: hooks:

View File

@ -43,7 +43,8 @@ jobs:
python: 'pypy3' python: 'pypy3'
- env: TOXENV=py35-xdist - env: TOXENV=py35-xdist
python: '3.5' dist: trusty
python: '3.5.0'
# Coverage for: # Coverage for:
# - pytester's LsofFdLeakChecker # - pytester's LsofFdLeakChecker

View File

@ -0,0 +1 @@
Fixed ``TypeError`` when importing pytest on Python 3.5.0 and 3.5.1.

View File

@ -591,7 +591,7 @@ class ExceptionInfo(Generic[_E]):
) )
return fmt.repr_excinfo(self) return fmt.repr_excinfo(self)
def match(self, regexp: Union[str, Pattern]) -> bool: def match(self, regexp: "Union[str, Pattern]") -> bool:
""" """
Check whether the regular expression 'regexp' is found in the string Check whether the regular expression 'regexp' is found in the string
representation of the exception using ``re.search``. If it matches representation of the exception using ``re.search``. If it matches

View File

@ -9,6 +9,7 @@ import sys
from contextlib import contextmanager from contextlib import contextmanager
from inspect import Parameter from inspect import Parameter
from inspect import signature from inspect import signature
from typing import overload
import attr import attr
import py import py
@ -347,3 +348,9 @@ class FuncargnamesCompatAttr:
warnings.warn(FUNCARGNAMES, stacklevel=2) warnings.warn(FUNCARGNAMES, stacklevel=2)
return self.fixturenames return self.fixturenames
if sys.version_info < (3, 5, 2): # pragma: no cover
def overload(f): # noqa: F811
return f

View File

@ -13,7 +13,6 @@ from typing import Callable
from typing import cast from typing import cast
from typing import Generic from typing import Generic
from typing import Optional from typing import Optional
from typing import overload
from typing import Pattern from typing import Pattern
from typing import Tuple from typing import Tuple
from typing import TypeVar from typing import TypeVar
@ -22,12 +21,14 @@ from typing import Union
from more_itertools.more import always_iterable from more_itertools.more import always_iterable
import _pytest._code import _pytest._code
from _pytest.compat import overload
from _pytest.compat import STRING_TYPES from _pytest.compat import STRING_TYPES
from _pytest.outcomes import fail from _pytest.outcomes import fail
if False: # TYPE_CHECKING if False: # TYPE_CHECKING
from typing import Type # noqa: F401 (used in type string) from typing import Type # noqa: F401 (used in type string)
BASE_TYPE = (type, STRING_TYPES) BASE_TYPE = (type, STRING_TYPES)
@ -547,12 +548,12 @@ _E = TypeVar("_E", bound=BaseException)
def raises( def raises(
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]], expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
*, *,
match: Optional[Union[str, Pattern]] = ... match: "Optional[Union[str, Pattern]]" = ...
) -> "RaisesContext[_E]": ) -> "RaisesContext[_E]":
... # pragma: no cover ... # pragma: no cover
@overload @overload # noqa: F811
def raises( def raises(
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]], expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
func: Callable, func: Callable,
@ -563,10 +564,10 @@ def raises(
... # pragma: no cover ... # pragma: no cover
def raises( def raises( # noqa: F811
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]], expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
*args: Any, *args: Any,
match: Optional[Union[str, Pattern]] = None, match: Optional[Union[str, "Pattern"]] = None,
**kwargs: Any **kwargs: Any
) -> Union["RaisesContext[_E]", Optional[_pytest._code.ExceptionInfo[_E]]]: ) -> Union["RaisesContext[_E]", Optional[_pytest._code.ExceptionInfo[_E]]]:
r""" r"""
@ -724,7 +725,7 @@ class RaisesContext(Generic[_E]):
self, self,
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]], expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
message: str, message: str,
match_expr: Optional[Union[str, Pattern]] = None, match_expr: Optional[Union[str, "Pattern"]] = None,
) -> None: ) -> None:
self.expected_exception = expected_exception self.expected_exception = expected_exception
self.message = message self.message = message

View File

@ -7,11 +7,11 @@ from typing import Callable
from typing import Iterator from typing import Iterator
from typing import List from typing import List
from typing import Optional from typing import Optional
from typing import overload
from typing import Pattern from typing import Pattern
from typing import Tuple from typing import Tuple
from typing import Union from typing import Union
from _pytest.compat import overload
from _pytest.fixtures import yield_fixture from _pytest.fixtures import yield_fixture
from _pytest.outcomes import fail from _pytest.outcomes import fail
@ -58,26 +58,26 @@ def deprecated_call(func=None, *args, **kwargs):
def warns( def warns(
expected_warning: Union["Type[Warning]", Tuple["Type[Warning]", ...]], expected_warning: Union["Type[Warning]", Tuple["Type[Warning]", ...]],
*, *,
match: Optional[Union[str, Pattern]] = ... match: "Optional[Union[str, Pattern]]" = ...
) -> "WarningsChecker": ) -> "WarningsChecker":
... # pragma: no cover ... # pragma: no cover
@overload @overload # noqa: F811
def warns( def warns(
expected_warning: Union["Type[Warning]", Tuple["Type[Warning]", ...]], expected_warning: Union["Type[Warning]", Tuple["Type[Warning]", ...]],
func: Callable, func: Callable,
*args: Any, *args: Any,
match: Optional[Union[str, Pattern]] = ..., match: Optional[Union[str, "Pattern"]] = ...,
**kwargs: Any **kwargs: Any
) -> Union[Any]: ) -> Union[Any]:
... # pragma: no cover ... # pragma: no cover
def warns( def warns( # noqa: F811
expected_warning: Union["Type[Warning]", Tuple["Type[Warning]", ...]], expected_warning: Union["Type[Warning]", Tuple["Type[Warning]", ...]],
*args: Any, *args: Any,
match: Optional[Union[str, Pattern]] = None, match: Optional[Union[str, "Pattern"]] = None,
**kwargs: Any **kwargs: Any
) -> Union["WarningsChecker", Any]: ) -> Union["WarningsChecker", Any]:
r"""Assert that code raises a particular class of warning. r"""Assert that code raises a particular class of warning.
@ -207,7 +207,7 @@ class WarningsChecker(WarningsRecorder):
expected_warning: Optional[ expected_warning: Optional[
Union["Type[Warning]", Tuple["Type[Warning]", ...]] Union["Type[Warning]", Tuple["Type[Warning]", ...]]
] = None, ] = None,
match_expr: Optional[Union[str, Pattern]] = None, match_expr: Optional[Union[str, "Pattern"]] = None,
) -> None: ) -> None:
super().__init__() super().__init__()

View File

@ -163,9 +163,16 @@ class TestRaises:
class T: class T:
def __call__(self): def __call__(self):
# Early versions of Python 3.5 have some bug causing the
# __call__ frame to still refer to t even after everything
# is done. This makes the test pass for them.
if sys.version_info < (3, 5, 2): # pragma: no cover
del self
raise ValueError raise ValueError
t = T() t = T()
refcount = len(gc.get_referrers(t))
if method == "function": if method == "function":
pytest.raises(ValueError, t) pytest.raises(ValueError, t)
else: else:
@ -175,14 +182,7 @@ class TestRaises:
# ensure both forms of pytest.raises don't leave exceptions in sys.exc_info() # ensure both forms of pytest.raises don't leave exceptions in sys.exc_info()
assert sys.exc_info() == (None, None, None) assert sys.exc_info() == (None, None, None)
del t assert refcount == len(gc.get_referrers(t))
# Make sure this does get updated in locals dict
# otherwise it could keep a reference
locals()
# ensure the t instance is not stuck in a cyclic reference
for o in gc.get_objects():
assert type(o) is not T
def test_raises_match(self): def test_raises_match(self):
msg = r"with base \d+" msg = r"with base \d+"