Merge master into linter.

This commit is contained in:
Dave Halter
2015-12-15 12:28:38 +01:00
11 changed files with 144 additions and 19 deletions

View File

@@ -34,5 +34,6 @@ Phillip Berndt (@phillipberndt) <phillip.berndt@gmail.com>
Ian Lee (@IanLee1521) <IanLee1521@gmail.com>
Farkhad Khatamov (@hatamov) <comsgn@gmail.com>
Kevin Kelley (@kelleyk) <kelleyk@kelleyk.net>
Sid Shanker (@squidarth) <sid.p.shanker@gmail.com>
Note: (@user) means a github user name.

View File

@@ -33,12 +33,14 @@ It's really easy.
Jedi can currently be used with the following editors:
- Vim (jedi-vim_, YouCompleteMe_)
- Emacs (Jedi.el_, elpy_, anaconda-mode_, ycmd_)
- Emacs (Jedi.el_, company-mode_, elpy_, anaconda-mode_, ycmd_)
- Sublime Text (SublimeJEDI_ [ST2 + ST3], anaconda_ [only ST3])
- SynWrite_
- TextMate_ (Not sure if it's actually working)
- Kate_ version 4.13+ supports it natively, you have to enable it, though. [`proof
<https://projects.kde.org/projects/kde/applications/kate/repository/show?rev=KDE%2F4.13>`_]
- Atom_ (autocomplete-python_)
- SourceLair_
And it powers the following projects:
@@ -95,7 +97,7 @@ You can run Jedi on cPython 2.6, 2.7, 3.2, 3.3 or 3.4, but it should also
understand/parse code older than those versions.
Tips on how to use Jedi efficiently can be found `here
<https://jedi.readthedocs.org/en/latest/docs/recipes.html>`_.
<https://jedi.readthedocs.org/en/latest/docs/features.html#recipes>`_.
API
---
@@ -176,6 +178,7 @@ For more detailed information visit the `testing documentation
.. _jedi-vim: https://github.com/davidhalter/jedi-vim
.. _youcompleteme: http://valloric.github.io/YouCompleteMe/
.. _Jedi.el: https://github.com/tkf/emacs-jedi
.. _company-mode: https://github.com/syohex/emacs-company-jedi
.. _elpy: https://github.com/jorgenschaefer/elpy
.. _anaconda-mode: https://github.com/proofit404/anaconda-mode
.. _ycmd: https://github.com/abingham/emacs-ycmd
@@ -185,3 +188,6 @@ For more detailed information visit the `testing documentation
.. _wdb: https://github.com/Kozea/wdb
.. _TextMate: https://github.com/lawrenceakka/python-jedi.tmbundle
.. _Kate: http://kate-editor.org
.. _Atom: https://atom.io/
.. _autocomplete-python: https://atom.io/packages/autocomplete-python
.. _SourceLair: https://www.sourcelair.com

View File

@@ -47,6 +47,14 @@ Kate:
<https://projects.kde.org/projects/kde/applications/kate/repository/entry/addons/kate/pate/src/plugins/python_autocomplete_jedi.py?rev=KDE%2F4.13>`__,
you have to enable it, though.
Atom:
- autocomplete-python_
SourceLair:
- SourceLair_
.. _other-software:
@@ -86,3 +94,5 @@ Using a custom ``$HOME/.pythonrc.py``
.. _wdb: https://github.com/Kozea/wdb
.. _TextMate: https://github.com/lawrenceakka/python-jedi.tmbundle
.. _kate: http://kate-editor.org/
.. _autocomplete-python: https://atom.io/packages/autocomplete-python
.. _SourceLair: https://www.sourcelair.com

View File

@@ -76,8 +76,8 @@ class Script(object):
:type source: str
:param line: The line to perform actions on (starting with 1).
:type line: int
:param col: The column of the cursor (starting with 0).
:type col: int
:param column: The column of the cursor (starting with 0).
:type column: int
:param path: The path of the file in the file system, or ``''`` if
it hasn't been saved yet.
:type path: str or None
@@ -179,7 +179,7 @@ class Script(object):
if unfinished_dotted:
return completion_names
else:
return keywords.keyword_names(self._evaluator, 'import')
return set([keywords.keyword(self._evaluator, 'import').name])
if isinstance(user_stmt, tree.Import):
module = self._parser.module()
@@ -190,7 +190,11 @@ class Script(object):
if names is None and not isinstance(user_stmt, tree.Import):
if not path and not dot:
# add keywords
completion_names += keywords.keyword_names(self._evaluator, all=True)
completion_names += keywords.completion_names(
self._evaluator,
user_stmt,
self._pos,
module)
# TODO delete? We should search for valid parser
# transformations.
completion_names += self._simple_complete(path, dot, like)

View File

@@ -4,7 +4,7 @@ import keyword
from jedi._compatibility import is_py3
from jedi import common
from jedi.evaluate.helpers import FakeName
from jedi.parser.tree import Leaf
try:
from pydoc_data import topics as pydoc_topics
except ImportError:
@@ -17,22 +17,50 @@ else:
keys = keyword.kwlist + ['None', 'False', 'True']
def keywords(evaluator, string='', pos=(0, 0), all=False):
if all:
def has_inappropriate_leaf_keyword(pos, module):
relevant_errors = filter(
lambda error: error.first_pos[0] == pos[0],
module.error_statement_stacks)
for error in relevant_errors:
if error.next_token in keys:
return True
return False
def completion_names(evaluator, stmt, pos, module):
keyword_list = all_keywords(evaluator)
if not isinstance(stmt, Leaf) or has_inappropriate_leaf_keyword(pos, module):
keyword_list = filter(
lambda keyword: not keyword.only_valid_as_leaf,
keyword_list
)
return [keyword.name for keyword in keyword_list]
def all_keywords(evaluator, pos=(0, 0)):
return set([Keyword(evaluator, k, pos) for k in keys])
def keyword(evaluator, string, pos=(0, 0)):
if string in keys:
return set([Keyword(evaluator, string, pos)])
return set()
def keyword_names(evaluator, *args, **kwargs):
return [k.name for k in keywords(evaluator, *args, **kwargs)]
return Keyword(evaluator, string, pos)
else:
return None
def get_operator(evaluator, string, pos):
return Keyword(evaluator, string, pos)
keywords_only_valid_as_leaf = (
'continue',
'break',
)
class Keyword(object):
def __init__(self, evaluator, name, pos):
self.name = FakeName(name, self, pos)
@@ -42,6 +70,10 @@ class Keyword(object):
def get_parent_until(self):
return self.parent
@property
def only_valid_as_leaf(self):
return self.name.value in keywords_only_valid_as_leaf
@property
def names(self):
""" For a `parsing.Name` like comparision """

View File

@@ -207,6 +207,21 @@ class dict():
return d
class enumerate():
def __init__(self, sequence, start=0):
self.__sequence = sequence
def __iter__(self):
for i in self.__sequence:
yield 1, i
def __next__(self):
return next(self.__iter__())
def next(self):
return next(self.__iter__())
class reversed():
def __init__(self, sequence):
self.__sequence = sequence

View File

@@ -305,6 +305,10 @@ class LeafWithNewLines(Leaf):
return end_pos_line, end_pos_col
@utf8_repr
def __repr__(self):
return "<%s: %r>" % (type(self).__name__, self.value)
class Whitespace(LeafWithNewLines):
"""Contains NEWLINE and ENDMARKER tokens."""
__slots__ = ()

View File

@@ -51,6 +51,26 @@ left
#? int()
[a for a in {1:'x'}][0]
##? str()
{a-1:b for a,b in {1:'a', 3:1.0}.items()}[0]
# with a set literal
#? int()
[a for a in {1, 2, 3}][0]
##? set()
{a for a in range(10)}
##? int()
[x for x in {a for a in range(10)}][0]
##? int()
{a for a in range(10)}.pop()
##? int()
iter({a for a in range(10)}).next()
# list comprehensions should also work in combination with functions
def listen(arg):
for x in arg:

View File

@@ -4,3 +4,24 @@ raise
#? ['except', 'Exception']
except
#? []
b + continu
#? []
b + continue
#? ['continue']
b; continue
#? ['continue']
b; continu
#? []
c + brea
#? []
a + break
#? ['break']
b; break

View File

@@ -65,6 +65,15 @@ class X(): pass
#? type
type(X)
# -----------------
# enumerate
# -----------------
for i, j in enumerate(["as", "ad"]):
#? int()
i
#? str()
j
# -----------------
# re
# -----------------

View File

@@ -295,9 +295,12 @@ def collect_dir_tests(base_dir, test_files, check_thirdparty=False):
skip = 'Thirdparty-Library %s not found.' % lib
path = os.path.join(base_dir, f_name)
source = open(path).read()
if not is_py3:
source = unicode(source, 'UTF-8')
if is_py3:
source = open(path, encoding='utf-8').read()
else:
source = unicode(open(path).read(), 'UTF-8')
for case in collect_file_tests(StringIO(source),
lines_to_execute):
case.path = path