PY-34047 Handle keyword-only arguments in constructors of stub return values

On the whole, such stub calls look shaggy and could probably be replaced by
plain parameterless invocations altogether. It's also doubtful why we use
them only when analyzing docstrings of non-function callables, but questioning
whether they are needed in the first place seems out of scope of the current
issue. At least we don't produce warnings while generating them anymore.

GitOrigin-RevId: 25650f121e88141df081874f346d0cff2d31e3bb
This commit is contained in:
Mikhail Golubev
2019-12-17 12:36:49 +00:00
committed by intellij-monorepo-bot
parent 15eeb501e9
commit ce6b36702a
10 changed files with 72 additions and 9 deletions
+8
View File
@@ -27,6 +27,10 @@ if version[0] >= 3:
def the_exec(source, context):
exec (source, context)
# noinspection PyUnresolvedReferences
from inspect import getfullargspec
else: # < 3.0
import __builtin__ as the_builtins
@@ -40,6 +44,10 @@ else: # < 3.0
#noinspection PyRedundantParentheses
exec (source) in context
def getfullargspec(func):
import inspect
return inspect.getargspec(func) + ([], None, {})
if version[0] == 2 and version[1] < 4:
HAS_DECORATORS = False
+3 -8
View File
@@ -429,12 +429,7 @@ def restore_by_inspect(p_func):
"""
Returns paramlist restored by inspect.
"""
if version[0] > 2:
args, varg, kwarg, defaults, kwonlyargs, kwonlydefaults, _ = inspect.getfullargspec(p_func)
else:
args, varg, kwarg, defaults = inspect.getargspec(p_func)
kwonlyargs = []
kwonlydefaults = None
args, varg, kwarg, defaults, kwonlyargs, kwonlydefaults, _ = getfullargspec(p_func)
spec = []
if defaults:
dcnt = len(defaults) - 1
@@ -544,8 +539,8 @@ def detect_constructor(p_class):
# try to inspect the thing
constr = getattr(p_class, "__init__")
if constr and inspect and inspect.isfunction(constr):
args, _, _, _ = inspect.getargspec(constr)
return ", ".join(args)
args, _, _, _, kwonlyargs, _, _ = getfullargspec(constr)
return ", ".join(args + [a + '=' + a for a in kwonlyargs])
else:
return None
@@ -0,0 +1,16 @@
# encoding: utf-8
# module mod
# from mod.py
# by generator 1000.0
# no doc
# imports
import lib as lib # <ref>
# functions
def function_like(p_int): # real signature unknown; restored from __doc__
""" MyClass function_like(int) """
return lib.MyClass(self, foo=foo)
# no classes
@@ -0,0 +1,16 @@
# encoding: utf-8
# module mod
# from mod.py
# by generator 1000.0
# no doc
# imports
import lib as lib # <ref>
# functions
def function_like(p_int): # real signature unknown; restored from __doc__
""" MyClass function_like(int) """
return lib.MyClass(self, foo=foo)
# no classes
@@ -0,0 +1,9 @@
class MyClass:
def __init__(self, *, foo=None):
pass
def __call__(self):
"""
MyClass function_like()
"""
pass
@@ -0,0 +1,15 @@
import lib
class Factory:
def __call__(self, p):
"""
MyClass function_like(int)
"""
# Emulate synthetic non-function callable where the signature
# and the stub return value are restored from its docstring.
function_like = Factory().__call__
del Factory
@@ -377,7 +377,11 @@ class SkeletonGenerationTest(FunctionalGeneratorTestCase):
""")
@python3_only
def test_keyword_only_arguments(self):
def test_keyword_only_arguments_in_signatures(self):
self.check_generator_output('mod', 'mod.py')
@python3_only
def test_keyword_only_arguments_in_return_type_constructor(self):
self.check_generator_output('mod', 'mod.py')