1
0
forked from VimPlug/jedi

Cleanse the API from Python 2 stuff

This commit is contained in:
Dave Halter
2020-07-02 10:24:44 +02:00
parent f7b445353f
commit a51f667be8
6 changed files with 50 additions and 76 deletions

View File

@@ -34,9 +34,7 @@ def _get_signature_param_names(signatures, positional_count, used_kwargs):
# Add named params # Add named params
for call_sig in signatures: for call_sig in signatures:
for i, p in enumerate(call_sig.params): for i, p in enumerate(call_sig.params):
# Allow protected access, because it's a public API. kind = p.kind
# TODO reconsider with Python 2 drop
kind = p._name.get_kind()
if i < positional_count and kind == Parameter.POSITIONAL_OR_KEYWORD: if i < positional_count and kind == Parameter.POSITIONAL_OR_KEYWORD:
continue continue
if kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.KEYWORD_ONLY) \ if kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.KEYWORD_ONLY) \
@@ -51,8 +49,7 @@ def _must_be_kwarg(signatures, positional_count, used_kwargs):
must_be_kwarg = True must_be_kwarg = True
for signature in signatures: for signature in signatures:
for i, p in enumerate(signature.params): for i, p in enumerate(signature.params):
# TODO reconsider with Python 2 drop kind = p.kind
kind = p._name.get_kind()
if kind is Parameter.VAR_POSITIONAL: if kind is Parameter.VAR_POSITIONAL:
# In case there were not already kwargs, the next param can # In case there were not already kwargs, the next param can
# always be a normal argument. # always be a normal argument.

View File

