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

Run pyupgrade rules #821

Merged
merged 4 commits into from
Oct 11, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions pyanalyze/analysis_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
import secrets
import sys
import types
from collections.abc import Mapping
from dataclasses import dataclass
from pathlib import Path
from typing import Callable, List, Mapping, Optional, Set, Union
from typing import Callable, Optional, Union


def _all_files(
root: Union[str, Path], filter_function: Optional[Callable[[str], bool]] = None
) -> Set[str]:
) -> set[str]:
"""Returns the set of all files at the given root.

Filtered optionally by the filter_function.
Expand All @@ -34,7 +35,7 @@ def _all_files(

def files_with_extension_from_directory(
extension: str, dirname: Union[str, Path]
) -> Set[str]:
) -> set[str]:
"""Finds all files in a given directory with this extension."""
return _all_files(dirname, filter_function=lambda fn: fn.endswith("." + extension))

Expand All @@ -48,8 +49,8 @@ def get_indentation(line: str) -> int:


def get_line_range_for_node(
node: Union[ast.stmt, ast.expr], lines: List[str]
) -> List[int]:
node: Union[ast.stmt, ast.expr], lines: list[str]
) -> list[int]:
"""Returns the lines taken up by a Python ast node.

lines is a list of code lines for the file the node came from.
Expand Down Expand Up @@ -136,7 +137,7 @@ def is_positional_only_arg_name(name: str, class_name: Optional[str] = None) ->
return name.startswith("__") and not name.endswith("__")


def get_attribute_path(node: ast.AST) -> Optional[List[str]]:
def get_attribute_path(node: ast.AST) -> Optional[list[str]]:
"""Gets the full path of an attribute lookup.

For example, the code string "a.model.question.Question" will resolve to the path
Expand Down
5 changes: 3 additions & 2 deletions pyanalyze/annotated_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
"""

import enum
from collections.abc import Iterable
from dataclasses import dataclass
from datetime import datetime, timezone, tzinfo
from typing import Any, Callable, Iterable, Optional, Type, Union
from typing import Any, Callable, Optional, Union

from pyanalyze.value import CanAssign, CanAssignContext, Value, flatten_values

Expand Down Expand Up @@ -126,7 +127,7 @@ def can_assign_non_literal(self, value: Value) -> CanAssign:

@dataclass(frozen=True)
class EnumName(AnnotatedTypesCheck):
enum_cls: Type[enum.Enum]
enum_cls: type[enum.Enum]

def predicate(self, value: str) -> bool:
try:
Expand Down
33 changes: 9 additions & 24 deletions pyanalyze/annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,10 @@
import builtins
import contextlib
import typing
from collections.abc import Callable, Hashable
from collections.abc import Callable, Container, Generator, Hashable, Mapping, Sequence
from contextlib import AbstractContextManager
from dataclasses import InitVar, dataclass, field
from typing import (
TYPE_CHECKING,
Any,
Container,
ContextManager,
Generator,
List,
Mapping,
NewType,
Optional,
Sequence,
Set,
Tuple,
TypeVar,
Union,
cast,
)
from typing import TYPE_CHECKING, Any, NewType, Optional, TypeVar, Union, cast

import qcore
import typing_extensions
Expand Down Expand Up @@ -144,9 +129,9 @@ class Context:

should_suppress_undefined_names: bool = field(default=False, init=False)
"""While this is True, no errors are shown for undefined names."""
_being_evaluated: Set[int] = field(default_factory=set, init=False)
_being_evaluated: set[int] = field(default_factory=set, init=False)

def suppress_undefined_names(self) -> ContextManager[None]:
def suppress_undefined_names(self) -> AbstractContextManager[None]:
"""Temporarily suppress errors about undefined names."""
return qcore.override(self, "should_suppress_undefined_names", True)

