forked from VimPlug/jedi
Merge master into linter.
This commit is contained in:
@@ -34,5 +34,6 @@ Phillip Berndt (@phillipberndt) <phillip.berndt@gmail.com>
|
|||||||
Ian Lee (@IanLee1521) <IanLee1521@gmail.com>
|
Ian Lee (@IanLee1521) <IanLee1521@gmail.com>
|
||||||
Farkhad Khatamov (@hatamov) <comsgn@gmail.com>
|
Farkhad Khatamov (@hatamov) <comsgn@gmail.com>
|
||||||
Kevin Kelley (@kelleyk) <kelleyk@kelleyk.net>
|
Kevin Kelley (@kelleyk) <kelleyk@kelleyk.net>
|
||||||
|
Sid Shanker (@squidarth) <sid.p.shanker@gmail.com>
|
||||||
|
|
||||||
Note: (@user) means a github user name.
|
Note: (@user) means a github user name.
|
||||||
|
|||||||
10
README.rst
10
README.rst
@@ -33,12 +33,14 @@ It's really easy.
|
|||||||
Jedi can currently be used with the following editors:
|
Jedi can currently be used with the following editors:
|
||||||
|
|
||||||
- Vim (jedi-vim_, YouCompleteMe_)
|
- 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])
|
- Sublime Text (SublimeJEDI_ [ST2 + ST3], anaconda_ [only ST3])
|
||||||
- SynWrite_
|
- SynWrite_
|
||||||
- TextMate_ (Not sure if it's actually working)
|
- TextMate_ (Not sure if it's actually working)
|
||||||
- Kate_ version 4.13+ supports it natively, you have to enable it, though. [`proof
|
- 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>`_]
|
<https://projects.kde.org/projects/kde/applications/kate/repository/show?rev=KDE%2F4.13>`_]
|
||||||
|
- Atom_ (autocomplete-python_)
|
||||||
|
- SourceLair_
|
||||||
|
|
||||||
And it powers the following projects:
|
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.
|
understand/parse code older than those versions.
|
||||||
|
|
||||||
Tips on how to use Jedi efficiently can be found `here
|
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
|
API
|
||||||
---
|
---
|
||||||
@@ -176,6 +178,7 @@ For more detailed information visit the `testing documentation
|
|||||||
.. _jedi-vim: https://github.com/davidhalter/jedi-vim
|
.. _jedi-vim: https://github.com/davidhalter/jedi-vim
|
||||||
.. _youcompleteme: http://valloric.github.io/YouCompleteMe/
|
.. _youcompleteme: http://valloric.github.io/YouCompleteMe/
|
||||||
.. _Jedi.el: https://github.com/tkf/emacs-jedi
|
.. _Jedi.el: https://github.com/tkf/emacs-jedi
|
||||||
|
.. _company-mode: https://github.com/syohex/emacs-company-jedi
|
||||||
.. _elpy: https://github.com/jorgenschaefer/elpy
|
.. _elpy: https://github.com/jorgenschaefer/elpy
|
||||||
.. _anaconda-mode: https://github.com/proofit404/anaconda-mode
|
.. _anaconda-mode: https://github.com/proofit404/anaconda-mode
|
||||||
.. _ycmd: https://github.com/abingham/emacs-ycmd
|
.. _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
|
.. _wdb: https://github.com/Kozea/wdb
|
||||||
.. _TextMate: https://github.com/lawrenceakka/python-jedi.tmbundle
|
.. _TextMate: https://github.com/lawrenceakka/python-jedi.tmbundle
|
||||||
.. _Kate: http://kate-editor.org
|
.. _Kate: http://kate-editor.org
|
||||||
|
.. _Atom: https://atom.io/
|
||||||
|
.. _autocomplete-python: https://atom.io/packages/autocomplete-python
|
||||||
|
.. _SourceLair: https://www.sourcelair.com
|
||||||
|
|||||||
@@ -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>`__,
|
<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.
|
you have to enable it, though.
|
||||||
|
|
||||||
|
Atom:
|
||||||
|
|
||||||
|
- autocomplete-python_
|
||||||
|
|
||||||
|
SourceLair:
|
||||||
|
|
||||||
|
- SourceLair_
|
||||||
|
|
||||||
|
|
||||||
.. _other-software:
|
.. _other-software:
|
||||||
|
|
||||||
@@ -86,3 +94,5 @@ Using a custom ``$HOME/.pythonrc.py``
|
|||||||
.. _wdb: https://github.com/Kozea/wdb
|
.. _wdb: https://github.com/Kozea/wdb
|
||||||
.. _TextMate: https://github.com/lawrenceakka/python-jedi.tmbundle
|
.. _TextMate: https://github.com/lawrenceakka/python-jedi.tmbundle
|
||||||
.. _kate: http://kate-editor.org/
|
.. _kate: http://kate-editor.org/
|
||||||
|
.. _autocomplete-python: https://atom.io/packages/autocomplete-python
|
||||||
|
.. _SourceLair: https://www.sourcelair.com
|
||||||
|
|||||||
@@ -76,8 +76,8 @@ class Script(object):
|
|||||||
:type source: str
|
:type source: str
|
||||||
:param line: The line to perform actions on (starting with 1).
|
:param line: The line to perform actions on (starting with 1).
|
||||||
:type line: int
|
:type line: int
|
||||||
:param col: The column of the cursor (starting with 0).
|
:param column: The column of the cursor (starting with 0).
|
||||||
:type col: int
|
:type column: int
|
||||||
:param path: The path of the file in the file system, or ``''`` if
|
:param path: The path of the file in the file system, or ``''`` if
|
||||||
it hasn't been saved yet.
|
it hasn't been saved yet.
|
||||||
:type path: str or None
|
:type path: str or None
|
||||||
@@ -179,7 +179,7 @@ class Script(object):
|
|||||||
if unfinished_dotted:
|
if unfinished_dotted:
|
||||||
return completion_names
|
return completion_names
|
||||||
else:
|
else:
|
||||||
return keywords.keyword_names(self._evaluator, 'import')
|
return set([keywords.keyword(self._evaluator, 'import').name])
|
||||||
|
|
||||||
if isinstance(user_stmt, tree.Import):
|
if isinstance(user_stmt, tree.Import):
|
||||||
module = self._parser.module()
|
module = self._parser.module()
|
||||||
@@ -190,7 +190,11 @@ class Script(object):
|
|||||||
if names is None and not isinstance(user_stmt, tree.Import):
|
if names is None and not isinstance(user_stmt, tree.Import):
|
||||||
if not path and not dot:
|
if not path and not dot:
|
||||||
# add keywords
|
# 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
|
# TODO delete? We should search for valid parser
|
||||||
# transformations.
|
# transformations.
|
||||||
completion_names += self._simple_complete(path, dot, like)
|
completion_names += self._simple_complete(path, dot, like)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import keyword
|
|||||||
from jedi._compatibility import is_py3
|
from jedi._compatibility import is_py3
|
||||||
from jedi import common
|
from jedi import common
|
||||||
from jedi.evaluate.helpers import FakeName
|
from jedi.evaluate.helpers import FakeName
|
||||||
|
from jedi.parser.tree import Leaf
|
||||||
try:
|
try:
|
||||||
from pydoc_data import topics as pydoc_topics
|
from pydoc_data import topics as pydoc_topics
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@@ -17,22 +17,50 @@ else:
|
|||||||
keys = keyword.kwlist + ['None', 'False', 'True']
|
keys = keyword.kwlist + ['None', 'False', 'True']
|
||||||
|
|
||||||
|
|
||||||
def keywords(evaluator, string='', pos=(0, 0), all=False):
|
def has_inappropriate_leaf_keyword(pos, module):
|
||||||
if all:
|
relevant_errors = filter(
|
||||||
return set([Keyword(evaluator, k, pos) for k in keys])
|
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:
|
if string in keys:
|
||||||
return set([Keyword(evaluator, string, pos)])
|
return Keyword(evaluator, string, pos)
|
||||||
return set()
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def keyword_names(evaluator, *args, **kwargs):
|
|
||||||
return [k.name for k in keywords(evaluator, *args, **kwargs)]
|
|
||||||
|
|
||||||
|
|
||||||
def get_operator(evaluator, string, pos):
|
def get_operator(evaluator, string, pos):
|
||||||
return Keyword(evaluator, string, pos)
|
return Keyword(evaluator, string, pos)
|
||||||
|
|
||||||
|
|
||||||
|
keywords_only_valid_as_leaf = (
|
||||||
|
'continue',
|
||||||
|
'break',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Keyword(object):
|
class Keyword(object):
|
||||||
def __init__(self, evaluator, name, pos):
|
def __init__(self, evaluator, name, pos):
|
||||||
self.name = FakeName(name, self, pos)
|
self.name = FakeName(name, self, pos)
|
||||||
@@ -42,6 +70,10 @@ class Keyword(object):
|
|||||||
def get_parent_until(self):
|
def get_parent_until(self):
|
||||||
return self.parent
|
return self.parent
|
||||||
|
|
||||||
|
@property
|
||||||
|
def only_valid_as_leaf(self):
|
||||||
|
return self.name.value in keywords_only_valid_as_leaf
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def names(self):
|
def names(self):
|
||||||
""" For a `parsing.Name` like comparision """
|
""" For a `parsing.Name` like comparision """
|
||||||
|
|||||||
@@ -207,6 +207,21 @@ class dict():
|
|||||||
return d
|
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():
|
class reversed():
|
||||||
def __init__(self, sequence):
|
def __init__(self, sequence):
|
||||||
self.__sequence = sequence
|
self.__sequence = sequence
|
||||||
|
|||||||
@@ -305,6 +305,10 @@ class LeafWithNewLines(Leaf):
|
|||||||
return end_pos_line, end_pos_col
|
return end_pos_line, end_pos_col
|
||||||
|
|
||||||
|
|
||||||
|
@utf8_repr
|
||||||
|
def __repr__(self):
|
||||||
|
return "<%s: %r>" % (type(self).__name__, self.value)
|
||||||
|
|
||||||
class Whitespace(LeafWithNewLines):
|
class Whitespace(LeafWithNewLines):
|
||||||
"""Contains NEWLINE and ENDMARKER tokens."""
|
"""Contains NEWLINE and ENDMARKER tokens."""
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|||||||
@@ -51,6 +51,26 @@ left
|
|||||||
#? int()
|
#? int()
|
||||||
[a for a in {1:'x'}][0]
|
[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
|
# list comprehensions should also work in combination with functions
|
||||||
def listen(arg):
|
def listen(arg):
|
||||||
for x in arg:
|
for x in arg:
|
||||||
|
|||||||
@@ -4,3 +4,24 @@ raise
|
|||||||
|
|
||||||
#? ['except', 'Exception']
|
#? ['except', 'Exception']
|
||||||
except
|
except
|
||||||
|
|
||||||
|
#? []
|
||||||
|
b + continu
|
||||||
|
|
||||||
|
#? []
|
||||||
|
b + continue
|
||||||
|
|
||||||
|
#? ['continue']
|
||||||
|
b; continue
|
||||||
|
|
||||||
|
#? ['continue']
|
||||||
|
b; continu
|
||||||
|
|
||||||
|
#? []
|
||||||
|
c + brea
|
||||||
|
|
||||||
|
#? []
|
||||||
|
a + break
|
||||||
|
|
||||||
|
#? ['break']
|
||||||
|
b; break
|
||||||
|
|||||||
@@ -65,6 +65,15 @@ class X(): pass
|
|||||||
#? type
|
#? type
|
||||||
type(X)
|
type(X)
|
||||||
|
|
||||||
|
# -----------------
|
||||||
|
# enumerate
|
||||||
|
# -----------------
|
||||||
|
for i, j in enumerate(["as", "ad"]):
|
||||||
|
#? int()
|
||||||
|
i
|
||||||
|
#? str()
|
||||||
|
j
|
||||||
|
|
||||||
# -----------------
|
# -----------------
|
||||||
# re
|
# re
|
||||||
# -----------------
|
# -----------------
|
||||||
|
|||||||
@@ -295,9 +295,12 @@ def collect_dir_tests(base_dir, test_files, check_thirdparty=False):
|
|||||||
skip = 'Thirdparty-Library %s not found.' % lib
|
skip = 'Thirdparty-Library %s not found.' % lib
|
||||||
|
|
||||||
path = os.path.join(base_dir, f_name)
|
path = os.path.join(base_dir, f_name)
|
||||||
source = open(path).read()
|
|
||||||
if not is_py3:
|
if is_py3:
|
||||||
source = unicode(source, 'UTF-8')
|
source = open(path, encoding='utf-8').read()
|
||||||
|
else:
|
||||||
|
source = unicode(open(path).read(), 'UTF-8')
|
||||||
|
|
||||||
for case in collect_file_tests(StringIO(source),
|
for case in collect_file_tests(StringIO(source),
|
||||||
lines_to_execute):
|
lines_to_execute):
|
||||||
case.path = path
|
case.path = path
|
||||||
|
|||||||
Reference in New Issue
Block a user