Skip to content

and expression with bool() does not work with Optionals #5540

Open
@sk-

Description

@sk-

For the following code, mypy reports an incompatible type error on the function f

from typing import Optional

def f(x:Optional[str]) -> bool:
  return bool(x) and g(x)

def f2(x:Optional[str]) -> bool:
  if x:
    return g(x)
  return False

def g(x: str) -> bool:
  return bool(x)
test.py:4: error: Argument 1 to "g" has incompatible type "Optional[str]"; expected "str"

however the code is equivalent to the one in f2, for which no error is raised.

  • What are the versions of mypy and Python you are using?
    Mypy: 0.620, Python: 3.6.5

  • What are the mypy flags you are using? (For example --strict-optional)

[mypy]
# This flag should be removed here and enabled per module when we have a
# considerable number of stubs for external libraries.
ignore_missing_imports = True
strict_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
check_untyped_defs = True

Activity

ilevkivskyi

ilevkivskyi commented on Aug 30, 2018

@ilevkivskyi
Member

For mypy bool is just a function with type (object) -> bool, so it doesn't know that, e.g., for None this function always returns False. We can of course special-case this (especially with literal types coming soon). But taking into account that there is an equivalent (and IMO better/more readable) pattern, I think this is low priority.

sk-

sk- commented on Aug 30, 2018

@sk-
Author

Thanks @ilevkivskyi for the explanation. "final types" would help in this case without having to special case bool, right? Do you know when are they planned to be implemented?"

Regarding readability, without types one would just write:

def f(x):
  return x and g(x)

but with types we have to write:

def f(x:Optional[str]) -> bool:
  if x:
    return g(x)
  return False

which is much more verbose.

Or the alternative in the OP using bool. In both cases we need to add extra code to make sure the types are as advertised.

ilevkivskyi

ilevkivskyi commented on Aug 30, 2018

@ilevkivskyi
Member

Note that x and g(x) will be a string if x is an empty string (try this in Python interpreter). So the two functions you wrote above are not equivalent, and this is why IMO the second is better.

Do you know when are they planned to be implemented?

Soon.

stephen-akerson-rh

stephen-akerson-rh commented on Sep 11, 2019

@stephen-akerson-rh

I have a similar issue. With the following snippet:

def f(x: str):
    return x*2

def g(x: str = None, y: str = None)
    if y and not x:
        raise Exception("x required when y is present")
    if y:
      return f(x)
    return x

mypy reports:

error: Argument 1 to "f" has incompatible type "Optional[str]"; expected "str".

It therefore seems mypy is unaware of the check for the existence of x any time y is passed to g (see the conditional on L5).

Note: this also seems related to: https://gist.github.com/reillysiemens/4f60233f321d84b5db911f00b17757a0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @sk-@ilevkivskyi@stephen-akerson-rh

        Issue actions

          and expression with bool() does not work with Optionals · Issue #5540 · python/mypy