@@ -257,7 +257,7 @@ def _get_cached_default_environment():
return InterpreterEnvironment() return InterpreterEnvironment()
def find_virtualenvs(paths=None, **kwargs): def find_virtualenvs(paths=None, *, safe=True, use_environment_vars=True):
""" """
:param paths: A list of paths in your file system to be scanned for :param paths: A list of paths in your file system to be scanned for
Virtualenvs. It will search in these paths and potentially execute the Virtualenvs. It will search in these paths and potentially execute the
@@ -274,47 +274,44 @@ def find_virtualenvs(paths=None, **kwargs):
:yields: :class:`.Environment` :yields: :class:`.Environment`
""" """
def py27_comp(paths=None, safe=True, use_environment_vars=True): if paths is None:
if paths is None: paths = []
paths = []
_used_paths = set() _used_paths = set()
if use_environment_vars: if use_environment_vars:
# Using this variable should be safe, because attackers might be # Using this variable should be safe, because attackers might be
# able to drop files (via git) but not environment variables. # able to drop files (via git) but not environment variables.
virtual_env = _get_virtual_env_from_var() virtual_env = _get_virtual_env_from_var()
if virtual_env is not None: if virtual_env is not None:
yield virtual_env yield virtual_env
_used_paths.add(virtual_env.path) _used_paths.add(virtual_env.path)
conda_env = _get_virtual_env_from_var(_CONDA_VAR) conda_env = _get_virtual_env_from_var(_CONDA_VAR)
if conda_env is not None: if conda_env is not None:
yield conda_env yield conda_env
_used_paths.add(conda_env.path) _used_paths.add(conda_env.path)
for directory in paths: for directory in paths:
if not os.path.isdir(directory): if not os.path.isdir(directory):
continue
directory = os.path.abspath(directory)
for path in os.listdir(directory):
path = os.path.join(directory, path)
if path in _used_paths:
# A path shouldn't be inferred twice.
continue continue
_used_paths.add(path)
directory = os.path.abspath(directory) try:
for path in os.listdir(directory): executable = _get_executable_path(path, safe=safe)
path = os.path.join(directory, path) yield Environment(executable)
if path in _used_paths: except InvalidPythonEnvironment:
# A path shouldn't be inferred twice. pass
continue
_used_paths.add(path)
try:
executable = _get_executable_path(path, safe=safe)
yield Environment(executable)
except InvalidPythonEnvironment:
pass
return py27_comp(paths, **kwargs)
def find_system_environments(**kwargs): def find_system_environments(*, env_vars={}):
""" """
Ignores virtualenvs and returns the Python versions that were installed on Ignores virtualenvs and returns the Python versions that were installed on
your system. This might return nothing, if you're running Python e.g. from your system. This might return nothing, if you're running Python e.g. from
@@ -326,14 +323,14 @@ def find_system_environments(**kwargs):
""" """
for version_string in _SUPPORTED_PYTHONS: for version_string in _SUPPORTED_PYTHONS:
try: try:
yield get_system_environment(version_string, **kwargs) yield get_system_environment(version_string, env_vars=env_vars)
except InvalidPythonEnvironment: except InvalidPythonEnvironment:
pass pass
# TODO: this function should probably return a list of environments since # TODO: this function should probably return a list of environments since
# multiple Python installations can be found on a system for the same version. # multiple Python installations can be found on a system for the same version.
def get_system_environment(version, **kwargs): def get_system_environment(version, *, env_vars={}):
""" """
Return the first Python environment found for a string of the form 'X.Y' Return the first Python environment found for a string of the form 'X.Y'
where X and Y are the major and minor versions of Python. where X and Y are the major and minor versions of Python.
@@ -350,26 +347,20 @@ def get_system_environment(version, **kwargs):
if os.name == 'nt': if os.name == 'nt':
for exe in _get_executables_from_windows_registry(version): for exe in _get_executables_from_windows_registry(version):
try: try:
return Environment(exe, **kwargs) return Environment(exe, env_vars=env_vars)
except InvalidPythonEnvironment: except InvalidPythonEnvironment:
pass pass
raise InvalidPythonEnvironment("Cannot find executable python%s." % version) raise InvalidPythonEnvironment("Cannot find executable python%s." % version)
def create_environment(path, safe=True, **kwargs): def create_environment(path, *, safe=True, env_vars={}):
""" """
Make it possible to manually create an Environment object by specifying a Make it possible to manually create an Environment object by specifying a
Virtualenv path or an executable path and optional environment variables. Virtualenv path or an executable path and optional environment variables.
:raises: :exc:`.InvalidPythonEnvironment` :raises: :exc:`.InvalidPythonEnvironment`
:returns: :class:`.Environment` :returns: :class:`.Environment`
TODO: make env_vars a kwarg when Python 2 is dropped. For now, preserve API
""" """
return _create_environment(path, safe, **kwargs)
def _create_environment(path, safe=True, env_vars={}):
if os.path.isfile(path): if os.path.isfile(path):
_assert_safe(path, safe) _assert_safe(path, safe)
return Environment(path, env_vars=env_vars) return Environment(path, env_vars=env_vars)
@@ -393,11 +384,7 @@ def _get_executable_path(path, safe=True):
def _get_executables_from_windows_registry(version): def _get_executables_from_windows_registry(version):
# The winreg module is named _winreg on Python 2. import winreg
try:
import winreg
except ImportError:
import _winreg as winreg
# TODO: support Python Anaconda. # TODO: support Python Anaconda.
sub_keys = [ sub_keys = [

View File

@@ -295,8 +295,7 @@ def _iter_arguments(nodes, position):
# Returns Generator[Tuple[star_count, Optional[key_start: str], had_equal]] # Returns Generator[Tuple[star_count, Optional[key_start: str], had_equal]]
nodes_before = [c for c in nodes if c.start_pos < position] nodes_before = [c for c in nodes if c.start_pos < position]
if nodes_before[-1].type == 'arglist': if nodes_before[-1].type == 'arglist':
for x in _iter_arguments(nodes_before[-1].children, position): yield from _iter_arguments(nodes_before[-1].children, position)
yield x # Python 2 :(
return return
previous_node_yielded = False previous_node_yielded = False
@@ -321,7 +320,7 @@ def _iter_arguments(nodes, position):
else: else:
yield 0, None, False yield 0, None, False
stars_seen = 0 stars_seen = 0
elif node.type in ('testlist', 'testlist_star_expr'): # testlist is Python 2 elif node.type == 'testlist_star_expr':
for n in node.children[::2]: for n in node.children[::2]:
if n.type == 'star_expr': if n.type == 'star_expr':
stars_seen = 1 stars_seen = 1

View File

@@ -211,7 +211,7 @@ class Project(object):
self._environment = get_cached_default_environment() self._environment = get_cached_default_environment()
return self._environment return self._environment
def search(self, string, **kwargs): def search(self, string, *, all_scopes=False):
""" """
Searches a name in the whole project. If the project is very big, Searches a name in the whole project. If the project is very big,
at some point Jedi will stop searching. However it's also very much at some point Jedi will stop searching. However it's also very much
@@ -232,7 +232,7 @@ class Project(object):
functions and classes. functions and classes.
:yields: :class:`.Name` :yields: :class:`.Name`
""" """
return self._search(string, **kwargs) return self._search_func(string, all_scopes=all_scopes)
def complete_search(self, string, **kwargs): def complete_search(self, string, **kwargs):
""" """
@@ -246,9 +246,6 @@ class Project(object):
""" """
return self._search_func(string, complete=True, **kwargs) return self._search_func(string, complete=True, **kwargs)
def _search(self, string, all_scopes=False): # Python 2..
return self._search_func(string, all_scopes=all_scopes)
@_try_to_skip_duplicates @_try_to_skip_duplicates
def _search_func(self, string, complete=False, all_scopes=False): def _search_func(self, string, complete=False, all_scopes=False):
# Using a Script is they easiest way to get an empty module context. # Using a Script is they easiest way to get an empty module context.
@@ -290,7 +287,7 @@ class Project(object):
continue continue
debug.dbg('Search of a specific module %s', m) debug.dbg('Search of a specific module %s', m)
for x in search_in_module( yield from search_in_module(
inference_state, inference_state,
m, m,
names=[m.name], names=[m.name],
@@ -299,15 +296,14 @@ class Project(object):
complete=complete, complete=complete,
convert=True, convert=True,
ignore_imports=True, ignore_imports=True,
): )
yield x # Python 2...
# 2. Search for identifiers in the project. # 2. Search for identifiers in the project.
for module_context in search_in_file_ios(inference_state, file_ios, name): for module_context in search_in_file_ios(inference_state, file_ios, name):
names = get_module_names(module_context.tree_node, all_scopes=all_scopes) names = get_module_names(module_context.tree_node, all_scopes=all_scopes)
names = [module_context.create_name(n) for n in names] names = [module_context.create_name(n) for n in names]
names = _remove_imports(names) names = _remove_imports(names)
for x in search_in_module( yield from search_in_module(
inference_state, inference_state,
module_context, module_context,
names=names, names=names,
@@ -315,8 +311,7 @@ class Project(object):
wanted_names=wanted_names, wanted_names=wanted_names,
complete=complete, complete=complete,
ignore_imports=True, ignore_imports=True,
): )
yield x # Python 2...
# 3. Search for modules on sys.path # 3. Search for modules on sys.path
sys_path = [ sys_path = [
@@ -326,7 +321,7 @@ class Project(object):
if not p.startswith(self._path) if not p.startswith(self._path)
] ]
names = list(iter_module_names(inference_state, empty_module_context, sys_path)) names = list(iter_module_names(inference_state, empty_module_context, sys_path))
for x in search_in_module( yield from search_in_module(
inference_state, inference_state,
empty_module_context, empty_module_context,
names=names, names=names,
@@ -334,8 +329,7 @@ class Project(object):
wanted_names=wanted_names, wanted_names=wanted_names,
complete=complete, complete=complete,
convert=True, convert=True,
): )
yield x # Python 2...
def __repr__(self): def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self._path) return '<%s: %s>' % (self.__class__.__name__, self._path)

View File

@@ -350,8 +350,7 @@ def _find_non_global_names(nodes):
if node.type == 'trailer' and node.children[0] == '.': if node.type == 'trailer' and node.children[0] == '.':
continue continue
for x in _find_non_global_names(children): # Python 2... yield from _find_non_global_names(children)
yield x
def _get_code_insertion_node(node, is_bound_method): def _get_code_insertion_node(node, is_bound_method):

View File

@@ -97,10 +97,8 @@ def increase_indent_cm(title=None, color='MAGENTA'):
dbg('End: ' + title, color=color) dbg('End: ' + title, color=color)
def dbg(message, *args, **kwargs): def dbg(message, *args, color='GREEN'):
""" Looks at the stack, to see if a debug message should be printed. """ """ Looks at the stack, to see if a debug message should be printed. """
# Python 2 compatibility, because it doesn't understand default args
color = kwargs.pop('color', 'GREEN')
assert color assert color
if debug_function and enable_notice: if debug_function and enable_notice: