Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix TypeError when importing pytest on Python 3.5.0 and 3.5.1 #5752

Merged
merged 6 commits into from
Aug 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ repos:
hooks:
- id: flake8
language_version: python3
additional_dependencies: [flake8-typing-imports]
additional_dependencies: [flake8-typing-imports==1.3.0]
- repo: https://github.com/asottile/reorder_python_imports
rev: v1.4.0
hooks:
Expand Down
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ jobs:
python: 'pypy3'

- env: TOXENV=py35-xdist
python: '3.5'
dist: trusty
python: '3.5.0'
Copy link
Member

@Zac-HD Zac-HD Aug 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on my experience with Hypothesis, we need tests to ensure that Pytest's typing-related things don't regress on 3.5.0 or 3.5.x, meaning an additional environment rather than pinning to .0.

It's kinda annoying, but there we are - it's stuff like this that makes me worried about the exotic proposals for CPython release cadence and sympathetic to the "batteries are leaking" argument.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have 3.5.x in Azure, no?
btw: Django only supports the latest patch releases of Python versions.


# Coverage for:
# - pytester's LsofFdLeakChecker
Expand Down
1 change: 1 addition & 0 deletions changelog/5751.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed ``TypeError`` when importing pytest on Python 3.5.0 and 3.5.1.
2 changes: 1 addition & 1 deletion src/_pytest/_code/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ def getrepr(
)
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
representation of the exception using ``re.search``. If it matches
Expand Down
7 changes: 7 additions & 0 deletions src/_pytest/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from contextlib import contextmanager
from inspect import Parameter
from inspect import signature
from typing import overload

import attr
import py
Expand Down Expand Up @@ -347,3 +348,9 @@ def funcargnames(self):

warnings.warn(FUNCARGNAMES, stacklevel=2)
return self.fixturenames


if sys.version_info < (3, 5, 2): # pragma: no cover

def overload(f): # noqa: F811
return f
13 changes: 7 additions & 6 deletions src/_pytest/python_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from typing import cast
from typing import Generic
from typing import Optional
from typing import overload
from typing import Pattern
from typing import Tuple
from typing import TypeVar
Expand All @@ -22,12 +21,14 @@
from more_itertools.more import always_iterable

import _pytest._code
from _pytest.compat import overload
from _pytest.compat import STRING_TYPES
from _pytest.outcomes import fail

if False: # TYPE_CHECKING
from typing import Type # noqa: F401 (used in type string)


BASE_TYPE = (type, STRING_TYPES)


Expand Down Expand Up @@ -547,12 +548,12 @@ def _is_numpy_array(obj):
def raises(
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
*,
match: Optional[Union[str, Pattern]] = ...
match: "Optional[Union[str, Pattern]]" = ...
) -> "RaisesContext[_E]":
... # pragma: no cover


@overload
@overload # noqa: F811
def raises(
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
func: Callable,
Expand All @@ -563,10 +564,10 @@ def raises(
... # pragma: no cover


def raises(
def raises( # noqa: F811
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
*args: Any,
match: Optional[Union[str, Pattern]] = None,
match: Optional[Union[str, "Pattern"]] = None,
**kwargs: Any
) -> Union["RaisesContext[_E]", Optional[_pytest._code.ExceptionInfo[_E]]]:
r"""
Expand Down Expand Up @@ -724,7 +725,7 @@ def __init__(
self,
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
message: str,
match_expr: Optional[Union[str, Pattern]] = None,
match_expr: Optional[Union[str, "Pattern"]] = None,
) -> None:
self.expected_exception = expected_exception
self.message = message
Expand Down
14 changes: 7 additions & 7 deletions src/_pytest/recwarn.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
from typing import Iterator
from typing import List
from typing import Optional
from typing import overload
from typing import Pattern
from typing import Tuple
from typing import Union

from _pytest.compat import overload
from _pytest.fixtures import yield_fixture
from _pytest.outcomes import fail

Expand Down Expand Up @@ -58,26 +58,26 @@ def deprecated_call(func=None, *args, **kwargs):
def warns(
expected_warning: Union["Type[Warning]", Tuple["Type[Warning]", ...]],
*,
match: Optional[Union[str, Pattern]] = ...
match: "Optional[Union[str, Pattern]]" = ...
) -> "WarningsChecker":
... # pragma: no cover


@overload
@overload # noqa: F811
def warns(
expected_warning: Union["Type[Warning]", Tuple["Type[Warning]", ...]],
func: Callable,
*args: Any,
match: Optional[Union[str, Pattern]] = ...,
match: Optional[Union[str, "Pattern"]] = ...,
**kwargs: Any
) -> Union[Any]:
... # pragma: no cover


def warns(
def warns( # noqa: F811
expected_warning: Union["Type[Warning]", Tuple["Type[Warning]", ...]],
*args: Any,
match: Optional[Union[str, Pattern]] = None,
match: Optional[Union[str, "Pattern"]] = None,
**kwargs: Any
) -> Union["WarningsChecker", Any]:
r"""Assert that code raises a particular class of warning.
Expand Down Expand Up @@ -207,7 +207,7 @@ def __init__(
expected_warning: Optional[
Union["Type[Warning]", Tuple["Type[Warning]", ...]]
] = None,
match_expr: Optional[Union[str, Pattern]] = None,
match_expr: Optional[Union[str, "Pattern"]] = None,
) -> None:
super().__init__()

Expand Down
16 changes: 8 additions & 8 deletions testing/python/raises.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,16 @@ def test_raises_cyclic_reference(self, method):

class T:
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
bluetech marked this conversation as resolved.
Show resolved Hide resolved
raise ValueError

t = T()
refcount = len(gc.get_referrers(t))

if method == "function":
pytest.raises(ValueError, t)
else:
Expand All @@ -175,14 +182,7 @@ def __call__(self):
# ensure both forms of pytest.raises don't leave exceptions in sys.exc_info()
assert sys.exc_info() == (None, None, None)

del 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
assert refcount == len(gc.get_referrers(t))

def test_raises_match(self):
msg = r"with base \d+"
Expand Down