Skip to content

Commit

Permalink
Mypy upgrade from 0.782 to 0.991 (#343)
Browse files Browse the repository at this point in the history
Summary:
<!--
Thank you for your interest in this project. Bugs filed and PRs submitted are appreciated!

Please make sure that you are familiar with and follow the Code of Conduct of this project which can be found at https://github.com/facebook/TestSlide/blob/main/CODE_OF_CONDUCT.md

Also, please make sure you're familiar with and follow the instructions in the contributing guidelines which can  be found at https://github.com/facebook/TestSlide/blob/main/CONTRIBUTING.md

-->

**What:**
mypy is currently pinned on an old version, and type checks are currently breaking the tests.

**Why:**

I saw a comment somewhere about avoiding type checker pain by upgrading, and decided to face the pain.

A side-effect is that the type check that is currently broken around the arguments to `type()` got fixed just by upgrading.

**How:**

Review needed. In several cases I'm adding more ignores, because I cannot see a simple resolution.

Fixed a lexer issue for Pygments by adding the extension in the Sphinx config file.

**Risks:**

Tests are passing.

Biggest change is in the frame checking code in `mock_constructor.py` - if a caller frame can't be found, then the previous one can't be found, and the attempt to get frame info to set up the `_CallableMock` would probably fail? I can't see how this would happen in reality, but using type refinement made mypy happy.

If someone can come up with a test case that would generate a None for the currentframe() call, I'll add it and test it.

**Checklist**:

- [ ] Added tests, if you've added code that should be tested (Unsure if needed)
- [ ] Updated the documentation, if you've changed APIs N/A
- [x] Ensured the test suite passes
- [x] Made sure your code lints
- [x] Completed the Contributor License Agreement ("CLA")

Pull Request resolved: #343

Reviewed By: cricalix

Differential Revision: D42067967

Pulled By: deathowl

fbshipit-source-id: 8915a9172a1be440209a9d9ef3d693da12fe452e
  • Loading branch information
cricalix authored and facebook-github-bot committed Dec 15, 2022
1 parent 4316dad commit 61b016b
Show file tree
Hide file tree
Showing 10 changed files with 38 additions and 24 deletions.
2 changes: 1 addition & 1 deletion docs/conf.py
Expand Up @@ -45,7 +45,7 @@
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = []
extensions = ["IPython.sphinxext.ipython_console_highlighting"]

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
Expand Down
2 changes: 1 addition & 1 deletion requirements-dev.txt
Expand Up @@ -3,7 +3,7 @@ coverage
coveralls
flake8
isort~=5.1
mypy==0.782
mypy==0.991
ipython
sphinx
sphinx-autobuild
Expand Down
5 changes: 3 additions & 2 deletions tests/copyright_check/config.py
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 = []
filelist: List[str] = []

# If we want to ignore, add directories in ignore_dirs
ignore_dirs = []
ignore_dirs: List[str] = []
2 changes: 1 addition & 1 deletion tests/copyright_check/copyright_validator.py
Expand Up @@ -13,7 +13,7 @@
import re
import sys

import config
import config # type: ignore[import]


def print_logs(*args, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion tests/lib_testslide.py
Expand Up @@ -357,7 +357,7 @@ def passes_if_TypeVar_in_signature(self):
https://github.com/facebook/TestSlide/issues/165
"""

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

self.callable_template = with_typevar_return
Expand Down
1 change: 1 addition & 0 deletions tests/pep487_unittest.py
Expand Up @@ -7,6 +7,7 @@

import testslide


class QuestBase:
def __init_subclass__(cls, swallow, **kwargs):
cls.swallow = swallow
Expand Down
9 changes: 6 additions & 3 deletions testslide/cli.py
Expand Up @@ -41,8 +41,8 @@ def _filename_to_module_name(name: str) -> str:
def _get_all_test_case_subclasses() -> List[TestCase]:
def get_all_subclasses(base: Type[unittest.TestCase]) -> List[TestCase]:
return list(
{ # type: ignore
"{}.{}".format(c.__module__, c.__name__): c
{ # type: ignore[arg-type]
"{}.{}".format(c.__module__, c.__name__): c # type: ignore
for c in (
base.__subclasses__() # type: ignore
+ [g for s in base.__subclasses__() for g in get_all_subclasses(s)] # type: ignore
Expand Down Expand Up @@ -386,7 +386,10 @@ def run(self) -> int:
try:
parsed_args = self.parser.parse_args(self.args)
except SystemExit as e:
return e.code
# Basically, argparse has a `.error()` method that calls a `.exit()` method,
# which in turn calls `sys.exit()`, passing an int parameter.
# Ignore the detection that it might be a None or str.
return e.code # type: ignore
config = self._get_config_from_parsed_args(parsed_args)

if config.profile_threshold_ms is not None:
Expand Down
4 changes: 2 additions & 2 deletions testslide/import_profiler.py
Expand Up @@ -115,8 +115,8 @@ def __exit__(
def _profiled_import(
self,
name: str,
globals: Dict[str, Any] = None,
locals: Dict[str, Any] = None,
globals: Optional[Dict[str, Any]] = None,
locals: Optional[Dict[str, Any]] = None,
fromlist: Tuple = (),
level: int = 0,
) -> None:
Expand Down
33 changes: 21 additions & 12 deletions testslide/mock_constructor.py
Expand Up @@ -355,20 +355,29 @@ def mock_constructor(
elif not issubclass(original_class, object):
raise ValueError("Old style classes are not supported.")

caller_frame = inspect.currentframe().f_back # type: ignore
caller_frame = inspect.currentframe()
# loading the context ends up reading files from disk and that might block
# the event loop, so we don't do it.
caller_frame_info = inspect.getframeinfo(caller_frame, context=0) # type: ignore
callable_mock = _CallableMock(original_class, "__new__", caller_frame_info)
mocked_class = _patch_and_return_mocked_class(
target,
class_name,
target_class_id,
original_class,
callable_mock,
type_validation,
**kwargs,
)
if caller_frame is not None:
prev_frame = caller_frame.f_back
if prev_frame:
caller_frame_info = inspect.getframeinfo(prev_frame, context=0)
callable_mock = _CallableMock(original_class, "__new__", caller_frame_info) # type: ignore[assignment]
mocked_class = _patch_and_return_mocked_class(
target,
class_name,
target_class_id,
original_class,
callable_mock, # type: ignore[arg-type]
type_validation,
**kwargs,
)
else:
raise Exception("Cannot retrieve previous frame for caller frame")
else:
raise Exception(
"Cannot retrieve current frame, cannot create a CallableMock"
)

def original_callable(cls: type, *args: Any, **kwargs: Any) -> Any:
global _init_args_from_original_callable, _init_kwargs_from_original_callable
Expand Down
2 changes: 1 addition & 1 deletion testslide/runner.py
Expand Up @@ -766,7 +766,7 @@ def __init__(
contexts: List[Context],
formatter: Union[SlowImportWarningMixin, DocumentFormatter],
shuffle: bool = False,
seed: int = None,
seed: Optional[int] = None,
focus: bool = False,
fail_fast: bool = False,
fail_if_focused: bool = False,
Expand Down

0 comments on commit 61b016b

Please sign in to comment.