mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 22:14:27 +08:00
Make partial use the __doc__ of its function, fixes #1621
This commit is contained in:
@@ -18,6 +18,7 @@ def _stub_to_python_value_set(stub_value, ignore_compiled=False):
|
||||
|
||||
was_instance = stub_value.is_instance()
|
||||
if was_instance:
|
||||
arguments = getattr(stub_value, '_arguments', None)
|
||||
stub_value = stub_value.py__class__()
|
||||
|
||||
qualified_names = stub_value.get_qualified_names()
|
||||
@@ -30,11 +31,12 @@ def _stub_to_python_value_set(stub_value, ignore_compiled=False):
|
||||
method_name = qualified_names[-1]
|
||||
qualified_names = qualified_names[:-1]
|
||||
was_instance = True
|
||||
arguments = None
|
||||
|
||||
values = _infer_from_stub(stub_module_context, qualified_names, ignore_compiled)
|
||||
if was_instance:
|
||||
values = ValueSet.from_sets(
|
||||
c.execute_with_values()
|
||||
c.execute_with_values() if arguments is None else c.execute(arguments)
|
||||
for c in values
|
||||
if c.is_class()
|
||||
)
|
||||
|
||||
@@ -474,11 +474,10 @@ def collections_namedtuple(value, arguments, callback):
|
||||
class PartialObject(ValueWrapper):
|
||||
def __init__(self, actual_value, arguments, instance=None):
|
||||
super(PartialObject, self).__init__(actual_value)
|
||||
self._actual_value = actual_value
|
||||
self._arguments = arguments
|
||||
self._instance = instance
|
||||
|
||||
def _get_function(self, unpacked_arguments):
|
||||
def _get_functions(self, unpacked_arguments):
|
||||
key, lazy_value = next(unpacked_arguments, (None, None))
|
||||
if key is not None or lazy_value is None:
|
||||
debug.warning("Partial should have a proper function %s", self._arguments)
|
||||
@@ -487,8 +486,8 @@ class PartialObject(ValueWrapper):
|
||||
|
||||
def get_signatures(self):
|
||||
unpacked_arguments = self._arguments.unpack()
|
||||
func = self._get_function(unpacked_arguments)
|
||||
if func is None:
|
||||
funcs = self._get_functions(unpacked_arguments)
|
||||
if funcs is None:
|
||||
return []
|
||||
|
||||
arg_count = 0
|
||||
@@ -500,17 +499,30 @@ class PartialObject(ValueWrapper):
|
||||
arg_count += 1
|
||||
else:
|
||||
keys.add(key)
|
||||
return [PartialSignature(s, arg_count, keys) for s in func.get_signatures()]
|
||||
return [PartialSignature(s, arg_count, keys) for s in funcs.get_signatures()]
|
||||
|
||||
def py__call__(self, arguments):
|
||||
func = self._get_function(self._arguments.unpack())
|
||||
if func is None:
|
||||
funcs = self._get_functions(self._arguments.unpack())
|
||||
if funcs is None:
|
||||
return NO_VALUES
|
||||
|
||||
return func.execute(
|
||||
return funcs.execute(
|
||||
MergedPartialArguments(self._arguments, arguments, self._instance)
|
||||
)
|
||||
|
||||
def py__doc__(self):
|
||||
"""
|
||||
In CPython partial does not replace the docstring. However we are still
|
||||
imitating it here, because we want this docstring to be worth something
|
||||
for the user.
|
||||
"""
|
||||
callables = self._get_functions(self._arguments.unpack())
|
||||
if callables is None:
|
||||
return ''
|
||||
for callable_ in callables:
|
||||
return callable_.py__doc__()
|
||||
return ''
|
||||
|
||||
def py__get__(self, instance, class_value):
|
||||
return ValueSet([self])
|
||||
|
||||
@@ -519,7 +531,7 @@ class PartialMethodObject(PartialObject):
|
||||
def py__get__(self, instance, class_value):
|
||||
if instance is None:
|
||||
return ValueSet([self])
|
||||
return ValueSet([PartialObject(self._actual_value, self._arguments, instance)])
|
||||
return ValueSet([PartialObject(self._wrapped_value, self._arguments, instance)])
|
||||
|
||||
|
||||
class PartialSignature(SignatureWrapper):
|
||||
|
||||
@@ -422,6 +422,19 @@ def test_decorator(Script):
|
||||
assert d.docstring(raw=True) == 'Nice docstring'
|
||||
|
||||
|
||||
def test_partial(Script):
|
||||
code = dedent('''
|
||||
def foo():
|
||||
'x y z'
|
||||
from functools import partial
|
||||
x = partial(foo)
|
||||
x''')
|
||||
|
||||
p1, p2 = Script(code).infer()
|
||||
assert p1.docstring(raw=True) == 'x y z'
|
||||
assert p2.docstring(raw=True) == 'x y z'
|
||||
|
||||
|
||||
def test_basic_str_init_signature(Script, disable_typeshed):
|
||||
# See GH #1414 and GH #1426
|
||||
code = dedent('''
|
||||
|
||||
Reference in New Issue
Block a user