[feature-request] Require first-party imports to target highest exporting non-ancestor module
- Dominant language
- Rust
- Stars
- 49.7k
- Forks
- 2.4k
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 458
Description
A symbol can be defined in one module and re-exported from several others. When importing a symbol from an external typed library, the convention is to import from as close to the root as possible. This is how popular auto-import resolution tools work (see my very similar post in [this pylance discussion](https://github.com/microsoft/pylance-release/discussions/3050#discussioncomment-3197660):
>If the same name is exported from multiple modules, the auto-import logic in pyright and pylance prefer the shortest module path. Only the shortest path is listed in the completion list, and the longer paths are de-duped.
In large projects, sometimes you have big submodules that you want to provide an "internal public" interface for-- e.g. if you have a large submodule `project.foo`, you might want project-internal code to import only from `project.foo` itself, rather than `project.foo.*` submodules.
I'd like to suggest that `ruff` offer a rule that enforces this by requiring internal imports resolve to the shortest module that exposes a symbol. So:
```
### project/foo/__init__.py
# redundant alias is necessary to expose `BAR` as public for `project.foo`
from .bar import BAR as BAR
### project/foo/bar.py
BAR = "BAR"
### project/baz.py
from project.foo.bar import BAR # ERROR: should import from project.foo instead
```
Contributor guide
Research direction
No Ruff files, tests, or entry points are named in the issue. Start by locating Ruff’s existing first-party import resolution and related rule tests, then compare the reported project/foo example with current behavior. Done means internal imports resolve to the shortest non-ancestor module that exposes the symbol.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust
- Domain
- developer-experience, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100