Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
bd3c60a
Creating if branch to check for TupleExpr
Malika1109 Dec 1, 2023
8a0aee6
Checking if all elements iin the TupleExpr are enums
Malika1109 Dec 1, 2023
23d13f9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 1, 2023
f73e3fa
Fixed indent issues
Malika1109 Dec 1, 2023
aaec558
Merge branch 'in-exhaustive-checking' of https://github.com/Malika110…
Malika1109 Dec 1, 2023
e14adcb
Modified operators.py
Malika1109 Dec 1, 2023
018cf15
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 1, 2023
38102c7
Fixed formatting issues
Malika1109 Dec 1, 2023
a3fb558
Merge branch 'master' into in-exhaustive-checking
Malika1109 Dec 1, 2023
cd9826c
Merging purposes commit
Malika1109 Dec 1, 2023
ec1c3d4
Merging purposes commit
Malika1109 Dec 1, 2023
526f430
Resolved merge conflicts in typinig_extensions.pyi
Malika1109 Dec 1, 2023
605f66c
Resolved merge conflicts in typinig_extensions.pyi
Malika1109 Dec 1, 2023
c70b3f1
Merge pull request #1 from python/master
Malika1109 Dec 1, 2023
b56ab60
Resolved formatting issues
Malika1109 Dec 1, 2023
8116d9f
Merge branch 'master' of https://github.com/Malika1109/mypy into in-e…
Malika1109 Dec 1, 2023
090bc6f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 1, 2023
2df876c
Modified pyproject.tomll for ruff error
Malika1109 Dec 2, 2023
4a9e582
Made changes to handling of in for open-source errors
Malika1109 Dec 4, 2023
9bd590e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 4, 2023
6dd351c
Changed handling of in operator
Malika1109 Dec 4, 2023
17e1b7e
Changed handling of in operator
Malika1109 Dec 4, 2023
30b6cae
successfully created the check-in-exhaustive-checking-3.test file for…
a-khaldi Dec 5, 2023
fc611bc
removed the 3 in the name of the file for clarity + began the test wi…
a-khaldi Dec 5, 2023
4d38b0b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 5, 2023
4420ed8
testing is done without any comments, want to make sure it passes bef…
a-khaldi Dec 5, 2023
652caa4
testing is done without any comments, want to make sure it passes bef…
a-khaldi Dec 5, 2023
b4bf17a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 5, 2023
55d3b2f
removed unneeded comments & code
ssaloos Dec 5, 2023
16ca296
Delete feature-test.py for PR
GulnazSerikbay Dec 5, 2023
e7694a8
added comments for clarity and minor changes to in exhaustive checkin…
Dec 6, 2023
64a8ab5
added some enum type extraction + test
GulnazSerikbay Dec 6, 2023
6973a96
Merge branch
GulnazSerikbay Dec 6, 2023
5a060f7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 6, 2023
8144105
small fix
GulnazSerikbay Dec 6, 2023
69aec40
merge for pull and push
GulnazSerikbay Dec 6, 2023
046370e
removed some code
GulnazSerikbay Dec 6, 2023
06c8d98
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 6, 2023
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
19 changes: 19 additions & 0 deletions feature-test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from enum import Enum
from typing_extensions import assert_never


class MyEnum(Enum):
A = 1
B = 2
C = 3


def my_function(a: MyEnum) -> bool:
if a == MyEnum.A:
return True
elif a in (MyEnum.B, MyEnum.C):
return False
assert_never(a)


