Callable[[Any * N], Any]: Trouble matching against constructors for certain built-in types
davidfstr opened this issue · 2 comments
In the test suite's test_callable_p_r
you will see lines like:
# NOTE: Cannot introspect constructor for certain built-in types
# TODO: Define __signature__ for failing internal types
self.assertTryCastFailure(Callable[[], Any], bool)
self.assertTryCastFailure(Callable[[], Any], int)
self.assertTryCastSuccess(Callable[[], Any], float)
self.assertTryCastSuccess(Callable[[], Any], complex)
self.assertTryCastFailure(Callable[[], Any], str)
self.assertTryCastSuccess(Callable[[], Any], list)
self.assertTryCastFailure(Callable[[], Any], dict)
self.assertTryCastSuccess(Callable[[], Any], tuple)
We want all of those lines to all be assertTryCastSuccess
(and still have the test pass).
The failing lines above occur because an inspect.Signature
cannot be generated for the constructor of certain built-in types:
inspect.signature(bool) # ERROR: ValueError: no signature found for builtin type
inspect.signature(int) # ERROR: ValueError: no signature found for builtin type
inspect.signature(float) # OK
inspect.signature(complex) # OK
inspect.signature(str) # ERROR: ValueError: no signature found for builtin type
inspect.signature(list) # OK
inspect.signature(dict) # ERROR: ValueError: no signature found for builtin type
inspect.signature(tuple) # OK
Based on reading the implementation of inspect.signature()
and the underlying _signature_from_callable()
, it looks like the desired fix would be to define an __signature__
on the type itself. For example:
sig = inspect.Signature()
bool.__signature__ = sig # ERROR: TypeError: can't set attributes of built-in/extension type 'bool'
assert inspect.signature(bool) == sig
Unfortunately as the ERROR above alludes, there's no way to set __signature__
directly from normal Python code.
Next steps:
- Find/create issue on upstream Python issue tracker RE
inspect.signature(bool)
(and calls on similar built-in types) not working - Shepherd that issue to resolution
The inspect.signature()
documentation alludes:
Note: Some callables may not be introspectable in certain implementations of Python. For example, in CPython, some built-in functions defined in C provide no metadata about their arguments.
I think this issue should be considered a bug (and therefore prioritized higher than a normal enhancement) because its existence means that when checking against a Callable[[Any * N], Any] type, the output of trycast is NOT Decidable, which is a goal articulated in trycast's Philosophy.
However this issue is NOT a regression in functionality, so doesn't merit the "regression" label.