Skip to content

Fix autoimport.sqlite deriving module names from non-package folders#848

Open
deepakganesh78 wants to merge 1 commit into
python-rope:masterfrom
deepakganesh78:fix/issue823-autoimport-modname
Open

Fix autoimport.sqlite deriving module names from non-package folders#848
deepakganesh78 wants to merge 1 commit into
python-rope:masterfrom
deepakganesh78:fix/issue823-autoimport-modname

Conversation

@deepakganesh78

Copy link
Copy Markdown

Fixes #823

Root cause

AutoImport._resource_to_module in rope/contrib/autoimport/sqlite.py derived a module's name from its path relative to the project root:

resource_modname = get_modname_from_path(
    resource_path, self.project_package.path, add_package_name=False
)

get_modname_from_path simply joins every intermediate directory name, so it includes folders that are not Python packages. For a layout like

<root>/shared/src/shared/__init__.py
<root>/shared/src/shared/documents.py

where shared/ (top) and src/ are not packages, the sqlite backend reported the module as shared.src.shared.documents instead of the correct shared.documents.

The pickle backend does not have this bug because it uses libutils.modname, which walks up the package hierarchy from the resource and stops at the first directory without an __init__.py.

Fix

Use libutils.modname(resource) in the sqlite backend's _resource_to_module, matching the pickle backend so both agree and intermediate non-package folders are excluded. The now-unused get_modname_from_path import is removed.

Tests

Added test_resource_to_module_skips_non_package_folders which builds a src/mypkg/documents.py structure (where src/ is not a package) and asserts the derived modname is mypkg.documents. It fails on master (src.mypkg.documents) and passes with this change.

Full suite: 2092 passed, 8 skipped, 5 xfailed in a per-repo venv.

…ython-rope#823)

`AutoImport._resource_to_module` computed a module's name via
`get_modname_from_path(resource_path, project_package.path)`, i.e. the
resource's path relative to the project root. This blindly joins every
intermediate directory name, so a module under a non-package folder such
as `<root>/shared/src/shared/documents.py` was reported as
`shared.src.shared.documents` instead of the correct `shared.documents`.

The pickle backend does not have this problem because it derives the name
with `libutils.modname`, which walks up the package hierarchy and stops at
the first directory without an `__init__.py`. Use the same helper in the
sqlite backend so both backends agree and intermediate non-package folders
are excluded from the module name.

Fixes python-rope#823
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

autoimport.sqlite uses the relative path as module name

1 participant