facebook / facebook/pyrefly

search_path: package in later entry shadows module in earlier entry

Open
#3,407 6 comments 0 reactions 1 assignee Claimed by @connernilsen View on GitHub
configuration
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.