search_path: package in later entry shadows module in earlier entry
- Dominant language
- Rust
- Stars
- 7k
- Forks
- 516
- PR merge metrics
- No merged PRs in 30d
Description
### Describe the Bug
**pyrefly version:** 1.0.0
**Related:** #1691
## Summary
When two `search_path` entries both provide a name — one as a module (`.py` file) and one as a package (directory with `__init__.py`) — pyrefly picks the **package**, regardless of which entry comes first. Python's own import system picks the **first match**, whether module or package.
## Minimal reproduction
https://github.com/kain88-de/pyrefly-bug
```
src/myapp/widget.py # defines WidgetHandler
src/myapp/main.py # from widget import WidgetHandler
src/test/widget/__init__.py # empty package, same name
```
```toml
[tool.pyrefly]
search_path = ["src/myapp", "src/test"]
```
```
$ pyrefly check
ERROR Could not import `WidgetHandler` from `widget` [missing-module-attribute]
--> src/myapp/main.py:1:20
|
1 | from widget import WidgetHandler
| ^^^^^^^^^^^^^
```
## Expected behaviour
`search_path[0]` (`src/myapp`) is checked first. `src/myapp/widget.py` is found and provides `WidgetHandler`. No error.
This matches Python's own behaviour:
```python
import sys
sys.path = ["src/myapp", "src/test"]
from widget import WidgetHandler # finds src/myapp/widget.py — correct
```
## Actual behaviour
pyrefly resolves `widget` to `src/test/widget/__init__.py` (the empty package in `search_path[1]`) instead of `src/myapp/widget.py` (the module in `search_path[0]`), then reports `missing-module-attribute` because `WidgetHandler` is not in the empty `__init__.py`.
## Comparison with other type checkers
Running `./check.sh` from the reproduction repo:
```
mypy → PASS (no issues found)
basedpyright → PASS (0 errors, 0 warnings, 0 notes)
pyrefly → FAIL (missing-module-attribute on WidgetHandler)
```
Both mypy and basedpyright follow sys.path order and resolve correctly.
### Sandbox Link
_No response_
### (Only applicable for extension issues) IDE Information
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.