Moved from #3573:
@jbrains
I notice that OnPressHandler.__call__() returns object, but the documentation doesn't say what value the framework expects it to return. Anything? None?
@rmartin16
A return type of object is the same as a return type of Any insofar as the return type can be anything in Python. The difference is that type checkers allow any operation on Any return types while only operations that all are valid for all objects can be used for object return types. Mypy has more thoughts on this.
The intention here is to avoid proliferating Any return types in to user code.
@jbrains
Thank you for that extra information, but I still don't know what value the framework wants me to return here. It can be any object, but what is the purpose of returning a value here? I would be returning it to Toga and I don't know what it would do with that value.
If, as I suspect, the answer is "nothing", then perhaps the protocol should be changed so that the return type is None. I'm at best an Advanced Beginner in Python, so I'm asking the "I'm new here" kinds of questions.
@rmartin16
The return type is object here because Toga is indifferent about the return type. Specifically for an on press handler, the return value is discarded and not returned from the framework. So, this handler can return whatever is necessary; for instance, a handler may have other purposes outside of the on press handling where the return type would be useful. In which case, if the Protocol was limited to the None return type, that handler wouldn't be valid. Nonetheless, None is a completely reasonable type for this handler to return.
@freakboy3742
From a purely documentation perspective, for most of these handlers, we're in a position to be very specific about the return type - almost all of them will return None; a handful (like on_close on a Window) will return bool. Is there any reason we couldn't be more specific on the return type declaration?
@rmartin16
Just that it's an artificial limitation; it prevents an arbitrary function as the handler from satisfying type checking.
That said, I guess the real question here is communicating the API's behavior. The current docstring for OnPressHandler is A handler that will be invoked when a button is pressed.. Adding to that The return value is ignored. may sufficiently help clarify this behavior.
Either way, though; I imagine most users will write dedicated methods for the handlers anyhow :)
@freakboy3742
Ah - ok - this is more of a case where from a strict documentation perspective, the return type is None, but from a "we want to allow an arbitrary function that might return a value" to not be rejected by strict typecheckers.
That makes sense; in which case, adding documentation as you note would make sense - as would a corresponding FAQ entry for "why do all the handlers have a type annotation of object, but are documented as 'return value ignored'"?
@mhsmith
it prevents an arbitrary function as the handler from satisfying type checking
Only developers who enable type checking would be affected by this, but they're exactly the kind of developer who'd prefer that we were strict about function return type hints. So I think None is more useful here.
None would also produce much clearer documentation than having to write "any object, but actually we ignore it" on every event handler.
@freakboy3742
Only developers who enable type checking would be affected by this, but they're exactly the kind of developer who'd prefer that we were strict about function return type hints. So I think None is more useful here.
I don't know that this is necessarily true. My observation is that a lot of the reports we've had of typing issues don't come from MyPy/PyRight/ty users, but from PyCharm users complaining about "the squiggly lines in their IDE".
I'll grant those users are less likely to be pushing the "Any function as a handler" approach, though.
Moved from #3573:
@jbrains
I notice that
OnPressHandler.__call__()returnsobject, but the documentation doesn't say what value the framework expects it to return. Anything?None?@rmartin16
A return type of object is the same as a return type of Any insofar as the return type can be anything in Python. The difference is that type checkers allow any operation on Any return types while only operations that all are valid for all objects can be used for object return types. Mypy has more thoughts on this.
The intention here is to avoid proliferating Any return types in to user code.
@jbrains
Thank you for that extra information, but I still don't know what value the framework wants me to return here. It can be any object, but what is the purpose of returning a value here? I would be returning it to Toga and I don't know what it would do with that value.
If, as I suspect, the answer is "nothing", then perhaps the protocol should be changed so that the return type is None. I'm at best an Advanced Beginner in Python, so I'm asking the "I'm new here" kinds of questions.
@rmartin16
The return type is object here because Toga is indifferent about the return type. Specifically for an on press handler, the return value is discarded and not returned from the framework. So, this handler can return whatever is necessary; for instance, a handler may have other purposes outside of the on press handling where the return type would be useful. In which case, if the Protocol was limited to the None return type, that handler wouldn't be valid. Nonetheless, None is a completely reasonable type for this handler to return.
@freakboy3742
From a purely documentation perspective, for most of these handlers, we're in a position to be very specific about the return type - almost all of them will return None; a handful (like on_close on a Window) will return bool. Is there any reason we couldn't be more specific on the return type declaration?
@rmartin16
Just that it's an artificial limitation; it prevents an arbitrary function as the handler from satisfying type checking.
That said, I guess the real question here is communicating the API's behavior. The current docstring for OnPressHandler is A handler that will be invoked when a button is pressed.. Adding to that The return value is ignored. may sufficiently help clarify this behavior.
Either way, though; I imagine most users will write dedicated methods for the handlers anyhow :)
@freakboy3742
Ah - ok - this is more of a case where from a strict documentation perspective, the return type is None, but from a "we want to allow an arbitrary function that might return a value" to not be rejected by strict typecheckers.
That makes sense; in which case, adding documentation as you note would make sense - as would a corresponding FAQ entry for "why do all the handlers have a type annotation of object, but are documented as 'return value ignored'"?
@mhsmith
Only developers who enable type checking would be affected by this, but they're exactly the kind of developer who'd prefer that we were strict about function return type hints. So I think None is more useful here.
None would also produce much clearer documentation than having to write "any object, but actually we ignore it" on every event handler.
@freakboy3742
I don't know that this is necessarily true. My observation is that a lot of the reports we've had of typing issues don't come from MyPy/PyRight/ty users, but from PyCharm users complaining about "the squiggly lines in their IDE".
I'll grant those users are less likely to be pushing the "Any function as a handler" approach, though.