diff --git a/CHANGELOG.md b/CHANGELOG.md index ba328bd9a..11052c63d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - #895 patchedast Starred and keyword now consumes their syntactically expected and ** (@lieryan) - #896 patchedast cleanup and refactoring (@lieryan) - #905 Ignore `node_modules` directories by default when scanning project files and source folders. (@marcoeangeli) +- #922 Classify autoimport project sources by path containment (@marlon-costa-dc) - #926, #929 Raise RefactoringError instead of IndexError/ModuleSyntaxError when extracting an empty or whitespace-only region (@aliassar) - #933 Add type annotations to project.py (@lieryan) - #119, #928 Fix IndexError in rename and find occurrences when a `from` import is the last thing in a module without a trailing newline (@mcepl) diff --git a/rope/contrib/autoimport/utils.py b/rope/contrib/autoimport/utils.py index 11ee6f20e..324ea3173 100644 --- a/rope/contrib/autoimport/utils.py +++ b/rope/contrib/autoimport/utils.py @@ -49,7 +49,9 @@ def get_package_source( """Detect the source of a given package. Rudimentary implementation.""" if name in sys.builtin_module_names: return Source.BUILTIN - if project is not None and project.address in str(package): + if project is not None and package.resolve().is_relative_to( + project.root.pathlib.resolve() + ): return Source.PROJECT if "site-packages" in package.parts: return Source.SITE_PACKAGE diff --git a/ropetest/contrib/autoimport/utilstest.py b/ropetest/contrib/autoimport/utilstest.py index 511e1a541..d807debe2 100644 --- a/ropetest/contrib/autoimport/utilstest.py +++ b/ropetest/contrib/autoimport/utilstest.py @@ -14,6 +14,25 @@ def test_get_package_source_not_project(mod1_path): assert utils.get_package_source(mod1_path, None, "") == Source.UNKNOWN +def test_get_package_source_project_prefix_is_not_ancestry(project): + sibling = Path(project.address + "-other") / "module.py" + assert utils.get_package_source(sibling, project, "module") == Source.UNKNOWN + + +def test_get_package_source_project_sibling(project): + sibling = project.root.pathlib.with_name(project.root.pathlib.name + "-other") + sibling.mkdir() + module = sibling / "outside.py" + module.touch() + try: + assert utils.get_package_source(module, project, "outside") == Source.UNKNOWN + escaped = project.root.pathlib / ".." / sibling.name / module.name + assert utils.get_package_source(escaped, project, "outside") == Source.UNKNOWN + finally: + module.unlink() + sibling.rmdir() + + def test_get_package_source_pytest(example_external_package_path): # pytest is not installed as part of the standard library # but should be installed into site_packages,