bazel-contrib / bazel-contrib/rules_mypy
'Module has no attribute "xxx"' when mixing `py_binary` deps and `__init__` reexports
- Dominant language
- Starlark
- Stars
- 12
- Forks
- 13
- PR merge metrics
- No merged PRs in 30d
Description
Thanks for the great work on this project! We've adopted it throughout parts of our monorepo and we really like it.
While trying to expand our usage of `rules_mypy`, I've run into an issue which I believe is a bug. I was able to produce a minimal example, which seems to have something to do with `__init__.py` files that depend on `py_binary` targets (rather than `py_library`).
For clarity, `rules_python` allows depending on `py_binary` targets as if they were `py_library`s. There isn't really any difference, except the presence of a `if __name__ == "__main__":` block which is ignored. We have several library files with small main sections at the bottom for ad-hoc debugging.
# MRE
`example/BUILD.bazel`
```
py_binary(
name = "main",
srcs = ["main.py"],
deps = ["//example/foo:__init__"],
)
```
`example/main.py`
```python
import example.foo as foo
if __name__ == "__main__":
print(foo.do_something())
```
`example/foo/BUILD.bazel`
```
py_library(
name = "__init__",
srcs = ["__init__.py"],
deps = [":a"],
)
py_binary(
name = "a",
srcs = ["a.py"],
)
```
`example/foo/__init__.py`
```python
from example.foo.a import do_something
__all__ = ["do_something"]
```
`example/foo/a.py`
```python
def do_something():
return "hello"
if __name__ == "__main__":
print(do_something())
```
## Result
When I run `bazel build //example/...` I see the following error:
```bash
example/main.py:4: error: Module has no attribute "do_something" [attr-defined]
```
Removing the `if __name__ == "__main__"` from `a.py` and switching to a `py_library` target causes this example to succeed. Outside of bazel, mypy does not complain about either case.
Contributor guide
Research direction
Start with the minimal reproduction in example/BUILD.bazel, example/main.py, example/foo/BUILD.bazel, example/foo/__init__.py, and example/foo/a.py. Run bazel build //example/... and compare the py_binary dependency case with the py_library case; done means the reproduced import no longer reports the missing do_something attribute.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- build-system, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 52/100