diff --git a/mypy/checkmember.py b/mypy/checkmember.py index f7d002f17eb9..60430839ff62 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Callable, Optional, Sequence, cast +from typing import TYPE_CHECKING, Callable, Sequence, cast from mypy import meet, message_registry, subtypes from mypy.erasetype import erase_typevars @@ -777,7 +777,7 @@ def analyze_var( result: Type = t typ = get_proper_type(typ) - call_type: Optional[ProperType] = None + call_type: ProperType | None = None if var.is_initialized_in_class and (not is_instance_var(var) or mx.is_operator): if isinstance(typ, FunctionLike) and not typ.is_type_obj(): call_type = typ diff --git a/mypy/config_parser.py b/mypy/config_parser.py index 7748c3b25966..4dbd6477c81e 100644 --- a/mypy/config_parser.py +++ b/mypy/config_parser.py @@ -292,14 +292,18 @@ def parse_config_file( ) if report_dirs: print( - "%sPer-module sections should not specify reports (%s)" - % (prefix, ", ".join(s + "_report" for s in sorted(report_dirs))), + prefix, + "Per-module sections should not specify reports ({})".format( + ", ".join(s + "_report" for s in sorted(report_dirs)) + ), file=stderr, ) if set(updates) - PER_MODULE_OPTIONS: print( - "%sPer-module sections should only specify per-module flags (%s)" - % (prefix, ", ".join(sorted(set(updates) - PER_MODULE_OPTIONS))), + prefix, + "Per-module sections should only specify per-module flags ({})".format( + ", ".join(sorted(set(updates) - PER_MODULE_OPTIONS)) + ), file=stderr, ) updates = {k: v for k, v in updates.items() if k in PER_MODULE_OPTIONS} @@ -315,8 +319,9 @@ def parse_config_file( "*" in x and x != "*" for x in glob.split(".") ): print( - "%sPatterns must be fully-qualified module names, optionally " - "with '*' in some components (e.g spam.*.eggs.*)" % prefix, + prefix, + "Patterns must be fully-qualified module names, optionally " + "with '*' in some components (e.g spam.*.eggs.*)", file=stderr, ) else: @@ -329,7 +334,7 @@ def get_prefix(file_read: str, name: str) -> str: else: module_name_str = name - return f"{file_read}: [{module_name_str}]: " + return f"{file_read}: [{module_name_str}]:" def is_toml(filename: str) -> bool: @@ -411,8 +416,7 @@ def destructure_overrides(toml_data: dict[str, Any]) -> dict[str, Any]: raise ConfigTOMLValueError( "toml config file contains " "[[tool.mypy.overrides]] sections with conflicting " - "values. Module '%s' has two different values for '%s'" - % (module, new_key) + f"values. Module '{module}' has two different values for '{new_key}'" ) result[old_config_name][new_key] = new_value diff --git a/mypy/main.py b/mypy/main.py index 30f6cfe97455..a4357dca7890 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -187,8 +187,7 @@ def flush_errors(new_messages: list[str], serious: bool) -> None: and not options.non_interactive ): print( - "Warning: unused section(s) in %s: %s" - % ( + "Warning: unused section(s) in {}: {}".format( options.config_file, get_config_module_names( options.config_file, diff --git a/mypy/messages.py b/mypy/messages.py index 4b71bd876dcc..bba9c3c3cdea 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -1454,20 +1454,19 @@ def cannot_determine_type_in_base(self, name: str, base: str, context: Context) self.fail(f'Cannot determine type of "{name}" in base class "{base}"', context) def no_formal_self(self, name: str, item: CallableType, context: Context) -> None: + type = format_type(item, self.options) self.fail( - 'Attribute function "%s" with type %s does not accept self argument' - % (name, format_type(item, self.options)), - context, + f'Attribute function "{name}" with type {type} does not accept self argument', context ) def incompatible_self_argument( self, name: str, arg: Type, sig: CallableType, is_classmethod: bool, context: Context ) -> None: kind = "class attribute function" if is_classmethod else "attribute function" + arg_type = format_type(arg, self.options) + sig_type = format_type(sig, self.options) self.fail( - 'Invalid self argument %s to %s "%s" with type %s' - % (format_type(arg, self.options), kind, name, format_type(sig, self.options)), - context, + f'Invalid self argument {arg_type} to {kind} "{name}" with type {sig_type}', context ) def incompatible_conditional_function_def( @@ -1487,8 +1486,8 @@ def cannot_instantiate_abstract_class( ) -> None: attrs = format_string_list([f'"{a}"' for a in abstract_attributes]) self.fail( - 'Cannot instantiate abstract class "%s" with abstract ' - "attribute%s %s" % (class_name, plural_s(abstract_attributes), attrs), + f'Cannot instantiate abstract class "{class_name}" with abstract ' + f"attribute{plural_s(abstract_attributes)} {attrs}", context, code=codes.ABSTRACT, ) diff --git a/mypy/solve.py b/mypy/solve.py index 95377ea9f93e..17e1ca047818 100644 --- a/mypy/solve.py +++ b/mypy/solve.py @@ -3,7 +3,7 @@ from __future__ import annotations from collections import defaultdict -from typing import Iterable, Sequence, Tuple +from typing import Iterable, Sequence from typing_extensions import TypeAlias as _TypeAlias from mypy.constraints import SUBTYPE_OF, SUPERTYPE_OF, Constraint, infer_constraints @@ -333,7 +333,7 @@ def is_trivial_bound(tp: ProperType) -> bool: return isinstance(tp, Instance) and tp.type.fullname == "builtins.object" -def find_linear(c: Constraint) -> Tuple[bool, TypeVarId | None]: +def find_linear(c: Constraint) -> tuple[bool, TypeVarId | None]: """Find out if this constraint represent a linear relationship, return target id if yes.""" if isinstance(c.origin_type_var, TypeVarType): if isinstance(c.target, TypeVarType): diff --git a/mypyc/ir/class_ir.py b/mypyc/ir/class_ir.py index 682e30629118..61f0fc36e1b3 100644 --- a/mypyc/ir/class_ir.py +++ b/mypyc/ir/class_ir.py @@ -70,7 +70,7 @@ class VTableMethod(NamedTuple): - cls: "ClassIR" + cls: "ClassIR" # noqa: UP037 name: str method: FuncIR shadow_method: FuncIR | None diff --git a/mypyc/ir/ops.py b/mypyc/ir/ops.py index d80c479211b7..2d64cc79d822 100644 --- a/mypyc/ir/ops.py +++ b/mypyc/ir/ops.py @@ -1575,5 +1575,5 @@ def visit_keep_alive(self, op: KeepAlive) -> T: # (Serialization and deserialization *will* be used for incremental # compilation but so far it is not hooked up to anything.) class DeserMaps(NamedTuple): - classes: dict[str, "ClassIR"] - functions: dict[str, "FuncIR"] + classes: dict[str, ClassIR] + functions: dict[str, FuncIR] diff --git a/mypyc/ir/rtypes.py b/mypyc/ir/rtypes.py index fa46feb0b59a..fecfaee5ef77 100644 --- a/mypyc/ir/rtypes.py +++ b/mypyc/ir/rtypes.py @@ -23,8 +23,8 @@ from __future__ import annotations from abc import abstractmethod -from typing import TYPE_CHECKING, ClassVar, Generic, TypeVar -from typing_extensions import Final, TypeGuard +from typing import TYPE_CHECKING, ClassVar, Final, Generic, TypeVar +from typing_extensions import TypeGuard from mypyc.common import IS_32_BIT_PLATFORM, PLATFORM_SIZE, JsonDict, short_name from mypyc.namegen import NameGenerator diff --git a/pyproject.toml b/pyproject.toml index 67201acb9b94..18ba23671d9c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,8 @@ select = [ "B", # flake8-bugbear "I", # isort "RUF100", # Unused noqa comments - "PGH004" # blanket noqa comments + "PGH004", # blanket noqa comments + "UP", # pyupgrade ] ignore = [ @@ -49,6 +50,7 @@ ignore = [ "E501", # conflicts with black "E731", # Do not assign a `lambda` expression, use a `def` "E741", # Ambiguous variable name + "UP032", # 'f-string always preferable to format' is controversial ] unfixable = [