mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-08 06:44:46 +08:00
Merge with master.
This commit is contained in:
34
.travis.yml
34
.travis.yml
@@ -1,23 +1,25 @@
|
||||
language: python
|
||||
python: 3.5
|
||||
sudo: false
|
||||
env:
|
||||
- TOXENV=py26
|
||||
- TOXENV=py27
|
||||
- TOXENV=py33
|
||||
- TOXENV=py34
|
||||
- TOXENV=py35
|
||||
- TOXENV=pypy
|
||||
- TOXENV=cov
|
||||
- TOXENV=sith
|
||||
python:
|
||||
- 2.6
|
||||
- 2.7
|
||||
- 3.3
|
||||
- 3.4
|
||||
- 3.5
|
||||
- 3.6
|
||||
- pypy
|
||||
matrix:
|
||||
allow_failures:
|
||||
- env: TOXENV=cov
|
||||
- env: TOXENV=sith
|
||||
- env: TOXENV=pypy
|
||||
python: 3.5
|
||||
allow_failures:
|
||||
- python: pypy
|
||||
- env: TOXENV=cov
|
||||
- env: TOXENV=sith
|
||||
include:
|
||||
- python: 3.5
|
||||
env: TOXENV=cov
|
||||
- python: 3.5
|
||||
env: TOXENV=sith
|
||||
install:
|
||||
- pip install --quiet tox
|
||||
- pip install --quiet tox-travis
|
||||
script:
|
||||
- tox
|
||||
after_script:
|
||||
|
||||
@@ -48,6 +48,10 @@ 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.
|
||||
|
||||
Visual Studio Code:
|
||||
|
||||
- `Python Extension`_
|
||||
|
||||
Atom:
|
||||
|
||||
- autocomplete-python_
|
||||
@@ -112,3 +116,4 @@ Using a custom ``$HOME/.pythonrc.py``
|
||||
.. _GNOME Builder: https://wiki.gnome.org/Apps/Builder/
|
||||
.. _gedi: https://github.com/isamert/gedi
|
||||
.. _Eric IDE: http://eric-ide.python-projects.org
|
||||
.. _Python Extension: https://marketplace.visualstudio.com/items?itemName=donjayamanne.python
|
||||
|
||||
@@ -105,7 +105,7 @@ class Script(object):
|
||||
|
||||
if source is None:
|
||||
# TODO add a better warning than the traceback!
|
||||
with open(path) as f:
|
||||
with open(path, 'rb') as f:
|
||||
source = f.read()
|
||||
|
||||
self._source = common.source_to_unicode(source, encoding)
|
||||
@@ -206,8 +206,8 @@ class Script(object):
|
||||
|
||||
def goto_assignments(self, follow_imports=False):
|
||||
"""
|
||||
Return the first definition found. Imports and statements aren't
|
||||
followed. Multiple objects may be returned, because Python itself is a
|
||||
Return the first definition found, while optionally following imports.
|
||||
Multiple objects may be returned, because Python itself is a
|
||||
dynamic language, which means depending on an option you can have two
|
||||
different versions of a function.
|
||||
|
||||
|
||||
@@ -8,8 +8,13 @@ from jedi.parser.tree import Leaf
|
||||
try:
|
||||
from pydoc_data import topics as pydoc_topics
|
||||
except ImportError:
|
||||
# Python 2.6
|
||||
import pydoc_topics
|
||||
# Python 2
|
||||
try:
|
||||
import pydoc_topics
|
||||
except ImportError:
|
||||
# This is for Python 3 embeddable version, which dont have
|
||||
# pydoc_data module in its file python3x.zip.
|
||||
pydoc_topics = None
|
||||
|
||||
if is_py3:
|
||||
if is_py35:
|
||||
@@ -108,6 +113,9 @@ def imitate_pydoc(string):
|
||||
It's not possible to get the pydoc's without starting the annoying pager
|
||||
stuff.
|
||||
"""
|
||||
if pydoc_topics is None:
|
||||
return ''
|
||||
|
||||
# str needed because of possible unicode stuff in py2k (pydoc doesn't work
|
||||
# with unicode strings)
|
||||
string = str(string)
|
||||
|
||||
@@ -430,7 +430,7 @@ class Evaluator(object):
|
||||
def_ = name.get_definition()
|
||||
is_simple_name = name.parent.type not in ('power', 'trailer')
|
||||
if is_simple_name:
|
||||
if name.parent.type == 'classdef':
|
||||
if name.parent.type == 'classdef' and name.parent.name == name:
|
||||
return [er.ClassContext(self, name.parent, context)]
|
||||
elif name.parent.type == 'funcdef':
|
||||
return [er.FunctionContext(self, context, name.parent)]
|
||||
|
||||
@@ -28,14 +28,13 @@ def get_venv_path(venv):
|
||||
def _get_sys_path_with_egglinks(sys_path):
|
||||
"""Find all paths including those referenced by egg-links.
|
||||
|
||||
Egg-link-referenced directories are inserted into path immediately after
|
||||
Egg-link-referenced directories are inserted into path immediately before
|
||||
the directory on which their links were found. Such directories are not
|
||||
taken into consideration by normal import mechanism, but they are traversed
|
||||
when doing pkg_resources.require.
|
||||
"""
|
||||
result = []
|
||||
for p in sys_path:
|
||||
result.append(p)
|
||||
# pkg_resources does not define a specific order for egg-link files
|
||||
# using os.listdir to enumerate them, we're sorting them to have
|
||||
# reproducible tests.
|
||||
@@ -48,6 +47,7 @@ def _get_sys_path_with_egglinks(sys_path):
|
||||
# pkg_resources package only interprets the first
|
||||
# non-empty line in egg-link files.
|
||||
break
|
||||
result.append(p)
|
||||
return result
|
||||
|
||||
|
||||
|
||||
161
jedi/parser/grammar3.6.txt
Normal file
161
jedi/parser/grammar3.6.txt
Normal file
@@ -0,0 +1,161 @@
|
||||
# Grammar for Python
|
||||
|
||||
# Note: Changing the grammar specified in this file will most likely
|
||||
# require corresponding changes in the parser module
|
||||
# (../Modules/parsermodule.c). If you can't make the changes to
|
||||
# that module yourself, please co-ordinate the required changes
|
||||
# with someone who can; ask around on python-dev for help. Fred
|
||||
# Drake <fdrake@acm.org> will probably be listening there.
|
||||
|
||||
# NOTE WELL: You should also follow all the steps listed at
|
||||
# https://docs.python.org/devguide/grammar.html
|
||||
|
||||
# Start symbols for the grammar:
|
||||
# file_input is a module or sequence of commands read from an input file;
|
||||
# single_input is a single interactive statement;
|
||||
# eval_input is the input for the eval() functions.
|
||||
# NB: compound_stmt in single_input is followed by extra NEWLINE!
|
||||
file_input: (NEWLINE | stmt)* ENDMARKER
|
||||
single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
|
||||
eval_input: testlist NEWLINE* ENDMARKER
|
||||
|
||||
decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
|
||||
decorators: decorator+
|
||||
decorated: decorators (classdef | funcdef | async_funcdef)
|
||||
|
||||
# NOTE: Francisco Souza/Reinoud Elhorst, using ASYNC/'await' keywords instead of
|
||||
# skipping python3.5+ compatibility, in favour of 3.7 solution
|
||||
async_funcdef: 'async' funcdef
|
||||
funcdef: 'def' NAME parameters ['->' test] ':' suite
|
||||
|
||||
parameters: '(' [typedargslist] ')'
|
||||
typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [',' [
|
||||
'*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]]
|
||||
| '**' tfpdef [',']]]
|
||||
| '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]]
|
||||
| '**' tfpdef [','])
|
||||
tfpdef: NAME [':' test]
|
||||
varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [
|
||||
'*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]]
|
||||
| '**' vfpdef [',']]]
|
||||
| '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]]
|
||||
| '**' vfpdef [',']
|
||||
)
|
||||
vfpdef: NAME
|
||||
|
||||
stmt: simple_stmt | compound_stmt
|
||||
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
|
||||
small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
|
||||
import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
|
||||
expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) |
|
||||
('=' (yield_expr|testlist_star_expr))*)
|
||||
annassign: ':' test ['=' test]
|
||||
testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
|
||||
augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' |
|
||||
'<<=' | '>>=' | '**=' | '//=')
|
||||
# For normal and annotated assignments, additional restrictions enforced by the interpreter
|
||||
del_stmt: 'del' exprlist
|
||||
pass_stmt: 'pass'
|
||||
flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
|
||||
break_stmt: 'break'
|
||||
continue_stmt: 'continue'
|
||||
return_stmt: 'return' [testlist]
|
||||
yield_stmt: yield_expr
|
||||
raise_stmt: 'raise' [test ['from' test]]
|
||||
import_stmt: import_name | import_from
|
||||
import_name: 'import' dotted_as_names
|
||||
# note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS
|
||||
import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
|
||||
'import' ('*' | '(' import_as_names ')' | import_as_names))
|
||||
import_as_name: NAME ['as' NAME]
|
||||
dotted_as_name: dotted_name ['as' NAME]
|
||||
import_as_names: import_as_name (',' import_as_name)* [',']
|
||||
dotted_as_names: dotted_as_name (',' dotted_as_name)*
|
||||
dotted_name: NAME ('.' NAME)*
|
||||
global_stmt: 'global' NAME (',' NAME)*
|
||||
nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
|
||||
assert_stmt: 'assert' test [',' test]
|
||||
|
||||
compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | async_stmt
|
||||
async_stmt: 'async' (funcdef | with_stmt | for_stmt)
|
||||
if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
|
||||
while_stmt: 'while' test ':' suite ['else' ':' suite]
|
||||
for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
|
||||
try_stmt: ('try' ':' suite
|
||||
((except_clause ':' suite)+
|
||||
['else' ':' suite]
|
||||
['finally' ':' suite] |
|
||||
'finally' ':' suite))
|
||||
with_stmt: 'with' with_item (',' with_item)* ':' suite
|
||||
with_item: test ['as' expr]
|
||||
# NB compile.c makes sure that the default except clause is last
|
||||
except_clause: 'except' [test ['as' NAME]]
|
||||
# Edit by Francisco Souza/David Halter: The stmt is now optional. This reflects
|
||||
# how Jedi allows classes and functions to be empty, which is beneficial for
|
||||
# autocompletion.
|
||||
suite: simple_stmt | NEWLINE INDENT stmt* DEDENT
|
||||
|
||||
test: or_test ['if' or_test 'else' test] | lambdef
|
||||
test_nocond: or_test | lambdef_nocond
|
||||
lambdef: 'lambda' [varargslist] ':' test
|
||||
lambdef_nocond: 'lambda' [varargslist] ':' test_nocond
|
||||
or_test: and_test ('or' and_test)*
|
||||
and_test: not_test ('and' not_test)*
|
||||
not_test: 'not' not_test | comparison
|
||||
comparison: expr (comp_op expr)*
|
||||
# <> isn't actually a valid comparison operator in Python. It's here for the
|
||||
# sake of a __future__ import described in PEP 401 (which really works :-)
|
||||
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
|
||||
star_expr: '*' expr
|
||||
expr: xor_expr ('|' xor_expr)*
|
||||
xor_expr: and_expr ('^' and_expr)*
|
||||
and_expr: shift_expr ('&' shift_expr)*
|
||||
shift_expr: arith_expr (('<<'|'>>') arith_expr)*
|
||||
arith_expr: term (('+'|'-') term)*
|
||||
term: factor (('*'|'@'|'/'|'%'|'//') factor)*
|
||||
factor: ('+'|'-'|'~') factor | power
|
||||
power: atom_expr ['**' factor]
|
||||
atom_expr: ['await'] atom trailer*
|
||||
atom: ('(' [yield_expr|testlist_comp] ')' |
|
||||
'[' [testlist_comp] ']' |
|
||||
'{' [dictorsetmaker] '}' |
|
||||
NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False')
|
||||
testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
|
||||
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
|
||||
subscriptlist: subscript (',' subscript)* [',']
|
||||
subscript: test | [test] ':' [test] [sliceop]
|
||||
sliceop: ':' [test]
|
||||
exprlist: (expr|star_expr) (',' (expr|star_expr))* [',']
|
||||
testlist: test (',' test)* [',']
|
||||
dictorsetmaker: ( ((test ':' test | '**' expr)
|
||||
(comp_for | (',' (test ':' test | '**' expr))* [','])) |
|
||||
((test | star_expr)
|
||||
(comp_for | (',' (test | star_expr))* [','])) )
|
||||
|
||||
classdef: 'class' NAME ['(' [arglist] ')'] ':' suite
|
||||
|
||||
arglist: argument (',' argument)* [',']
|
||||
|
||||
# The reason that keywords are test nodes instead of NAME is that using NAME
|
||||
# results in an ambiguity. ast.c makes sure it's a NAME.
|
||||
# "test '=' test" is really "keyword '=' test", but we have no such token.
|
||||
# These need to be in a single rule to avoid grammar that is ambiguous
|
||||
# to our LL(1) parser. Even though 'test' includes '*expr' in star_expr,
|
||||
# we explicitly match '*' here, too, to give it proper precedence.
|
||||
# Illegal combinations and orderings are blocked in ast.c:
|
||||
# multiple (test comp_for) arguments are blocked; keyword unpackings
|
||||
# that precede iterable unpackings are blocked; etc.
|
||||
argument: ( test [comp_for] |
|
||||
test '=' test |
|
||||
'**' test |
|
||||
'*' test )
|
||||
|
||||
comp_iter: comp_for | comp_if
|
||||
comp_for: ['async'] 'for' exprlist 'in' or_test [comp_iter]
|
||||
comp_if: 'if' test_nocond [comp_iter]
|
||||
|
||||
# not used in grammar, but may appear in "node" passed from Parser to Compiler
|
||||
encoding_decl: NAME
|
||||
|
||||
yield_expr: 'yield' [yield_arg]
|
||||
yield_arg: 'from' test | testlist
|
||||
@@ -159,7 +159,6 @@ class ParserPickling(object):
|
||||
# 0 means version is not defined (= always delete cache):
|
||||
if data.get('version', 0) != self.version:
|
||||
self.clear_cache()
|
||||
self.__index = {}
|
||||
else:
|
||||
self.__index = data['index']
|
||||
return self.__index
|
||||
@@ -179,6 +178,7 @@ class ParserPickling(object):
|
||||
|
||||
def clear_cache(self):
|
||||
shutil.rmtree(self._cache_directory())
|
||||
self.__index = {}
|
||||
|
||||
def _get_hashed_path(self, path):
|
||||
return self._get_path('%s.pkl' % hashlib.md5(path.encode("utf-8")).hexdigest())
|
||||
|
||||
@@ -162,6 +162,7 @@ class Mixin(SuperClass):
|
||||
def method_mixin(self):
|
||||
return int
|
||||
|
||||
#? 20 SuperClass
|
||||
class SubClass(SuperClass):
|
||||
class_sub = 3
|
||||
def __init__(self):
|
||||
|
||||
14
test/run.py
14
test/run.py
@@ -25,10 +25,10 @@ multiple Python versions.
|
||||
.. _tox: http://testrun.org/tox
|
||||
|
||||
Integration test cases are located in ``test/completion`` directory
|
||||
and each test cases are indicated by the comment ``#?`` (completions /
|
||||
definitions), ``#!`` (assignments) and ``#<`` (usages). There is also
|
||||
support for third party libraries. In a normal test run they are not
|
||||
being executed, you have to provide a ``--thirdparty`` option.
|
||||
and each test case is indicated by either the comment ``#?`` (completions /
|
||||
definitions), ``#!`` (assignments), or ``#<`` (usages).
|
||||
There is also support for third party libraries. In a normal test run they are
|
||||
not being executed, you have to provide a ``--thirdparty`` option.
|
||||
|
||||
In addition to standard `-k` and `-m` options in py.test, you can use
|
||||
`-T` (`--test-files`) option to specify integration test cases to run.
|
||||
@@ -64,7 +64,7 @@ happening.
|
||||
Auto-Completion
|
||||
+++++++++++++++
|
||||
|
||||
Uses comments to specify a test in the next line. The comment says, which
|
||||
Uses comments to specify a test in the next line. The comment says which
|
||||
results are expected. The comment always begins with `#?`. The last row
|
||||
symbolizes the cursor.
|
||||
|
||||
@@ -94,8 +94,8 @@ Tests look like this::
|
||||
#! ['abc=1']
|
||||
abc
|
||||
|
||||
Additionally it is possible to add a number which describes to position of
|
||||
the test (otherwise it's just end of line)::
|
||||
Additionally it is possible to specify the column by adding a number, which
|
||||
describes the position of the test (otherwise it's just the end of line)::
|
||||
|
||||
#! 2 ['abc=1']
|
||||
abc
|
||||
|
||||
@@ -41,9 +41,9 @@ def test_get_venv_path(venv):
|
||||
site_pkgs = (glob(pjoin(venv, 'lib', 'python*', 'site-packages')) +
|
||||
glob(pjoin(venv, 'lib', 'site-packages')))[0]
|
||||
ETALON = [
|
||||
site_pkgs,
|
||||
pjoin('/path', 'from', 'egg-link'),
|
||||
pjoin(site_pkgs, '.', 'relative', 'egg-link', 'path'),
|
||||
site_pkgs,
|
||||
pjoin(site_pkgs, 'dir-from-foo-pth'),
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user