mypy icon indicating copy to clipboard operation
mypy copied to clipboard

Add check for comparisons like `None in list/set/tuple`

Open eladshoshani opened this issue 1 year ago • 4 comments

Implements #17152 Fixes #17149

Summary

This PR adds to mypy the ability to recognize conditions like if None in [a, b, c]: and refine the types of a, b, c in the relevant scope. The supported expressions are ListExpr, TupleExpr, SetExpr.

eladshoshani avatar Apr 23 '24 00:04 eladshoshani

Diff from mypy_primer, showing the effect of this PR on open source code:

pylint (https://github.com/pycqa/pylint)
- Warning: unused section(s) in pyproject.toml: module = ['_pytest.*', 'colorama', 'contributors_txt', 'coverage', 'git.*', 'mccabe', 'pytest', 'pytest_benchmark.*', 'sphinx.*']
- pylint/constants.py:104: error: Returning Any from function declared to return "str"  [no-any-return]
- pylint/utils/utils.py:387: error: Returning Any from function declared to return "str"  [no-any-return]
- pylint/utils/utils.py:379: error: Unused "type: ignore" comment  [unused-ignore]
+ pylint/checkers/utils.py:1419: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
+ https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
+ Please report a bug at https://github.com/python/mypy/issues
+ version: 1.11.0+dev.b236e035513e8b72d790147dc06612e3635de32d
+ pylint/checkers/utils.py:1419: : note: use --pdb to drop into pdb
+ Traceback (most recent call last):
+   File "", line 8, in <module>
+     sys.exit(console_entry())
+   File "/__main__.py", line 15, in console_entry
+     main()
+   File "/main.py", line 100, in main
+     res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
+   File "/main.py", line 182, in run_build
+     res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
+   File "/build.py", line 192, in build
+     result = _build(
+   File "/build.py", line 266, in _build
+     graph = dispatch(sources, manager, stdout)
+   File "/build.py", line 2942, in dispatch
+     process_graph(graph, manager)
+   File "/build.py", line 3340, in process_graph
+     process_stale_scc(graph, scc, manager)
+   File "/build.py", line 3441, in process_stale_scc
+     graph[id].type_check_first_pass()
+   File "/build.py", line 2310, in type_check_first_pass
+     self.type_checker().check_first_pass()
+   File "/checker.py", line 482, in check_first_pass
+     self.accept(d)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 787, in accept
+     return visitor.visit_func_def(self)
+   File "/checker.py", line 1001, in visit_func_def
+     self._visit_func_def(defn)
+   File "/checker.py", line 1005, in _visit_func_def
+     self.check_func_item(defn, name=defn.name)
+   File "/checker.py", line 1078, in check_func_item
+     self.check_func_def(defn, typ, name, allow_empty)
+   File "/checker.py", line 1310, in check_func_def
+     self.accept(item.body)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1223, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 2803, in visit_block
+     self.accept(s)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1404, in accept
+     return visitor.visit_for_stmt(self)
+   File "/checker.py", line 4797, in visit_for_stmt
+     self.accept_loop(s.body, s.else_body)
+   File "/checker.py", line 610, in accept_loop
+     self.accept(body)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1223, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 2803, in visit_block
+     self.accept(s)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1491, in accept
+     return visitor.visit_if_stmt(self)
+   File "/checker.py", line 4555, in visit_if_stmt
+     if_map, else_map = self.find_isinstance_check(e)
+   File "/checker.py", line 5701, in find_isinstance_check
+     if_map, else_map = self.find_isinstance_check_helper(node)
+   File "/checker.py", line 5950, in find_isinstance_check_helper
+     and not any(is_literal_none(i) for i in right.items)
+ AttributeError: 'NameExpr' object has no attribute 'items'

flake8-pyi (https://github.com/PyCQA/flake8-pyi)
+ pyi.py:722: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
+ https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
+ Please report a bug at https://github.com/python/mypy/issues
+ version: 1.11.0+dev.b236e035513e8b72d790147dc06612e3635de32d
+ pyi.py:722: : note: use --pdb to drop into pdb
+ Traceback (most recent call last):
+   File "", line 8, in <module>
+     sys.exit(console_entry())
+   File "/__main__.py", line 15, in console_entry
+     main()
+   File "/main.py", line 100, in main
+     res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
+   File "/main.py", line 182, in run_build
+     res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
+   File "/build.py", line 192, in build
+     result = _build(
+   File "/build.py", line 266, in _build
+     graph = dispatch(sources, manager, stdout)
+   File "/build.py", line 2942, in dispatch
+     process_graph(graph, manager)
+   File "/build.py", line 3340, in process_graph
+     process_stale_scc(graph, scc, manager)
+   File "/build.py", line 3441, in process_stale_scc
+     graph[id].type_check_first_pass()
+   File "/build.py", line 2310, in type_check_first_pass
+     self.type_checker().check_first_pass()
+   File "/checker.py", line 482, in check_first_pass
+     self.accept(d)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1142, in accept
+     return visitor.visit_class_def(self)
+   File "/checker.py", line 2341, in visit_class_def
+     self.accept(defn.defs)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1223, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 2803, in visit_block
+     self.accept(s)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 787, in accept
+     return visitor.visit_func_def(self)
+   File "/checker.py", line 1001, in visit_func_def
+     self._visit_func_def(defn)
+   File "/checker.py", line 1005, in _visit_func_def
+     self.check_func_item(defn, name=defn.name)
+   File "/checker.py", line 1078, in check_func_item
+     self.check_func_def(defn, typ, name, allow_empty)
+   File "/checker.py", line 1310, in check_func_def
+     self.accept(item.body)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1223, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 2803, in visit_block
+     self.accept(s)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1491, in accept
+     return visitor.visit_if_stmt(self)
+   File "/checker.py", line 4555, in visit_if_stmt
+     if_map, else_map = self.find_isinstance_check(e)
+   File "/checker.py", line 5701, in find_isinstance_check
+     if_map, else_map = self.find_isinstance_check_helper(node)
+   File "/checker.py", line 5950, in find_isinstance_check_helper
+     and not any(is_literal_none(i) for i in right.items)
+ AttributeError: 'IndexExpr' object has no attribute 'items'

schema_salad (https://github.com/common-workflow-language/schema_salad)
+ /tmp/mypy_primer/projects/_schema_salad_venv/lib/python3.10/site-packages/ruamel/yaml/representer.py:112: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
+ https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
+ Please report a bug at https://github.com/python/mypy/issues
+ version: 1.11.0+dev.b236e035513e8b72d790147dc06612e3635de32d
+ note: use --pdb to drop into pdb
+ Traceback (most recent call last):
+   File "", line 8, in <module>
+     sys.exit(console_entry())
+   File "/__main__.py", line 15, in console_entry
+     main()
+   File "/main.py", line 100, in main
+     res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
+   File "/main.py", line 182, in run_build
+     res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
+   File "/build.py", line 192, in build
+     result = _build(
+   File "/build.py", line 266, in _build
+     graph = dispatch(sources, manager, stdout)
+   File "/build.py", line 2942, in dispatch
+     process_graph(graph, manager)
+   File "/build.py", line 3340, in process_graph
+     process_stale_scc(graph, scc, manager)
+   File "/build.py", line 3441, in process_stale_scc
+     graph[id].type_check_first_pass()
+   File "/build.py", line 2310, in type_check_first_pass
+     self.type_checker().check_first_pass()
+   File "/checker.py", line 482, in check_first_pass
+     self.accept(d)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1142, in accept
+     return visitor.visit_class_def(self)
+   File "/checker.py", line 2341, in visit_class_def
+     self.accept(defn.defs)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1223, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 2803, in visit_block
+     self.accept(s)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 787, in accept
+     return visitor.visit_func_def(self)
+   File "/checker.py", line 1001, in visit_func_def
+     self._visit_func_def(defn)
+   File "/checker.py", line 1005, in _visit_func_def
+     self.check_func_item(defn, name=defn.name)
+   File "/checker.py", line 1078, in check_func_item
+     self.check_func_def(defn, typ, name, allow_empty)
+   File "/checker.py", line 1310, in check_func_def
+     self.accept(item.body)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1223, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 2803, in visit_block
+     self.accept(s)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1491, in accept
+     return visitor.visit_if_stmt(self)
+   File "/checker.py", line 4567, in visit_if_stmt
+     self.accept(s.else_body)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1223, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 2803, in visit_block
+     self.accept(s)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1404, in accept
+     return visitor.visit_for_stmt(self)
+   File "/checker.py", line 4797, in visit_for_stmt
+     self.accept_loop(s.body, s.else_body)
+   File "/checker.py", line 617, in accept_loop
+     self.accept(else_body)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1223, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 2803, in visit_block
+     self.accept(s)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1491, in accept
+     return visitor.visit_if_stmt(self)
+   File "/checker.py", line 4555, in visit_if_stmt
+     if_map, else_map = self.find_isinstance_check(e)
+   File "/checker.py", line 5701, in find_isinstance_check
+     if_map, else_map = self.find_isinstance_check_helper(node)
+   File "/checker.py", line 5950, in find_isinstance_check_helper
+     and not any(is_literal_none(i) for i in right.items)
+ AttributeError: 'MemberExpr' object has no attribute 'items'

pandas (https://github.com/pandas-dev/pandas)
- pandas/io/formats/printing.py:262: error: Unused "type: ignore" comment  [unused-ignore]
+ pandas/core/reshape/reshape.py:749: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
+ https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
+ Please report a bug at https://github.com/python/mypy/issues
+ version: 1.11.0+dev.b236e035513e8b72d790147dc06612e3635de32d
+ pandas/core/reshape/reshape.py:749: : note: use --pdb to drop into pdb
- pandas/core/apply.py:251: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/tests/scalar/timedelta/test_timedelta.py:586: error: Untyped decorator makes function "test_hash_equality_invariance" untyped  [misc]
- pandas/plotting/_matplotlib/tools.py:82: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/style.py:307: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/converter.py:370: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/converter.py:371: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/converter.py:373: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/converter.py:374: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/converter.py:985: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/tests/io/test_sql.py:599: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/timeseries.py:143: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/timeseries.py:156: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/timeseries.py:174: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/timeseries.py:177: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/timeseries.py:180: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:539: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:541: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:542: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:545: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:557: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1275: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1276: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1605: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1610: error: Unused "type: ignore[attr-defined]" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1627: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1630: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1632: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1634: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1650: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1656: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1673: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1676: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1694: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1768: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:1771: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:2039: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:2105: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/core.py:2108: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/hist.py:178: error: Unused "type: ignore[arg-type, index]" comment  [unused-ignore]
- pandas/plotting/_matplotlib/hist.py:209: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/hist.py:211: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/hist.py:213: error: Unused "type: ignore" comment  [unused-ignore]
- pandas/plotting/_matplotlib/hist.py:215: error: Unused "type: ignore" comment  [unused-ignore]
+ Traceback (most recent call last):
+   File "", line 8, in <module>
+     sys.exit(console_entry())
+   File "/__main__.py", line 15, in console_entry
+     main()
+   File "/main.py", line 100, in main
+     res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
+   File "/main.py", line 182, in run_build
+     res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
+   File "/build.py", line 192, in build
+     result = _build(
+   File "/build.py", line 266, in _build
+     graph = dispatch(sources, manager, stdout)
+   File "/build.py", line 2942, in dispatch
+     process_graph(graph, manager)
+   File "/build.py", line 3340, in process_graph
+     process_stale_scc(graph, scc, manager)
+   File "/build.py", line 3441, in process_stale_scc
+     graph[id].type_check_first_pass()
+   File "/build.py", line 2310, in type_check_first_pass
+     self.type_checker().check_first_pass()
+   File "/checker.py", line 482, in check_first_pass
+     self.accept(d)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 787, in accept
+     return visitor.visit_func_def(self)
+   File "/checker.py", line 1001, in visit_func_def
+     self._visit_func_def(defn)
+   File "/checker.py", line 1005, in _visit_func_def
+     self.check_func_item(defn, name=defn.name)
+   File "/checker.py", line 1078, in check_func_item
+     self.check_func_def(defn, typ, name, allow_empty)
+   File "/checker.py", line 1310, in check_func_def
+     self.accept(item.body)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1223, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 2803, in visit_block
+     self.accept(s)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1419, in accept
+     return visitor.visit_return_stmt(self)
+   File "/checker.py", line 4445, in visit_return_stmt
+     self.check_return_stmt(s)
+   File "/checker.py", line 4481, in check_return_stmt
+     self.expr_checker.accept(
+   File "/checkexpr.py", line 5760, in accept
+     typ = node.accept(self)
+   File "/nodes.py", line 1907, in accept
+     return visitor.visit_call_expr(self)
+   File "/checkexpr.py", line 476, in visit_call_expr
+     return self.visit_call_expr_inner(e, allow_none_return=allow_none_return)
+   File "/checkexpr.py", line 605, in visit_call_expr_inner
+     ret_type = self.check_call_expr_with_callee_type(
+   File "/checkexpr.py", line 1456, in check_call_expr_with_callee_type
+     ret_type, callee_type = self.check_call(
+   File "/checkexpr.py", line 1550, in check_call
+     return self.check_callable_call(
+   File "/checkexpr.py", line 1760, in check_callable_call
+     arg_types = self.infer_arg_types_in_context(callee, args, arg_kinds, formal_to_actual)
+   File "/checkexpr.py", line 1934, in infer_arg_types_in_context
+     res[ai] = self.accept(args[ai], arg_type)
+   File "/checkexpr.py", line 5760, in accept
+     typ = node.accept(self)
+   File "/nodes.py", line 2338, in accept
+     return visitor.visit_list_comprehension(self)
+   File "/checkexpr.py", line 5507, in visit_list_comprehension
+     return self.check_generator_or_comprehension(
+   File "/checkexpr.py", line 5563, in check_generator_or_comprehension
+     return self.check_call(constructor, [gen.left_expr], [nodes.ARG_POS], gen)[0]
+   File "/checkexpr.py", line 1550, in check_call
+     return self.check_callable_call(
+   File "/checkexpr.py", line 1735, in check_callable_call
+     callee = self.infer_function_type_arguments(
+   File "/checkexpr.py", line 2047, in infer_function_type_arguments
+     arg_types = self.infer_arg_types_in_context(
+   File "/checkexpr.py", line 1934, in infer_arg_types_in_context
+     res[ai] = self.accept(args[ai], arg_type)
+   File "/checkexpr.py", line 5760, in accept
+     typ = node.accept(self)
+   File "/nodes.py", line 2411, in accept
+     return visitor.visit_conditional_expr(self)
+   File "/checkexpr.py", line 5636, in visit_conditional_expr
+     if_map, else_map = self.chk.find_isinstance_check(e.cond)
+   File "/checker.py", line 5701, in find_isinstance_check
+     if_map, else_map = self.find_isinstance_check_helper(node)
+   File "/checker.py", line 5950, in find_isinstance_check_helper
+     and not any(is_literal_none(i) for i in right.items)
+ AttributeError: 'NameExpr' object has no attribute 'items'

manticore (https://github.com/trailofbits/manticore)
+ manticore/platforms/decree.py:378: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
+ https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
+ Please report a bug at https://github.com/python/mypy/issues
+ version: 1.11.0+dev.b236e035513e8b72d790147dc06612e3635de32d
+ manticore/platforms/decree.py:378: : note: use --pdb to drop into pdb
- manticore/native/manticore.py:47: note: By default the bodies of untyped functions are not checked, consider using --check-untyped-defs  [annotation-unchecked]
+ Traceback (most recent call last):
+   File "", line 8, in <module>
+     sys.exit(console_entry())
+   File "/__main__.py", line 15, in console_entry
+     main()
+   File "/main.py", line 100, in main
+     res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
+   File "/main.py", line 182, in run_build
+     res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
+   File "/build.py", line 192, in build
+     result = _build(
+   File "/build.py", line 266, in _build
+     graph = dispatch(sources, manager, stdout)
+   File "/build.py", line 2942, in dispatch
+     process_graph(graph, manager)
+   File "/build.py", line 3340, in process_graph
+     process_stale_scc(graph, scc, manager)
+   File "/build.py", line 3441, in process_stale_scc
+     graph[id].type_check_first_pass()
+   File "/build.py", line 2310, in type_check_first_pass
+     self.type_checker().check_first_pass()
+   File "/checker.py", line 482, in check_first_pass
+     self.accept(d)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1142, in accept
+     return visitor.visit_class_def(self)
+   File "/checker.py", line 2341, in visit_class_def
+     self.accept(defn.defs)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1223, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 2803, in visit_block
+     self.accept(s)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 787, in accept
+     return visitor.visit_func_def(self)
+   File "/checker.py", line 1001, in visit_func_def
+     self._visit_func_def(defn)
+   File "/checker.py", line 1005, in _visit_func_def
+     self.check_func_item(defn, name=defn.name)
+   File "/checker.py", line 1078, in check_func_item
+     self.check_func_def(defn, typ, name, allow_empty)
+   File "/checker.py", line 1310, in check_func_def
+     self.accept(item.body)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1223, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 2803, in visit_block
+     self.accept(s)
+   File "/checker.py", line 590, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1491, in accept
+     return visitor.visit_if_stmt(self)
+   File "/checker.py", line 4555, in visit_if_stmt
+     if_map, else_map = self.find_isinstance_check(e)
+   File "/checker.py", line 5701, in find_isinstance_check
+     if_map, else_map = self.find_isinstance_check_helper(node)
+   File "/checker.py", line 5950, in find_isinstance_check_helper
+     and not any(is_literal_none(i) for i in right.items)
+ AttributeError: 'MemberExpr' object has no attribute 'items'

sympy (https://github.com/sympy/sympy)
+ sympy/core/tests/test_logic.py:23: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
+ https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
+ Please report a bug at https://github.com/python/mypy/issues
+ version: 1.11.0+dev.b236e035513e8b72d790147dc06612e3635de32d
+ sympy/core/tests/test_logic.py:23: : note: use --pdb to drop into pdb
- Warning: unused section(s) in pyproject.toml: module = ['gmpy.*', 'pydy.*', 'python-sat.*']
- sympy/utilities/lambdify.py:807: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/utilities/lambdify.py:809: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/utilities/lambdify.py:811: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/utilities/lambdify.py:813: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/utilities/lambdify.py:815: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/utilities/lambdify.py:817: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/utilities/lambdify.py:819: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/utilities/lambdify.py:821: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/utilities/lambdify.py:823: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/utilities/lambdify.py:849: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/utilities/lambdify.py:905: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/logic/boolalg.py:1016: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/logic/boolalg.py:1305: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/core/numbers.py:3429: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/ntheory/continued_fraction.py:182: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/tensor/array/sparse_ndim_array.py:104: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/sets/sets.py:78: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/sets/sets.py:1813: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/sets/handlers/comparison.py:9: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/matrices/matrixbase.py:1968: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/calculus/accumulationbounds.py:702: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/vector/basisdependent.py:4: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/vector/basisdependent.py:149: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:40: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:359: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:366: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:372: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:382: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:407: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:423: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:429: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:435: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:453: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:458: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:462: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:469: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:473: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:479: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:483: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:499: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:503: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:510: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:535: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:555: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:611: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:628: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:633: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:637: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:644: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:652: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:662: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:687: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:706: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:724: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:729: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:734: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:738: error: Unused "type: ignore" comment  [unused-ignore]
- sympy/assumptions/handlers/sets.py:746: error: Unused "type: ignore" comment  [unused-ignore]

... (truncated 1275 lines) ...```

github-actions[bot] avatar Apr 23 '24 00:04 github-actions[bot]

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

github-actions[bot] avatar Apr 23 '24 11:04 github-actions[bot]

The new feature is ready and I tested it on all kinds of code samples, but something in the automatic tests that I added in the check-optional.test file got stuck. I don't have any more time right now to work on the feature, so I leave the correction/deletion of these tests to the CR

eladshoshani avatar Apr 23 '24 11:04 eladshoshani

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

github-actions[bot] avatar Apr 23 '24 12:04 github-actions[bot]