Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@ jobs:
uses: AndreMiras/coveralls-python-action@develop
with:
parallel-finished: true


17 changes: 17 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
[mypy]
python_version = 3.9
ignore_missing_imports = True
follow_imports = skip
files = testslide, tests, pytest-testslide, util

[mypy-coverage.*]
ignore_missing_imports = True
[mypy-asyncio.log.*]
Expand All @@ -10,6 +16,17 @@ ignore_missing_imports = True
ignore_missing_imports = True
[mypy-setuptools.*]
ignore_missing_imports = True

# Ignore type checking in test helper packages to avoid false positives
[mypy-pytest-testslide.*]
ignore_errors = True

[mypy-pytest_testslide.*]
ignore_errors = True

[mypy-tests.*]
ignore_errors = True

[mypy-testslide.testslide]
disallow_untyped_calls = True
disallow_untyped_defs = True
Expand Down
29 changes: 15 additions & 14 deletions pytest-testslide/pytest_testslide.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
# LICENSE file in the root directory of this source tree.

# pyre-unsafe
# mypy: ignore-errors

from collections.abc import Callable, Iterator
from typing import Any, Callable, Iterator, Optional, Type, List
from types import TracebackType
from typing import Any

import pytest
import testslide as testslide_module
Expand All @@ -20,16 +20,16 @@ def _register_assertion(self, assertion: Callable) -> None:

def __enter__(self) -> "_TestSlideFixture":
# pyre-fixme[16]: `_TestSlideFixture` has no attribute `_assertions`.
self._assertions: list[Callable] = []
testslide_module.mock_callable.register_assertion = self._register_assertion
self._assertions: List[Callable] = []
testslide_module.mock_callable.register_assertion = self._register_assertion # type: ignore[attr-defined]
return self

def __exit__(
self,
exc_type: type | None,
exc_val: Exception | None,
exc_tb: TracebackType,
):
exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> Optional[bool]:
# pyre-fixme[16]: Module `lib` has no attribute `AggregatedExceptions`.
aggregated_exceptions = testslide_module.bdd.lib.AggregatedExceptions()
try:
Expand All @@ -41,28 +41,29 @@ def __exit__(
aggregated_exceptions.append_exception(be)

finally:
testslide_module.mock_callable.unpatch_all_callable_mocks()
testslide_module.mock_constructor.unpatch_all_constructor_mocks()
testslide_module.patch_attribute.unpatch_all_mocked_attributes()
testslide_module.mock_callable.unpatch_all_callable_mocks() # type: ignore[attr-defined]
testslide_module.mock_constructor.unpatch_all_constructor_mocks() # type: ignore[attr-defined]
testslide_module.patch_attribute.unpatch_all_mocked_attributes() # type: ignore[attr-defined]
if aggregated_exceptions.exceptions:
pytest.fail(str(aggregated_exceptions), False)
return None

@staticmethod
def mock_callable(
*args: Any, **kwargs: Any
) -> testslide_module.mock_callable._MockCallableDSL:
) -> Any:
return testslide_module.mock_callable.mock_callable(*args, **kwargs)

@staticmethod
def mock_async_callable(
*args: Any, **kwargs: Any
) -> testslide_module.core.mock_callable._MockAsyncCallableDSL:
) -> Any:
return testslide_module.mock_callable.mock_async_callable(*args, **kwargs)

@staticmethod
def mock_constructor(
*args: Any, **kwargs: Any
) -> testslide_module.mock_constructor._MockConstructorDSL:
) -> Any:
return testslide_module.mock_constructor.mock_constructor(*args, **kwargs)

@staticmethod
Expand Down
5 changes: 3 additions & 2 deletions tests/copyright_check/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# LICENSE file in the root directory of this source tree.

from pathlib import Path
from typing import List

debug_logs = False

Expand All @@ -12,7 +13,7 @@
default_check_dir = rootdir / "copyright_check"

# if want to run specific files, add to this list
filelist: list[str] = []
filelist: List[str] = []

# If we want to ignore, add directories in ignore_dirs
ignore_dirs: list[str] = []
ignore_dirs: List[str] = []
5 changes: 3 additions & 2 deletions tests/dsl_unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import subprocess
import time
import unittest
from typing import List
from unittest.mock import call, Mock, patch

from testslide.bdd.dsl import context, fcontext, xcontext
Expand Down Expand Up @@ -38,7 +39,7 @@ class SomeTestCase(unittest.TestCase):
Used to test TestSlide and unittest.TestCase integration.
"""

CALLS: list[str] = []
CALLS: List[str] = []

def setUp(self):
self.CALLS.append("setUp")
Expand Down Expand Up @@ -69,7 +70,7 @@ class SomeTestCase2(unittest.TestCase):
Used to test TestSlide and unittest.TestCase integration.
"""

CALLS: list[str] = []
CALLS: List[str] = []

def setUp(self):
self.CALLS.append("setUp2")
Expand Down
6 changes: 3 additions & 3 deletions tests/lib_testslide.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import inspect
import unittest.mock
from typing import Optional, TypeVar
from typing import Optional, Type, TypeVar

