mirror of https://github.com/python/cpython
bpo-36542: Allow to overwrite the signature for Python functions. (GH-12705)
This commit is contained in:
parent
96aeaec647
commit
d53cf99dca
|
@ -649,6 +649,7 @@ class Bdb:
|
|||
self.quitting = True
|
||||
sys.settrace(None)
|
||||
return res
|
||||
runcall.__text_signature__ = '($self, func, /, *args, **kwds)'
|
||||
|
||||
|
||||
def set_trace():
|
||||
|
|
|
@ -124,6 +124,7 @@ class Profile(_lsprof.Profiler):
|
|||
return func(*args, **kw)
|
||||
finally:
|
||||
self.disable()
|
||||
runcall.__text_signature__ = '($self, func, /, *args, **kw)'
|
||||
|
||||
def __enter__(self):
|
||||
self.enable()
|
||||
|
|
|
@ -1018,6 +1018,8 @@ class UserDict(_collections_abc.MutableMapping):
|
|||
self.update(dict)
|
||||
if kwargs:
|
||||
self.update(kwargs)
|
||||
__init__.__text_signature__ = '($self, dict=None, /, **kwargs)'
|
||||
|
||||
def __len__(self): return len(self.data)
|
||||
def __getitem__(self, key):
|
||||
if key in self.data:
|
||||
|
|
|
@ -567,6 +567,7 @@ class Executor(object):
|
|||
'got %d' % (len(args)-1))
|
||||
|
||||
raise NotImplementedError()
|
||||
submit.__text_signature__ = '($self, fn, /, *args, **kwargs)'
|
||||
|
||||
def map(self, fn, *iterables, timeout=None, chunksize=1):
|
||||
"""Returns an iterator equivalent to map(fn, iter).
|
||||
|
|
|
@ -630,6 +630,7 @@ class ProcessPoolExecutor(_base.Executor):
|
|||
|
||||
self._start_queue_management_thread()
|
||||
return f
|
||||
submit.__text_signature__ = _base.Executor.submit.__text_signature__
|
||||
submit.__doc__ = _base.Executor.submit.__doc__
|
||||
|
||||
def map(self, fn, *iterables, timeout=None, chunksize=1):
|
||||
|
|
|
@ -174,6 +174,7 @@ class ThreadPoolExecutor(_base.Executor):
|
|||
self._work_queue.put(w)
|
||||
self._adjust_thread_count()
|
||||
return f
|
||||
submit.__text_signature__ = _base.Executor.submit.__text_signature__
|
||||
submit.__doc__ = _base.Executor.submit.__doc__
|
||||
|
||||
def _adjust_thread_count(self):
|
||||
|
|
|
@ -454,6 +454,7 @@ class _BaseExitStack:
|
|||
_exit_wrapper.__wrapped__ = callback
|
||||
self._push_exit_callback(_exit_wrapper)
|
||||
return callback # Allow use as a decorator
|
||||
callback.__text_signature__ = '($self, callback, /, *args, **kwds)'
|
||||
|
||||
def _push_cm_exit(self, cm, cm_exit):
|
||||
"""Helper to correctly register callbacks to __exit__ methods."""
|
||||
|
@ -615,6 +616,7 @@ class AsyncExitStack(_BaseExitStack, AbstractAsyncContextManager):
|
|||
_exit_wrapper.__wrapped__ = callback
|
||||
self._push_exit_callback(_exit_wrapper, False)
|
||||
return callback # Allow use as a decorator
|
||||
push_async_callback.__text_signature__ = '($self, callback, /, *args, **kwds)'
|
||||
|
||||
async def aclose(self):
|
||||
"""Immediately unwind the context stack."""
|
||||
|
|
|
@ -110,3 +110,4 @@ def wrapper(*args, **kwds):
|
|||
echo()
|
||||
nocbreak()
|
||||
endwin()
|
||||
wrapper.__text_signature__ = '(func, /, *args, **kwds)'
|
||||
|
|
|
@ -388,6 +388,7 @@ class partialmethod(object):
|
|||
self.func = func
|
||||
self.args = args
|
||||
self.keywords = keywords
|
||||
__init__.__text_signature__ = '($self, func, /, *args, **keywords)'
|
||||
|
||||
def __repr__(self):
|
||||
args = ", ".join(map(repr, self.args))
|
||||
|
|
|
@ -2121,7 +2121,7 @@ def _signature_from_builtin(cls, func, skip_bound_arg=True):
|
|||
return _signature_fromstr(cls, func, s, skip_bound_arg)
|
||||
|
||||
|
||||
def _signature_from_function(cls, func):
|
||||
def _signature_from_function(cls, func, skip_bound_arg=True):
|
||||
"""Private helper: constructs Signature for the given python function."""
|
||||
|
||||
is_duck_function = False
|
||||
|
@ -2133,6 +2133,10 @@ def _signature_from_function(cls, func):
|
|||
# of pure function:
|
||||
raise TypeError('{!r} is not a Python function'.format(func))
|
||||
|
||||
s = getattr(func, "__text_signature__", None)
|
||||
if s:
|
||||
return _signature_fromstr(cls, func, s, skip_bound_arg)
|
||||
|
||||
Parameter = cls._parameter_cls
|
||||
|
||||
# Parameter information.
|
||||
|
@ -2301,7 +2305,8 @@ def _signature_from_callable(obj, *,
|
|||
if isfunction(obj) or _signature_is_functionlike(obj):
|
||||
# If it's a pure Python function, or an object that is duck type
|
||||
# of a Python function (Cython functions, for instance), then:
|
||||
return _signature_from_function(sigcls, obj)
|
||||
return _signature_from_function(sigcls, obj,
|
||||
skip_bound_arg=skip_bound_arg)
|
||||
|
||||
if _signature_is_builtin(obj):
|
||||
return _signature_from_builtin(sigcls, obj,
|
||||
|
|
|
@ -419,6 +419,7 @@ class Server(object):
|
|||
|
||||
self.incref(c, ident)
|
||||
return ident, tuple(exposed)
|
||||
create.__text_signature__ = '($self, c, typeid, /, *args, **kwds)'
|
||||
|
||||
def get_methods(self, c, token):
|
||||
'''
|
||||
|
@ -1309,6 +1310,7 @@ if HAS_SHMEM:
|
|||
if hasattr(self.registry[typeid][-1], "_shared_memory_proxy"):
|
||||
kwargs['shared_memory_context'] = self.shared_memory_context
|
||||
return Server.create(*args, **kwargs)
|
||||
create.__text_signature__ = '($self, c, typeid, /, *args, **kwargs)'
|
||||
|
||||
def shutdown(self, c):
|
||||
"Call unlink() on all tracked shared memory, terminate the Server."
|
||||
|
|
|
@ -447,6 +447,7 @@ class Profile:
|
|||
return func(*args, **kw)
|
||||
finally:
|
||||
sys.setprofile(None)
|
||||
runcall.__text_signature__ = '($self, func, /, *args, **kw)'
|
||||
|
||||
|
||||
#******************************************************************
|
||||
|
|
|
@ -3782,6 +3782,17 @@ class TestSignatureDefinitions(unittest.TestCase):
|
|||
with self.subTest(builtin=name):
|
||||
self.assertIsNone(obj.__text_signature__)
|
||||
|
||||
def test_python_function_override_signature(self):
|
||||
def func(*args, **kwargs):
|
||||
pass
|
||||
func.__text_signature__ = '($self, a, b=1, *args, c, d=2, **kwargs)'
|
||||
sig = inspect.signature(func)
|
||||
self.assertIsNotNone(sig)
|
||||
self.assertEqual(str(sig), '(self, /, a, b=1, *args, c, d=2, **kwargs)')
|
||||
func.__text_signature__ = '($self, a, b=1, /, *args, c, d=2, **kwargs)'
|
||||
sig = inspect.signature(func)
|
||||
self.assertEqual(str(sig), '(self, a, b=1, /, *args, c, d=2, **kwargs)')
|
||||
|
||||
|
||||
class NTimesUnwrappable:
|
||||
def __init__(self, n):
|
||||
|
|
|
@ -476,6 +476,7 @@ class Trace:
|
|||
if not self.donothing:
|
||||
sys.settrace(None)
|
||||
return result
|
||||
runfunc.__text_signature__ = '($self, func, /, *args, **kw)'
|
||||
|
||||
def file_module_function_of(self, frame):
|
||||
code = frame.f_code
|
||||
|
|
|
@ -102,6 +102,7 @@ def addModuleCleanup(*args, **kwargs):
|
|||
args = tuple(args)
|
||||
|
||||
_module_cleanups.append((function, args, kwargs))
|
||||
addModuleCleanup.__text_signature__ = '(function, /, *args, **kwargs)'
|
||||
|
||||
|
||||
def doModuleCleanups():
|
||||
|
@ -498,8 +499,8 @@ class TestCase(object):
|
|||
args = tuple(args)
|
||||
|
||||
self._cleanups.append((function, args, kwargs))
|
||||
addCleanup.__text_signature__ = '($self, function, /, *args, **kwargs)'
|
||||
|
||||
@classmethod
|
||||
def addClassCleanup(*args, **kwargs):
|
||||
"""Same as addCleanup, except the cleanup items are called even if
|
||||
setUpClass fails (unlike tearDownClass)."""
|
||||
|
@ -514,6 +515,8 @@ class TestCase(object):
|
|||
args = tuple(args)
|
||||
|
||||
cls._class_cleanups.append((function, args, kwargs))
|
||||
addClassCleanup.__text_signature__ = '($cls, function, /, *args, **kwargs)'
|
||||
addClassCleanup = classmethod(addClassCleanup)
|
||||
|
||||
def setUp(self):
|
||||
"Hook method for setting up the test fixture before exercising it."
|
||||
|
|
|
@ -569,6 +569,7 @@ class finalize:
|
|||
info.index = next(self._index_iter)
|
||||
self._registry[self] = info
|
||||
finalize._dirty = True
|
||||
__init__.__text_signature__ = '($self, obj, func, /, *args, **kwargs)'
|
||||
|
||||
def __call__(self, _=None):
|
||||
"""If alive then mark as dead and return func(*args, **kwargs);
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
The signature of Python functions can now be overridden by specifying the
|
||||
``__text_signature__`` attribute.
|
Loading…
Reference in New Issue