mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-20 04:29:47 +00:00
[ty] Make implicit submodule imports only occur in global scope (#21370)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (${{ github.repository == 'astral-sh/ruff' && 'depot-windows-2022-16' || 'windows-latest' }}) (push) Blocked by required conditions
CI / cargo test (macos-latest) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / ty completion evaluation (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks instrumented (ruff) (push) Blocked by required conditions
CI / benchmarks instrumented (ty) (push) Blocked by required conditions
CI / benchmarks walltime (medium|multithreaded) (push) Blocked by required conditions
CI / benchmarks walltime (small|large) (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (${{ github.repository == 'astral-sh/ruff' && 'depot-windows-2022-16' || 'windows-latest' }}) (push) Blocked by required conditions
CI / cargo test (macos-latest) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / ty completion evaluation (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks instrumented (ruff) (push) Blocked by required conditions
CI / benchmarks instrumented (ty) (push) Blocked by required conditions
CI / benchmarks walltime (medium|multithreaded) (push) Blocked by required conditions
CI / benchmarks walltime (small|large) (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
This loses any ability to have "per-function" implicit submodule imports, to avoid the "ok but now we need per-scope imports" and "ok but this should actually introduce a global that only exists during this function" problems. A simple and clean implementation with no weird corners. Fixes https://github.com/astral-sh/ty/issues/1482
This commit is contained in:
parent
2bc6c78e26
commit
9ce3230add
3 changed files with 16 additions and 29 deletions
|
|
@ -9,18 +9,16 @@ This file currently covers the following details:
|
|||
- **froms are locals**: a `from..import` can only define locals, it does not have global
|
||||
side-effects. Specifically any submodule attribute `a` that's implicitly introduced by either
|
||||
`from .a import b` or `from . import a as b` (in an `__init__.py(i)`) is a local and not a
|
||||
global. If you do such an import at the top of a file you won't notice this. However if you do
|
||||
such an import in a function, that means it will only be function-scoped (so you'll need to do
|
||||
it in every function that wants to access it, making your code less sensitive to execution
|
||||
order).
|
||||
global. However we only introduce this symbol if the `from..import` is in global-scope. This
|
||||
means imports at the start of a file work as you'd expect, while imports in a function don't
|
||||
introduce submodule attributes.
|
||||
|
||||
- **first from first serve**: only the *first* `from..import` in an `__init__.py(i)` that imports a
|
||||
particular direct submodule of the current package introduces that submodule as a local.
|
||||
Subsequent imports of the submodule will not introduce that local. This reflects the fact that
|
||||
in actual python only the first import of a submodule (in the entire execution of the program)
|
||||
introduces it as an attribute of the package. By "first" we mean "the first time in this scope
|
||||
(or any parent scope)". This pairs well with the fact that we are specifically introducing a
|
||||
local (as long as you don't accidentally shadow or overwrite the local).
|
||||
introduces it as an attribute of the package. By "first" we mean "the first time in global
|
||||
scope".
|
||||
|
||||
- **dot re-exports**: `from . import a` in an `__init__.pyi` is considered a re-export of `a`
|
||||
(equivalent to `from . import a as a`). This is required to properly handle many stubs in the
|
||||
|
|
@ -949,9 +947,8 @@ def funcmod(x: int) -> int:
|
|||
|
||||
## LHS `from` Imports In Functions
|
||||
|
||||
If a `from` import occurs in a function, LHS symbols should only be visible in that function. This
|
||||
very blatantly is not runtime-accurate, but exists to try to force you to write "obviously
|
||||
deterministically correct" imports instead of relying on execution order.
|
||||
If a `from` import occurs in a function, we simply ignore its LHS effects to avoid modeling
|
||||
execution-order-specific behaviour (and to discourage people writing code that has it).
|
||||
|
||||
`mypackage/__init__.py`:
|
||||
|
||||
|
|
@ -959,13 +956,14 @@ deterministically correct" imports instead of relying on execution order.
|
|||
def run1():
|
||||
from .funcmod import other
|
||||
|
||||
# TODO: this would be nice to support
|
||||
# error: [unresolved-reference]
|
||||
funcmod.funcmod(1)
|
||||
|
||||
def run2():
|
||||
from .funcmod import other
|
||||
|
||||
# TODO: this is just a bug! We only register the first
|
||||
# import of `funcmod` in the entire file, and not per-scope!
|
||||
# TODO: this would be nice to support
|
||||
# error: [unresolved-reference]
|
||||
funcmod.funcmod(2)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue