1
0
forked from VimPlug/jedi

Add a latest grammar to the evaluator and use it to avoid importing from parso import parse.

This commit is contained in:
Dave Halter
2017-05-24 00:37:36 -04:00
parent b90589b62e
commit cd8932fbfc
10 changed files with 31 additions and 26 deletions

View File

@@ -64,6 +64,8 @@ import copy
import sys import sys
from parso.python import tree from parso.python import tree
from parso import load_python_grammar
from jedi import debug from jedi import debug
from jedi.common import unite from jedi.common import unite
from jedi.evaluate import representation as er from jedi.evaluate import representation as er
@@ -87,6 +89,7 @@ from jedi import parser_utils
class Evaluator(object): class Evaluator(object):
def __init__(self, grammar, sys_path=None): def __init__(self, grammar, sys_path=None):
self.grammar = grammar self.grammar = grammar
self.latest_grammar = load_python_grammar('3.6')
self.memoize_cache = {} # for memoize decorators self.memoize_cache = {} # for memoize decorators
# To memorize modules -> equals `sys.modules`. # To memorize modules -> equals `sys.modules`.
self.modules = {} # like `sys.modules`. self.modules = {} # like `sys.modules`.

View File

@@ -9,10 +9,10 @@ import inspect
import types import types
from itertools import chain from itertools import chain
from jedi._compatibility import is_py3, builtins, unicode, is_py34
from parso.python import parse
from parso.python import tree from parso.python import tree
from jedi._compatibility import is_py3, builtins, unicode, is_py34
modules = {} modules = {}
@@ -47,7 +47,7 @@ class FakeDoesNotExist(Exception):
pass pass
def _load_faked_module(module): def _load_faked_module(grammar, module):
module_name = module.__name__ module_name = module.__name__
if module_name == '__builtin__' and not is_py3: if module_name == '__builtin__' and not is_py3:
module_name = 'builtins' module_name = 'builtins'
@@ -62,7 +62,7 @@ def _load_faked_module(module):
except IOError: except IOError:
modules[module_name] = None modules[module_name] = None
return return
modules[module_name] = m = parse(unicode(source)) modules[module_name] = m = grammar.parse(unicode(source))
if module_name == 'builtins' and not is_py3: if module_name == 'builtins' and not is_py3:
# There are two implementations of `open` for either python 2/3. # There are two implementations of `open` for either python 2/3.
@@ -105,12 +105,12 @@ def get_module(obj):
return builtins return builtins
def _faked(module, obj, name): def _faked(grammar, module, obj, name):
# Crazy underscore actions to try to escape all the internal madness. # Crazy underscore actions to try to escape all the internal madness.
if module is None: if module is None:
module = get_module(obj) module = get_module(obj)
faked_mod = _load_faked_module(module) faked_mod = _load_faked_module(grammar, module)
if faked_mod is None: if faked_mod is None:
return None, None return None, None
@@ -168,8 +168,8 @@ def memoize_faked(obj):
@memoize_faked @memoize_faked
def _get_faked(module, obj, name=None): def _get_faked(grammar, module, obj, name=None):
result, fake_module = _faked(module, obj, name) result, fake_module = _faked(grammar, module, obj, name)
if result is None: if result is None:
# We're not interested in classes. What we want is functions. # We're not interested in classes. What we want is functions.
raise FakeDoesNotExist raise FakeDoesNotExist
@@ -197,7 +197,7 @@ def get_faked(evaluator, module, obj, name=None, parent_context=None):
else: else:
raise FakeDoesNotExist raise FakeDoesNotExist
faked, fake_module = _get_faked(module and module.obj, obj, name) faked, fake_module = _get_faked(evaluator.latest_grammar, module and module.obj, obj, name)
if module is not None: if module is not None:
module.get_used_names = fake_module.get_used_names module.get_used_names = fake_module.get_used_names
return faked return faked

View File

@@ -5,7 +5,6 @@ Used only for REPL Completion.
import inspect import inspect
import os import os
from parso.python import parse
from jedi import settings from jedi import settings
from jedi.evaluate import compiled from jedi.evaluate import compiled
from jedi.cache import underscore_memoization from jedi.cache import underscore_memoization

View File

@@ -22,7 +22,6 @@ from jedi._compatibility import u
from jedi.common import unite from jedi.common import unite
from jedi.evaluate import context from jedi.evaluate import context
from jedi.evaluate.cache import memoize_default from jedi.evaluate.cache import memoize_default
from parso.python import parse
from jedi.common import indent_block from jedi.common import indent_block
from jedi.evaluate.iterable import SequenceLiteralContext, FakeSequence from jedi.evaluate.iterable import SequenceLiteralContext, FakeSequence
@@ -132,7 +131,8 @@ def _evaluate_for_statement_string(module_context, string):
# Take the default grammar here, if we load the Python 2.7 grammar here, it # Take the default grammar here, if we load the Python 2.7 grammar here, it
# will be impossible to use `...` (Ellipsis) as a token. Docstring types # will be impossible to use `...` (Ellipsis) as a token. Docstring types
# don't need to conform with the current grammar. # don't need to conform with the current grammar.
module = parse(code.format(indent_block(string))) grammar = module_context.evaluator.latest_grammar
module = grammar.parse(code.format(indent_block(string)))
try: try:
funcdef = next(module.iter_funcdefs()) funcdef = next(module.iter_funcdefs())
# First pick suite, then simple_stmt and then the node, # First pick suite, then simple_stmt and then the node,

View File

@@ -16,7 +16,6 @@ import os
import pkgutil import pkgutil
import sys import sys
from parso.python import parse
from parso.python import tree from parso.python import tree
from parso.tree import search_ancestor from parso.tree import search_ancestor
from parso.cache import parser_cache from parso.cache import parser_cache
@@ -471,7 +470,7 @@ def _load_module(evaluator, path=None, code=None, sys_path=None, parent_module=N
if path is not None and path.endswith(('.py', '.zip', '.egg')) \ if path is not None and path.endswith(('.py', '.zip', '.egg')) \
and dotted_path not in settings.auto_import_modules: and dotted_path not in settings.auto_import_modules:
module_node = parse( module_node = evaluator.grammar.parse(
code=code, path=path, cache=True, diff_cache=True, code=code, path=path, cache=True, diff_cache=True,
cache_path=settings.cache_directory) cache_path=settings.cache_directory)

View File

@@ -20,10 +20,12 @@ x support for type hint comments for functions, `# type: (int, str) -> int`.
""" """
import itertools import itertools
import os import os
import re
from parso import ParserSyntaxError from parso import ParserSyntaxError
from parso.python import parse, tree from parso.python import tree
from jedi.common import unite from jedi.common import unite
from jedi.evaluate.cache import memoize_default from jedi.evaluate.cache import memoize_default
from jedi.evaluate import compiled from jedi.evaluate import compiled
@@ -31,7 +33,6 @@ from jedi.evaluate.context import LazyTreeContext
from jedi import debug from jedi import debug
from jedi import _compatibility from jedi import _compatibility
from jedi import parser_utils from jedi import parser_utils
import re
def _evaluate_for_annotation(context, annotation, index=None): def _evaluate_for_annotation(context, annotation, index=None):
@@ -63,7 +64,7 @@ def _fix_forward_reference(context, node):
if isinstance(evaled_node, compiled.CompiledObject) and \ if isinstance(evaled_node, compiled.CompiledObject) and \
isinstance(evaled_node.obj, str): isinstance(evaled_node.obj, str):
try: try:
new_node = parse( new_node = context.evaluator.grammar.parse(
_compatibility.unicode(evaled_node.obj), _compatibility.unicode(evaled_node.obj),
start_symbol='eval_input', start_symbol='eval_input',
error_recovery=False error_recovery=False
@@ -110,7 +111,7 @@ def infer_return_types(function_context):
_typing_module = None _typing_module = None
def _get_typing_replacement_module(): def _get_typing_replacement_module(grammar):
""" """
The idea is to return our jedi replacement for the PEP-0484 typing module The idea is to return our jedi replacement for the PEP-0484 typing module
as discussed at https://github.com/davidhalter/jedi/issues/663 as discussed at https://github.com/davidhalter/jedi/issues/663
@@ -121,7 +122,7 @@ def _get_typing_replacement_module():
os.path.abspath(os.path.join(__file__, "../jedi_typing.py")) os.path.abspath(os.path.join(__file__, "../jedi_typing.py"))
with open(typing_path) as f: with open(typing_path) as f:
code = _compatibility.unicode(f.read()) code = _compatibility.unicode(f.read())
_typing_module = parse(code) _typing_module = grammar.parse(code)
return _typing_module return _typing_module
@@ -155,7 +156,7 @@ def py__getitem__(context, typ, node):
from jedi.evaluate.representation import ModuleContext from jedi.evaluate.representation import ModuleContext
typing = ModuleContext( typing = ModuleContext(
context.evaluator, context.evaluator,
module_node=_get_typing_replacement_module(), module_node=_get_typing_replacement_module(context.evaluator.latest_grammar),
path=None path=None
) )
factories = typing.py__getattribute__("factory") factories = typing.py__getattribute__("factory")

View File

@@ -117,10 +117,11 @@ from ast import literal_eval
from io import StringIO from io import StringIO
from functools import reduce from functools import reduce
import parso
import jedi import jedi
from jedi import debug from jedi import debug
from jedi._compatibility import unicode, is_py3 from jedi._compatibility import unicode, is_py3
from parso.python import parse
from jedi.api.classes import Definition from jedi.api.classes import Definition
from jedi.api.completion import get_user_scope from jedi.api.completion import get_user_scope
from jedi import parser_utils from jedi import parser_utils
@@ -132,6 +133,9 @@ TEST_ASSIGNMENTS = 2
TEST_USAGES = 3 TEST_USAGES = 3
grammar36 = parso.load_python_grammar('3.6')
class IntegrationTestCase(object): class IntegrationTestCase(object):
def __init__(self, test_type, correct, line_nr, column, start, line, def __init__(self, test_type, correct, line_nr, column, start, line,
path=None, skip=None): path=None, skip=None):
@@ -188,7 +192,7 @@ class IntegrationTestCase(object):
should_be = set() should_be = set()
for match in re.finditer('(?:[^ ]+)', correct): for match in re.finditer('(?:[^ ]+)', correct):
string = match.group(0) string = match.group(0)
parser = parse(string, start_symbol='eval_input', error_recovery=False) parser = grammar36.parse(string, start_symbol='eval_input', error_recovery=False)
parser_utils.move(parser.get_root_node(), self.line_nr) parser_utils.move(parser.get_root_node(), self.line_nr)
element = parser.get_root_node() element = parser.get_root_node()
module_context = script._get_module() module_context = script._get_module()

View File

@@ -8,7 +8,7 @@ from jedi.evaluate.sys_path import (_get_parent_dir_with_file,
_check_module) _check_module)
from jedi.evaluate import Evaluator from jedi.evaluate import Evaluator
from jedi.evaluate.representation import ModuleContext from jedi.evaluate.representation import ModuleContext
from parso.python import parse from parso import parse
from parso import load_python_grammar from parso import load_python_grammar
from ..helpers import cwd_at from ..helpers import cwd_at

View File

@@ -1,6 +1,6 @@
from textwrap import dedent from textwrap import dedent
from parso.python import parse from parso import parse
import jedi import jedi

View File

@@ -11,7 +11,6 @@ import pytest
from jedi import Script from jedi import Script
from jedi import api from jedi import api
from jedi import common
from jedi.evaluate import imports from jedi.evaluate import imports
from parso.python import parse from parso.python import parse
from .helpers import TestCase, cwd_at from .helpers import TestCase, cwd_at