mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-19 03:55:57 +08:00
Merge remote-tracking branch 'origin/master' into typeshed
This commit is contained in:
@@ -17,7 +17,7 @@ import parso
|
|||||||
|
|
||||||
_VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
_VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
||||||
|
|
||||||
_SUPPORTED_PYTHONS = ['3.6', '3.5', '3.4', '3.3', '2.7']
|
_SUPPORTED_PYTHONS = ['3.7', '3.6', '3.5', '3.4', '3.3', '2.7']
|
||||||
_SAFE_PATHS = ['/usr/bin', '/usr/local/bin']
|
_SAFE_PATHS = ['/usr/bin', '/usr/local/bin']
|
||||||
_CURRENT_VERSION = '%s.%s' % (sys.version_info.major, sys.version_info.minor)
|
_CURRENT_VERSION = '%s.%s' % (sys.version_info.major, sys.version_info.minor)
|
||||||
|
|
||||||
@@ -147,13 +147,18 @@ class InterpreterEnvironment(_BaseEnvironment):
|
|||||||
|
|
||||||
|
|
||||||
def _get_virtual_env_from_var():
|
def _get_virtual_env_from_var():
|
||||||
|
"""Get virtualenv environment from VIRTUAL_ENV environment variable.
|
||||||
|
|
||||||
|
It uses `safe=False` with ``create_environment``, because the environment
|
||||||
|
variable is considered to be safe / controlled by the user solely.
|
||||||
|
"""
|
||||||
var = os.environ.get('VIRTUAL_ENV')
|
var = os.environ.get('VIRTUAL_ENV')
|
||||||
if var is not None:
|
if var is not None:
|
||||||
if var == sys.prefix:
|
if var == sys.prefix:
|
||||||
return SameEnvironment()
|
return SameEnvironment()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return create_environment(var)
|
return create_environment(var, safe=False)
|
||||||
except InvalidPythonEnvironment:
|
except InvalidPythonEnvironment:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -318,10 +323,10 @@ def _get_executables_from_windows_registry(version):
|
|||||||
|
|
||||||
# TODO: support Python Anaconda.
|
# TODO: support Python Anaconda.
|
||||||
sub_keys = [
|
sub_keys = [
|
||||||
r'SOFTWARE\Python\PythonCore\{version}\InstallPath',
|
r'SOFTWARE\Python\PythonCore\{version}\InstallPath',
|
||||||
r'SOFTWARE\Wow6432Node\Python\PythonCore\{version}\InstallPath',
|
r'SOFTWARE\Wow6432Node\Python\PythonCore\{version}\InstallPath',
|
||||||
r'SOFTWARE\Python\PythonCore\{version}-32\InstallPath',
|
r'SOFTWARE\Python\PythonCore\{version}-32\InstallPath',
|
||||||
r'SOFTWARE\Wow6432Node\Python\PythonCore\{version}-32\InstallPath'
|
r'SOFTWARE\Wow6432Node\Python\PythonCore\{version}-32\InstallPath'
|
||||||
]
|
]
|
||||||
for root_key in [winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE]:
|
for root_key in [winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE]:
|
||||||
for sub_key in sub_keys:
|
for sub_key in sub_keys:
|
||||||
|
|||||||
@@ -358,21 +358,39 @@ class SequenceLiteralContext(Sequence):
|
|||||||
return [] # Direct closing bracket, doesn't contain items.
|
return [] # Direct closing bracket, doesn't contain items.
|
||||||
|
|
||||||
if array_node.type == 'testlist_comp':
|
if array_node.type == 'testlist_comp':
|
||||||
return array_node.children[::2]
|
# filter out (for now) pep 448 single-star unpacking
|
||||||
|
return [value for value in array_node.children[::2]
|
||||||
|
if value.type != "star_expr"]
|
||||||
elif array_node.type == 'dictorsetmaker':
|
elif array_node.type == 'dictorsetmaker':
|
||||||
kv = []
|
kv = []
|
||||||
iterator = iter(array_node.children)
|
iterator = iter(array_node.children)
|
||||||
for key in iterator:
|
for key in iterator:
|
||||||
op = next(iterator, None)
|
if key == "**":
|
||||||
if op is None or op == ',':
|
# dict with pep 448 double-star unpacking
|
||||||
kv.append(key) # A set.
|
# for now ignoring the values imported by **
|
||||||
else:
|
next(iterator)
|
||||||
assert op == ':' # A dict.
|
|
||||||
kv.append((key, next(iterator)))
|
|
||||||
next(iterator, None) # Possible comma.
|
next(iterator, None) # Possible comma.
|
||||||
|
else:
|
||||||
|
op = next(iterator, None)
|
||||||
|
if op is None or op == ',':
|
||||||
|
if key.type == "star_expr":
|
||||||
|
# pep 448 single-star unpacking
|
||||||
|
# for now ignoring values imported by *
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
kv.append(key) # A set.
|
||||||
|
else:
|
||||||
|
assert op == ':' # A dict.
|
||||||
|
kv.append((key, next(iterator)))
|
||||||
|
next(iterator, None) # Possible comma.
|
||||||
return kv
|
return kv
|
||||||
else:
|
else:
|
||||||
return [array_node]
|
if array_node.type == "star_expr":
|
||||||
|
# pep 448 single-star unpacking
|
||||||
|
# for now ignoring values imported by *
|
||||||
|
return []
|
||||||
|
else:
|
||||||
|
return [array_node]
|
||||||
|
|
||||||
def exact_key_items(self):
|
def exact_key_items(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -264,7 +264,8 @@ def eval_atom(context, atom):
|
|||||||
array_node_c = array_node.children
|
array_node_c = array_node.children
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
array_node_c = []
|
array_node_c = []
|
||||||
if c[0] == '{' and (array_node == '}' or ':' in array_node_c):
|
if c[0] == '{' and (array_node == '}' or ':' in array_node_c or
|
||||||
|
'**' in array_node_c):
|
||||||
context = iterable.DictLiteralContext(context.evaluator, context, atom)
|
context = iterable.DictLiteralContext(context.evaluator, context, atom)
|
||||||
else:
|
else:
|
||||||
context = iterable.SequenceLiteralContext(context.evaluator, context, atom)
|
context = iterable.SequenceLiteralContext(context.evaluator, context, atom)
|
||||||
|
|||||||
10
setup.py
10
setup.py
@@ -31,7 +31,15 @@ setup(name='jedi',
|
|||||||
packages=find_packages(exclude=['test', 'test.*']),
|
packages=find_packages(exclude=['test', 'test.*']),
|
||||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||||
install_requires=install_requires,
|
install_requires=install_requires,
|
||||||
extras_require={'dev': ['docopt']},
|
extras_require={
|
||||||
|
'testing': [
|
||||||
|
'pytest>=2.3.5',
|
||||||
|
# docopt for sith doctests
|
||||||
|
'docopt',
|
||||||
|
# coloroma for colored debug output
|
||||||
|
'colorama',
|
||||||
|
],
|
||||||
|
},
|
||||||
package_data={'jedi': ['evaluate/compiled/fake/*.pym']},
|
package_data={'jedi': ['evaluate/compiled/fake/*.pym']},
|
||||||
platforms=['any'],
|
platforms=['any'],
|
||||||
classifiers=[
|
classifiers=[
|
||||||
|
|||||||
@@ -131,3 +131,46 @@ set_t2 = set()
|
|||||||
|
|
||||||
#? ['clear', 'copy']
|
#? ['clear', 'copy']
|
||||||
set_t2.c
|
set_t2.c
|
||||||
|
|
||||||
|
# -----------------
|
||||||
|
# pep 448 unpacking generalizations
|
||||||
|
# -----------------
|
||||||
|
# python >= 3.5
|
||||||
|
|
||||||
|
d = {'a': 3}
|
||||||
|
|
||||||
|
#? dict()
|
||||||
|
{**d}
|
||||||
|
|
||||||
|
#? str()
|
||||||
|
{**d, "b": "b"}["b"]
|
||||||
|
|
||||||
|
# Should resolve to int() but jedi is not smart enough yet
|
||||||
|
# Here to make sure it doesn't result in crash though
|
||||||
|
#?
|
||||||
|
{**d}["a"]
|
||||||
|
|
||||||
|
s = {1, 2, 3}
|
||||||
|
|
||||||
|
#? set()
|
||||||
|
{*s}
|
||||||
|
|
||||||
|
#? set()
|
||||||
|
{*s, 4, *s}
|
||||||
|
|
||||||
|
s = {1, 2, 3}
|
||||||
|
# Should resolve to int() but jedi is not smart enough yet
|
||||||
|
# Here to make sure it doesn't result in crash though
|
||||||
|
#?
|
||||||
|
{*s}.pop()
|
||||||
|
|
||||||
|
#? int()
|
||||||
|
{*s, 4}.pop()
|
||||||
|
|
||||||
|
# Should resolve to int() but jedi is not smart enough yet
|
||||||
|
# Here to make sure it doesn't result in crash though
|
||||||
|
#?
|
||||||
|
[*s][0]
|
||||||
|
|
||||||
|
#? int()
|
||||||
|
[*s, 4][0]
|
||||||
|
|||||||
@@ -126,11 +126,12 @@ class StaticAnalysisCase(object):
|
|||||||
return "<%s: %s>" % (self.__class__.__name__, os.path.basename(self._path))
|
return "<%s: %s>" % (self.__class__.__name__, os.path.basename(self._path))
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture(scope='session')
|
||||||
def venv_path(tmpdir, environment):
|
def venv_path(tmpdir_factory, environment):
|
||||||
if environment.version_info.major < 3:
|
if environment.version_info.major < 3:
|
||||||
pytest.skip("python -m venv does not exist in Python 2")
|
pytest.skip("python -m venv does not exist in Python 2")
|
||||||
|
|
||||||
|
tmpdir = tmpdir_factory.mktemp('venv_path')
|
||||||
dirname = os.path.join(tmpdir.dirname, 'venv')
|
dirname = os.path.join(tmpdir.dirname, 'venv')
|
||||||
|
|
||||||
# We cannot use the Python from tox because tox creates virtualenvs and
|
# We cannot use the Python from tox because tox creates virtualenvs and
|
||||||
|
|||||||
@@ -110,3 +110,22 @@ def test_create_environment_venv_path(venv_path):
|
|||||||
def test_create_environment_executable():
|
def test_create_environment_executable():
|
||||||
environment = create_environment(sys.executable)
|
environment = create_environment(sys.executable)
|
||||||
assert environment.executable == sys.executable
|
assert environment.executable == sys.executable
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_default_environment_from_env_does_not_use_safe(tmpdir, monkeypatch):
|
||||||
|
fake_python = os.path.join(str(tmpdir), 'fake_python')
|
||||||
|
with open(fake_python, 'w') as f:
|
||||||
|
f.write('')
|
||||||
|
|
||||||
|
def _get_subprocess(self):
|
||||||
|
if self._start_executable != fake_python:
|
||||||
|
raise RuntimeError('Should not get called!')
|
||||||
|
self.executable = fake_python
|
||||||
|
self.path = 'fake'
|
||||||
|
|
||||||
|
monkeypatch.setattr('jedi.api.environment.Environment._get_subprocess',
|
||||||
|
_get_subprocess)
|
||||||
|
|
||||||
|
monkeypatch.setenv('VIRTUAL_ENV', fake_python)
|
||||||
|
env = get_default_environment()
|
||||||
|
assert env.path == 'fake'
|
||||||
|
|||||||
21
tox.ini
21
tox.ini
@@ -1,16 +1,10 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist = py27, py34, py35, py36
|
envlist = py27, py34, py35, py36
|
||||||
[testenv]
|
[testenv]
|
||||||
deps =
|
extras = testing
|
||||||
pytest>=2.3.5
|
|
||||||
pytest-cache
|
|
||||||
# docopt for sith doctests
|
|
||||||
docopt
|
|
||||||
# coloroma for colored debug output
|
|
||||||
colorama
|
|
||||||
# Overwrite the parso version (only used sometimes).
|
# Overwrite the parso version (only used sometimes).
|
||||||
# git+https://github.com/davidhalter/parso.git
|
# deps =
|
||||||
-rrequirements.txt
|
# git+https://github.com/davidhalter/parso.git
|
||||||
passenv = JEDI_TEST_ENVIRONMENT
|
passenv = JEDI_TEST_ENVIRONMENT
|
||||||
setenv =
|
setenv =
|
||||||
# https://github.com/tomchristie/django-rest-framework/issues/1957
|
# https://github.com/tomchristie/django-rest-framework/issues/1957
|
||||||
@@ -24,34 +18,29 @@ setenv =
|
|||||||
env36: JEDI_TEST_ENVIRONMENT=36
|
env36: JEDI_TEST_ENVIRONMENT=36
|
||||||
env37: JEDI_TEST_ENVIRONMENT=37
|
env37: JEDI_TEST_ENVIRONMENT=37
|
||||||
commands =
|
commands =
|
||||||
py.test {posargs:jedi test}
|
pytest {posargs:jedi test}
|
||||||
[testenv:py27]
|
[testenv:py27]
|
||||||
deps =
|
deps =
|
||||||
# for testing the typing module
|
# for testing the typing module
|
||||||
typing
|
typing
|
||||||
# numpydoc for typing scipy stack
|
# numpydoc for typing scipy stack
|
||||||
numpydoc
|
numpydoc
|
||||||
{[testenv]deps}
|
|
||||||
[testenv:py34]
|
[testenv:py34]
|
||||||
deps =
|
deps =
|
||||||
typing
|
typing
|
||||||
numpydoc
|
numpydoc
|
||||||
{[testenv]deps}
|
|
||||||
[testenv:py35]
|
[testenv:py35]
|
||||||
deps =
|
deps =
|
||||||
numpydoc
|
numpydoc
|
||||||
{[testenv]deps}
|
|
||||||
[testenv:py36]
|
[testenv:py36]
|
||||||
deps =
|
deps =
|
||||||
numpydoc
|
numpydoc
|
||||||
{[testenv]deps}
|
|
||||||
[testenv:cov]
|
[testenv:cov]
|
||||||
deps =
|
deps =
|
||||||
coverage
|
coverage
|
||||||
numpydoc
|
numpydoc
|
||||||
{[testenv]deps}
|
|
||||||
commands =
|
commands =
|
||||||
coverage run --source jedi -m py.test
|
coverage run --source jedi -m pytest
|
||||||
coverage report
|
coverage report
|
||||||
[testenv:sith]
|
[testenv:sith]
|
||||||
commands =
|
commands =
|
||||||
|
|||||||
Reference in New Issue
Block a user