From 64351570148d5ac90b2c51bf4edf8bf418911353 Mon Sep 17 00:00:00 2001 From: Peter Gaultney Date: Tue, 9 Apr 2019 12:01:54 -0500 Subject: [PATCH 1/2] document ternary/conditional type inference limitations --- docs/source/common_issues.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/source/common_issues.rst b/docs/source/common_issues.rst index a4da8ec135465..bb2ddbef4d7b9 100644 --- a/docs/source/common_issues.rst +++ b/docs/source/common_issues.rst @@ -339,6 +339,24 @@ style anyway). We can write the above code without a cast by using g(o + 1) # Okay; type of o is inferred as int here ... +Note that MyPy cannot always narrow a type based on ``isinstance()`` +used within a ternary/conditional expression, e.g.: + +.. code-block:: python + + def f(x: AnyStr, y: AnyStr) -> bytes: + x += y + + r = x.encode('ascii') if isinstance(x, str) else x + # results in 'error: "bytes" has no attribute "encode"; maybe "decode"?' + + if isinstance(x, str): + r = x.encode('ascii') # whereas MyPy can narrow within an if statement + else: + r = x + ... + + Type inference in mypy is designed to work well in common cases, to be predictable and to let the type checker give useful error messages. More powerful type inference strategies often have complex From d6dae26ece8230696eb51222f6b672cae4162ba7 Mon Sep 17 00:00:00 2001 From: Peter Gaultney Date: Tue, 16 Apr 2019 10:01:21 -0500 Subject: [PATCH 2/2] simplified doc example; fixed spelling --- docs/source/common_issues.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/source/common_issues.rst b/docs/source/common_issues.rst index bb2ddbef4d7b9..b705717a0cdcb 100644 --- a/docs/source/common_issues.rst +++ b/docs/source/common_issues.rst @@ -339,24 +339,22 @@ style anyway). We can write the above code without a cast by using g(o + 1) # Okay; type of o is inferred as int here ... -Note that MyPy cannot always narrow a type based on ``isinstance()`` +Note that Mypy cannot always narrow a type based on ``isinstance()`` used within a ternary/conditional expression, e.g.: .. code-block:: python - def f(x: AnyStr, y: AnyStr) -> bytes: - x += y - + def f(x: AnyStr) -> bytes: r = x.encode('ascii') if isinstance(x, str) else x # results in 'error: "bytes" has no attribute "encode"; maybe "decode"?' if isinstance(x, str): - r = x.encode('ascii') # whereas MyPy can narrow within an if statement + r = x.encode('ascii') # whereas Mypy can narrow within an if statement else: r = x + return r ... - Type inference in mypy is designed to work well in common cases, to be predictable and to let the type checker give useful error messages. More powerful type inference strategies often have complex