Skip to content

Commit ec5d4c6

Browse files
Merge branch 'master' into patch-3
2 parents 1da9046 + faac780 commit ec5d4c6

16 files changed

+216
-96
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## Next Release
44

5+
### Deprecated Flag: \--force-uppercase-builtins
6+
7+
Mypy only supports Python 3.9+. The \--force-uppercase-builtins flag is now deprecated and a no-op. It will be removed in a future version.
8+
9+
Contributed by Marc Mueller (PR [19176](https://github.com/python/mypy/pull/19176))
10+
511
## Mypy 1.16
612

713
We’ve just uploaded mypy 1.16 to the Python Package Index ([PyPI](https://pypi.org/project/mypy/)).

docs/source/command_line.rst

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -937,11 +937,6 @@ in error messages.
937937
useful or they may be overly noisy. If ``N`` is negative, there is
938938
no limit. The default limit is -1.
939939

940-
.. option:: --force-uppercase-builtins
941-
942-
Always use ``List`` instead of ``list`` in error messages,
943-
even on Python 3.9+.
944-
945940
.. option:: --force-union-syntax
946941

947942
Always use ``Union[]`` and ``Optional[]`` for union types

docs/source/config_file.rst

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -922,14 +922,6 @@ These options may only be set in the global section (``[mypy]``).
922922

923923
Show absolute paths to files.
924924

925-
.. confval:: force_uppercase_builtins
926-
927-
:type: boolean
928-
:default: False
929-
930-
Always use ``List`` instead of ``list`` in error messages,
931-
even on Python 3.9+.
932-
933925
.. confval:: force_union_syntax
934926

935927
:type: boolean

mypy/checker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2664,7 +2664,7 @@ def check_typevar_defaults(self, tvars: Sequence[TypeVarLikeType]) -> None:
26642664
continue
26652665
if not is_subtype(tv.default, tv.upper_bound):
26662666
self.fail("TypeVar default must be a subtype of the bound type", tv)
2667-
if tv.values and not any(tv.default == value for value in tv.values):
2667+
if tv.values and not any(is_same_type(tv.default, value) for value in tv.values):
26682668
self.fail("TypeVar default must be one of the constraint types", tv)
26692669

26702670
def check_enum(self, defn: ClassDef) -> None:

mypy/checkexpr.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6171,7 +6171,7 @@ def visit_type_var_expr(self, e: TypeVarExpr) -> Type:
61716171
):
61726172
if not is_subtype(p_default, e.upper_bound):
61736173
self.chk.fail("TypeVar default must be a subtype of the bound type", e)
6174-
if e.values and not any(p_default == value for value in e.values):
6174+
if e.values and not any(is_same_type(p_default, value) for value in e.values):
61756175
self.chk.fail("TypeVar default must be one of the constraint types", e)
61766176
return AnyType(TypeOfAny.special_form)
61776177

mypy/main.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,7 @@ def add_invertible_flag(
801801
help="Disable strict Optional checks (inverse: --strict-optional)",
802802
)
803803

804+
# This flag is deprecated, Mypy only supports Python 3.9+
804805
add_invertible_flag(
805806
"--force-uppercase-builtins", default=False, help=argparse.SUPPRESS, group=none_group
806807
)
@@ -1494,6 +1495,9 @@ def set_strict_flags() -> None:
14941495
if options.strict_concatenate and not strict_option_set:
14951496
print("Warning: --strict-concatenate is deprecated; use --extra-checks instead")
14961497

1498+
if options.force_uppercase_builtins:
1499+
print("Warning: --force-uppercase-builtins is deprecated; mypy only supports Python 3.9+")
1500+
14971501
# Set target.
14981502
if special_opts.modules + special_opts.packages:
14991503
options.build_type = BuildType.MODULE

mypy/messages.py

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,13 +1823,10 @@ def need_annotation_for_var(
18231823
recommended_type = f"Optional[{type_dec}]"
18241824
elif node.type.type.fullname in reverse_builtin_aliases:
18251825
# partial types other than partial None
1826-
alias = reverse_builtin_aliases[node.type.type.fullname]
1827-
alias = alias.split(".")[-1]
1828-
if alias == "Dict":
1826+
name = node.type.type.fullname.partition(".")[2]
1827+
if name == "dict":
18291828
type_dec = f"{type_dec}, {type_dec}"
1830-
if self.options.use_lowercase_names():
1831-
alias = alias.lower()
1832-
recommended_type = f"{alias}[{type_dec}]"
1829+
recommended_type = f"{name}[{type_dec}]"
18331830
if recommended_type is not None:
18341831
hint = f' (hint: "{node.name}: {recommended_type} = ...")'
18351832

@@ -2424,8 +2421,7 @@ def format_long_tuple_type(self, typ: TupleType) -> str:
24242421
"""Format very long tuple type using an ellipsis notation"""
24252422
item_cnt = len(typ.items)
24262423
if item_cnt > MAX_TUPLE_ITEMS:
2427-
return "{}[{}, {}, ... <{} more items>]".format(
2428-
"tuple" if self.options.use_lowercase_names() else "Tuple",
2424+
return "tuple[{}, {}, ... <{} more items>]".format(
24292425
format_type_bare(typ.items[0], self.options),
24302426
format_type_bare(typ.items[1], self.options),
24312427
str(item_cnt - 2),
@@ -2610,10 +2606,7 @@ def format_literal_value(typ: LiteralType) -> str:
26102606
if itype.type.fullname == "typing._SpecialForm":
26112607
# This is not a real type but used for some typing-related constructs.
26122608
return "<typing special form>"
2613-
if itype.type.fullname in reverse_builtin_aliases and not options.use_lowercase_names():
2614-
alias = reverse_builtin_aliases[itype.type.fullname]
2615-
base_str = alias.split(".")[-1]
2616-
elif verbosity >= 2 or (fullnames and itype.type.fullname in fullnames):
2609+
if verbosity >= 2 or (fullnames and itype.type.fullname in fullnames):
26172610
base_str = itype.type.fullname
26182611
else:
26192612
base_str = itype.type.name
@@ -2624,7 +2617,7 @@ def format_literal_value(typ: LiteralType) -> str:
26242617
return base_str
26252618
elif itype.type.fullname == "builtins.tuple":
26262619
item_type_str = format(itype.args[0])
2627-
return f"{'tuple' if options.use_lowercase_names() else 'Tuple'}[{item_type_str}, ...]"
2620+
return f"tuple[{item_type_str}, ...]"
26282621
else:
26292622
# There are type arguments. Convert the arguments to strings.
26302623
return f"{base_str}[{format_list(itype.args)}]"
@@ -2660,11 +2653,7 @@ def format_literal_value(typ: LiteralType) -> str:
26602653
if typ.partial_fallback.type.fullname != "builtins.tuple":
26612654
return format(typ.partial_fallback)
26622655
type_items = format_list(typ.items) or "()"
2663-
if options.use_lowercase_names():
2664-
s = f"tuple[{type_items}]"
2665-
else:
2666-
s = f"Tuple[{type_items}]"
2667-
return s
2656+
return f"tuple[{type_items}]"
26682657
elif isinstance(typ, TypedDictType):
26692658
# If the TypedDictType is named, return the name
26702659
if not typ.is_anonymous():
@@ -2736,8 +2725,7 @@ def format_literal_value(typ: LiteralType) -> str:
27362725
elif isinstance(typ, UninhabitedType):
27372726
return "Never"
27382727
elif isinstance(typ, TypeType):
2739-
type_name = "type" if options.use_lowercase_names() else "Type"
2740-
return f"{type_name}[{format(typ.item)}]"
2728+
return f"type[{format(typ.item)}]"
27412729
elif isinstance(typ, FunctionLike):
27422730
func = typ
27432731
if func.is_type_obj():

mypy/options.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import re
55
import sys
66
import sysconfig
7+
import warnings
78
from collections.abc import Mapping
89
from re import Pattern
910
from typing import Any, Callable, Final
@@ -400,6 +401,7 @@ def __init__(self) -> None:
400401

401402
self.disable_bytearray_promotion = False
402403
self.disable_memoryview_promotion = False
404+
# Deprecated, Mypy only supports Python 3.9+
403405
self.force_uppercase_builtins = False
404406
self.force_union_syntax = False
405407

@@ -413,9 +415,12 @@ def __init__(self) -> None:
413415
self.mypyc_skip_c_generation = False
414416

415417
def use_lowercase_names(self) -> bool:
416-
if self.python_version >= (3, 9):
417-
return not self.force_uppercase_builtins
418-
return False
418+
warnings.warn(
419+
"options.use_lowercase_names() is deprecated and will be removed in a future version",
420+
DeprecationWarning,
421+
stacklevel=2,
422+
)
423+
return True
419424

420425
def use_or_syntax(self) -> bool:
421426
if self.python_version >= (3, 10):

mypy/plugins/dataclasses.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,6 @@ def collect_attributes(self) -> list[DataclassAttribute] | None:
546546
# in the parent. We can implement this via a dict without disrupting the attr order
547547
# because dicts preserve insertion order in Python 3.7+.
548548
found_attrs: dict[str, DataclassAttribute] = {}
549-
found_dataclass_supertype = False
550549
for info in reversed(cls.info.mro[1:-1]):
551550
if "dataclass_tag" in info.metadata and "dataclass" not in info.metadata:
552551
# We haven't processed the base class yet. Need another pass.
@@ -556,7 +555,6 @@ def collect_attributes(self) -> list[DataclassAttribute] | None:
556555

557556
# Each class depends on the set of attributes in its dataclass ancestors.
558557
self._api.add_plugin_dependency(make_wildcard_trigger(info.fullname))
559-
found_dataclass_supertype = True
560558

561559
for data in info.metadata["dataclass"]["attributes"]:
562560
name: str = data["name"]
@@ -720,8 +718,7 @@ def collect_attributes(self) -> list[DataclassAttribute] | None:
720718
)
721719

722720
all_attrs = list(found_attrs.values())
723-
if found_dataclass_supertype:
724-
all_attrs.sort(key=lambda a: a.kw_only)
721+
all_attrs.sort(key=lambda a: a.kw_only)
725722

726723
# Third, ensure that arguments without a default don't follow
727724
# arguments that have a default and that the KW_ONLY sentinel

mypy/types.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3463,12 +3463,11 @@ def visit_overloaded(self, t: Overloaded, /) -> str:
34633463

34643464
def visit_tuple_type(self, t: TupleType, /) -> str:
34653465
s = self.list_str(t.items) or "()"
3466-
tuple_name = "tuple" if self.options.use_lowercase_names() else "Tuple"
34673466
if t.partial_fallback and t.partial_fallback.type:
34683467
fallback_name = t.partial_fallback.type.fullname
34693468
if fallback_name != "builtins.tuple":
3470-
return f"{tuple_name}[{s}, fallback={t.partial_fallback.accept(self)}]"
3471-
return f"{tuple_name}[{s}]"
3469+
return f"tuple[{s}, fallback={t.partial_fallback.accept(self)}]"
3470+
return f"tuple[{s}]"
34723471

34733472
def visit_typeddict_type(self, t: TypedDictType, /) -> str:
34743473
def item_str(name: str, typ: str) -> str:
@@ -3511,11 +3510,7 @@ def visit_ellipsis_type(self, t: EllipsisType, /) -> str:
35113510
return "..."
35123511

35133512
def visit_type_type(self, t: TypeType, /) -> str:
3514-
if self.options.use_lowercase_names():
3515-
type_name = "type"
3516-
else:
3517-
type_name = "Type"
3518-
return f"{type_name}[{t.item.accept(self)}]"
3513+
return f"type[{t.item.accept(self)}]"
35193514

35203515
def visit_placeholder_type(self, t: PlaceholderType, /) -> str:
35213516
return f"<placeholder {t.fullname}>"

0 commit comments

Comments
 (0)