import testslide.core.lib
from testslide.bdd.dsl import context
Expand Down Expand Up @@ -190,7 +190,7 @@ def ignores_nested_TypeVar(self):
https://github.com/facebook/TestSlide/issues/165
"""

def with_typevar(arg1: type[T]) -> None:
def with_typevar(arg1: Type[T]) -> None:
pass

self.callable_template = with_typevar
Expand Down Expand Up @@ -355,7 +355,7 @@ def passes_if_TypeVar_in_signature(self):
https://github.com/facebook/TestSlide/issues/165
"""

def with_typevar_return() -> type[TypeVar("T")]: # type: ignore[empty-body]
def with_typevar_return() -> Type[TypeVar("T")]: # type: ignore[empty-body]
pass

self.callable_template = with_typevar_return
Expand Down
2 changes: 1 addition & 1 deletion tests/mock_async_callable_testslide.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ async def raises_TypeCheckError_when_returning_coroutine_instance(self):

with self.assertRaisesRegex(
TypeCheckError,
r"^type of return must be typing.List\[str\]; got .+(asyncio|coroutine)",
r"^type of return must be (typing\.)?[Ll]ist\[str\]; got .+(asyncio|coroutine)",
):
await self.callable_target(*self.call_args, **self.call_kwargs)

Expand Down
3 changes: 2 additions & 1 deletion tests/mock_constructor_testslide.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import contextlib
import sys
from typing import Optional

from testslide.bdd.dsl import context
from testslide.core.lib import TypeCheckError
Expand Down Expand Up @@ -44,7 +45,7 @@ class Target(TargetParent):
CLASS_ATTR = "CLASS_ATTR"
__slots__ = ("args", "kwargs", "p2_super", "p3_super")

def __init__(self, message: str | None = None, *args, **kwargs):
def __init__(self, message: Optional[str] = None, *args, **kwargs):
self.p2_super = False
super().__init__(p2_super=True)

Expand Down
29 changes: 14 additions & 15 deletions tests/sample_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

from collections.abc import Awaitable, Coroutine
from typing import Any, Union
from typing import Any, Awaitable, Coroutine, Dict, List, Optional, Tuple, Union

attribute = "value"
typedattr: str = "bruh"
Expand All @@ -28,7 +27,7 @@ def property_attribute(self):
return "property_attribute"

def instance_method_with_star_args(
self, first, *args: str, a: bool, b: int, c: int | None, d: int = 3
self, first, *args: str, a: bool, b: int, c: Optional[int], d: int = 3
) -> int:
return 3

Expand Down Expand Up @@ -70,36 +69,36 @@ def _privatefun(self) -> str:
class ParentTarget(TargetStr):
def instance_method(
self, arg1: str, arg2: str, kwarg1: str = "", kwarg2: str = ""
) -> list[str]:
) -> List[str]:
return ["original response"]

async def async_instance_method(
self, arg1: str, arg2: str, kwarg1: str = "", kwarg2: str = ""
) -> list[str]:
) -> List[str]:
return ["async original response"]

@staticmethod
def static_method(
arg1: str, arg2: str, kwarg1: str = "", kwarg2: str = ""
) -> list[str]:
) -> List[str]:
return ["original response"]

@staticmethod
async def async_static_method(
arg1: str, arg2: str, kwarg1: str = "", kwarg2: str = ""
) -> list[str]:
) -> List[str]:
return ["async original response"]

@classmethod
def class_method(
cls, arg1: str, arg2: str, kwarg1: str = "", kwarg2: str = ""
) -> list[str]:
) -> List[str]:
return ["original response"]

@classmethod
async def async_class_method(
cls, arg1: str, arg2: str, kwarg1: str = "", kwarg2: str = ""
) -> list[str]:
) -> List[str]:
return ["async original response"]

async def __aiter__(self):
Expand Down Expand Up @@ -137,40 +136,40 @@ def f2(self, arg: Any) -> str:

def test_function(
arg1: str, arg2: str, kwarg1: str = "", kwarg2: str = ""
) -> list[str]:
) -> List[str]:
"This function is used by some unit tests only"
return ["original response"]


async def async_test_function(
arg1: str, arg2: str, kwarg1: str = "", kwarg2: str = ""
) -> list[str]:
) -> List[str]:
"This function is used by some unit tests only"
return ["original response"]


def test_function_returns_awaitable(
arg1: str, arg2: str, kwarg1: str = "", kwarg2: str = ""
) -> Awaitable[list[str]]:
) -> Awaitable[List[str]]:
"This function is used by some unit tests only"
return async_test_function(arg1, arg2, kwarg1, kwarg2)


def test_function_returns_coroutine(
arg1: str, arg2: str, kwarg1: str = "", kwarg2: str = ""
) -> Coroutine[Any, Any, list[str]]:
) -> Coroutine[Any, Any, List[str]]:
"This function is used by some unit tests only"
return async_test_function(arg1, arg2, kwarg1, kwarg2)


UnionArgType = dict[str, Union[str, int]]
UnionArgType = Dict[str, Union[str, int]]


def test_union(arg: UnionArgType) -> None:
pass


TupleArgType = dict[str, tuple[str, int]]
TupleArgType = Dict[str, Tuple[str, int]]


def test_tuple(arg: TupleArgType) -> None:
Expand Down
Loading