Kaydet (Commit) 8dfb4576 authored tarafından Yury Selivanov's avatar Yury Selivanov

inspect.signature: Check for function-like objects before builtins. Issue #17159

üst e2df3ea6
...@@ -1911,15 +1911,15 @@ def _signature_internal(obj, follow_wrapper_chains=True, skip_bound_arg=True): ...@@ -1911,15 +1911,15 @@ def _signature_internal(obj, follow_wrapper_chains=True, skip_bound_arg=True):
return sig.replace(parameters=new_params) return sig.replace(parameters=new_params)
if _signature_is_builtin(obj):
return _signature_from_builtin(Signature, obj,
skip_bound_arg=skip_bound_arg)
if isfunction(obj) or _signature_is_functionlike(obj): if isfunction(obj) or _signature_is_functionlike(obj):
# If it's a pure Python function, or an object that is duck type # If it's a pure Python function, or an object that is duck type
# of a Python function (Cython functions, for instance), then: # of a Python function (Cython functions, for instance), then:
return Signature.from_function(obj) return Signature.from_function(obj)
if _signature_is_builtin(obj):
return _signature_from_builtin(Signature, obj,
skip_bound_arg=skip_bound_arg)
if isinstance(obj, functools.partial): if isinstance(obj, functools.partial):
wrapped_sig = _signature_internal(obj.func, wrapped_sig = _signature_internal(obj.func,
follow_wrapper_chains, follow_wrapper_chains,
......
...@@ -14,6 +14,7 @@ import sys ...@@ -14,6 +14,7 @@ import sys
import types import types
import unicodedata import unicodedata
import unittest import unittest
import unittest.mock
try: try:
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
...@@ -1836,6 +1837,21 @@ class TestSignatureObject(unittest.TestCase): ...@@ -1836,6 +1837,21 @@ class TestSignatureObject(unittest.TestCase):
('kwargs', ..., ..., "var_keyword")), ('kwargs', ..., ..., "var_keyword")),
...)) ...))
# Test with cython-like builtins:
_orig_isdesc = inspect.ismethoddescriptor
def _isdesc(obj):
if hasattr(obj, '_builtinmock'):
return True
return _orig_isdesc(obj)
with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
builtin_func = funclike(func)
# Make sure that our mock setup is working
self.assertFalse(inspect.ismethoddescriptor(builtin_func))
builtin_func._builtinmock = True
self.assertTrue(inspect.ismethoddescriptor(builtin_func))
self.assertEqual(inspect.signature(builtin_func), sig_func)
def test_signature_functionlike_class(self): def test_signature_functionlike_class(self):
# We only want to duck type function-like objects, # We only want to duck type function-like objects,
# not classes. # not classes.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment