typeshed icon indicating copy to clipboard operation
typeshed copied to clipboard

Callable[[], Any] vs Callable[[], object]

Open Akuli opened this issue 3 years ago • 5 comments

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?

Akuli avatar Oct 05 '21 10:10 Akuli

Callable[[], object] is the better option. It also potentially avoids an Any import.

srittau avatar Oct 05 '21 11:10 srittau

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

Akuli avatar Oct 05 '21 11:10 Akuli

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).

JelleZijlstra avatar Oct 05 '21 14:10 JelleZijlstra

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.

Akuli avatar Oct 05 '21 15:10 Akuli

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.

srittau avatar Oct 05 '21 15:10 srittau

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

Avasam avatar Jun 13 '23 02:06 Avasam

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.

srittau avatar Jun 13 '23 05:06 srittau

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.

AlexWaygood avatar Jun 13 '23 08:06 AlexWaygood