From 6ad62e18d23441c96611a7eea683ca84b6d3983d Mon Sep 17 00:00:00 2001 From: Peter Law Date: Sun, 30 Aug 2020 15:21:19 +0100 Subject: [PATCH 1/8] deque is in collections, not queue Though it seems that the queue module does use it internally, which is why this was working. --- jedi/inference/compiled/subprocess/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jedi/inference/compiled/subprocess/__init__.py b/jedi/inference/compiled/subprocess/__init__.py index 0795de30..cd5fe74c 100644 --- a/jedi/inference/compiled/subprocess/__init__.py +++ b/jedi/inference/compiled/subprocess/__init__.py @@ -7,6 +7,7 @@ goals: 2. Make it possible to handle different Python versions as well as virtualenvs. """ +import collections import os import sys import queue @@ -168,7 +169,7 @@ class CompiledSubprocess: def __init__(self, executable, env_vars=None): self._executable = executable self._env_vars = env_vars - self._inference_state_deletion_queue = queue.deque() + self._inference_state_deletion_queue = collections.deque() self._cleanup_callable = lambda: None def __repr__(self): From 75624f0e3c40c503fd9a2dca9f6fdac046b1b191 Mon Sep 17 00:00:00 2001 From: Peter Law Date: Sun, 30 Aug 2020 15:23:08 +0100 Subject: [PATCH 2/8] Convert more things to Python 3 idioms --- jedi/api/project.py | 42 ++++++++++++++++++++++++------------------ jedi/debug.py | 5 +---- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/jedi/api/project.py b/jedi/api/project.py index 95c1ca23..da0f31d7 100644 --- a/jedi/api/project.py +++ b/jedi/api/project.py @@ -106,7 +106,16 @@ class Project: with open(self._get_json_path(self._path), 'w') as f: return json.dump((_SERIALIZER_VERSION, data), f) - def __init__(self, path, **kwargs): + def __init__( + self, + path, + *, + environment_path=None, + load_unsafe_extensions=False, + sys_path=None, + added_sys_path=(), + smart_sys_path=True, + ) -> None: """ :param path: The base path for this project. :param environment_path: The Python executable path, typically the path @@ -125,25 +134,22 @@ class Project: local directories. Otherwise you will have to rely on your packages being properly configured on the ``sys.path``. """ - def py2_comp(path, environment_path=None, load_unsafe_extensions=False, - sys_path=None, added_sys_path=(), smart_sys_path=True): - if isinstance(path, str): - path = Path(path).absolute() - self._path = path - self._environment_path = environment_path - if sys_path is not None: - # Remap potential pathlib.Path entries - sys_path = list(map(str, sys_path)) - self._sys_path = sys_path - self._smart_sys_path = smart_sys_path - self._load_unsafe_extensions = load_unsafe_extensions - self._django = False + if isinstance(path, str): + path = Path(path).absolute() + self._path = path + + self._environment_path = environment_path + if sys_path is not None: # Remap potential pathlib.Path entries - self.added_sys_path = list(map(str, added_sys_path)) - """The sys path that is going to be added at the end of the """ - - py2_comp(path, **kwargs) + sys_path = list(map(str, sys_path)) + self._sys_path = sys_path + self._smart_sys_path = smart_sys_path + self._load_unsafe_extensions = load_unsafe_extensions + self._django = False + # Remap potential pathlib.Path entries + self.added_sys_path = list(map(str, added_sys_path)) + """The sys path that is going to be added at the end of the """ @property def path(self): diff --git a/jedi/debug.py b/jedi/debug.py index 2b2bcfb8..99a90601 100644 --- a/jedi/debug.py +++ b/jedi/debug.py @@ -106,10 +106,7 @@ def dbg(message, *args, color='GREEN'): debug_function(color, i + 'dbg: ' + message % tuple(repr(a) for a in args)) -def warning(message, *args, **kwargs): - format = kwargs.pop('format', True) - assert not kwargs - +def warning(message, *args, format=True): if debug_function and enable_warning: i = ' ' * _debug_indent if format: From b9fd84e11cf8342000cafa8b5b3f406606ffcc8d Mon Sep 17 00:00:00 2001 From: Peter Law Date: Sun, 30 Aug 2020 15:48:54 +0100 Subject: [PATCH 3/8] Add sanity-check exception Found by mypy while adding types. --- jedi/api/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index 946f2c83..0c4db2dc 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -105,6 +105,9 @@ class Script: self.path = path.absolute() if path else None if code is None: + if path is None: + raise ValueError("Must provide at least one of code or path") + # TODO add a better warning than the traceback! with open(path, 'rb') as f: code = f.read() From 392dcdf015123c5768aef45f56e756322638ec9f Mon Sep 17 00:00:00 2001 From: Peter Law Date: Sun, 30 Aug 2020 16:14:00 +0100 Subject: [PATCH 4/8] Fix potential bug passing exception to function excepting str Found while adding type annotations. --- jedi/inference/sys_path.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jedi/inference/sys_path.py b/jedi/inference/sys_path.py index e701686f..2e404279 100644 --- a/jedi/inference/sys_path.py +++ b/jedi/inference/sys_path.py @@ -205,7 +205,7 @@ def _get_buildout_script_paths(search_path: Path): except (UnicodeDecodeError, IOError) as e: # Probably a binary file; permission error or race cond. because # file got deleted. Ignore it. - debug.warning(e) + debug.warning(str(e)) continue From 2d11e02fdb15d3311034417ddd2a3666d63e9ab9 Mon Sep 17 00:00:00 2001 From: Peter Law Date: Sun, 30 Aug 2020 16:15:22 +0100 Subject: [PATCH 5/8] Remove redundant invalid documentation line This is now replaced by the type signature. --- jedi/inference/sys_path.py | 1 - 1 file changed, 1 deletion(-) diff --git a/jedi/inference/sys_path.py b/jedi/inference/sys_path.py index 2e404279..062a0aa3 100644 --- a/jedi/inference/sys_path.py +++ b/jedi/inference/sys_path.py @@ -186,7 +186,6 @@ def _get_buildout_script_paths(search_path: Path): directory that look like python files. :param search_path: absolute path to the module. - :type search_path: str """ project_root = _get_parent_dir_with_file(search_path, 'buildout.cfg') if not project_root: From 87388ae00f45f64c648843cfa6a7780b839c876d Mon Sep 17 00:00:00 2001 From: Peter Law Date: Sun, 30 Aug 2020 16:41:22 +0100 Subject: [PATCH 6/8] Drop dead line --- jedi/api/helpers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/jedi/api/helpers.py b/jedi/api/helpers.py index 98685918..e8ce3881 100644 --- a/jedi/api/helpers.py +++ b/jedi/api/helpers.py @@ -205,7 +205,6 @@ def filter_follow_imports(names, follow_builtin_imports=False): class CallDetails: def __init__(self, bracket_leaf, children, position): - ['bracket_leaf', 'call_index', 'keyword_name_str'] self.bracket_leaf = bracket_leaf self._children = children self._position = position From 25a3e31ca8cfd14d479184ea22535c30ea16bf3f Mon Sep 17 00:00:00 2001 From: Peter Law Date: Sun, 30 Aug 2020 17:14:38 +0100 Subject: [PATCH 7/8] Add a __repr__ --- jedi/inference/gradual/typing.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jedi/inference/gradual/typing.py b/jedi/inference/gradual/typing.py index 5559339b..c2f08a33 100644 --- a/jedi/inference/gradual/typing.py +++ b/jedi/inference/gradual/typing.py @@ -431,6 +431,9 @@ class NewType(Value): from jedi.inference.compiled.value import CompiledValueName return CompiledValueName(self, 'NewType') + def __repr__(self) -> str: + return '%s' % (self.tree_node, self._type_value_set) + class CastFunction(ValueWrapper): @repack_with_argument_clinic('type, object, /') From aa265a44e14c60538b1efc68e2b142b8061f1797 Mon Sep 17 00:00:00 2001 From: Peter Law Date: Sun, 30 Aug 2020 18:03:03 +0100 Subject: [PATCH 8/8] Have all py__file__ methods return a Path --- jedi/inference/compiled/access.py | 6 ++++-- jedi/inference/compiled/value.py | 8 +++----- jedi/inference/context.py | 14 ++++++++------ jedi/inference/value/namespace.py | 5 ++++- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/jedi/inference/compiled/access.py b/jedi/inference/compiled/access.py index 2a674448..91f2da08 100644 --- a/jedi/inference/compiled/access.py +++ b/jedi/inference/compiled/access.py @@ -8,6 +8,8 @@ import warnings import re import builtins import typing +from pathlib import Path +from typing import Optional from jedi.inference.compiled.getattr_static import getattr_static @@ -179,9 +181,9 @@ class DirectObjectAccess: def py__bool__(self): return bool(self._obj) - def py__file__(self): + def py__file__(self) -> Optional[Path]: try: - return self._obj.__file__ + return Path(self._obj.__file__) except AttributeError: return None diff --git a/jedi/inference/compiled/value.py b/jedi/inference/compiled/value.py index 7b61e717..baad4d63 100644 --- a/jedi/inference/compiled/value.py +++ b/jedi/inference/compiled/value.py @@ -5,6 +5,7 @@ import re from functools import partial from inspect import Parameter from pathlib import Path +from typing import Optional from jedi import debug from jedi.inference.utils import to_list @@ -305,11 +306,8 @@ class CompiledModule(CompiledValue): return () return tuple(name.split('.')) - def py__file__(self): - path = self.access_handle.py__file__() - if path is None: - return None - return Path(path) + def py__file__(self) -> Optional[Path]: + return self.access_handle.py__file__() # type: ignore[no-any-return] class CompiledName(AbstractNameDefinition): diff --git a/jedi/inference/context.py b/jedi/inference/context.py index dd5b10da..5bc6b994 100644 --- a/jedi/inference/context.py +++ b/jedi/inference/context.py @@ -1,5 +1,7 @@ from abc import abstractmethod from contextlib import contextmanager +from pathlib import Path +from typing import Optional from parso.tree import search_ancestor from parso.python.tree import Name @@ -307,8 +309,8 @@ class FunctionContext(TreeContextMixin, ValueContext): class ModuleContext(TreeContextMixin, ValueContext): - def py__file__(self): - return self._value.py__file__() + def py__file__(self) -> Optional[Path]: + return self._value.py__file__() # type: ignore[no-any-return] def get_filters(self, until_position=None, origin_scope=None): filters = self._value.get_filters(origin_scope) @@ -355,8 +357,8 @@ class NamespaceContext(TreeContextMixin, ValueContext): def string_names(self): return self._value.string_names - def py__file__(self): - return self._value.py__file__() + def py__file__(self) -> Optional[Path]: + return self._value.py__file__() # type: ignore[no-any-return] class ClassContext(TreeContextMixin, ValueContext): @@ -405,8 +407,8 @@ class CompiledModuleContext(CompiledContext): def string_names(self): return self._value.string_names - def py__file__(self): - return self._value.py__file__() + def py__file__(self) -> Optional[Path]: + return self._value.py__file__() # type: ignore[no-any-return] def _get_global_filters_for_name(context, name_or_none, position): diff --git a/jedi/inference/value/namespace.py b/jedi/inference/value/namespace.py index f9f5d09f..11737cc9 100644 --- a/jedi/inference/value/namespace.py +++ b/jedi/inference/value/namespace.py @@ -1,3 +1,6 @@ +from pathlib import Path +from typing import Optional + from jedi.inference.cache import inference_state_method_cache from jedi.inference.filters import DictFilter from jedi.inference.names import ValueNameMixin, AbstractNameDefinition @@ -41,7 +44,7 @@ class ImplicitNamespaceValue(Value, SubModuleDictMixin): string_name = self.py__package__()[-1] return ImplicitNSName(self, string_name) - def py__file__(self): + def py__file__(self) -> Optional[Path]: return None def py__package__(self):