Skip to content
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

Feature proposal: an option --any-as-object to avoid false negatives #12856

Open
calimeroteknik opened this issue May 23, 2022 · 4 comments
Open
Labels
feature topic-configuration Configuration files and flags topic-disallow-any The disallow-any-* family of flags

Comments

@calimeroteknik
Copy link

Feature

Mypy would have an option to consider any occurrence of Any as being object in order to issue a warning or error when Any is used as if it were any type more specific than object.

Related #3194

Pitch

It turned out that the typeshed will rather "err on the side of convenience" and use Any to avoid causing annoyance in existing codebases.
This opens the door to potential type errors at run time without ever getting so much as a warning from mypy.
This option would allow to turn the problem on its head for those who wish to do so, giving an option to err on the side of caution rather than convenience — the benefit of ensuring no runtime type errors, at the cost of more hoops to jump through.

When using the WSGI protocol for example, using --disallow-any-expr, this ended in utter confusion due to different standards seemingly applied to my code on the one hand, and the libraries on the other:

from wsgiref.types import WSGIEnvironment, StartResponse, InputStream
from typing import Iterable

def f(a: str) -> int:
	return int(a)

def wsgi_callable(environ: WSGIEnvironment, start_response: StartResponse) -> Iterable[bytes]:
	# No error:
	content_length1 = f(environ['CONTENT_LENGTH'])

	# error: Expression has type "Any":
	content_length2 = f("0" if environ['CONTENT_LENGTH'] == "" else environ['CONTENT_LENGTH'])

	return []

To have an error in one case and not the other was completely confusing to begin with, since in all logic, both expressions have the same type (str in this case). Therefore, the intuition was that they should either be both valid or both wrong.
Looking further, I discovered that in the first case, I was actually not protected against a runtime type error due to Any: https://github.com/python/cpython/blob/main/Lib/wsgiref/types.py#L29

I understand that the typeshed uses Any to avoid creating too many errors in existing code bases, but since I'm getting started from scratch I would actually like to get the "annoyance" over potential runtime type errors.
It is for the same reason that mypy already has various 'strictness' options, for users who have an approach where they value guarantees that actually hold, more than being spared to go the final mile.

The option proposed here would elegantly convert cases with potential for false negatives to cases with potential for false positives.

Thanks to jinsun on the official #python IRC for the original concept of Any → object.

@AlexWaygood AlexWaygood added topic-configuration Configuration files and flags topic-disallow-any The disallow-any-* family of flags labels May 23, 2022
@KotlinIsland

This comment was marked as off-topic.

@Dreamsorcerer
Copy link
Contributor

I think this is an exact duplicate of #9153. The title/wording has changed a couple of times, but the end goal has always been to ultimately treat Any like object.

It turned out that the typeshed will rather "err on the side of convenience" and use Any to avoid causing annoyance in existing codebases.

I think Any and object have different semantics, it's the type checker's job to decide what to do with them. object means the function should work with anything passed to it (e.g print(), https://github.com/python/typeshed/blob/master/stdlib/builtins.pyi#L1508). Any means that the code is dynamically typed, we can't figure out a 'safe' static type. I think typeshed does this correctly, it's down to the type checker to increase strictness.

This could also mean that's it's worth having one flag that treats everything as object, and another which still warns about Any in an external function's parameters (as long as you are using that parameter). The latter could be used to highlight places where you don't have type safety and need to be extra careful (but, given there is little you can do about it, would just be annoying to most people).

@calimeroteknik
Copy link
Author

calimeroteknik commented Jul 18, 2022

In fact it isn't. #9153 is about reducing strictness; this is about having even more of it. (as an available option for those who wish to use it, not affecting anyone else)

@Dreamsorcerer
Copy link
Contributor

Dreamsorcerer commented Jul 19, 2022

Ah, from your example, I'd argue that is a bug with mypy. It doesn't consider x to be an expression. The python documentation does consider that to be an expression, so I'd say that errors should be appearing in your first instance with --disallow-any-expr. So, I think the object discussion is not necessarily related, it's just a bug with that feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature topic-configuration Configuration files and flags topic-disallow-any The disallow-any-* family of flags
Projects
None yet
Development

No branches or pull requests

4 participants