From 8055516d2a1d13d86a962d5abf4d84944e204c09 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Fri, 11 Aug 2023 18:37:06 +0100 Subject: [PATCH] Address CR --- docs/source/command_line.rst | 29 +++++++++++------------------ docs/source/config_file.rst | 5 +++-- mypy/checkexpr.py | 3 ++- test-data/unit/check-flags.test | 4 ++++ 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index 21981d2fb05e..0b30b959bb58 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -354,36 +354,29 @@ definitions or calls. This flag allows to selectively disable :option:`--disallow-untyped-calls` for functions and methods defined in specific packages, modules, or classes. - Note that each exception entry acts as a prefix. For example: + Note that each exception entry acts as a prefix. For example (assuming there + are no type annotations for ``numpy`` available): .. code-block:: python - # mypy --disallow-untyped-calls --untyped-call-exception=foo --untyped-call-exception=bar.A - from foo import test_foo - from bar import A, B - from baz import test_baz + # mypy --disallow-untyped-calls + # --untyped-call-exception=numpy.random + # --untyped-call-exception=foo.A + import numpy as np + from foo import A, B - test_foo(42) # OK, function comes from module `foo` - test_baz(42) # E: Call to untyped function "test_baz" in typed context + np.random.gamma(1.0) # OK, function comes from package `numpy.random` + np.fft.fft([1, 2, 3]) # E: Call to untyped function "fft" in typed context - a: A - b: B - a.meth() # OK, method was defined in class `bar.A` - b.meth() # E: Call to untyped function "meth" in typed context + A().meth() # OK, method was defined in class `bar.A` + B().meth() # E: Call to untyped function "meth" in typed context # file foo.py - def test_foo(x): pass - - # file bar.py class A: def meth(self): pass class B: def meth(self): pass - # file baz.py - def test_baz(x): pass - - .. option:: --disallow-untyped-defs This flag reports an error whenever it encounters a function definition diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index 8f39a33cf336..42c2f5d917dd 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -519,8 +519,9 @@ section of the command line docs. Selectively excludes functions and methods defined in specific packages, modules, and classes from action of :confval:`disallow_untyped_calls`. - Note, this option does not support per-file configuration, the exception - list is defined globally for all your code. + This also applies to all submodules of packages (i.e. everything inside + a given prefix). Note, this option does not support per-file configuration, + the exception list is defined globally for all your code. .. confval:: disallow_untyped_defs diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 9c4694730a46..eb7b54a832af 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -565,7 +565,8 @@ def visit_call_expr_inner(self, e: CallExpr, allow_none_return: bool = False) -> assert object_type is not None fullname = self.method_fullname(object_type, member) if not fullname or not any( - fullname.startswith(p) for p in self.chk.options.untyped_call_exception + fullname == p or fullname.startswith(f"{p}.") + for p in self.chk.options.untyped_call_exception ): self.msg.untyped_function_call(callee_type, e) diff --git a/test-data/unit/check-flags.test b/test-data/unit/check-flags.test index 3a1b374560a4..b645a5713219 100644 --- a/test-data/unit/check-flags.test +++ b/test-data/unit/check-flags.test @@ -2082,9 +2082,11 @@ f(reveal_type(y)) # E: Call to untyped function "f" in typed context \ from foo import test_foo from bar import A, B from baz import test_baz +from foobar import bad test_foo(42) # OK test_baz(42) # E: Call to untyped function "test_baz" in typed context +bad(42) # E: Call to untyped function "bad" in typed context a: A b: B @@ -2092,6 +2094,8 @@ a.meth() # OK b.meth() # E: Call to untyped function "meth" in typed context [file foo.py] def test_foo(x): pass +[file foobar.py] +def bad(x): pass [file bar.py] class A: def meth(self): pass