mirror of
https://github.com/davidhalter/jedi.git
synced 2026-01-06 04:03:21 +08:00
add a stdlib module to make it easy to write functions in pure python (instead of evaluating them)
This commit is contained in:
90
jedi/evaluate/stdlib.py
Normal file
90
jedi/evaluate/stdlib.py
Normal file
@@ -0,0 +1,90 @@
|
||||
"""
|
||||
Implementations of standard library functions, because it's not possible to
|
||||
understand them with Jedi.
|
||||
"""
|
||||
|
||||
from jedi.evaluate import builtin
|
||||
from jedi.evaluate import representation as er
|
||||
from jedi.parser import representation as pr
|
||||
from jedi import debug
|
||||
|
||||
|
||||
class NotInStdLib(LookupError):
|
||||
pass
|
||||
|
||||
|
||||
def execute(evaluator, obj, params):
|
||||
if not isinstance(obj, (er.Generator, er.Array)):
|
||||
obj_name = str(obj.name)
|
||||
if obj.parent == builtin.Builtin.scope:
|
||||
# for now we just support builtin functions.
|
||||
try:
|
||||
return _implemented['builtins'][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)):
|
||||
debug.warning('getattr called without instance')
|
||||
continue
|
||||
|
||||
for arr_name in names:
|
||||
if not isinstance(arr_name, er.Instance):
|
||||
debug.warning('getattr called without str')
|
||||
continue
|
||||
if len(arr_name.var_args) != 1:
|
||||
debug.warning('jedi getattr is too simple')
|
||||
key = arr_name.var_args[0]
|
||||
stmts += evaluator.follow_path(iter([key]), [obj], obj)
|
||||
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 [er.Instance(evaluator, su[0])]
|
||||
return []
|
||||
|
||||
|
||||
_implemented = {
|
||||
'builtins': {
|
||||
'getattr': builtins_getattr,
|
||||
'type': builtins_type,
|
||||
'super': builtins_super,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user