Skip to content

Commit

Permalink
Strict types
Browse files Browse the repository at this point in the history
ghstack-source-id: 4303ab1db6871595b27652120d74f8dc5f0ae627
Pull Request resolved: #438
  • Loading branch information
amyreese committed Apr 15, 2024
1 parent 911d4e8 commit 305b555
Show file tree
Hide file tree
Showing 14 changed files with 73 additions and 65 deletions.
37 changes: 21 additions & 16 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,24 @@ Home = "https://fixit.rtfd.io"
Github = "https://github.com/Instagram/Fixit"
Changelog = "https://github.com/Instagram/Fixit/blob/main/CHANGELOG.md"

[tool.attribution]
name = "Fixit"
package = "fixit"
signed_tags = true
version_file = false
ignored_authors = ["dependabot"]

[tool.black]
target-version = ["py37"]
target-version = ["py38"]

[tool.fixit]
enable = ["fixit.rules"]
python-version = "3.10"
formatter = "ufmt"

[[tool.fixit.overrides]]
path = "examples"
enable = [".examples.noop"]

[tool.hatch.version]
source = "vcs"
Expand Down Expand Up @@ -109,18 +125,7 @@ build = [
"sphinx-build -a -b html docs html",
]

[tool.fixit]
enable = ["fixit.rules"]
python-version = "3.10"
formatter = "ufmt"

[[tool.fixit.overrides]]
path = "examples"
enable = [".examples.noop"]

[tool.attribution]
name = "Fixit"
package = "fixit"
signed_tags = true
version_file = false
ignored_authors = ["dependabot"]
[tool.mypy]
strict = true
python_version = "3.8"
ignore_missing_imports = true
12 changes: 6 additions & 6 deletions src/fixit/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def main(
config_file: Optional[Path],
tags: str,
rules: str,
):
) -> None:
level = logging.WARNING
if debug is not None:
level = logging.DEBUG if debug else logging.ERROR
Expand Down Expand Up @@ -106,7 +106,7 @@ def lint(
ctx: click.Context,
diff: bool,
paths: Sequence[Path],
):
) -> None:
"""
lint one or more paths and return suggestions
Expand Down Expand Up @@ -153,7 +153,7 @@ def fix(
interactive: bool,
diff: bool,
paths: Sequence[Path],
):
) -> None:
"""
lint and autofix one or more files and return results
Expand Down Expand Up @@ -206,7 +206,7 @@ def fix(
@main.command()
@click.pass_context
@click.argument("rules", nargs=-1, required=True, type=str)
def test(ctx: click.Context, rules: Sequence[str]):
def test(ctx: click.Context, rules: Sequence[str]) -> None:
"""
test lint rules and their VALID/INVALID cases
"""
Expand All @@ -230,7 +230,7 @@ def test(ctx: click.Context, rules: Sequence[str]):
@main.command()
@click.pass_context
@click.argument("paths", nargs=-1, type=click.Path(path_type=Path))
def upgrade(ctx: click.Context, paths: Sequence[Path]):
def upgrade(ctx: click.Context, paths: Sequence[Path]) -> None:
"""
upgrade lint rules and apply deprecation fixes
Expand All @@ -245,7 +245,7 @@ def upgrade(ctx: click.Context, paths: Sequence[Path]):
@main.command()
@click.pass_context
@click.argument("paths", nargs=-1, type=click.Path(exists=True, path_type=Path))
def debug(ctx: click.Context, paths: Sequence[Path]):
def debug(ctx: click.Context, paths: Sequence[Path]) -> None:
"""
print materialized configuration for paths
"""
Expand Down
9 changes: 5 additions & 4 deletions src/fixit/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
Optional,
Sequence,
Set,
Tuple,
Type,
Union,
)

from packaging.specifiers import SpecifierSet

from packaging.version import InvalidVersion, Version

from .format import FORMAT_STYLES
Expand Down Expand Up @@ -69,7 +69,7 @@ def __init__(self, msg: str, rule: QualifiedRule):
super().__init__(msg)
self.rule = rule

def __reduce__(self):
def __reduce__(self) -> Tuple[Type[RuntimeError], Any]:
return type(self), (*self.args, self.rule)


Expand Down Expand Up @@ -230,7 +230,7 @@ def collect_rules(

if config.tags:
disabled_rules.update(
{R: "tags" for R in all_rules if R.TAGS not in config.tags}
{R: "tags" for R in all_rules if R.TAGS not in config.tags} # type: ignore[comparison-overlap]
)
all_rules -= set(disabled_rules)

Expand Down Expand Up @@ -314,6 +314,7 @@ def read_configs(paths: List[Path]) -> List[RawConfig]:
def get_sequence(
config: RawConfig, key: str, *, data: Optional[Dict[str, Any]] = None
) -> Sequence[str]:
value: Sequence[str]
if data:
value = data.pop(key, ())
else:
Expand Down Expand Up @@ -400,7 +401,7 @@ def process_subpath(
options: Optional[RuleOptionsTable] = None,
python_version: Any = None,
formatter: Optional[str] = None,
):
) -> None:
nonlocal target_python_version
nonlocal target_formatter

Expand Down
2 changes: 1 addition & 1 deletion src/fixit/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def on_visit(self, node: CSTNode) -> bool:
# don't visit children if we're going to replace the parent anyways
return node not in replacements

def on_leave(self, node: CSTNode, updated: CSTNode) -> NodeReplacement:
def on_leave(self, node: CSTNode, updated: CSTNode) -> NodeReplacement: # type: ignore[type-arg]
if node in replacements:
new = replacements[node]
return new
Expand Down
13 changes: 6 additions & 7 deletions src/fixit/ftypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@
from libcst import CSTNode, CSTNodeT, FlattenSentinel, RemovalSentinel
from libcst._add_slots import add_slots
from libcst.metadata import CodePosition as CodePosition, CodeRange as CodeRange

from packaging.version import Version

__all__ = ("Version",)

T = TypeVar("T")

STDIN = Path("-")
Expand All @@ -48,9 +49,7 @@
TimingsHook = Callable[[Timings], None]

VisitorMethod = Callable[[CSTNode], None]
VisitHook = Callable[[str], ContextManager]

Version
VisitHook = Callable[[str], ContextManager[None]]


@dataclass(frozen=True)
Expand Down Expand Up @@ -212,7 +211,7 @@ class Config:
# post-run processing
formatter: Optional[str] = None

def __post_init__(self):
def __post_init__(self) -> None:
self.path = self.path.resolve()
self.root = self.root.resolve()

Expand All @@ -222,7 +221,7 @@ class RawConfig:
path: Path
data: Dict[str, Any]

def __post_init__(self):
def __post_init__(self) -> None:
self.path = self.path.resolve()


Expand All @@ -237,7 +236,7 @@ class LintViolation:
range: CodeRange
message: str
node: CSTNode
replacement: Optional[NodeReplacement]
replacement: Optional[NodeReplacement[CSTNode]]
diff: str = ""

@property
Expand Down
2 changes: 1 addition & 1 deletion src/fixit/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ def report(
message: Optional[str] = None,
*,
position: Optional[Union[CodePosition, CodeRange]] = None,
replacement: Optional[NodeReplacement] = None,
replacement: Optional[NodeReplacement[CSTNode]] = None,
) -> None:
"""
Report a lint rule violation.
Expand Down
10 changes: 6 additions & 4 deletions src/fixit/rules/compare_singleton_primitives_by_is.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +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 typing import cast, FrozenSet, Union
from typing import cast, FrozenSet, Set, Union

import libcst as cst
from libcst.metadata import QualifiedName, QualifiedNameProvider, QualifiedNameSource
Expand Down Expand Up @@ -78,9 +78,11 @@ class CompareSingletonPrimitivesByIs(LintRule):
}
)

