incompatible_default_to_explicit_init_py
- Dominant language
- Java
- Stars
- 25.8k
- Forks
- 4.6k
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 72
Description
**Flag:** `--incompatible_default_to_explicit_init_py`
**Available since:** 1.2
**Will be flipped in:** ???
**Feature tracking issue:** #7386
## Motivation
For `py_binary` and `py_test` targets, Bazel currently automatically creates empty `__init__.py` files in the runfiles tree wherever it is needed to import Python files. This is done in the ancestor directories of paths that contain Python files, up to but not including the top-level workspace directory, where an explicit `__init__.py` file must be used. Thus for example, if your `py_binary` target depends (directly or indirectly) on `//pkg/subpkg:foo.py`, but your workspace has no `//pkg:__init__.py` or `//pkg/subpkg:__init__.py` (or these files were not declared as dependencies), your target will behave as if they exist and are empty.
We want to deprecate this because it is magic at a distance. Python programmers are already used to creating `__init__.py` files in their source trees, so doing it behind their backs introduces confusion and changes the semantics of imports (since these directories will no longer be considered namespace packages). Eliminating this behavior also should allow us to remove some special runfiles logic.
## Change
`py_binary` and `py_test` already have a `legacy_create_init` attribute which effectively defaults to true. With this flag enabled, the effective default becomes false. You can still opt back into true for targets that need it, but in the future we will do another incompatible change to remove the attribute altogether.
I say "effectively" true or false because before this flag was added, the attribute was an actual boolean, and now it is a tristate that defaults to auto, where auto means consult this flag. It is possible some .bzl macro that tries to introspect a `py_binary` or `py_test`'s attributes dictionary (via `native.existing_rules`) will observe this change in attribute type, even without enabling the incompatible flag.
## Migration
If your build depended on having empty `__init__.py` files automatically created, you should explicitly create these files in your source tree and add them to the `srcs` of the relevant `py_library` targets. If for whatever reason that's not feasible at the moment, you can temporarily opt out of this change on a per-target basis even when the flag itself is enabled, by explicitly adding `legacy_create_init = True` to your targets.
## Timing
It is currently unclear how burdensome migration will be, so we do not yet know when we will flip this flag.
Contributor guide
Assessment
This issue has not been assessed yet.