From 83d4ec9e847920e4b6a199a934468f467f9b9e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Labb=C3=A9?= Date: Sat, 5 Dec 2020 21:00:28 -0300 Subject: [PATCH 1/4] Catch 'PermissionError' for unreadable directories --- jedi/api/project.py | 7 +++++-- jedi/inference/sys_path.py | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/jedi/api/project.py b/jedi/api/project.py index 41554314..4ba6b7d0 100644 --- a/jedi/api/project.py +++ b/jedi/api/project.py @@ -366,8 +366,11 @@ class Project: def _is_potential_project(path): for name in _CONTAINS_POTENTIAL_PROJECT: - if path.joinpath(name).exists(): - return True + try: + if path.joinpath(name).exists(): + return True + except PermissionError: + continue return False diff --git a/jedi/inference/sys_path.py b/jedi/inference/sys_path.py index 48b9ac89..9dd588db 100644 --- a/jedi/inference/sys_path.py +++ b/jedi/inference/sys_path.py @@ -171,8 +171,11 @@ def _get_paths_from_buildout_script(inference_state, buildout_script_path): def _get_parent_dir_with_file(path: Path, filename): for parent in path.parents: - if parent.joinpath(filename).is_file(): - return parent + try: + if parent.joinpath(filename).is_file(): + return parent + except PermissionError: + continue return None From 12a2d10595fe7b9f7b88c76b75c05fad75cb531b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Labb=C3=A9?= Date: Sun, 6 Dec 2020 15:25:46 -0300 Subject: [PATCH 2/4] Catch 'OSError' instead of just 'PermissionError' --- jedi/api/project.py | 2 +- jedi/inference/sys_path.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jedi/api/project.py b/jedi/api/project.py index 4ba6b7d0..8c438f26 100644 --- a/jedi/api/project.py +++ b/jedi/api/project.py @@ -369,7 +369,7 @@ def _is_potential_project(path): try: if path.joinpath(name).exists(): return True - except PermissionError: + except OSError: continue return False diff --git a/jedi/inference/sys_path.py b/jedi/inference/sys_path.py index 9dd588db..e701686f 100644 --- a/jedi/inference/sys_path.py +++ b/jedi/inference/sys_path.py @@ -174,7 +174,7 @@ def _get_parent_dir_with_file(path: Path, filename): try: if parent.joinpath(filename).is_file(): return parent - except PermissionError: + except OSError: continue return None From 47e60107b29c8c16dfcfe1fd906518f868521e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Labb=C3=A9?= Date: Sun, 6 Dec 2020 15:26:20 -0300 Subject: [PATCH 3/4] Add tests for 'test_get_parent_dir_with_file' and 'test_is_potential_project' --- test/test_api/test_project.py | 19 +++++++++++++++++++ test/test_inference/test_sys_path.py | 10 ++++++++++ 2 files changed, 29 insertions(+) diff --git a/test/test_api/test_project.py b/test/test_api/test_project.py index c8533618..9ca4686c 100644 --- a/test/test_api/test_project.py +++ b/test/test_api/test_project.py @@ -6,6 +6,7 @@ import pytest from ..helpers import get_example_dir, set_cwd, root_dir, test_dir from jedi import Interpreter from jedi.api import Project, get_default_project +from jedi.api.project import _is_potential_project, _CONTAINS_POTENTIAL_PROJECT def test_django_default_project(Script): @@ -160,3 +161,21 @@ def test_complete_search(Script, string, completions, all_scopes): project = Project(test_dir) defs = project.complete_search(string, all_scopes=all_scopes) assert [d.complete for d in defs] == completions + + +@pytest.mark.parametrize( + 'path,expected', [ + (Path(__file__).parents[2], True), # The path of the project + (Path(__file__).parents[1], False), # The path of the tests, not a project + (Path.home(), None) + ] +) +def test_is_potential_project(path, expected): + + if expected is None: + try: + expected = _CONTAINS_POTENTIAL_PROJECT in os.listdir(path) + except OSError: + expected = False + + assert _is_potential_project(path) == expected diff --git a/test/test_inference/test_sys_path.py b/test/test_inference/test_sys_path.py index 2fa0e4df..d22cc2e0 100644 --- a/test/test_inference/test_sys_path.py +++ b/test/test_inference/test_sys_path.py @@ -108,3 +108,13 @@ def test_transform_path_to_dotted(sys_path_, module_path, expected, is_package): module_path = os.path.abspath(module_path) assert sys_path.transform_path_to_dotted(sys_path_, Path(module_path)) \ == (expected, is_package) + + +@pytest.mark.parametrize( + 'path,filename,expected', [ + (Path(__file__).parents[1], "setup.py", Path(__file__).parents[2]), + (Path(__file__).parents[2], os.path.basename(__file__), None) + ] +) +def test_get_parent_dir_with_file(path, filename, expected): + assert sys_path._get_parent_dir_with_file(path, filename) == expected From 6dcae857a7a1ad333508400bda6d3c218e70d5b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Labb=C3=A9?= Date: Mon, 7 Dec 2020 14:50:04 -0300 Subject: [PATCH 4/4] Remove 'test_get_parent_dir_with_file' --- test/test_inference/test_sys_path.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/test/test_inference/test_sys_path.py b/test/test_inference/test_sys_path.py index d22cc2e0..2fa0e4df 100644 --- a/test/test_inference/test_sys_path.py +++ b/test/test_inference/test_sys_path.py @@ -108,13 +108,3 @@ def test_transform_path_to_dotted(sys_path_, module_path, expected, is_package): module_path = os.path.abspath(module_path) assert sys_path.transform_path_to_dotted(sys_path_, Path(module_path)) \ == (expected, is_package) - - -@pytest.mark.parametrize( - 'path,filename,expected', [ - (Path(__file__).parents[1], "setup.py", Path(__file__).parents[2]), - (Path(__file__).parents[2], os.path.basename(__file__), None) - ] -) -def test_get_parent_dir_with_file(path, filename, expected): - assert sys_path._get_parent_dir_with_file(path, filename) == expected