Merge with master

The deprecation of Python2.6 and the insertion of environments made it quite difficult to merge.
This commit is contained in:
Dave Halter
2018-01-20 18:58:43 +01:00
48 changed files with 205 additions and 210 deletions

1
.gitignore vendored
View File

@@ -5,6 +5,7 @@
.tox
.coveralls.yml
.coverage
.idea
/build/
/docs/_build/
/dist/

View File

@@ -3,6 +3,12 @@
Changelog
---------
0.12.0 (2018-01-01)
+++++++++++++++++++
- Remove Python 2.6
- VirtualEnvs
0.11.1 (2017-12-14)
+++++++++++++++++++

View File

@@ -2,16 +2,23 @@
Jedi - an awesome autocompletion/static analysis library for Python
###################################################################
.. image:: https://secure.travis-ci.org/davidhalter/jedi.png?branch=master
:target: http://travis-ci.org/davidhalter/jedi
:alt: Travis-CI build status
.. image:: https://img.shields.io/pypi/v/jedi.svg?style=flat
:target: https://pypi.python.org/pypi/jedi
:alt: PyPI version
.. image:: https://coveralls.io/repos/davidhalter/jedi/badge.png?branch=master
.. image:: https://img.shields.io/pypi/pyversions/jedi.svg
:target: https://pypi.python.org/pypi/jedi
:alt: Supported Python versions
.. image:: https://travis-ci.org/davidhalter/jedi.svg?branch=master
:target: https://travis-ci.org/davidhalter/jedi
:alt: Travis CI build status
.. image:: https://coveralls.io/repos/davidhalter/jedi/badge.svg?branch=master
:target: https://coveralls.io/r/davidhalter/jedi
:alt: Coverage Status
:alt: Coverage status
*If you have specific questions, please add an issue or ask on* `stackoverflow
*If you have specific questions, please add an issue or ask on* `Stack Overflow
<https://stackoverflow.com/questions/tagged/python-jedi>`_ *with the label* ``python-jedi``.
@@ -25,7 +32,7 @@ related names and to list all names in a Python file and infer them. Jedi
understands docstrings and you can use Jedi autocompletion in your REPL as
well.
Jedi uses a very simple API to connect with IDE's. There's a reference
Jedi uses a very simple API to connect with IDEs. There's a reference
implementation as a `VIM-Plugin <https://github.com/davidhalter/jedi-vim>`_,
which uses Jedi's autocompletion. We encourage you to use Jedi in your IDEs.
It's really easy.
@@ -45,7 +52,7 @@ Jedi can currently be used with the following editors/projects:
- Gedit (gedi_)
- wdb_ - Web Debugger
- `Eric IDE`_ (Available as a plugin)
- `Ipython 6.0.0+ <https://ipython.readthedocs.io/en/stable/whatsnew/version6.html>`_
- `IPython 6.0.0+ <https://ipython.readthedocs.io/en/stable/whatsnew/version6.html>`_
and many more!
@@ -96,7 +103,7 @@ understands, see: `Features
<https://jedi.readthedocs.org/en/latest/docs/features.html>`_. A list of
caveats can be found on the same page.
You can run Jedi on cPython 2.6, 2.7, 3.3, 3.4 or 3.5 but it should also
You can run Jedi on CPython 2.7 or 3.3+ but it should also
understand/parse code older than those versions.
Tips on how to use Jedi efficiently can be found `here
@@ -123,7 +130,7 @@ The returned objects are very powerful and really all you might need.
Autocompletion in your REPL (IPython, etc.)
-------------------------------------------
Starting with Ipython `6.0.0` Jedi is a dependency of IPython. Autocompletion
Starting with IPython `6.0.0` Jedi is a dependency of IPython. Autocompletion
in IPython is therefore possible without additional configuration.
It's possible to have Jedi autocompletion in REPL modes - `example video <https://vimeo.com/122332037>`_.
@@ -178,7 +185,7 @@ Tests are also run automatically on `Travis CI
<https://travis-ci.org/davidhalter/jedi/>`_.
For more detailed information visit the `testing documentation
<https://jedi.readthedocs.org/en/latest/docs/testing.html>`_
<https://jedi.readthedocs.org/en/latest/docs/testing.html>`_.
Acknowledgements

View File

@@ -19,7 +19,6 @@
{% endblock %}
{%- block footer %}
<div class="footer">
&copy; Copyright {{ copyright }}.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>.
</div>
{% if pagename == 'index' %}

View File

@@ -45,7 +45,7 @@ master_doc = 'index'
# General information about the project.
project = u'Jedi'
copyright = u'2012 - {today.year}, Jedi contributors'.format(today=datetime.date.today())
copyright = u'jedi contributors'
import jedi
from jedi.utils import version_info

View File

@@ -20,7 +20,7 @@ make it work.
General Features
----------------
- python 2.6+ and 3.3+ support
- Python 2.7 and 3.3+ support
- ignores syntax errors and wrong indentation
- can deal with complex module / function / class structures
- virtualenv support
@@ -64,7 +64,7 @@ Not yet implemented:
- manipulations of instances outside the instance variables without using
methods
- implicit namespace packages (Python 3.3+, `PEP 420 <https://www.python.org/dev/peps/pep-0420/>`_)
- implicit namespace packages (Python 3.4+, `PEP 420 <https://www.python.org/dev/peps/pep-0420/>`_)
Will probably never be implemented:
@@ -88,7 +88,7 @@ etc.
**Security**
Security is an important issue for |jedi|. Therefore no Python code is
executed. As long as you write pure python, everything is evaluated
executed. As long as you write pure Python, everything is evaluated
statically. But: If you use builtin modules (``c_builtin``) there is no other
option than to execute those modules. However: Execute isn't that critical (as
e.g. in pythoncomplete, which used to execute *every* import!), because it
@@ -117,7 +117,7 @@ one of the following docstring/annotation syntax styles:
https://www.python.org/dev/peps/pep-0484/
function annotations (python 3 only; python 2 function annotations with
function annotations (Python 3 only; Python 2 function annotations with
comments in planned but not yet implemented)
::
@@ -129,7 +129,7 @@ comments in planned but not yet implemented)
node.| # complete here
assignment, for-loop and with-statement type hints (all python versions).
assignment, for-loop and with-statement type hints (all Python versions).
Note that the type hints must be on the same line as the statement
::
@@ -142,7 +142,7 @@ Note that the type hints must be on the same line as the statement
print(f + 3)
Most of the features in PEP-0484 are supported including the typing module
(for python < 3.5 you have to do ``pip install typing`` to use these),
(for Python < 3.5 you have to do ``pip install typing`` to use these),
and forward references.
Things that are missing (and this is not an exhaustive list; some of these

View File

@@ -1,5 +1,5 @@
"""
To ensure compatibility from Python ``2.6`` - ``3.3``, a module has been
To ensure compatibility from Python ``2.7`` - ``3.x``, a module has been
created. Clearly there is huge need to use conforming syntax.
"""
import sys
@@ -13,12 +13,10 @@ try:
except ImportError:
pass
# Cannot use sys.version.major and minor names, because in Python 2.6 it's not
# a namedtuple.
is_py3 = sys.version_info[0] >= 3
is_py33 = is_py3 and sys.version_info[1] >= 3
is_py34 = is_py3 and sys.version_info[1] >= 4
is_py26 = not is_py3 and sys.version_info[1] < 7
is_py35 = is_py3 and sys.version_info[1] >= 5
py_version = int(str(sys.version_info[0]) + str(sys.version_info[1]))
@@ -74,7 +72,7 @@ def find_module_py33(string, path=None, loader=None, full_name=None):
raise ImportError("Originally " + repr(e))
if loader is None:
raise ImportError("Couldn't find a loader for {0}".format(string))
raise ImportError("Couldn't find a loader for {}".format(string))
try:
is_package = loader.is_package(string)
@@ -127,14 +125,7 @@ def find_module_pre_py33(string, path=None, full_name=None):
if loader:
is_package = loader.is_package(string)
is_archive = hasattr(loader, 'archive')
try:
module_path = loader.get_filename(string)
except AttributeError:
# fallback for py26
try:
module_path = loader._get_filename(string)
except AttributeError:
continue
if is_package:
module_path = os.path.dirname(module_path)
if is_archive:
@@ -142,10 +133,10 @@ def find_module_pre_py33(string, path=None, full_name=None):
file = None
if not is_package or is_archive:
file = DummyFile(loader, string)
return (file, module_path, is_package)
return file, module_path, is_package
except ImportError:
pass
raise ImportError("No module named {0}".format(string))
raise ImportError("No module named {}".format(string))
find_module = find_module_py33 if is_py33 else find_module_pre_py33
@@ -260,11 +251,6 @@ import ast
def literal_eval(string):
# py3.0, py3.1 and py32 don't support unicode literals. Support those, I
# don't want to write two versions of the tokenizer.
if is_py3 and sys.version_info.minor < 3:
if re.match('[uU][\'"]', string):
string = string[1:]
return ast.literal_eval(string)

View File

@@ -12,8 +12,8 @@ arguments.
import os
import sys
import parso
from parso.python import tree
from parso import python_bytes_to_unicode, split_lines
from jedi._compatibility import force_unicode, is_py3
from jedi.parser_utils import get_executable_nodes
@@ -94,9 +94,29 @@ class Script(object):
with open(path, 'rb') as f:
source = f.read()
# TODO do we really want that?
self._source = python_bytes_to_unicode(source, encoding, errors='replace')
self._code_lines = split_lines(self._source)
# Load the Python grammar of the current interpreter.
self._grammar = parso.load_grammar()
if sys_path is not None and not is_py3:
sys_path = list(map(force_unicode, sys_path))
# Load the Python grammar of the current interpreter.
project = get_default_project()
# TODO deprecate and remove sys_path from the Script API.
if sys_path is not None:
project._sys_path = sys_path
self._evaluator = Evaluator(project, environment=environment, script_path=path)
self._project = project
debug.speed('init')
self._module_node, source = self._evaluator.parse_and_get_code(
code=source,
path=self.path,
cache=False, # No disk cache, because the current script often changes.
diff_cache=True,
cache_path=settings.cache_directory
)
debug.speed('parsed')
self._code_lines = parso.split_lines(source)
line = max(len(self._code_lines), 1) if line is None else line
if not (0 < line <= len(self._code_lines)):
raise ValueError('`line` parameter is not in a valid range.')
@@ -111,35 +131,8 @@ class Script(object):
cache.clear_time_caches()
debug.reset_time()
if sys_path is not None and not is_py3:
sys_path = list(map(force_unicode, sys_path))
# Load the Python grammar of the current interpreter.
project = get_default_project()
# TODO deprecate and remove sys_path from the Script API.
if sys_path is not None:
project._sys_path = sys_path
self._evaluator = Evaluator(project, environment=environment, script_path=path)
self._project = project
debug.speed('init')
@cache.memoize_method
def _get_module_node(self):
return self._evaluator.grammar.parse(
code=self._source,
path=self.path,
cache=False, # No disk cache, because the current script often changes.
diff_cache=True,
cache_path=settings.cache_directory
)
@cache.memoize_method
def _get_module(self):
module = ModuleContext(
self._evaluator,
self._get_module_node(),
self.path
)
module = ModuleContext(self._evaluator, self._module_node, self.path)
if self.path is not None:
name = dotted_path_in_sys_path(self._evaluator.get_sys_path(), self.path)
if name is not None:
@@ -178,10 +171,9 @@ class Script(object):
:rtype: list of :class:`classes.Definition`
"""
module_node = self._get_module_node()
leaf = module_node.get_name_of_position(self._pos)
leaf = self._module_node.get_name_of_position(self._pos)
if leaf is None:
leaf = module_node.get_leaf_for_position(self._pos)
leaf = self._module_node.get_leaf_for_position(self._pos)
if leaf is None:
return []
@@ -212,7 +204,7 @@ class Script(object):
else:
yield name
tree_name = self._get_module_node().get_name_of_position(self._pos)
tree_name = self._module_node.get_name_of_position(self._pos)
if tree_name is None:
return []
context = self._evaluator.create_context(self._get_module(), tree_name)
@@ -243,7 +235,7 @@ class Script(object):
:rtype: list of :class:`classes.Definition`
"""
tree_name = self._get_module_node().get_name_of_position(self._pos)
tree_name = self._module_node.get_name_of_position(self._pos)
if tree_name is None:
# Must be syntax
return []
@@ -270,7 +262,7 @@ class Script(object):
:rtype: list of :class:`classes.CallSignature`
"""
call_signature_details = \
helpers.get_call_signature_details(self._get_module_node(), self._pos)
helpers.get_call_signature_details(self._module_node, self._pos)
if call_signature_details is None:
return []
@@ -295,10 +287,9 @@ class Script(object):
def _analysis(self):
self._evaluator.is_analysis = True
module_node = self._get_module_node()
self._evaluator.analysis_modules = [module_node]
self._evaluator.analysis_modules = [self._module_node]
try:
for node in get_executable_nodes(module_node):
for node in get_executable_nodes(self._module_node):
context = self._get_module().create_context(node)
if node.type in ('funcdef', 'classdef'):
# Resolve the decorators.
@@ -374,10 +365,9 @@ class Interpreter(Script):
self.namespaces = namespaces
def _get_module(self):
parser_module = super(Interpreter, self)._get_module_node()
return interpreter.MixedModuleContext(
self._evaluator,
parser_module,
self._module_node,
self.namespaces,
path=self.path
)
@@ -413,7 +403,7 @@ def names(source=None, path=None, encoding='utf-8', all_scopes=False,
module_context.create_context(name if name.parent.type == 'file_input' else name.parent),
name
)
) for name in get_module_names(script._get_module_node(), all_scopes)
) for name in get_module_names(script._module_node, all_scopes)
]
return sorted(filter(def_ref_filter, defs), key=lambda x: (x.line, x.column))

View File

@@ -555,7 +555,7 @@ class Definition(BaseDefinition):
.. todo:: Add full path. This function is should return a
`module.class.function` path.
"""
position = '' if self.in_builtin_module else '@%s' % (self.line)
position = '' if self.in_builtin_module else '@%s' % self.line
return "%s:%s%s" % (self.module_name, self.description, position)
@memoize_method

View File

@@ -64,6 +64,7 @@ that are not used are just being ignored.
from parso.python import tree
import parso
from parso import python_bytes_to_unicode
from jedi import debug
from jedi import parser_utils
@@ -106,6 +107,7 @@ class Evaluator(object):
self.access_cache = {}
self.reset_recursion_limitations()
self.allow_different_encoding = True
@property
@evaluator_function_cache()
@@ -366,3 +368,15 @@ class Evaluator(object):
node = node.parent
scope_node = parent_scope(node)
return from_scope_node(scope_node, is_nested=True, node_is_object=node_is_object)
def parse_and_get_code(self, code, path, **kwargs):
if self.allow_different_encoding:
if code is None:
with open(path, 'rb') as f:
code = f.read()
code = python_bytes_to_unicode(code, errors='replace')
return self.grammar.parse(code=code, path=path, **kwargs), code
def parse(self, *args, **kwargs):
return self.parse_and_get_code(*args, **kwargs)[0]

View File

@@ -10,6 +10,7 @@ from jedi.evaluate.base_context import NO_CONTEXTS
from jedi.evaluate.context import iterable
from jedi.evaluate.param import get_params, ExecutedParam
def try_iter_content(types, depth=0):
"""Helper method for static analysis."""
if depth > 10:
@@ -29,6 +30,8 @@ def try_iter_content(types, depth=0):
class AbstractArguments(object):
context = None
argument_node = None
trailer = None
def eval_argument_clinic(self, parameters):
"""Uses a list with argument clinic information (see PEP 436)."""
@@ -95,10 +98,9 @@ class TreeArguments(AbstractArguments):
self.trailer = trailer # Can be None, e.g. in a class definition.
def _split(self):
if isinstance(self.argument_node, (tuple, list)):
for el in self.argument_node:
yield 0, el
else:
if self.argument_node is None:
return
if not (self.argument_node.type == 'arglist' or (
# in python 3.5 **arg is an argument, not arglist
(self.argument_node.type == 'argument') and
@@ -197,7 +199,11 @@ class TreeArguments(AbstractArguments):
arguments = param.var_args
break
return [arguments.argument_node or arguments.trailer]
if arguments.argument_node is not None:
return [arguments.argument_node]
if arguments.trailer is not None:
return [arguments.trailer]
return []
class ValuesArguments(AbstractArguments):

View File

@@ -89,7 +89,7 @@ else:
return getattr(klass, '__dict__', _sentinel)
return _shadowed_dict_newstyle(klass)
class _OldStyleClass():
class _OldStyleClass:
pass
_oldstyle_instance_type = type(_OldStyleClass())
@@ -124,7 +124,7 @@ def _safe_hasattr(obj, name):
def _safe_is_data_descriptor(obj):
return (_safe_hasattr(obj, '__set__') or _safe_hasattr(obj, '__delete__'))
return _safe_hasattr(obj, '__set__') or _safe_hasattr(obj, '__delete__')
def getattr_static(obj, attr, default=_sentinel):

View File

@@ -66,7 +66,7 @@ class MixedName(compiled.CompiledName):
contexts = list(self.infer())
if not contexts:
# This means a start_pos that doesn't exist (compiled objects).
return (0, 0)
return 0, 0
return contexts[0].name.start_pos
@start_pos.setter

View File

@@ -132,7 +132,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, TreeContext)):
def py__package__(self):
if self._get_init_directory() is None:
return re.sub(r'\.?[^\.]+$', '', self.py__name__())
return re.sub(r'\.?[^.]+$', '', self.py__name__())
else:
return self.py__name__()

View File

@@ -188,7 +188,7 @@ def _evaluate_for_statement_string(module_context, string):
Need this docstring so that if the below part is not valid Python this
is still a function.
'''
{0}
{}
"""))
if string is None:
return []
@@ -252,7 +252,7 @@ def _execute_array_values(evaluator, array):
for typ in lazy_context.infer()
)
values.append(LazyKnownContexts(objects))
return set([FakeSequence(evaluator, array.array_type, values)])
return {FakeSequence(evaluator, array.array_type, values)}
else:
return array.execute_evaluated()

View File

@@ -158,7 +158,7 @@ def _check_name_for_execution(evaluator, context, compare_node, name, trailer):
def create_func_excs():
arglist = trailer.children[1]
if arglist == ')':
arglist = ()
arglist = None
args = TreeArguments(evaluator, context, arglist, trailer)
if value_node.type == 'funcdef':
yield value.get_function_execution(args)

View File

@@ -26,7 +26,7 @@ class AbstractNameDefinition(object):
def goto(self):
# Typically names are already definitions and therefore a goto on that
# name will always result on itself.
return set([self])
return {self}
def get_root_context(self):
return self.parent_context.get_root_context()
@@ -386,7 +386,7 @@ def get_global_filters(evaluator, context, until_position, origin_scope):
... def func():
... y = None
... '''))
>>> module_node = script._get_module_node()
>>> module_node = script._module_node
>>> scope = next(module_node.iter_funcdefs())
>>> scope
<Function: func@3-5>

View File

@@ -465,7 +465,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')) \
and dotted_path not in settings.auto_import_modules:
module_node = evaluator.grammar.parse(
module_node = evaluator.parse(
code=code, path=path, cache=True, diff_cache=True,
cache_path=settings.cache_directory)

View File

@@ -263,8 +263,6 @@ def collections_namedtuple(evaluator, obj, arguments):
This has to be done by processing the namedtuple class template and
evaluating the result.
.. note:: |jedi| only supports namedtuples on Python >2.6.
"""
collections_context = obj.parent_context
_class_template_set = collections_context.py__getattribute__(u'_class_template')

View File

@@ -120,7 +120,7 @@ def eval_node(context, element):
def eval_trailer(context, base_contexts, trailer):
trailer_op, node = trailer.children[:2]
if node == ')': # `arglist` is optional.
node = ()
node = None
if trailer_op == '[':
trailer_op, node, _ = trailer.children
@@ -149,7 +149,7 @@ def eval_trailer(context, base_contexts, trailer):
name_or_str=node
)
else:
assert trailer_op == '('
assert trailer_op == '(', 'trailer_op is actually %s' % trailer_op
args = arguments.TreeArguments(context.evaluator, context, node, trailer)
return base_contexts.execute(args)
@@ -287,10 +287,10 @@ def eval_or_test(context, or_test):
# handle lazy evaluation of and/or here.
if operator in ('and', 'or'):
left_bools = set(left.py__bool__() for left in types)
if left_bools == set([True]):
if left_bools == {True}:
if operator == 'and':
types = context.eval_node(right)
elif left_bools == set([False]):
elif left_bools == {False}:
if operator != 'and':
types = context.eval_node(right)
# Otherwise continue, because of uncertainty.

View File

@@ -146,7 +146,7 @@ def detect_additional_paths(evaluator, script_path):
def _get_paths_from_buildout_script(evaluator, buildout_script_path):
try:
module_node = evaluator.grammar.parse(
module_node = evaluator.parse(
path=buildout_script_path,
cache=True,
cache_path=settings.cache_directory

View File

@@ -4,11 +4,10 @@ from inspect import cleandoc
from jedi._compatibility import literal_eval, force_unicode
from parso.python import tree
_EXECUTE_NODES = set([
'funcdef', 'classdef', 'import_from', 'import_name', 'test', 'or_test',
'and_test', 'not_test', 'comparison', 'expr', 'xor_expr', 'and_expr',
'shift_expr', 'arith_expr', 'atom_expr', 'term', 'factor', 'power', 'atom'
])
_EXECUTE_NODES = {'funcdef', 'classdef', 'import_from', 'import_name', 'test',
'or_test', 'and_test', 'not_test', 'comparison', 'expr',
'xor_expr', 'and_expr', 'shift_expr', 'arith_expr',
'atom_expr', 'term', 'factor', 'power', 'atom'}
_FLOW_KEYWORDS = (
'try', 'except', 'finally', 'else', 'if', 'elif', 'with', 'for', 'while'

View File

@@ -89,7 +89,7 @@ def setup_readline(namespace_module=__main__):
lines = split_lines(text)
position = (len(lines), len(lines[-1]))
name = get_on_completion_name(
interpreter._get_module_node(),
interpreter._module_node,
lines,
position
)

View File

@@ -32,7 +32,8 @@ setup(name='jedi',
license='MIT',
keywords='python completion refactoring vim',
long_description=readme,
packages=find_packages(exclude=['test']),
packages=find_packages(exclude=['test', 'test.*']),
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*',
install_requires=install_requires,
extras_require={'dev': ['docopt']},
package_data={'jedi': ['evaluate/compiled/fake/*.pym']},
@@ -44,7 +45,6 @@ setup(name='jedi',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',

View File

@@ -403,8 +403,6 @@ def test_func():
x
# python >= 2.7
# Set literals are not valid in 2.6.
#? int()
tuple({1})[0]

View File

@@ -286,8 +286,6 @@ with open('') as f:
#? str()
line
# Nested with statements don't exist in Python 2.6.
# python >= 2.7
with open('') as f1, open('') as f2:
#? ['closed']
f1.closed

View File

@@ -210,6 +210,5 @@ d[2]
next(iter({a for a in range(10)}))
# with a set literal (also doesn't work in 2.6).
#? int()
[a for a in {1, 2, 3}][0]

View File

@@ -211,6 +211,17 @@ class X():
#?
self.x()
def decorator_var_args(function, *args):
return function(*args)
@decorator_var_args
def function_var_args(param):
return param
#? int()
function_var_args(1)
# -----------------
# method decorators
# -----------------

View File

@@ -288,8 +288,6 @@ third()[0]
# -----------------
# set.add
# -----------------
# Set literals are not valid in 2.6.
# python >= 2.7
st = {1.0}
for a in [1,2]:
st.add(a)

View File

@@ -47,10 +47,6 @@ b
class Employee:
pass
# The typing library is not installable for Python 2.6, therefore ignore the
# following tests.
# python >= 2.7
from typing import List
x = [] # type: List[Employee]
#? Employee()

View File

@@ -3,8 +3,6 @@ Test the typing library, with docstrings. This is needed since annotations
are not supported in python 2.7 else then annotating by comment (and this is
still TODO at 2016-01-23)
"""
# There's no Python 2.6 typing module.
# python >= 2.7
import typing
class B:
pass

View File

@@ -116,8 +116,6 @@ tup4.index
# -----------------
# set
# -----------------
# Set literals are not valid in 2.6.
# python >= 2.7
set_t = {1,2}
#? ['clear', 'copy']

View File

@@ -296,8 +296,6 @@ x = 32
[x for x in something]
x = 3
# Not supported syntax in Python 2.6.
# python >= 2.7
#< 1 (0,1), (0,10)
{x:1 for x in something}
#< 10 (0,1), (0,10)

View File

@@ -41,9 +41,9 @@ def parse_test_files_option(opt):
opt = str(opt)
if ':' in opt:
(f_name, rest) = opt.split(':', 1)
return (f_name, list(map(int, rest.split(','))))
return f_name, list(map(int, rest.split(',')))
else:
return (opt, [])
return opt, []
def pytest_generate_tests(metafunc):
@@ -127,7 +127,7 @@ class StaticAnalysisCase(object):
@pytest.fixture()
def cwd_tmpdir(monkeypatch, tmpdir):
with helpers.set_cwd(tmpdir.dirpath):
with helpers.set_cwd(tmpdir.strpath):
yield tmpdir

View File

@@ -206,7 +206,7 @@ class IntegrationTestCase(object):
completions = self.script(environment).completions()
#import cProfile; cProfile.run('script.completions()')
comp_str = set([c.name for c in completions])
comp_str = {c.name for c in completions}
return compare_cb(self, comp_str, set(literal_eval(self.correct)))
def run_goto_definitions(self, compare_cb, environment):

View File

@@ -103,8 +103,8 @@ def test_completion_on_complex_literals(Script):
_check_number(Script, '4.0j.', 'complex')
# No dot no completion - I thought, but 4j is actually a literall after
# which a keyword like or is allowed. Good times, haha!
assert (set([c.name for c in Script('4j').completions()]) ==
set(['if', 'and', 'in', 'is', 'not', 'or']))
assert ({c.name for c in Script('4j').completions()} ==
{'if', 'and', 'in', 'is', 'not', 'or'})
def test_goto_assignments_on_non_name(Script, environment):
@@ -152,7 +152,7 @@ def test_goto_definition_not_multiple(Script):
def test_usage_description(Script):
descs = [u.description for u in Script("foo = ''; foo").usages()]
assert set(descs) == set(["foo = ''", 'foo'])
assert set(descs) == {"foo = ''", 'foo'}
def test_get_line_code(Script):

View File

@@ -34,7 +34,7 @@ def test_follow_import_incomplete(Script):
# incomplete `from * import` part
datetime = check_follow_definition_types(Script, "from datetime import datetim")
assert set(datetime) == set(['class', 'instance']) # py33: builtin and pure py version
assert set(datetime) == {'class', 'instance'} # py33: builtin and pure py version
# os.path check
ospath = check_follow_definition_types(Script, "from os.path import abspat")

View File

@@ -68,25 +68,25 @@ def test_basedefinition_type(Script, environment):
def test_basedefinition_type_import(Script):
def get_types(source, **kwargs):
return set([t.type for t in Script(source, **kwargs).completions()])
return {t.type for t in Script(source, **kwargs).completions()}
# import one level
assert get_types('import t') == set(['module'])
assert get_types('import ') == set(['module'])
assert get_types('import datetime; datetime') == set(['module'])
assert get_types('import t') == {'module'}
assert get_types('import ') == {'module'}
assert get_types('import datetime; datetime') == {'module'}
# from
assert get_types('from datetime import timedelta') == set(['class'])
assert get_types('from datetime import timedelta; timedelta') == set(['class'])
assert get_types('from json import tool') == set(['module'])
assert get_types('from json import tool; tool') == set(['module'])
assert get_types('from datetime import timedelta') == {'class'}
assert get_types('from datetime import timedelta; timedelta') == {'class'}
assert get_types('from json import tool') == {'module'}
assert get_types('from json import tool; tool') == {'module'}
# import two levels
assert get_types('import json.tool; json') == set(['module'])
assert get_types('import json.tool; json.tool') == set(['module'])
assert get_types('import json.tool; json.tool.main') == set(['function'])
assert get_types('import json.tool') == set(['module'])
assert get_types('import json.tool', column=9) == set(['module'])
assert get_types('import json.tool; json') == {'module'}
assert get_types('import json.tool; json.tool') == {'module'}
assert get_types('import json.tool; json.tool.main') == {'function'}
assert get_types('import json.tool') == {'module'}
assert get_types('import json.tool', column=9) == {'module'}
def test_function_call_signature_in_doc(Script):

View File

@@ -16,8 +16,8 @@ else:
exec source in global_map """, 'blub', 'exec'))
class _GlobalNameSpace():
class SideEffectContainer():
class _GlobalNameSpace:
class SideEffectContainer:
pass
@@ -80,7 +80,7 @@ def test_numpy_like_non_zero():
def test_nested_resolve():
class XX():
class XX:
def x():
pass
@@ -168,7 +168,7 @@ def test_list():
def test_slice():
class Foo1():
class Foo1:
bar = []
baz = 'xbarx'
_assert_interpreter_complete('getattr(Foo1, baz[1:-1]).append',
@@ -177,7 +177,7 @@ def test_slice():
def test_getitem_side_effects():
class Foo2():
class Foo2:
def __getitem__(self, index):
# Possible side effects here, should therefore not call this.
if True:
@@ -190,7 +190,7 @@ def test_getitem_side_effects():
def test_property_error_oldstyle():
lst = []
class Foo3():
class Foo3:
@property
def bar(self):
lst.append(1)
@@ -261,7 +261,7 @@ def test_completion_param_annotations():
a, b, c = c.params
assert a._goto_definitions() == []
assert [d.name for d in b._goto_definitions()] == ['str']
assert set([d.name for d in c._goto_definitions()]) == set(['int', 'float'])
assert {d.name for d in c._goto_definitions()} == {'int', 'float'}
def test_more_complex_instances():
@@ -269,7 +269,7 @@ def test_more_complex_instances():
def foo(self, other):
return self
class Base():
class Base:
def wow(self):
return Something()

View File

@@ -63,3 +63,12 @@ def test_complete_at_zero(Script):
s = Script("", 1, 0).completions()
assert len(s) > 0
def test_wrong_encoding(Script, cwd_tmpdir):
x = cwd_tmpdir.join('x.py')
# Use both latin-1 and utf-8 (a really broken file).
x.write_binary(u'foobar = 1\nä'.encode('latin-1') + 'ä'.encode())
c, = Script('import x; x.foo', sys_path=['.']).completions()
assert c.name == 'foobar'

View File

@@ -1,7 +1,7 @@
def test_module_attributes(Script):
def_, = Script('__name__').completions()
assert def_.name == '__name__'
assert def_.line == None
assert def_.column == None
assert def_.line is None
assert def_.column is None
str_, = def_._goto_definitions()
assert str_.name == 'str'

View File

@@ -10,8 +10,6 @@ import pytest
from jedi._compatibility import find_module_py33, find_module
from ..helpers import cwd_at
from jedi._compatibility import is_py26
@pytest.mark.skipif('sys.version_info < (3,3)')
def test_find_module_py33():
@@ -163,9 +161,8 @@ def test_complete_on_empty_import(Script):
# relative import
assert 10 < len(Script("from . import classes", 1, 6, 'whatever.py').completions()) < 30
wanted = set(['ImportError', 'import', 'ImportWarning'])
assert set([c.name for c in Script("import").completions()]) == wanted
if not is_py26: # python 2.6 doesn't always come with a library `import*`.
wanted = {'ImportError', 'import', 'ImportWarning'}
assert {c.name for c in Script("import").completions()} == wanted
assert len(Script("import import", path='').completions()) > 0
# 111

View File

@@ -5,7 +5,6 @@ with "Black Box Tests".
from textwrap import dedent
import pytest
from jedi._compatibility import is_py26
# The namedtuple is different for different Python2.7 versions. Some versions
@@ -28,9 +27,6 @@ def test_namedtuple_str(letter, expected, Script):
dave.%s""") % letter
result = Script(source).completions()
completions = set(r.name for r in result)
if is_py26:
assert completions == set()
else:
assert completions == set(expected)
@@ -42,10 +38,7 @@ def test_namedtuple_list(Script):
garfield.l""")
result = Script(source).completions()
completions = set(r.name for r in result)
if is_py26:
assert completions == set()
else:
assert completions == set(['legs', 'length', 'large'])
assert completions == {'legs', 'length', 'large'}
def test_namedtuple_content(Script):

View File

@@ -15,9 +15,9 @@ def test_paths_from_assignment(Script):
expr_stmt = script._get_module_node().children[0]
return set(sys_path._paths_from_assignment(script._get_module(), expr_stmt))
assert paths('sys.path[0:0] = ["a"]') == set(['/foo/a'])
assert paths('sys.path = ["b", 1, x + 3, y, "c"]') == set(['/foo/b', '/foo/c'])
assert paths('sys.path = a = ["a"]') == set(['/foo/a'])
assert paths('sys.path[0:0] = ["a"]') == {'/foo/a'}
assert paths('sys.path = ["b", 1, x + 3, y, "c"]') == {'/foo/b', '/foo/c'}
assert paths('sys.path = a = ["a"]') == {'/foo/a'}
# Fail for complicated examples.
assert paths('sys.path, other = ["a"], 2') == set()

View File

@@ -7,7 +7,7 @@ from parso.python import tree
import pytest
class TestCallAndName():
class TestCallAndName:
def get_call(self, source):
# Get the simple_stmt and then the first one.
node = parse(source).children[0]

View File

@@ -41,7 +41,6 @@ def test_scipy_speed(Script):
s = 'import scipy.weave; scipy.weave.inline('
script = Script(s, 1, len(s), '')
script.call_signatures()
#print(jedi.imports.imports_processed)
@_check_speed(0.8)
@@ -63,10 +62,11 @@ def test_no_repr_computation(Script):
unwanted computation of repr(). Exemple : big pandas data.
See issue #919.
"""
class SlowRepr():
class SlowRepr:
"class to test what happens if __repr__ is very slow."
def some_method(self):
pass
def __repr__(self):
time.sleep(0.2)
test = SlowRepr()

