mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-08 14:54:47 +08:00
Implement properties properly
This commit is contained in:
@@ -16,11 +16,11 @@ from jedi._compatibility import force_unicode, Parameter
|
|||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi.inference.utils import safe_property
|
from jedi.inference.utils import safe_property
|
||||||
from jedi.inference.helpers import get_str_or_none
|
from jedi.inference.helpers import get_str_or_none
|
||||||
from jedi.inference.arguments import ValuesArguments, \
|
from jedi.inference.arguments import \
|
||||||
repack_with_argument_clinic, AbstractArguments, TreeArgumentsWrapper
|
repack_with_argument_clinic, AbstractArguments, TreeArgumentsWrapper
|
||||||
from jedi.inference import analysis
|
from jedi.inference import analysis
|
||||||
from jedi.inference import compiled
|
from jedi.inference import compiled
|
||||||
from jedi.inference.value.instance import BoundMethod, \
|
from jedi.inference.value.instance import \
|
||||||
AnonymousMethodExecutionContext, MethodExecutionContext
|
AnonymousMethodExecutionContext, MethodExecutionContext
|
||||||
from jedi.inference.base_value import ContextualizedNode, \
|
from jedi.inference.base_value import ContextualizedNode, \
|
||||||
NO_VALUES, ValueSet, ValueWrapper, LazyValueWrapper
|
NO_VALUES, ValueSet, ValueWrapper, LazyValueWrapper
|
||||||
@@ -121,19 +121,7 @@ def execute(callback):
|
|||||||
else:
|
else:
|
||||||
return call()
|
return call()
|
||||||
|
|
||||||
if isinstance(value, BoundMethod):
|
if value.is_bound_method():
|
||||||
if module_name == 'builtins':
|
|
||||||
if value.py__name__() == '__get__':
|
|
||||||
if value.class_context.py__name__() == 'property':
|
|
||||||
return builtins_property(
|
|
||||||
value,
|
|
||||||
arguments=arguments,
|
|
||||||
callback=call,
|
|
||||||
)
|
|
||||||
elif value.py__name__() in ('deleter', 'getter', 'setter'):
|
|
||||||
if value.class_context.py__name__() == 'property':
|
|
||||||
return ValueSet([value.instance])
|
|
||||||
|
|
||||||
return call()
|
return call()
|
||||||
|
|
||||||
# for now we just support builtin functions.
|
# for now we just support builtin functions.
|
||||||
@@ -191,17 +179,6 @@ def argument_clinic(string, want_obj=False, want_context=False,
|
|||||||
return f
|
return f
|
||||||
|
|
||||||
|
|
||||||
@argument_clinic('obj, type, /', want_obj=True, want_arguments=True)
|
|
||||||
def builtins_property(objects, types, obj, arguments):
|
|
||||||
property_args = obj.instance.arguments.unpack()
|
|
||||||
key, lazy_value = next(property_args, (None, None))
|
|
||||||
if key is not None or lazy_value is None:
|
|
||||||
debug.warning('property expected a first param, not %s', arguments)
|
|
||||||
return NO_VALUES
|
|
||||||
|
|
||||||
return lazy_value.infer().py__call__(arguments=ValuesArguments([objects]))
|
|
||||||
|
|
||||||
|
|
||||||
@argument_clinic('iterator[, default], /', want_inference_state=True)
|
@argument_clinic('iterator[, default], /', want_inference_state=True)
|
||||||
def builtins_next(iterators, defaults, inference_state):
|
def builtins_next(iterators, defaults, inference_state):
|
||||||
if inference_state.environment.version_info.major == 2:
|
if inference_state.environment.version_info.major == 2:
|
||||||
@@ -421,6 +398,35 @@ def builtins_classmethod(functions, obj, arguments):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PropertyObject(AttributeOverwrite, ValueWrapper):
|
||||||
|
def __init__(self, property_obj, function):
|
||||||
|
super(PropertyObject, self).__init__(property_obj)
|
||||||
|
self._function = function
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
return self._wrapped_value
|
||||||
|
|
||||||
|
def py__get__(self, instance, class_value):
|
||||||
|
if instance is None:
|
||||||
|
return NO_VALUES
|
||||||
|
return self._function.execute_with_values(instance)
|
||||||
|
|
||||||
|
@publish_method('deleter')
|
||||||
|
@publish_method('getter')
|
||||||
|
@publish_method('setter')
|
||||||
|
def _return_self(self):
|
||||||
|
return ValueSet({self})
|
||||||
|
|
||||||
|
|
||||||
|
@argument_clinic('func, /', want_callback=True)
|
||||||
|
def builtins_property(functions, callback):
|
||||||
|
return ValueSet(
|
||||||
|
PropertyObject(property_value, function)
|
||||||
|
for property_value in callback()
|
||||||
|
for function in functions
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def collections_namedtuple(obj, arguments, callback):
|
def collections_namedtuple(obj, arguments, callback):
|
||||||
"""
|
"""
|
||||||
Implementation of the namedtuple function.
|
Implementation of the namedtuple function.
|
||||||
@@ -737,6 +743,7 @@ _implemented = {
|
|||||||
'iter': builtins_iter,
|
'iter': builtins_iter,
|
||||||
'staticmethod': builtins_staticmethod,
|
'staticmethod': builtins_staticmethod,
|
||||||
'classmethod': builtins_classmethod,
|
'classmethod': builtins_classmethod,
|
||||||
|
'property': builtins_property,
|
||||||
},
|
},
|
||||||
'copy': {
|
'copy': {
|
||||||
'copy': _return_first_param,
|
'copy': _return_first_param,
|
||||||
|
|||||||
Reference in New Issue
Block a user