/vim/bundle/YouCompleteMe/third_party/ycmd/third_party/jedi/jedi/evaluate/stdlib.py
Python | 131 lines | 109 code | 0 blank | 22 comment | 1 complexity | 8fca85cabe298dc4d18da07571cf44e2 MD5 | raw file
- """
- Implementations of standard library functions, because it's not possible to
- understand them with Jedi.
- """
- from jedi._compatibility import unicode
- from jedi.evaluate import compiled
- from jedi.evaluate import representation as er
- from jedi.evaluate import iterable
- from jedi.evaluate.helpers import FakeArray, FakeStatement
- from jedi.parser import representation as pr
- from jedi import debug
- class NotInStdLib(LookupError):
- pass
- def execute(evaluator, obj, params):
- try:
- obj_name = str(obj.name)
- except AttributeError:
- pass
- else:
- if obj.parent == compiled.builtin:
- module_name = 'builtins'
- elif isinstance(obj.parent, pr.Module):
- module_name = str(obj.parent.name)
- else:
- module_name = ''
- # for now we just support builtin functions.
- try:
- return _implemented[module_name][obj_name](evaluator, obj, params)
- except KeyError:
- pass
- raise NotInStdLib()
- def _follow_param(evaluator, params, index):
- try:
- stmt = params[index]
- except IndexError:
- return []
- else:
- if isinstance(stmt, pr.Statement):
- return evaluator.eval_statement(stmt)
- else:
- return [stmt] # just some arbitrary object
- def builtins_getattr(evaluator, obj, params):
- stmts = []
- # follow the first param
- objects = _follow_param(evaluator, params, 0)
- names = _follow_param(evaluator, params, 1)
- for obj in objects:
- if not isinstance(obj, (er.Instance, er.Class, pr.Module, compiled.CompiledObject)):
- debug.warning('getattr called without instance')
- continue
- for name in names:
- s = unicode, str
- if isinstance(name, compiled.CompiledObject) and isinstance(name.obj, s):
- stmts += evaluator.follow_path(iter([name.obj]), [obj], obj)
- else:
- debug.warning('getattr called without str')
- continue
- return stmts
- def builtins_type(evaluator, obj, params):
- if len(params) == 1:
- # otherwise it would be a metaclass... maybe someday...
- objects = _follow_param(evaluator, params, 0)
- return [o.base for o in objects if isinstance(o, er.Instance)]
- return []
- def builtins_super(evaluator, obj, params):
- # TODO make this able to detect multiple inheritance super
- accept = (pr.Function,)
- func = params.get_parent_until(accept)
- if func.isinstance(*accept):
- cls = func.get_parent_until(accept + (pr.Class,),
- include_current=False)
- if isinstance(cls, pr.Class):
- cls = er.Class(evaluator, cls)
- su = cls.get_super_classes()
- if su:
- return evaluator.execute(su[0])
- return []
- def builtins_reversed(evaluator, obj, params):
- objects = tuple(_follow_param(evaluator, params, 0))
- if objects:
- # unpack the iterator values
- objects = tuple(iterable.get_iterator_types(objects))
- if objects:
- rev = reversed(objects)
- # Repack iterator values and then run it the normal way. This is
- # necessary, because `reversed` is a function and autocompletion
- # would fail in certain cases like `reversed(x).__iter__` if we
- # just returned the result directly.
- stmts = [FakeStatement([r]) for r in rev]
- objects = (iterable.Array(evaluator, FakeArray(stmts, objects[0].parent)),)
- return [er.Instance(evaluator, obj, objects)]
- def _return_first_param(evaluator, obj, params):
- if len(params) == 1:
- return _follow_param(evaluator, params, 0)
- return []
- _implemented = {
- 'builtins': {
- 'getattr': builtins_getattr,
- 'type': builtins_type,
- 'super': builtins_super,
- 'reversed': builtins_reversed,
- },
- 'copy': {
- 'copy': _return_first_param,
- 'deepcopy': _return_first_param,
- },
- 'json': {
- 'load': lambda *args: [],
- 'loads': lambda *args: [],
- },
- }