1
0
forked from VimPlug/jedi

Improve a doctest.

This commit is contained in:
Dave Halter
2016-12-15 01:07:44 +01:00
parent 6fe9971122
commit a4fdc716b0
4 changed files with 53 additions and 51 deletions

View File

@@ -164,6 +164,9 @@ class AbstractUsedNamesFilter(AbstractFilter):
return self._convert_names(name for name_list in self._used_names.values() return self._convert_names(name for name_list in self._used_names.values()
for name in self._filter(name_list)) for name in self._filter(name_list))
def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self.context)
class ParserTreeFilter(AbstractUsedNamesFilter): class ParserTreeFilter(AbstractUsedNamesFilter):
def __init__(self, evaluator, context, parser_scope, until_position=None, origin_scope=None): def __init__(self, evaluator, context, parser_scope, until_position=None, origin_scope=None):
@@ -257,6 +260,52 @@ class DictFilter(AbstractFilter):
def get_global_filters(evaluator, context, until_position, origin_scope): def get_global_filters(evaluator, context, until_position, origin_scope):
""" """
Returns all filters in order of priority for name resolution. Returns all filters in order of priority for name resolution.
For global name lookups. The filters will handle name resolution
themselves, but here we gather possible filters downwards.
>>> from jedi._compatibility import u, no_unicode_pprint
>>> from jedi import Script
>>> script = Script(u('''
... x = ['a', 'b', 'c']
... def func():
... y = None
... '''))
>>> module_node = script._get_module_node()
>>> scope = module_node.subscopes[0]
>>> scope
<Function: func@3-5>
>>> context = script._get_module().create_context(scope)
>>> filters = list(get_global_filters(context.evaluator, context, (4, 0), None))
First we get the names names from the function scope.
>>> no_unicode_pprint(filters[0])
<ParserTreeFilter: <ModuleContext: <Module: None@2-5>>>
>>> sorted(str(n) for n in filters[0].values())
['<TreeNameDefinition: func@(3, 4)>', '<TreeNameDefinition: x@(2, 0)>']
>>> filters[0]._until_position
(4, 0)
Then it yields the names from one level "lower". In this example, this is
the module scope. As a side note, you can see, that the position in the
filter is now None, because typically the whole module is loaded before the
function is called.
>>> filters[1].values() # global names -> there are none in our example.
[]
>>> list(filters[2].values()) # package modules -> Also empty.
[]
>>> sorted(name.string_name for name in filters[3].values()) # Module attributes
['__doc__', '__file__', '__name__', '__package__']
>>> print(filters[1]._until_position)
None
Finally, it yields the builtin filter, if `include_builtin` is
true (default).
>>> filters[4].values() #doctest: +ELLIPSIS
[<CompiledName: ...>, ...]
""" """
from jedi.evaluate.representation import FunctionExecutionContext from jedi.evaluate.representation import FunctionExecutionContext
while context is not None: while context is not None:

View File

@@ -585,57 +585,6 @@ def _check_isinstance_type(context, element, search_name):
def global_names_dict_generator(evaluator, scope, position): def global_names_dict_generator(evaluator, scope, position):
"""
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, no_unicode_pprint
>>> from jedi.parser import ParserWithRecovery, load_grammar
>>> parser = ParserWithRecovery(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 jedi.evaluate import Evaluator
>>> evaluator = Evaluator(load_grammar())
>>> scope = evaluator.wrap(scope)
>>> pairs = list(global_names_dict_generator(evaluator, scope, (4, 0)))
>>> no_unicode_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.
>>> no_unicode_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 in_func = False
while scope is not None: while scope is not None:
if not (scope.type == 'classdef' and in_func): if not (scope.type == 'classdef' and in_func):

View File

@@ -434,6 +434,9 @@ class InstanceVarArgs(object):
def get_calling_nodes(self): def get_calling_nodes(self):
return self._get_var_args().get_calling_nodes() return self._get_var_args().get_calling_nodes()
def __getattr__(self, name):
return getattr(self._var_args, name)
class InstanceFunctionExecution(er.FunctionExecutionContext): class InstanceFunctionExecution(er.FunctionExecutionContext):
def __init__(self, instance, parent_context, function_context, var_args): def __init__(self, instance, parent_context, function_context, var_args):

View File

@@ -186,6 +186,7 @@ class TreeArguments(AbstractArguments):
if param.var_args is None: if param.var_args is None:
break break
arguments = param.var_args arguments = param.var_args
break
return [arguments.argument_node or arguments.trailer] return [arguments.argument_node or arguments.trailer]