my_function(MyEnum.A)
90 changes: 54 additions & 36 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1247,7 +1247,8 @@ def check_func_def(
if (
arg_type.variance == COVARIANT
and defn.name not in ("__init__", "__new__", "__post_init__")
and not is_private(defn.name) # private methods are not inherited
# private methods are not inherited
and not is_private(defn.name)
):
ctx: Context = arg_type
if ctx.line < 0:
Expand Down Expand Up @@ -3112,7 +3113,8 @@ def check_compatibility_all_supers(
if (
isinstance(lvalue_node, Var)
and lvalue.kind in (MDEF, None)
and len(lvalue_node.info.bases) > 0 # None for Vars defined via self
# None for Vars defined via self
and len(lvalue_node.info.bases) > 0
):
for base in lvalue_node.info.mro[1:]:
tnode = base.names.get(lvalue_node.name)
Expand Down Expand Up @@ -5708,6 +5710,7 @@ def find_isinstance_check_helper(self, node: Expression) -> tuple[TypeMap, TypeM
operands = [collapse_walrus(x) for x in node.operands]
operand_types = []
narrowable_operand_index_to_hash = {}
# print(operands)
for i, expr in enumerate(operands):
if not self.has_type(expr):
return {}, {}
Expand Down Expand Up @@ -5810,49 +5813,62 @@ def has_no_custom_eq_checks(t: Type) -> bool:
narrowable_operand_index_to_hash.keys(),
)

# If we haven't been able to narrow types yet, we might be dealing with a
# explicit type(x) == some_type check
# If we haven't been able to narrow types yet, we might be dealing with a explicit type(x) == some_type check
if if_map == {} and else_map == {}:
if_map, else_map = self.find_type_equals_check(node, expr_indices)
# print("done4", if_map, else_map)
elif operator in {"in", "not in"}:
assert len(expr_indices) == 2
left_index, right_index = expr_indices
item_type = operand_types[left_index]
iterable_type = operand_types[right_index]
right_expr = operands[right_index]

if_map, else_map = {}, {}

if left_index in narrowable_operand_index_to_hash:
# We only try and narrow away 'None' for now
if is_overlapping_none(item_type):
collection_item_type = get_proper_type(
builtin_item_type(iterable_type)
)
if (
collection_item_type is not None
and not is_overlapping_none(collection_item_type)
and not (
isinstance(collection_item_type, Instance)
and collection_item_type.type.fullname == "builtins.object"
)
and is_overlapping_erased_types(item_type, collection_item_type)
):
if_map[operands[left_index]] = remove_optional(item_type)

if right_index in narrowable_operand_index_to_hash:
if_type, else_type = self.conditional_types_for_iterable(
item_type, iterable_type
if isinstance(right_expr, TupleExpr):
all_literal_enum = all(
self.is_literal_enum(element_expr) for element_expr in right_expr.items
)
expr = operands[right_index]
if if_type is None:
if_map = None
else:
if_map[expr] = if_type
if else_type is None:
if all_literal_enum:
# Set if_map for the entire tuple
if_map = {}
else_map = None
else:
else_map[expr] = else_type

else:
if left_index in narrowable_operand_index_to_hash:
# We only try and narrow away 'None' for now
if is_overlapping_none(item_type):
collection_item_type = get_proper_type(
builtin_item_type(iterable_type)
)
if (
collection_item_type is not None
and not is_overlapping_none(collection_item_type)
and not (
isinstance(collection_item_type, Instance)
and collection_item_type.type.fullname == "builtins.object"
)
and is_overlapping_erased_types(
item_type, collection_item_type
)
):
if_map[operands[left_index]] = remove_optional(item_type)

if right_index in narrowable_operand_index_to_hash:
if_type, else_type = self.conditional_types_for_iterable(
item_type, iterable_type
)
expr = operands[right_index]

if if_type is None:
if_map = None
else:
if_map[expr] = if_type
if else_type is None:
else_map = None
else:
else_map[expr] = else_type
else:
if_map = {}
else_map = {}
Expand Down Expand Up @@ -6151,6 +6167,7 @@ def refine_identity_comparison_expression(
expressions in the chain to a Literal type. Performing this coercion is sometimes
too aggressive of a narrowing, depending on context.
"""

should_coerce = True
if coerce_only_in_literal_context:

Expand Down Expand Up @@ -6246,9 +6263,6 @@ def should_coerce_inner(typ: Type) -> bool:
if sum_type_name is not None:
expr_type = try_expanding_sum_type_to_union(expr_type, sum_type_name)

# We intentionally use 'conditional_types' directly here instead of
# 'self.conditional_types_with_intersection': we only compute ad-hoc
# intersections when working with pure instances.
types = conditional_types(expr_type, target_type)
partial_type_maps.append(conditional_types_to_typemaps(expr, *types))

Expand Down Expand Up @@ -7196,7 +7210,10 @@ class Foo(Enum):
unit for the same reasons we sometimes treat 'True', 'False', or 'None' as a single
primitive unit.
"""

if not isinstance(n, MemberExpr) or not isinstance(n.expr, NameExpr):
# print(n, isinstance(n, MemberExpr))
# print(n, isinstance(n.expr, NameExpr))
return False

parent_type = self.lookup_type_or_none(n.expr)
Expand Down Expand Up @@ -7502,7 +7519,8 @@ def builtin_item_type(tp: Type) -> Type | None:
else:
normalized_items.append(it)
if all(not isinstance(it, AnyType) for it in get_proper_types(normalized_items)):
return make_simplified_union(normalized_items) # this type is not externally visible
# this type is not externally visible
return make_simplified_union(normalized_items)
elif isinstance(tp, TypedDictType):
# TypedDict always has non-optional string keys. Find the key type from the Mapping
# base class.
Expand Down
6 changes: 4 additions & 2 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -3473,7 +3473,8 @@ def visit_comparison_expr(self, e: ComparisonExpr) -> Type:
# a "Need type annotation ..." message, as it would be noise.
right_type = self.find_partial_type_ref_fast_path(right)
if right_type is None:
right_type = self.accept(right) # Validate the right operand
# Validate the right operand
right_type = self.accept(right)

right_type = get_proper_type(right_type)
item_types: Sequence[Type] = [right_type]
Expand Down Expand Up @@ -6094,7 +6095,8 @@ def __init__(self, ignore_in_type_obj: bool) -> None:
self.ignore_in_type_obj = ignore_in_type_obj

def visit_any(self, t: AnyType) -> bool:
return t.type_of_any != TypeOfAny.special_form # special forms are not real Any types
# special forms are not real Any types
return t.type_of_any != TypeOfAny.special_form

def visit_callable_type(self, t: CallableType) -> bool:
if self.ignore_in_type_obj and t.is_type_obj():
Expand Down
Loading