Skip to content

mypy: run pyupgrade #12711

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

Merged
merged 6 commits into from
May 1, 2022
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
2 changes: 1 addition & 1 deletion mypy/binder.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def update_from_options(self, frames: List[Frame]) -> bool:

frames = [f for f in frames if not f.unreachable]
changed = False
keys = set(key for f in frames for key in f.types)
keys = {key for f in frames for key in f.types}

for key in keys:
current_value = self._get(key)
Expand Down
152 changes: 76 additions & 76 deletions mypy/build.py

Large diffs are not rendered by default.

69 changes: 32 additions & 37 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,26 +97,23 @@
DeferredNodeType: _TypeAlias = Union[FuncDef, LambdaExpr, OverloadedFuncDef, Decorator]
FineGrainedDeferredNodeType: _TypeAlias = Union[FuncDef, MypyFile, OverloadedFuncDef]


# A node which is postponed to be processed during the next pass.
# In normal mode one can defer functions and methods (also decorated and/or overloaded)
# and lambda expressions. Nested functions can't be deferred -- only top-level functions
# and methods of classes not defined within a function can be deferred.
DeferredNode = NamedTuple(
'DeferredNode',
[
('node', DeferredNodeType),
('active_typeinfo', Optional[TypeInfo]), # And its TypeInfo (for semantic analysis
# self type handling)
])
class DeferredNode(NamedTuple):
node: DeferredNodeType
# And its TypeInfo (for semantic analysis self type handling
active_typeinfo: Optional[TypeInfo]


# Same as above, but for fine-grained mode targets. Only top-level functions/methods
# and module top levels are allowed as such.
FineGrainedDeferredNode = NamedTuple(
'FineGrainedDeferredNode',
[
('node', FineGrainedDeferredNodeType),
('active_typeinfo', Optional[TypeInfo]),
])
class FineGrainedDeferredNode(NamedTuple):
node: FineGrainedDeferredNodeType
active_typeinfo: Optional[TypeInfo]


# Data structure returned by find_isinstance_check representing
# information learned from the truth or falsehood of a condition. The
Expand All @@ -131,25 +128,23 @@
# (such as two references to the same variable). TODO: it would
# probably be better to have the dict keyed by the nodes' literal_hash
# field instead.

TypeMap: _TypeAlias = Optional[Dict[Expression, Type]]


# An object that represents either a precise type or a type with an upper bound;
# it is important for correct type inference with isinstance.
TypeRange = NamedTuple(
'TypeRange',
[
('item', Type),
('is_upper_bound', bool), # False => precise type
])
class TypeRange(NamedTuple):
item: Type
is_upper_bound: bool # False => precise type


# Keeps track of partial types in a single scope. In fine-grained incremental
# mode partial types initially defined at the top level cannot be completed in
# a function, and we use the 'is_function' attribute to enforce this.
PartialTypeScope = NamedTuple('PartialTypeScope', [('map', Dict[Var, Context]),
('is_function', bool),
('is_local', bool),
])
class PartialTypeScope(NamedTuple):
map: Dict[Var, Context]
is_function: bool
is_local: bool


