From 41b0252200a3d03f327f3c3f85bc672e730f0705 Mon Sep 17 00:00:00 2001 From: akamat10 Date: Sun, 29 Sep 2024 21:31:45 -0400 Subject: [PATCH 1/8] Change order of search path --- astroid/modutils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/astroid/modutils.py b/astroid/modutils.py index bf84b3b933..957be61cbe 100644 --- a/astroid/modutils.py +++ b/astroid/modutils.py @@ -278,7 +278,7 @@ def modpath_from_file_with_callback( filename = os.path.expanduser(_path_from_filename(filename)) paths_to_check = sys.path.copy() if path: - paths_to_check += path + paths_to_check = path + paths_to_check for pathname in itertools.chain( paths_to_check, map(_cache_normalize_path, paths_to_check) ): From 2228fd098aaeb5f3fd95c978d6630ebb755f2c48 Mon Sep 17 00:00:00 2001 From: akamat10 Date: Sat, 5 Oct 2024 22:04:55 -0400 Subject: [PATCH 2/8] Update test --- tests/test_modutils.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/test_modutils.py b/tests/test_modutils.py index 85452b0f77..96d0751c44 100644 --- a/tests/test_modutils.py +++ b/tests/test_modutils.py @@ -175,6 +175,41 @@ def test_import_symlink_with_source_outside_of_path(self) -> None: finally: os.remove(linked_file_name) + def test_modpath_from_file_path_order(self) -> None: + """Test for ordering of paths. + The test does the following: + 1. Add a tmp directory to beginning of sys.path + 2. Create a module file in sub directory of tmp directory + 3. If the sub directory is passed as additional directory, module name + should be relative to the subdirectory since additional directory has + higher precedence.""" + orig_path = sys.path.copy() + with tempfile.TemporaryDirectory() as tmp_dir: + try: + mod_name = "module" + sub_dirname = "subdir" + sub_dir = tmp_dir + "/" + sub_dirname + os.mkdir(sub_dir) + module_file = f"{sub_dir}/{mod_name}.py" + + sys.path.insert(0, str(tmp_dir)) + with open(module_file, "w+", encoding="utf-8"): + pass + + # Without additional directory, return relative to tmp_dir + self.assertEqual( + modutils.modpath_from_file(module_file), [sub_dirname, mod_name] + ) + + # With sub directory as additional directory, return relative to + # sub directory + self.assertEqual( + modutils.modpath_from_file(f"{sub_dir}/{mod_name}.py", [sub_dir]), + [mod_name], + ) + finally: + sys.path[:] = orig_path + def test_import_symlink_both_outside_of_path(self) -> None: with tempfile.NamedTemporaryFile() as tmpfile: linked_file_name = os.path.join(tempfile.gettempdir(), "symlinked_file.py") From 229d31c423548abcd18b8659b1a1fb230c001b0b Mon Sep 17 00:00:00 2001 From: akamat10 Date: Sat, 5 Oct 2024 22:10:59 -0400 Subject: [PATCH 3/8] Update Changelog --- ChangeLog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 73cc908ebc..5c5f86ac9f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,7 +20,8 @@ What's New in astroid 3.3.6? ============================ Release date: TBA - +* Change precedece of `path` arg in `modpath_from_file_with_callback` to be higher than `sys.path` + What's New in astroid 3.3.5? ============================ From e5e13641f7c8dfa5f4a32aa3fd32dabdbef7b950 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 6 Oct 2024 02:11:25 +0000 Subject: [PATCH 4/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5c5f86ac9f..719499cd82 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,7 +21,7 @@ What's New in astroid 3.3.6? Release date: TBA * Change precedece of `path` arg in `modpath_from_file_with_callback` to be higher than `sys.path` - + What's New in astroid 3.3.5? ============================ From 7f388fca4fd6528cd5ed0a36e442e3d4c520472a Mon Sep 17 00:00:00 2001 From: akamat10 Date: Sat, 5 Oct 2024 22:14:20 -0400 Subject: [PATCH 5/8] Update Changelog --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 719499cd82..2d9266ee85 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,7 +20,7 @@ What's New in astroid 3.3.6? ============================ Release date: TBA -* Change precedece of `path` arg in `modpath_from_file_with_callback` to be higher than `sys.path` +* Fix precedence of `path` arg in `modpath_from_file_with_callback` to be higher than `sys.path` What's New in astroid 3.3.5? From 0ee04e73e7c6a392d2220a8cff5feeb2c53a32f8 Mon Sep 17 00:00:00 2001 From: akamat10 Date: Mon, 7 Oct 2024 22:34:37 -0400 Subject: [PATCH 6/8] Create and use context manager for sys.path augmentation --- astroid/util.py | 23 +++++++++++++++++++++++ tests/test_modutils.py | 9 +++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/astroid/util.py b/astroid/util.py index 510b81cc13..3a7432bce2 100644 --- a/astroid/util.py +++ b/astroid/util.py @@ -5,6 +5,8 @@ from __future__ import annotations +import contextlib +import sys import warnings from typing import TYPE_CHECKING, Any, Final, Literal @@ -157,3 +159,24 @@ def safe_infer( return None # there is some kind of ambiguity except StopIteration: return value + +def _augment_sys_path(additional_paths: Sequence[str]) -> list[str]: + original = list(sys.path) + changes = [] + seen = set() + for additional_path in additional_paths: + if additional_path not in seen: + changes.append(additional_path) + seen.add(additional_path) + + sys.path[:] = changes + sys.path + return original + +@contextlib.contextmanager +def augmented_sys_path(additional_paths: Sequence[str]) -> Iterator[None]: + """Augment 'sys.path' by adding entries from additional_paths.""" + original = _augment_sys_path(additional_paths) + try: + yield + finally: + sys.path[:] = original diff --git a/tests/test_modutils.py b/tests/test_modutils.py index 96d0751c44..6b815d986c 100644 --- a/tests/test_modutils.py +++ b/tests/test_modutils.py @@ -22,6 +22,7 @@ from astroid import modutils from astroid.const import PY310_PLUS from astroid.interpreter._import import spec +from astroid.util import augmented_sys_path from . import resources @@ -178,21 +179,19 @@ def test_import_symlink_with_source_outside_of_path(self) -> None: def test_modpath_from_file_path_order(self) -> None: """Test for ordering of paths. The test does the following: - 1. Add a tmp directory to beginning of sys.path + 1. Add a tmp directory to beginning of sys.path via augmented_sys_path 2. Create a module file in sub directory of tmp directory 3. If the sub directory is passed as additional directory, module name should be relative to the subdirectory since additional directory has higher precedence.""" - orig_path = sys.path.copy() with tempfile.TemporaryDirectory() as tmp_dir: - try: + with augmented_sys_path([tmp_dir]): mod_name = "module" sub_dirname = "subdir" sub_dir = tmp_dir + "/" + sub_dirname os.mkdir(sub_dir) module_file = f"{sub_dir}/{mod_name}.py" - sys.path.insert(0, str(tmp_dir)) with open(module_file, "w+", encoding="utf-8"): pass @@ -207,8 +206,6 @@ def test_modpath_from_file_path_order(self) -> None: modutils.modpath_from_file(f"{sub_dir}/{mod_name}.py", [sub_dir]), [mod_name], ) - finally: - sys.path[:] = orig_path def test_import_symlink_both_outside_of_path(self) -> None: with tempfile.NamedTemporaryFile() as tmpfile: From 7374791773254064cffd8fe41f0a4a2b3ab3416a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 02:35:52 +0000 Subject: [PATCH 7/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- astroid/util.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/astroid/util.py b/astroid/util.py index 3a7432bce2..0292abb26d 100644 --- a/astroid/util.py +++ b/astroid/util.py @@ -160,6 +160,7 @@ def safe_infer( except StopIteration: return value + def _augment_sys_path(additional_paths: Sequence[str]) -> list[str]: original = list(sys.path) changes = [] @@ -172,6 +173,7 @@ def _augment_sys_path(additional_paths: Sequence[str]) -> list[str]: sys.path[:] = changes + sys.path return original + @contextlib.contextmanager def augmented_sys_path(additional_paths: Sequence[str]) -> Iterator[None]: """Augment 'sys.path' by adding entries from additional_paths.""" From 826fe0cc96101223c0a32627f39d2707615b0273 Mon Sep 17 00:00:00 2001 From: akamat10 Date: Mon, 7 Oct 2024 22:40:05 -0400 Subject: [PATCH 8/8] Fix pylint issues --- astroid/util.py | 1 + 1 file changed, 1 insertion(+) diff --git a/astroid/util.py b/astroid/util.py index 0292abb26d..3ddbc09040 100644 --- a/astroid/util.py +++ b/astroid/util.py @@ -8,6 +8,7 @@ import contextlib import sys import warnings +from collections.abc import Iterator, Sequence from typing import TYPE_CHECKING, Any, Final, Literal from astroid.exceptions import InferenceError