View File

@@ -56,7 +56,7 @@ class TestSetupReadline(unittest.TestCase):
string = 'os.path.join("a").upper'
assert self.completions(string) == [string]
c = set(['os.' + d for d in dir(os) if d.startswith('ch')])
c = {'os.' + d for d in dir(os) if d.startswith('ch')}
assert set(self.completions('os.ch')) == set(c)
finally:
del self.namespace.sys
@@ -68,12 +68,12 @@ class TestSetupReadline(unittest.TestCase):
def test_import(self):
s = 'from os.path import a'
assert set(self.completions(s)) == set([s + 'ltsep', s + 'bspath'])
assert set(self.completions(s)) == {s + 'ltsep', s + 'bspath'}
assert self.completions('import keyword') == ['import keyword']
import os
s = 'from os import '
goal = set([s + el for el in dir(os)])
goal = {s + el for el in dir(os)}
# There are minor differences, e.g. the dir doesn't include deleted
# items as well as items that are not only available on linux.
assert len(set(self.completions(s)).symmetric_difference(goal)) < 20
@@ -85,7 +85,7 @@ class TestSetupReadline(unittest.TestCase):
def test_preexisting_values(self):
self.namespace.a = range(10)
assert set(self.completions('a.')) == set(['a.' + n for n in dir(range(1))])
assert set(self.completions('a.')) == {'a.' + n for n in dir(range(1))}
del self.namespace.a
def test_colorama(self):

View File

@@ -24,10 +24,6 @@ setenv =
env37: JEDI_TEST_ENVIRONMENT=37
commands =
py.test {posargs:jedi test}
[testenv:py26]
deps =
unittest2
{[testenv]deps}
[testenv:py27]
deps =
# for testing the typing module