You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Question about type signature for "don't know" #3712
This is presently just a question, but perhaps it is a feature request.
As I'm annotating functions in a pre-existing codebase, I have found that I tend to have two distinct things that I'd like to annotate:
This function takes objects of any type as input
This function takes objects of a particular type as input, but I have absolutely no idea what that type is.
mypy has the Any type; presently, my assumption is that this is intended for the first bullet. I've been abusing it for the second bullet as well, but this means that if I come back to the signature later, I have no idea if the Any means "anything" or "dunno".
Does mypy have a better "Unknown" type? Would it be recommended to just say,
Unknown=Any
?
(I think most ideally, I could, perhaps with a flag like --flag-unknowns, ask mypy to emit warnings about uses of something like "Unknown".)
(In case you're wondering/thinking "just don't annotate it for the unknown case", I try to do that, but this mostly comes up with dicts where I know the key's type (usually, str) but not the values — e.g. Dict[str, ???], or in functions, where I know some of the args but not all of the arguments — e.g. (int, str, str, str, ?, ??, ???) -> Thing —, and I'd like to document and ideally get mypy's type-checking support for what I know.)
I guess it depends on what your workflow is. For your workflow I recommend just using the Unknown = Any alias. Also note that in some case it's fine to use object instead of Any -- this essentially means that if you want to do anything it (except something like str()) you have to use isinstance() to check the type. For dicts, I also recommend checking out TypedDict in the docs.
The first bullet is actually object. And Any is for the second one.
IMO that depends -- in stubs this is certainly true, but in implementation code, using object often means you get errors everywhere you use it inside the function.
If in Python/mypy object is equivalent to unknown (is object absolutely a top type in Python? Does it need any special handling in mypy?), then I think this issue can be closed since that already exists.
For example, currently json.loads is annotated with -> Any, so json.loads('5') + 'foo' type checks. But if it is changed to -> Unknown, then it is not possible to do anything with the return value except narrow it down with is or isinstance, so it's safe.
(Disclaimer: I don't actually think it's a good tradeoff to change json.loads to return Unknown/object, but it's a nice illustration for how this type can be useful. Also for JSON specifically it's possible to have a more precise recursive type Json = Union[None, bool, int, float, str, List[Json], Dict[str, Json]], so perhaps pickle is a better example).
Activity
gvanrossum commentedon Jul 13, 2017
I guess it depends on what your workflow is. For your workflow I recommend just using the
Unknown = Anyalias. Also note that in some case it's fine to useobjectinstead ofAny-- this essentially means that if you want to do anything it (except something like str()) you have to use isinstance() to check the type. For dicts, I also recommend checking out TypedDict in the docs.ilevkivskyi commentedon Jul 13, 2017
The first bullet is actually
object. AndAnyis for the second one.gvanrossum commentedon Jul 13, 2017
IMO that depends -- in stubs this is certainly true, but in implementation code, using
objectoften means you get errors everywhere you use it inside the function.bluetech commentedon Oct 24, 2018
If in Python/mypy
objectis equivalent tounknown(isobjectabsolutely a top type in Python? Does it need any special handling in mypy?), then I think this issue can be closed since that already exists.Some random comments:
TypeScript has an
unknowntop type for this: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-typeFor example, currently
json.loadsis annotated with-> Any, sojson.loads('5') + 'foo'type checks. But if it is changed to-> Unknown, then it is not possible to do anything with the return value except narrow it down withisorisinstance, so it's safe.(Disclaimer: I don't actually think it's a good tradeoff to change
json.loadsto returnUnknown/object, but it's a nice illustration for how this type can be useful. Also for JSON specifically it's possible to have a more precise recursive typeJson = Union[None, bool, int, float, str, List[Json], Dict[str, Json]], so perhaps pickle is a better example).gvanrossum commentedon Oct 24, 2018
Yeah,
objectis absolutely the top type in mypy. Closing.