Expand Down Expand Up @@ -961,7 +946,7 @@ def get_type_alias(
@dataclass(frozen=True)
class _SubscriptedValue(Value):
root: Optional[Value]
members: Tuple[Value, ...]
members: tuple[Value, ...]


@dataclass(frozen=True)
Expand All @@ -973,7 +958,7 @@ class TypeQualifierValue(Value):
@dataclass(frozen=True)
class DecoratorValue(Value):
decorator: object
args: Tuple[Value, ...]
args: tuple[Value, ...]


class _Visitor(ast.NodeVisitor):
Expand Down Expand Up @@ -1164,7 +1149,7 @@ def _value_of_origin_args(
is_typeddict: bool = False,
allow_unpack: bool = False,
) -> Value:
if origin is typing.Type or origin is type:
if origin is type or origin is type:
if not args:
return TypedValue(type)
return SubclassValue.make(_type_from_runtime(args[0], ctx))
Expand Down Expand Up @@ -1389,7 +1374,7 @@ def _make_callable_from_value(


def _make_annotated(origin: Value, metadata: Sequence[Value], ctx: Context) -> Value:
metadata_objs: List[Union[Value, Extension]] = []
metadata_objs: list[Union[Value, Extension]] = []
for entry in metadata:
if isinstance(entry, KnownValue):
if isinstance(entry.val, ParameterTypeGuard):
Expand Down
29 changes: 8 additions & 21 deletions pyanalyze/arg_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,11 @@
import sys
import textwrap
import typing
from collections.abc import Iterator, Mapping, Sequence
from dataclasses import dataclass, replace
from re import Pattern
from types import FunctionType, MethodType, ModuleType
from typing import (
Any,
Callable,
Dict,
Generic,
Iterator,
List,
Mapping,
Optional,
Pattern,
Sequence,
Tuple,
Type,
TypeVar,
Union,
)
from typing import Any, Callable, Generic, Optional, TypeVar, Union
from unittest import mock

import asynq
Expand Down Expand Up @@ -346,15 +333,15 @@ def unwrap(cls, typ: type, options: Options) -> type:
# specify the overloads. This will be unnecessary in 3.11+
# where we get to use typing.get_overloads().
def _raises_overload1(
expected_exception: Union[Type[_E], Tuple[Type[_E], ...]],
expected_exception: Union[type[_E], tuple[type[_E], ...]],
*,
match: Optional[Union[str, Pattern[str]]] = ...,
) -> _pytest.python_api.RaisesContext[_E]:
raise NotImplementedError

# TODO use ParamSpec here
def _raises_overload2(
expected_exception: Union[Type[_E], Tuple[Type[_E], ...]],
expected_exception: Union[type[_E], tuple[type[_E], ...]],
func: Callable[..., Any],
*args: Any,
**kwargs: Any,
Expand All @@ -363,7 +350,7 @@ def _raises_overload2(

def _get_pytest_signatures(
arg_spec_cache: "ArgSpecCache",
) -> Dict[object, ConcreteSignature]:
) -> dict[object, ConcreteSignature]:
"""Return hardcoded Signatures for specific pytest functions."""
sigs = [
arg_spec_cache.get_concrete_signature(_raises_overload1),
Expand Down Expand Up @@ -486,7 +473,7 @@ def _make_sig_parameter(
is_wrapped: bool,
index: int,
seen_paramspec_args: Optional[ParamSpecArgsValue],
) -> Tuple[Optional[SigParameter], bool, Optional[ParamSpecArgsValue]]:
) -> tuple[Optional[SigParameter], bool, Optional[ParamSpecArgsValue]]:
"""Given an inspect.Parameter, returns a Parameter object."""
if is_wrapped:
typ = AnyValue(AnySource.inference)
Expand Down Expand Up @@ -1018,7 +1005,7 @@ def _safe_get_signature(self, obj: Any) -> Optional[inspect.Signature]:
# Python 2.
return None

def get_type_parameters(self, typ: Union[type, str]) -> List[Value]:
def get_type_parameters(self, typ: Union[type, str]) -> list[Value]:
bases = self.get_generic_bases(typ, substitute_typevars=False)
tv_map = bases.get(typ, {})
return [tv for tv in tv_map.values()]
Expand Down
8 changes: 4 additions & 4 deletions pyanalyze/ast_annotator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import textwrap
import traceback
import types
from typing import Optional, Type, Union
from typing import Optional, Union

from .analysis_lib import make_module
from .error_code import ErrorCode
Expand All @@ -26,7 +26,7 @@
def annotate_code(
code: str,
*,
visitor_cls: Type[NameCheckVisitor] = NameCheckVisitor,
visitor_cls: type[NameCheckVisitor] = NameCheckVisitor,
dump: bool = False,
show_errors: bool = False,
verbose: bool = False,
Expand Down Expand Up @@ -73,7 +73,7 @@ def annotate_code(
def annotate_file(
path: Union[str, "os.PathLike[str]"],
*,
visitor_cls: Type[NameCheckVisitor] = NameCheckVisitor,
visitor_cls: type[NameCheckVisitor] = NameCheckVisitor,
verbose: bool = False,
dump: bool = False,
show_errors: bool = False,
Expand Down Expand Up @@ -159,7 +159,7 @@ def _annotate_module(
module: Optional[types.ModuleType],
tree: ast.Module,
code_str: str,
visitor_cls: Type[NameCheckVisitor],
visitor_cls: type[NameCheckVisitor],
show_errors: bool = False,
) -> None:
"""Annotate the AST for a module with inferred values.
Expand Down
8 changes: 4 additions & 4 deletions pyanalyze/asynq_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
import contextlib
import inspect
import types
from collections.abc import Iterator
from dataclasses import dataclass, field
from typing import Any, Callable, Iterator, Optional
from typing import Any, Callable, Optional

import asynq
import qcore
Expand Down Expand Up @@ -118,8 +119,7 @@ def check_call(self, value: Value, node: ast.Call) -> None:
replacement_node = None
self._show_impure_async_error(
node,
replacement_call="%s.%s_async"
% (_stringify_obj(inner_type), value.attr_name),
replacement_call=f"{_stringify_obj(inner_type)}.{value.attr_name}_async",
replacement_node=replacement_node,
)

Expand Down Expand Up @@ -232,7 +232,7 @@ def _stringify_obj(obj: Any) -> str:
return f"{_stringify_obj(cls)}.{obj.decorator.fn.__name__}"
elif isinstance(obj, super):
# self might not always be correct, but it's close enough
return "super(%s, self)" % _stringify_obj(obj.__self_class__)
return f"super({_stringify_obj(obj.__self_class__)}, self)"
else:
return f"{obj.__module__}.{obj.__name__}"

Expand Down
9 changes: 5 additions & 4 deletions pyanalyze/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
import inspect
import sys
import types
from collections.abc import Sequence
from dataclasses import dataclass
from enum import Enum
from typing import Any, Callable, ClassVar, Optional, Sequence, Tuple, Union
from typing import Any, Callable, ClassVar, Optional, Union

import asynq
import qcore
Expand Down Expand Up @@ -81,7 +82,7 @@ def get_attribute_from_typeshed(self, typ: type, *, on_class: bool) -> Value:

def get_attribute_from_typeshed_recursively(
self, fq_name: str, *, on_class: bool
) -> Tuple[Value, object]:
) -> tuple[Value, object]:
return UNINITIALIZED_VALUE, None

def should_ignore_none_attributes(self) -> bool:
Expand Down Expand Up @@ -210,7 +211,7 @@ def should_treat_as_any(cls, val: object, options: Options) -> bool:
return any(func(val) for func in option_value)


_CAT = Callable[[object], Optional[Tuple[Value, Value]]]
_CAT = Callable[[object], Optional[tuple[Value, Value]]]


class ClassAttributeTransformer(PyObjectSequenceOption[_CAT]):
Expand Down Expand Up @@ -502,7 +503,7 @@ def get_signature(self, callable: object) -> MaybeSignature:

def _get_attribute_from_mro(
typ: object, ctx: AttrContext, on_class: bool
) -> Tuple[Value, object, bool]:
) -> tuple[Value, object, bool]:
# Then go through the MRO and find base classes that may define the attribute.
if safe_isinstance(typ, type) and safe_issubclass(typ, Enum):
# Special case, to avoid picking an attribute of Enum instances (e.g., name)
Expand Down
Loading
Loading