mirror of
https://github.com/davidhalter/jedi.git
synced 2026-01-30 15:35:22 +08:00
Get completely rid of get_names_of_scope.
This commit is contained in:
@@ -13,7 +13,7 @@ check for -> a is a string). There's big potential in these checks.
|
||||
"""
|
||||
from itertools import chain
|
||||
|
||||
from jedi._compatibility import hasattr, unicode, u
|
||||
from jedi._compatibility import unicode, u
|
||||
from jedi.parser import tree as pr
|
||||
from jedi.parser import fast
|
||||
from jedi import debug
|
||||
@@ -420,7 +420,56 @@ def _check_isinstance_type(evaluator, element, search_name):
|
||||
|
||||
def global_names_dict_generator(evaluator, scope, position):
|
||||
"""
|
||||
For global lookups.
|
||||
For global name lookups. Yields tuples of (names_dict, position). If the
|
||||
position is None, the position does not matter anymore in that scope.
|
||||
|
||||
This function is used to include names from outer scopes. For example, when
|
||||
the current scope is function:
|
||||
|
||||
>>> from jedi._compatibility import u
|
||||
>>> from jedi.parser import Parser, load_grammar
|
||||
>>> parser = Parser(load_grammar(), u('''
|
||||
... x = ['a', 'b', 'c']
|
||||
... def func():
|
||||
... y = None
|
||||
... '''))
|
||||
>>> scope = parser.module.subscopes[0]
|
||||
>>> scope
|
||||
<Function: func@3-5>
|
||||
|
||||
`global_names_dict_generator` is a generator. First it yields names from
|
||||
most inner scope.
|
||||
|
||||
>>> from pprint import pprint
|
||||
>>> from jedi.evaluate import Evaluator
|
||||
>>> evaluator = Evaluator(load_grammar())
|
||||
>>> scope = er.wrap(evaluator, scope)
|
||||
>>> pairs = list(global_names_dict_generator(evaluator, scope, (4, 0)))
|
||||
>>> pprint(pairs[0])
|
||||
({'func': [], 'y': [<Name: y@4,4>]}, (4, 0))
|
||||
|
||||
Then it yields the names from one level "lower". In this example, this
|
||||
is the most outer scope. As you can see, the position in the tuple is now
|
||||
None, because typically the whole module is loaded before the function is
|
||||
called.
|
||||
|
||||
>>> pprint(pairs[1])
|
||||
({'func': [<Name: func@3,4>], 'x': [<Name: x@2,0>]}, None)
|
||||
|
||||
After that we have a few underscore names that are part of the module.
|
||||
|
||||
>>> sorted(pairs[2][0].keys())
|
||||
['__doc__', '__file__', '__name__', '__package__']
|
||||
>>> pairs[3] # global names -> there are none in our example.
|
||||
({}, None)
|
||||
>>> pairs[4] # package modules -> Also none.
|
||||
({}, None)
|
||||
|
||||
Finally, it yields names from builtin, if `include_builtin` is
|
||||
true (default).
|
||||
|
||||
>>> pairs[5][0].values() #doctest: +ELLIPSIS
|
||||
[[<CompiledName: ...>], ...]
|
||||
"""
|
||||
in_func = False
|
||||
while scope is not None:
|
||||
@@ -441,93 +490,6 @@ def global_names_dict_generator(evaluator, scope, position):
|
||||
yield names_dict, None
|
||||
|
||||
|
||||
def get_names_of_scope(evaluator, scope, position=None, star_search=True, include_builtin=True):
|
||||
"""
|
||||
Get all completions (names) possible for the current scope. The star search
|
||||
option is only here to provide an optimization. Otherwise the whole thing
|
||||
would probably start a little recursive madness.
|
||||
|
||||
This function is used to include names from outer scopes. For example, when
|
||||
the current scope is function:
|
||||
|
||||
>>> from jedi._compatibility import u
|
||||
>>> from jedi.parser import Parser, load_grammar
|
||||
>>> parser = Parser(load_grammar(), u('''
|
||||
... x = ['a', 'b', 'c']
|
||||
... def func():
|
||||
... y = None
|
||||
... '''))
|
||||
>>> scope = parser.module.subscopes[0]
|
||||
>>> scope
|
||||
<Function: func@3-5>
|
||||
|
||||
`get_names_of_scope` is a generator. First it yields names from most inner
|
||||
scope.
|
||||
|
||||
>>> from jedi.evaluate import Evaluator
|
||||
>>> pairs = list(get_names_of_scope(Evaluator(load_grammar()), scope))
|
||||
>>> pairs[0]
|
||||
(<Function: func@3-5>, [<Name: y@4,4>])
|
||||
|
||||
Then it yield the names from one level outer scope. For this example, this
|
||||
is the most outer scope.
|
||||
|
||||
>>> pairs[1]
|
||||
(<ModuleWrapper: <SubModule: None@1-5>>, [<Name: x@2,0>, <Name: func@3,4>])
|
||||
|
||||
After that we have a few underscore names that have been defined
|
||||
|
||||
>>> pairs[2]
|
||||
(<ModuleWrapper: <SubModule: None@1-5>>, [<LazyName: __file__@0,0>, ...])
|
||||
|
||||
|
||||
Finally, it yields names from builtin, if `include_builtin` is
|
||||
true (default).
|
||||
|
||||
>>> pairs[3] #doctest: +ELLIPSIS
|
||||
(<Builtin: ...builtin...>, [<CompiledName: ...>, ...])
|
||||
|
||||
:rtype: [(pr.Scope, [pr.Name])]
|
||||
:return: Return an generator that yields a pair of scope and names.
|
||||
"""
|
||||
in_func_scope = scope
|
||||
origin_scope = scope
|
||||
while scope:
|
||||
# We don't want submodules to report if we have modules.
|
||||
# As well as some non-scopes, which are parents of list comprehensions.
|
||||
if isinstance(scope, pr.SubModule) and scope.parent or not scope.is_scope():
|
||||
scope = scope.parent
|
||||
continue
|
||||
|
||||
# `pr.Class` is used, because the parent is never `Class`.
|
||||
# Ignore the Flows, because the classes and functions care for that.
|
||||
# InstanceElement of Class is ignored, if it is not the start scope.
|
||||
if not (scope != origin_scope and scope.isinstance(pr.Class)
|
||||
or scope.isinstance(er.Instance)
|
||||
and origin_scope.isinstance(er.Function, er.FunctionExecution)
|
||||
or isinstance(scope, compiled.CompiledObject)
|
||||
and scope.type() == 'class' and in_func_scope != scope):
|
||||
|
||||
if isinstance(scope, (pr.SubModule, fast.Module)):
|
||||
scope = er.ModuleWrapper(evaluator, scope)
|
||||
|
||||
for g in scope.scope_names_generator(position):
|
||||
yield g
|
||||
|
||||
scope = scope.parent
|
||||
# This is used, because subscopes (Flow scopes) would distort the
|
||||
# results.
|
||||
if scope and scope.isinstance(er.Function, pr.Function, er.FunctionExecution):
|
||||
in_func_scope = scope
|
||||
if in_func_scope != scope \
|
||||
and isinstance(in_func_scope, (pr.Function, er.FunctionExecution)):
|
||||
position = None
|
||||
|
||||
# Add builtins to the global scope.
|
||||
if include_builtin:
|
||||
yield compiled.builtin, compiled.builtin.get_defined_names()
|
||||
|
||||
|
||||
def check_tuple_assignments(types, name):
|
||||
"""
|
||||
Checks if tuples are assigned.
|
||||
|
||||
Reference in New Issue
Block a user