Skip to content

False warning: Returning Any from function declared to return "bool" #5697

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
stefanhoelzl opened this issue Sep 30, 2018 · 11 comments
Closed

Comments

@stefanhoelzl
Copy link

  • Are you reporting a bug, or opening a feature request? Bugreport
  • Please insert below the code you are checking with mypy
from typing import Any

class Structure():
    def __eq__(self, other: Any) -> bool:
        return {} == other
  • What is the actual behavior/output?
mypytest.py:5: warning: Returning Any from function declared to return "bool"
  • What is the behavior/output you expect? No error
  • What are the versions of mypy and Python you are using?
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 05:52:31) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin

mypy==0.630

  • What are the mypy flags you are using?
    --strict
@ilevkivskyi
Copy link
Member

Why do you think the warning is false? It looks like a totally reasonable warning, since --warn-return-any is part of --strict. If you don't like it, don't use this flag.

@stefanhoelzl
Copy link
Author

because {} == other should evaluate to a bool.
Which means the method returns a bool.
Then getting a warning Returning Any seems false to me.

@ilevkivskyi
Copy link
Member

Everything applied to Any evaluates to Any. A dynamic class can define __eq__ that returns a string, there is no guarantee it is a bool.

@ylathouris
Copy link

Everything applied to Any evaluates to Any. A dynamic class can define __eq__ that returns a string, there is no guarantee it is a bool.

This was helpful. Thank you!

@Torxed
Copy link

Torxed commented Nov 28, 2021

I get the same error when using:

def verify_password(plain_password :str, hashed_password :str) -> bool:
	return pwd_context.verify(plain_password, hashed_password)

Which is taken from the FastAPI docs. In this case .verify() is a verification function that to the best of my knowledge can only return True or False but is not typed: https://foss.heptapod.net/python-libs/passlib/-/blob/01dfe753e4f4590307611ef5c6304279a7364305/passlib/context.py?page=3#L2272-2313

I think I understand the rules of the Any evaluation, but perhaps I've misunderstood how mypy evaluates these cases.
Shouldn't the return value matter in mypy's checks? That is that it's a static value of False or True that gets returned?

In any case, the fix is simple enough:

def verify_password(plain_password :str, hashed_password :str) -> bool:
	return bool(pwd_context.verify(plain_password, hashed_password))

But it feels excessive to enforce one additional function call per call stack to please mypy, even in --strict mode.
It's the first time trying to use linters and type checkers, and this thread came up. I assumed it would deal with these cases "smartly", is that not the case?

@JelleZijlstra
Copy link
Member

@Torxed the fix seems simple here: mypy needs to be told what the return type of .verify() is. If there's no annotation, it doesn't know.

I would not recommend turning on the option that generates this error. It's too strict to be useful for most code.

@hauntsaninja
Copy link
Collaborator

--no-warn-return-any :-)

herostrat pushed a commit to herostrat/frigate that referenced this issue Nov 18, 2022
Not all elements from the event dict are sure to be something that can be evaluated

See e.g.: python/mypy#5697
blakeblackshear pushed a commit to blakeblackshear/frigate that referenced this issue Nov 19, 2022
* Typing: events.py

* Remove unused variable

* Fix return Any from return statement

Not all elements from the event dict are sure to be something that can be evaluated

See e.g.: python/mypy#5697

* Sort out Event disambiguity

There was a name collision of multiprocessing Event type and frigate events

Co-authored-by: Sebastian Englbrecht <[email protected]>
@mattmontero
Copy link

same issue here 👋

My little hack for this is to set a new variable, and type the variable. (Similar to @Torxed, but not explicitly casting)

from typing import Any

class Structure():
    def __eq__(self, other: Any) -> bool:
        outcome: bool = {} == other
        return outcome

@BabakAmini
Copy link

@Torxed the fix seems simple here: mypy needs to be told what the return type of .verify() is. If there's no annotation, it doesn't know.

The same problem affects me. It is evident that .verify() returns a boolean. Why is it invisible to Mypy?

image

@Torxed
Copy link

Torxed commented May 27, 2024

@Torxed the fix seems simple here: mypy needs to be told what the return type of .verify() is. If there's no annotation, it doesn't know.

The same problem affects me. It is evident that .verify() returns a boolean. Why is it invisible to Mypy?

image

It's actually not completely evident. Because the .verify() function actually lacks a typed annotation that mypy can interpret.
Your IDE however, might be able to parse the sphinx docstring since the verify docstring has a :returns: or, if exist, :rtype:.

But to the best of my understanding, passlib simply lacks native annotation in all possible .verify() functions.

And to the best of my understanding, mypy does not read or understand docstrings, and why would it, as it's a sphinx invented thing (as I understand it).

Would be nice if the project moved to https://pypi.org/project/sphinx-autodoc-typehints/ or something similar.

@BabakAmini
Copy link

@Torxed Thank you for your thoughtful explanations, as I had not given this topic much thought.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants