Move common to evaluate.utils.

This commit is contained in:
Dave Halter
2017-09-20 20:32:26 +02:00
parent 0c01a3b823
commit a433ee7a7e
17 changed files with 72 additions and 76 deletions

View File

@@ -67,7 +67,7 @@ from parso.python import tree
import parso
from jedi import debug
from jedi.common import unite
from jedi.evaluate.utils import unite
from jedi.evaluate import representation as er
from jedi.evaluate import imports
from jedi.evaluate import recursion

View File

@@ -1,5 +1,5 @@
from jedi._compatibility import Python3Method
from jedi.common import unite
from jedi.evaluate.utils import unite
from parso.python.tree import ExprStmt, CompFor
from jedi.parser_utils import clean_scope_docstring, get_doc_with_call_signature

View File

@@ -21,10 +21,9 @@ from textwrap import dedent
from parso import parse
from jedi._compatibility import u
from jedi.common import unite
from jedi.evaluate.utils import unite, indent_block
from jedi.evaluate import context
from jedi.evaluate.cache import evaluator_method_cache
from jedi.common import indent_block
from jedi.evaluate.iterable import SequenceLiteralContext, FakeSequence

View File

@@ -24,7 +24,7 @@ from jedi.evaluate.cache import evaluator_function_cache
from jedi.evaluate import imports
from jedi.evaluate.param import TreeArguments, create_default_params
from jedi.evaluate.helpers import is_stdlib_path
from jedi.common import to_list, unite
from jedi.evaluate.utils import to_list, unite
from jedi.parser_utils import get_parent_scope

View File

@@ -6,7 +6,7 @@ from abc import abstractmethod
from parso.tree import search_ancestor
from jedi.evaluate import flow_analysis
from jedi.common import to_list, unite
from jedi.evaluate.utils import to_list, unite
from jedi.parser_utils import get_parent_scope

View File

@@ -18,7 +18,7 @@ check for -> a is a string). There's big potential in these checks.
from parso.python import tree
from parso.tree import search_ancestor
from jedi import debug
from jedi.common import unite
from jedi.evaluate.utils import unite
from jedi import settings
from jedi.evaluate import representation as er
from jedi.evaluate.instance import AbstractInstanceContext

View File

@@ -24,7 +24,7 @@ from parso import python_bytes_to_unicode
from jedi._compatibility import find_module, unicode, ImplicitNSInfo
from jedi import debug
from jedi import settings
from jedi.common import unite
from jedi.evaluate.utils import unite
from jedi.evaluate import sys_path
from jedi.evaluate import helpers
from jedi.evaluate import compiled

View File

@@ -1,7 +1,7 @@
from abc import abstractproperty
from jedi._compatibility import is_py3
from jedi.common import unite
from jedi.evaluate.utils import unite
from jedi import debug
from jedi.evaluate import compiled
from jedi.evaluate import filters

View File

@@ -22,9 +22,9 @@ It is important to note that:
"""
from jedi import debug
from jedi import settings
from jedi import common
from jedi.common import unite, safe_property
from jedi.evaluate.utils import unite, safe_property
from jedi._compatibility import unicode, zip_longest, is_py3
from jedi.evaluate.utils import to_list
from jedi.evaluate import compiled
from jedi.evaluate import helpers
from jedi.evaluate import analysis
@@ -262,7 +262,7 @@ class Comprehension(AbstractSequence):
yield iterated
@evaluator_method_cache(default=[])
@common.to_list
@to_list
def _iterate(self):
comp_fors = tuple(get_comp_fors(self._get_comp_for()))
for result in self._nested(comp_fors):

View File

@@ -2,7 +2,7 @@ from collections import defaultdict
from jedi._compatibility import zip_longest
from jedi import debug
from jedi import common
from jedi.evaluate.utils import PushBackIterator
from parso.python import tree
from jedi.evaluate import iterable
from jedi.evaluate import analysis
@@ -258,7 +258,7 @@ def get_params(execution_context, var_args):
for param in funcdef.get_params():
param_dict[param.name.value] = param
unpacked_va = list(var_args.unpack(funcdef))
var_arg_iterator = common.PushBackIterator(iter(unpacked_va))
var_arg_iterator = PushBackIterator(iter(unpacked_va))
non_matching_keys = defaultdict(lambda: [])
keys_used = {}

View File

@@ -26,7 +26,7 @@ import re
from parso import ParserSyntaxError
from parso.python import tree
from jedi.common import unite
from jedi.evaluate.utils import unite
from jedi.evaluate.cache import evaluator_method_cache
from jedi.evaluate import compiled
from jedi.evaluate.context import LazyTreeContext

View File

@@ -12,7 +12,7 @@ compiled module that returns the types for C-builtins.
import collections
import re
from jedi.common import unite
from jedi.evaluate.utils import unite
from jedi.evaluate import compiled
from jedi.evaluate import representation as er
from jedi.evaluate.instance import InstanceFunctionExecution, \

View File

@@ -10,13 +10,13 @@ from jedi.evaluate.compiled import CompiledObject
from jedi.evaluate.context import ContextualizedNode
from jedi import settings
from jedi import debug
from jedi import common
from jedi.evaluate.utils import ignored
def get_venv_path(venv):
"""Get sys.path for specified virtual environment."""
sys_path = _get_venv_path_dirs(venv)
with common.ignored(ValueError):
with ignored(ValueError):
sys_path.remove('')
sys_path = _get_sys_path_with_egglinks(sys_path)
# As of now, get_venv_path_dirs does not scan built-in pythonpath and
@@ -194,7 +194,7 @@ def sys_path_with_modifications(evaluator, module_context):
curdir = os.path.abspath(os.curdir)
#TODO why do we need a chdir?
with common.ignored(OSError):
with ignored(OSError):
os.chdir(os.path.dirname(path))
buildout_script_paths = set()
@@ -246,7 +246,7 @@ def _detect_django_path(module_path):
result = []
for parent in traverse_parents(module_path):
with common.ignored(IOError):
with ignored(IOError):
with open(parent + os.path.sep + 'manage.py'):
debug.dbg('Found django path: %s', module_path)
result.append(parent)

110
jedi/evaluate/utils.py Normal file
View File

@@ -0,0 +1,110 @@
""" A universal module with functions / classes without dependencies. """
import sys
import contextlib
import functools
from jedi._compatibility import reraise
def to_list(func):
def wrapper(*args, **kwargs):
return list(func(*args, **kwargs))
return wrapper
def unite(iterable):
"""Turns a two dimensional array into a one dimensional."""
return set(typ for types in iterable for typ in types)
class UncaughtAttributeError(Exception):
"""
Important, because `__getattr__` and `hasattr` catch AttributeErrors
implicitly. This is really evil (mainly because of `__getattr__`).
`hasattr` in Python 2 is even more evil, because it catches ALL exceptions.
Therefore this class originally had to be derived from `BaseException`
instead of `Exception`. But because I removed relevant `hasattr` from
the code base, we can now switch back to `Exception`.
:param base: return values of sys.exc_info().
"""
def safe_property(func):
return property(reraise_uncaught(func))
def reraise_uncaught(func):
"""
Re-throw uncaught `AttributeError`.
Usage: Put ``@rethrow_uncaught`` in front of the function
which does **not** suppose to raise `AttributeError`.
AttributeError is easily get caught by `hasattr` and another
``except AttributeError`` clause. This becomes problem when you use
a lot of "dynamic" attributes (e.g., using ``@property``) because you
can't distinguish if the property does not exist for real or some code
inside of the "dynamic" attribute through that error. In a well
written code, such error should not exist but getting there is very
difficult. This decorator is to help us getting there by changing
`AttributeError` to `UncaughtAttributeError` to avoid unexpected catch.
This helps us noticing bugs earlier and facilitates debugging.
.. note:: Treating StopIteration here is easy.
Add that feature when needed.
"""
@functools.wraps(func)
def wrapper(*args, **kwds):
try:
return func(*args, **kwds)
except AttributeError:
exc_info = sys.exc_info()
reraise(UncaughtAttributeError(exc_info[1]), exc_info[2])
return wrapper
class PushBackIterator(object):
def __init__(self, iterator):
self.pushes = []
self.iterator = iterator
self.current = None
def push_back(self, value):
self.pushes.append(value)
def __iter__(self):
return self
def next(self):
""" Python 2 Compatibility """
return self.__next__()
def __next__(self):
if self.pushes:
self.current = self.pushes.pop()
else:
self.current = next(self.iterator)
return self.current
@contextlib.contextmanager
def ignored(*exceptions):
"""
Context manager that ignores all of the specified exceptions. This will
be in the standard library starting with Python 3.4.
"""
try:
yield
except exceptions:
pass
def indent_block(text, indention=' '):
"""This function indents a text block with a default of four spaces."""
temp = ''
while text and text[-1] == '\n':
temp += text[-1]
text = text[:-1]
lines = text.split('\n')
return '\n'.join(map(lambda s: indention + s, lines)) + temp