def is_singleton(self, node: cst.BaseExpression):
qual_name = cast(set, self.get_metadata(QualifiedNameProvider, node, set()))
return (
def is_singleton(self, node: cst.BaseExpression) -> bool:
qual_name = cast(
Set[QualifiedName], self.get_metadata(QualifiedNameProvider, node, set())
)
return bool(
isinstance(node, cst.Name)
and qual_name
and qual_name < self.QUALIFIED_SINGLETON_PRIMITIVES
Expand Down
4 changes: 1 addition & 3 deletions src/fixit/rules/rewrite_to_comprehension.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,7 @@ def visit_Call(self, node: cst.Call) -> None:

replacement = node.deep_replace(
node,
# pyre-fixme[6]: Expected `BaseAssignTargetExpression` for 1st
# param but got `BaseExpression`.
cst.DictComp(key=key, value=value, for_in=exp.for_in), # type: ignore
cst.DictComp(key=key, value=value, for_in=exp.for_in),
)

self.report(
Expand Down
2 changes: 1 addition & 1 deletion src/fixit/rules/use_async_sleep_in_async_def.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ async def func():
),
]

def __init__(self):
def __init__(self) -> None:
super().__init__()
# is async func
self.async_func = False
Expand Down
8 changes: 4 additions & 4 deletions src/fixit/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
from typing import Any, Callable, Collection, Dict, List, Mapping, Sequence, Type, Union

from .engine import diff_violation, LintRunner
from .ftypes import Config
from .rule import Invalid, LintRule, Valid
from .ftypes import Config, Invalid, Valid
from .rule import LintRule


def _dedent(src: str) -> str:
Expand All @@ -30,7 +30,7 @@ def get_fixture_path(

def validate_patch(report: Any, test_case: Invalid) -> None:
patch = report.patch
expected_replacement = test_case.expected_replacement # type: ignore
expected_replacement = test_case.expected_replacement

if patch is None:
if expected_replacement is not None:
Expand Down Expand Up @@ -168,7 +168,7 @@ def generate_lint_rule_test_cases(
test_case_classes: List[Type[unittest.TestCase]] = []
for test_case in gen_all_test_methods(rules):
rule_name = type(test_case.rule).__name__
test_methods_to_add: Dict[str, Callable] = {}
test_methods_to_add: Dict[str, Callable[..., Any]] = {}

for test_method_name, test_method_data in test_case.test_methods.items():

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

from fixit.config import collect_rules, Config
from fixit.ftypes import QualifiedRule
from fixit.config import collect_rules
from fixit.ftypes import Config, QualifiedRule

from fixit.testing import add_lint_rule_tests_to_module
from .config import ConfigTest
Expand Down
Loading

0 comments on commit 305b555

Please sign in to comment.