typeshed
typeshed copied to clipboard
Callable[[], Any] vs Callable[[], object]
Often the return value of a callback function is ignored. In those cases, I have previously used Callable[[], None]
, but then @srittau told me to use Callable[[], Any]
, and I changed all stubs I had written to typeshed.
It seems like Callable[[], object]
does the same thing as Callable[[], Any]
though, and when used in a .py
file, also prevents accidentally doing something with the return value. Would it be preferable in typeshed?
Callable[[], object]
is the better option. It also potentially avoids an Any
import.
There are quite a few Callable[blah, Any]
s, but not really too many to go through them all by hand:
akuli@akuli-desktop:~/typeshed$ git grep 'Callable\[\[.*\], Any\]' | grep -v @python2 | wc -l
269
For extra clarity, we could define Void = object
in _typeshed
and use it. This would semantically be like TypeScript's void (https://www.typescriptlang.org/docs/handbook/basic-types.html#void).
I don't really like the Void
idea.
Knowing that Void
exists, it would be weird to see -> None
instead of -> Void
. Many other languages use void
as the return type for functions that don't return anything.
I also don't like the idea of adding very frequently needed things to _typeshed
. If you really need to use something every time you make a callback function, it IMO belongs to typing
or typing_extensions
, not into _typeshed
. In general, I think project-specific "utils" libraries should be small, or ideally not needed at all. That said, we already have _typeshed.Self
, so maybe this doesn't really matter.
I also don't think this needs more clarity, as object
generally means "type doesn't matter". (It is different from Any
which means "type checkers, please don't complain".) That is exactly how it would be used in this context. So if you know how object
is used in typing, there is nothing surprising that needs to be clarified.
I've come to see _typeshed
as a staging ground for typing_extensions
, now that we seem to have consensus that moving some stuff over seems desirable.
Other than for semantics, where Any
is used as "not 'all' types fit, but too complex to represent", and where a hypothetical AnyOf
would fit, is there any case where using object
as the callable return type is detrimental over Any
? If not, this could be added as a rule to Flake8-PYI and fixed fairly quickly in typeshed. Even in the case where Any
is still used for the "too complex" semantic, imo it would promote adding a comment with more detail along with the # noqa
We've switched to use object
now, where the return value is ignored. Any
is still useful when the return value is not ignored and can't be expressed.
FWIW I experimented with adding a check to flake8-pyi, but couldn't see a way of doing it without a level of false positives that to me would be unacceptable :/
I don't want to close https://github.com/PyCQA/flake8-pyi/issues/237 yet though, as maybe we can figure out a way of doing non-blocking flake8-pyi checks that we can integrate well into our typeshed CI.