1
0
forked from VimPlug/jedi

basic __getitem__ implementation

This commit is contained in:
David Halter
2012-08-06 15:49:08 +02:00
parent 55b6d5b598
commit 8780199a33
3 changed files with 111 additions and 26 deletions

View File

@@ -139,16 +139,14 @@ class Instance(Executable):
# need to execute the __init__ function, because the dynamic param # need to execute the __init__ function, because the dynamic param
# searching needs it. # searching needs it.
try: try:
init_func = self.get_subscope_by_name('__init__') self.execute_subscope_by_name('__init__', self.var_args)
except KeyError: except KeyError:
pass pass
else:
self.get_init_execution(init_func).get_return_types()
@memoize_default() @memoize_default()
def get_init_execution(self, func): def get_init_execution(self, func):
instance_el = InstanceElement(self, Function(func)) func = InstanceElement(self, func)
return Execution(instance_el, self.var_args) return Execution(func, self.var_args)
def get_func_self_name(self, func): def get_func_self_name(self, func):
""" """
@@ -193,19 +191,22 @@ class Instance(Executable):
def get_subscope_by_name(self, name): def get_subscope_by_name(self, name):
for sub in reversed(self.base.subscopes): for sub in reversed(self.base.subscopes):
if sub.name.get_code() == name: if sub.name.get_code() == name:
return sub return InstanceElement(self, sub)
raise KeyError("Couldn't find subscope.") raise KeyError("Couldn't find subscope.")
def execute_subscope_by_name(self, name, args):
method = self.get_subscope_by_name(name)
if args.parent_stmt is None:
args.parent_stmt = method
return Execution(method, args).get_return_types()
def get_descriptor_return(self, obj): def get_descriptor_return(self, obj):
""" Throws a KeyError if there's no method. """ """ Throws a KeyError if there's no method. """
method = self.get_subscope_by_name('__get__')
# Arguments in __get__ descriptors are obj, class. # Arguments in __get__ descriptors are obj, class.
# `method` is the new parent of the array, don't know if that's good. # `method` is the new parent of the array, don't know if that's good.
v = [[obj], [obj.base]] if isinstance(obj, Instance) else [[], [obj]] v = [[obj], [obj.base]] if isinstance(obj, Instance) else [[], [obj]]
args = parsing.Array('tuple', method, values=v) args = parsing.Array(parsing.Array.TUPLE, None, values=v)
method = InstanceElement(self, method) return self.execute_subscope_by_name('__get__', args)
res = Execution(method, args).get_return_types()
return res
def get_defined_names(self): def get_defined_names(self):
""" """
@@ -219,10 +220,16 @@ class Instance(Executable):
names.append(InstanceElement(self, var)) names.append(InstanceElement(self, var))
return names return names
def get_index_types(self, index=None):
v = [[index]] if index is not None else []
args = parsing.Array(parsing.Array.NOARRAY, None, values=v)
try:
return self.execute_subscope_by_name('__getitem__', args)
except KeyError:
debug.warning('No __getitem__, cannot access the array.')
return []
def __getattr__(self, name): def __getattr__(self, name):
if name == 'get_index_types':
# TODO Call __getitem__ in such cases?
return lambda: []
if name not in ['start_pos', 'end_pos', 'name', 'get_imports']: if name not in ['start_pos', 'end_pos', 'name', 'get_imports']:
raise AttributeError("Instance %s: Don't touch this (%s)!" raise AttributeError("Instance %s: Don't touch this (%s)!"
% (self, name)) % (self, name))
@@ -431,17 +438,14 @@ class Execution(Executable):
try: try:
self.base.returns self.base.returns
except (AttributeError, DecoratorNotFound): except (AttributeError, DecoratorNotFound):
try: if hasattr(self.base, 'execute_subscope_by_name'):
# If it is an instance, we try to execute the __call__(). try:
call_method = self.base.get_subscope_by_name('__call__') stmts = self.base.execute_subscope_by_name('__call__',
except (AttributeError, KeyError): self.var_args)
debug.warning("no execution possible", self.base) except KeyError:
debug.warning("no __call__ func available", self.base)
else: else:
debug.dbg('__call__', call_method, self.base) debug.warning("no execution possible", self.base)
base = self.base
call_method = InstanceElement(base, call_method)
exe = Execution(call_method, self.var_args)
stmts = exe.get_return_types()
else: else:
stmts = self._get_function_returns(evaluate_generator) stmts = self._get_function_returns(evaluate_generator)

View File

@@ -1,4 +1,9 @@
"""
Pure Python implementation of some builtins.
This code is not going to be executed anywhere.
These implementations are not always correct, but should work as good as
possible for the auto completion.
"""
def next(iterator, default=None): def next(iterator, default=None):
if hasattr("next"): if hasattr("next"):
return iterator.next() return iterator.next()
@@ -6,8 +11,9 @@ def next(iterator, default=None):
return iterator.__next__() return iterator.__next__()
return default return default
class property(): class property():
def __init__(self, fget, fset = None, fdel = None, doc = None): def __init__(self, fget, fset=None, fdel=None, doc=None):
self.fget = fget self.fget = fget
self.fset = fset self.fset = fset
self.fdel = fdel self.fdel = fdel
@@ -34,6 +40,7 @@ class property():
self.fdel = func self.fdel = func
return self return self
class staticmethod(): class staticmethod():
def __init__(self, func): def __init__(self, func):
self.func = func self.func = func
@@ -41,6 +48,7 @@ class staticmethod():
def __get__(self, obj, cls): def __get__(self, obj, cls):
return self.func return self.func
class classmethod(): class classmethod():
def __init__(self, func): def __init__(self, func):
self._func = func self._func = func
@@ -49,3 +57,45 @@ class classmethod():
def _method(*args, **kwargs): def _method(*args, **kwargs):
return self._func(cls, *args, **kwargs) return self._func(cls, *args, **kwargs)
return _method return _method
class list():
def __init__(self, iterable=[]):
self.iterable = []
for i in iterable:
self.iterable += [i]
def __iter__(self):
for i in self.iterable:
yield i
def __getitem__(self, y):
return self.iterable[y]
def pop(self):
return self.iterable[-1]
class set():
def __init__(self, iterable=[]):
self.iterable = iterable
def __iter__(self):
for i in self.iterable:
yield i
def add(self, elem):
self.iterable += [elem]
def pop(self):
return self.iterable.pop()
def copy(self):
return self
def iter(collection, sentinel=None):
if sentinel:
yield collection()
else:
yield next(collection)

View File

@@ -138,3 +138,34 @@ dic2[r'asdf']
dic2[r'asdf'] dic2[r'asdf']
#? int() str() #? int() str()
dic2['just_something'] dic2['just_something']
# -----------------
# __getitem__
# -----------------
class GetItem():
def __getitem__(self, index):
return 1.0
#? float()
GetItem()[0]
class GetItem():
def __init__(self, el):
self.el = el
def __getitem__(self, index):
return self.el
#? str()
GetItem("")[1]
# -----------------
# conversions
# -----------------
#? str()
list([1,""])[1]
#? str()
list(set([1,""]))[1]