class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
Expand Down Expand Up @@ -891,7 +886,7 @@ def check_func_def(self, defn: FuncItem, typ: CallableType, name: Optional[str])
self.msg.unimported_type_becomes_any("Return type", ret_type, fdef)
for idx, arg_type in enumerate(fdef.type.arg_types):
if has_any_from_unimported_type(arg_type):
prefix = "Argument {} to \"{}\"".format(idx + 1, fdef.name)
prefix = f"Argument {idx + 1} to \"{fdef.name}\""
self.msg.unimported_type_becomes_any(prefix, arg_type, fdef)
check_for_explicit_any(fdef.type, self.options, self.is_typeshed_stub,
self.msg, context=fdef)
Expand Down Expand Up @@ -1062,9 +1057,9 @@ def check_default_args(self, item: FuncItem, body_is_trivial: bool) -> None:
name = arg.variable.name
msg = 'Incompatible default for '
if name.startswith('__tuple_arg_'):
msg += "tuple argument {}".format(name[12:])
msg += f"tuple argument {name[12:]}"
else:
msg += 'argument "{}"'.format(name)
msg += f'argument "{name}"'
self.check_simple_assignment(
arg.variable.type,
arg.initializer,
Expand Down Expand Up @@ -1964,7 +1959,7 @@ def check_enum_bases(self, defn: ClassDef) -> None:
continue
elif enum_base is not None:
self.fail(
'No base classes are allowed after "{}"'.format(enum_base),
f'No base classes are allowed after "{enum_base}"',
defn,
)
break
Expand Down Expand Up @@ -3308,8 +3303,8 @@ def check_simple_assignment(self, lvalue_type: Optional[Type], rvalue: Expressio
self.msg.deleted_as_lvalue(lvalue_type, context)
elif lvalue_type:
self.check_subtype(rvalue_type, lvalue_type, context, msg,
'{} has type'.format(rvalue_name),
'{} has type'.format(lvalue_name), code=code)
f'{rvalue_name} has type',
f'{lvalue_name} has type', code=code)
return rvalue_type

def check_member_assignment(self, instance_type: Type, attribute_type: Type,
Expand Down Expand Up @@ -3717,7 +3712,7 @@ def _type_check_raise_python2(self, e: Expression, s: RaiseStmt, typ: ProperType
expected_type = TypeType(exc_type)
self.check_subtype(
typ.items[0], expected_type, s,
'Argument 1 must be "{}" subtype'.format(expected_type),
f'Argument 1 must be "{expected_type}" subtype',
)

# Typecheck `traceback` part:
Expand All @@ -3732,7 +3727,7 @@ def _type_check_raise_python2(self, e: Expression, s: RaiseStmt, typ: ProperType
])
self.check_subtype(
typ.items[2], traceback_type, s,
'Argument 3 must be "{}" subtype'.format(traceback_type),
f'Argument 3 must be "{traceback_type}" subtype',
)
else:
expected_type_items = [
Expand Down Expand Up @@ -4302,7 +4297,7 @@ def _make_fake_typeinfo_and_full_name(
curr_module_: MypyFile,
) -> Tuple[TypeInfo, str]:
names_list = pretty_seq([x.type.name for x in base_classes_], "and")
short_name = '<subclass of {}>'.format(names_list)
short_name = f'<subclass of {names_list}>'
full_name_ = gen_unique_name(short_name, curr_module_.names)
cdef, info_ = self.make_fake_typeinfo(
curr_module_.fullname,
Expand Down Expand Up @@ -4354,7 +4349,7 @@ def intersect_instance_callable(self, typ: Instance, callable_type: CallableType
# have a valid fullname and a corresponding entry in a symbol table. We generate
# a unique name inside the symbol table of the current module.
cur_module = cast(MypyFile, self.scope.stack[0])
gen_name = gen_unique_name("<callable subtype of {}>".format(typ.type.name),
gen_name = gen_unique_name(f"<callable subtype of {typ.type.name}>",
cur_module.names)

# Synthesize a fake TypeInfo
Expand Down Expand Up @@ -5367,7 +5362,7 @@ def lookup(self, name: str) -> SymbolTableNode:
table = cast(MypyFile, b.node).names
if name in table:
return table[name]
raise KeyError('Failed lookup: {}'.format(name))
raise KeyError(f'Failed lookup: {name}')

def lookup_qualified(self, name: str) -> SymbolTableNode:
if '.' not in name:
Expand Down Expand Up @@ -5891,7 +5886,7 @@ def and_conditional_maps(m1: TypeMap, m2: TypeMap) -> TypeMap:
# arbitrarily give precedence to m2. (In the future, we could use
# an intersection type.)
result = m2.copy()
m2_keys = set(literal_hash(n2) for n2 in m2)
m2_keys = {literal_hash(n2) for n2 in m2}
for n1 in m1:
if literal_hash(n1) not in m2_keys:
result[n1] = m1[n1]
Expand Down Expand Up @@ -6561,7 +6556,7 @@ def is_static(func: Union[FuncBase, Decorator]) -> bool:
return is_static(func.func)
elif isinstance(func, FuncBase):
return func.is_static
assert False, "Unexpected func type: {}".format(type(func))
assert False, f"Unexpected func type: {type(func)}"


def is_subtype_no_promote(left: Type, right: Type) -> bool:
Expand Down
10 changes: 5 additions & 5 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def extract_refexpr_names(expr: RefExpr) -> Set[str]:
else:
break
else:
raise AssertionError("Unknown RefExpr subclass: {}".format(type(expr)))
raise AssertionError(f"Unknown RefExpr subclass: {type(expr)}")
return output


Expand Down Expand Up @@ -427,7 +427,7 @@ def method_fullname(self, object_type: Type, method_name: str) -> Optional[str]:
type_name = tuple_fallback(object_type).type.fullname

if type_name is not None:
return '{}.{}'.format(type_name, method_name)
return f'{type_name}.{method_name}'
else:
return None

Expand Down Expand Up @@ -582,7 +582,7 @@ def check_typeddict_call_with_kwargs(self, callee: TypedDictType,
self.chk.check_simple_assignment(
lvalue_type=item_expected_type, rvalue=item_value, context=item_value,
msg=message_registry.INCOMPATIBLE_TYPES,
lvalue_name='TypedDict item "{}"'.format(item_name),
lvalue_name=f'TypedDict item "{item_name}"',
rvalue_name='expression',
code=codes.TYPEDDICT_ITEM)

Expand Down Expand Up @@ -2189,7 +2189,7 @@ def visit_op_expr(self, e: OpExpr) -> Type:
e.method_type = method_type
return result
else:
raise RuntimeError('Unknown operator {}'.format(e.op))
raise RuntimeError(f'Unknown operator {e.op}')

def visit_comparison_expr(self, e: ComparisonExpr) -> Type:
"""Type check a comparison expression.
Expand Down Expand Up @@ -2286,7 +2286,7 @@ def visit_comparison_expr(self, e: ComparisonExpr) -> Type:
self.msg.dangerous_comparison(left_type, right_type, 'identity', e)
method_type = None
else:
raise RuntimeError('Unknown comparison operator {}'.format(operator))
raise RuntimeError(f'Unknown comparison operator {operator}')

e.method_types.append(method_type)

Expand Down
6 changes: 3 additions & 3 deletions mypy/checkmember.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ def analyze_type_callable_member_access(name: str,
# Look up from the 'type' type.
return _analyze_member_access(name, typ.fallback, mx)
else:
assert False, 'Unexpected type {}'.format(repr(ret_type))
assert False, f'Unexpected type {ret_type!r}'


def analyze_type_type_member_access(name: str,
Expand Down Expand Up @@ -410,7 +410,7 @@ def analyze_member_var_access(name: str,
result = getattr_type

# Call the attribute hook before returning.
fullname = '{}.{}'.format(method.info.fullname, name)
fullname = f'{method.info.fullname}.{name}'
hook = mx.chk.plugin.get_attribute_hook(fullname)
if hook:
result = hook(AttributeContext(get_proper_type(mx.original_type),
Expand Down Expand Up @@ -607,7 +607,7 @@ def analyze_var(name: str,
mx.not_ready_callback(var.name, mx.context)
# Implicit 'Any' type.
result = AnyType(TypeOfAny.special_form)
fullname = '{}.{}'.format(var.info.fullname, name)
fullname = f'{var.info.fullname}.{name}'
hook = mx.chk.plugin.get_attribute_hook(fullname)
if result and not mx.is_lvalue and not implicit:
result = analyze_descriptor_access(result, mx)
Expand Down
13 changes: 5 additions & 8 deletions mypy/checkpattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,10 @@
# For every Pattern a PatternType can be calculated. This requires recursively calculating
# the PatternTypes of the sub-patterns first.
# Using the data in the PatternType the match subject and captured names can be narrowed/inferred.
PatternType = NamedTuple(
'PatternType',
[
('type', Type), # The type the match subject can be narrowed to
('rest_type', Type), # The remaining type if the pattern didn't match
('captures', Dict[Expression, Type]), # The variables captured by the pattern
])
class PatternType(NamedTuple):
type: Type # The type the match subject can be narrowed to
rest_type: Type # The remaining type if the pattern didn't match
captures: Dict[Expression, Type] # The variables captured by the pattern


class PatternChecker(PatternVisitor[PatternType]):
Expand Down Expand Up @@ -628,7 +625,7 @@ def update_type_map(self,
) -> None:
# Calculating this would not be needed if TypeMap directly used literal hashes instead of
# expressions, as suggested in the TODO above it's definition
already_captured = set(literal_hash(expr) for expr in original_type_map)
already_captured = {literal_hash(expr) for expr in original_type_map}
for expr, typ in extra_type_map.items():
if literal_hash(expr) in already_captured:
node = get_var(expr)
Expand Down
2 changes: 1 addition & 1 deletion mypy/checkstrformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ def apply_field_accessors(self, spec: ConversionSpecifier, repl: Expression,
dummy, fnam="<format>", module=None, options=self.chk.options, errors=temp_errors
)
if temp_errors.is_errors():
self.msg.fail('Syntax error in format specifier "{}"'.format(spec.field),
self.msg.fail(f'Syntax error in format specifier "{spec.field}"',
ctx, code=codes.STRING_FORMATTING)
return TempNode(AnyType(TypeOfAny.from_error))

Expand Down
Loading