Compare commits

..

1 Commits

Author SHA1 Message Date
Aria Desires
15b69517fb make literally any import from any submodule a re-export unless renamed 2025-11-11 14:53:15 -05:00
8 changed files with 31 additions and 743 deletions

View File

@@ -1,8 +0,0 @@
[
{
"preview": "disabled"
},
{
"preview": "enabled"
}
]

View File

@@ -125,13 +125,6 @@ lambda a, /, c: a
*x: x
)
(
lambda
# comment
*x,
**y: x
)
(
lambda
# comment 1
@@ -142,17 +135,6 @@ lambda a, /, c: a
x
)
(
lambda
# comment 1
*
# comment 2
x,
**y:
# comment 3
x
)
(
lambda # comment 1
* # comment 2
@@ -160,14 +142,6 @@ lambda a, /, c: a
x
)
(
lambda # comment 1
* # comment 2
x,
y: # comment 3
x
)
lambda *x\
:x
@@ -222,17 +196,6 @@ lambda: ( # comment
x
)
(
lambda # 1
# 2
x, # 3
# 4
y
: # 5
# 6
x
)
(
lambda
x,
@@ -241,71 +204,6 @@ lambda: ( # comment
z
)
# Leading
lambda x: (
lambda y: lambda z: x
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ z # Trailing
) # Trailing
# Leading
lambda x: lambda y: lambda z: [
x,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
z
] # Trailing
# Trailing
lambda self, araa, kkkwargs=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs), e=1, f=2, g=2: d
# Regression tests for https://github.com/astral-sh/ruff/issues/8179

View File

@@ -4,7 +4,6 @@ use ruff_python_ast::ExprLambda;
use ruff_text_size::Ranged;
use crate::comments::dangling_comments;
use crate::comments::leading_comments;
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
use crate::other::parameters::ParametersParentheses;
use crate::prelude::*;
@@ -34,45 +33,24 @@ impl FormatNodeRule<ExprLambda> for FormatExprLambda {
if dangling_before_parameters.is_empty() {
write!(f, [space()])?;
} else {
write!(f, [dangling_comments(dangling_before_parameters)])?;
}
group(&format_with(|f: &mut PyFormatter| {
if f.context().node_level().is_parenthesized()
&& (parameters.len() > 1 || !dangling_before_parameters.is_empty())
{
let end_of_line_start = dangling_before_parameters
.partition_point(|comment| comment.line_position().is_end_of_line());
let (same_line_comments, own_line_comments) =
dangling_before_parameters.split_at(end_of_line_start);
write!(
f,
[parameters
.format()
.with_options(ParametersParentheses::Never)]
)?;
dangling_comments(same_line_comments).fmt(f)?;
write!(f, [token(":")])?;
write![
f,
[
soft_line_break(),
leading_comments(own_line_comments),
parameters
.format()
.with_options(ParametersParentheses::Never),
]
]
} else {
parameters
.format()
.with_options(ParametersParentheses::Never)
.fmt(f)
}?;
write!(f, [token(":")])?;
if dangling_after_parameters.is_empty() {
write!(f, [space()])
} else {
write!(f, [dangling_comments(dangling_after_parameters)])
}
}))
.fmt(f)?;
if dangling_after_parameters.is_empty() {
write!(f, [space()])?;
} else {
write!(f, [dangling_comments(dangling_after_parameters)])?;
}
} else {
write!(f, [token(":")])?;

View File

@@ -241,7 +241,7 @@ impl FormatNodeRule<Parameters> for FormatParameters {
let num_parameters = item.len();
if self.parentheses == ParametersParentheses::Never {
write!(f, [format_inner, dangling_comments(dangling)])
write!(f, [group(&format_inner), dangling_comments(dangling)])
} else if num_parameters == 0 {
let mut f = WithNodeLevel::new(NodeLevel::ParenthesizedExpression, f);
// No parameters, format any dangling comments between `()`

View File

@@ -1,6 +1,7 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/lambda.py
snapshot_kind: text
---
## Input
```python
@@ -131,13 +132,6 @@ lambda a, /, c: a
*x: x
)
(
lambda
# comment
*x,
**y: x
)
(
lambda
# comment 1
@@ -148,17 +142,6 @@ lambda a, /, c: a
x
)
(
lambda
# comment 1
*
# comment 2
x,
**y:
# comment 3
x
)
(
lambda # comment 1
* # comment 2
@@ -166,14 +149,6 @@ lambda a, /, c: a
x
)
(
lambda # comment 1
* # comment 2
x,
y: # comment 3
x
)
lambda *x\
:x
@@ -228,17 +203,6 @@ lambda: ( # comment
x
)
(
lambda # 1
# 2
x, # 3
# 4
y
: # 5
# 6
x
)
(
lambda
x,
@@ -247,71 +211,6 @@ lambda: ( # comment
z
)
# Leading
lambda x: (
lambda y: lambda z: x
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ z # Trailing
) # Trailing
# Leading
lambda x: lambda y: lambda z: [
x,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
z
] # Trailing
# Trailing
lambda self, araa, kkkwargs=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs), e=1, f=2, g=2: d
# Regression tests for https://github.com/astral-sh/ruff/issues/8179
@@ -338,22 +237,7 @@ def a():
```
## Outputs
### Output 1
```
indent-style = space
line-width = 88
indent-width = 4
quote-style = Double
line-ending = LineFeed
magic-trailing-comma = Respect
docstring-code = Disabled
docstring-code-line-width = "dynamic"
preview = Disabled
target_version = 3.10
source_type = Python
```
## Output
```python
# Leading
lambda x: x # Trailing
@@ -417,8 +301,7 @@ a = (
)
a = (
lambda
x, # Dangling
lambda x, # Dangling
y: 1
)
@@ -484,13 +367,6 @@ lambda a, /, c: a
*x: x
)
(
lambda
# comment
*x,
**y: x
)
(
lambda
# comment 1
@@ -500,16 +376,6 @@ lambda a, /, c: a
x
)
(
lambda
# comment 1
# comment 2
*x,
**y:
# comment 3
x
)
(
lambda # comment 1
# comment 2
@@ -517,14 +383,6 @@ lambda a, /, c: a
x
)
(
lambda # comment 1
# comment 2
*x,
y: # comment 3
x
)
lambda *x: x
(
@@ -577,87 +435,11 @@ lambda: ( # comment
)
(
lambda # 1
# 2
x, # 3
# 4
y: # 5
# 6
x
)
(
lambda
x,
lambda x,
# comment
y: z
)
# Leading
lambda x: (
lambda y: lambda z: x
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ z # Trailing
) # Trailing
# Leading
lambda x: lambda y: lambda z: [
x,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
z,
] # Trailing
# Trailing
lambda self, araa, kkkwargs=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(
*args, **kwargs
), e=1, f=2, g=2: d
@@ -669,8 +451,7 @@ def a():
c,
d,
e,
f=lambda
self,
f=lambda self,
*args,
**kwargs: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs),
)
@@ -681,365 +462,7 @@ def a():
c,
d,
e,
f=lambda
self,
araa,
kkkwargs,
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
args,
kwargs,
e=1,
f=2,
g=2: d,
g=10,
)
```
### Output 2
```
indent-style = space
line-width = 88
indent-width = 4
quote-style = Double
line-ending = LineFeed
magic-trailing-comma = Respect
docstring-code = Disabled
docstring-code-line-width = "dynamic"
preview = Enabled
target_version = 3.10
source_type = Python
```
```python
# Leading
lambda x: x # Trailing
# Trailing
# Leading
lambda x, y: x # Trailing
# Trailing
# Leading
lambda x, y: x, y # Trailing
# Trailing
# Leading
lambda x, /, y: x # Trailing
# Trailing
# Leading
lambda x: lambda y: lambda z: x # Trailing
# Trailing
# Leading
lambda x: lambda y: lambda z: (x, y, z) # Trailing
# Trailing
# Leading
lambda x: lambda y: lambda z: (x, y, z) # Trailing
# Trailing
# Leading
lambda x: lambda y: lambda z: (
x,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
z,
) # Trailing
# Trailing
a = (
lambda: # Dangling
1
)
a = (
lambda
x, # Dangling
y: 1
)
# Regression test: lambda empty arguments ranges were too long, leading to unstable
# formatting
(
lambda: ( #
),
)
# lambda arguments don't have parentheses, so we never add a magic trailing comma ...
def f(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = lambda x: y,
):
pass
# ...but we do preserve a trailing comma after the arguments
a = lambda b,: 0
lambda a,: 0
lambda *args,: 0
lambda **kwds,: 0
lambda a, *args,: 0
lambda a, **kwds,: 0
lambda *args, b,: 0
lambda *, b,: 0
lambda *args, **kwds,: 0
lambda a, *args, b,: 0
lambda a, *, b,: 0
lambda a, *args, **kwds,: 0
lambda *args, b, **kwds,: 0
lambda *, b, **kwds,: 0
lambda a, *args, b, **kwds,: 0
lambda a, *, b, **kwds,: 0
lambda a, /: a
lambda a, /, c: a
# Dangling comments without parameters.
(
lambda: # 3
None
)
(
lambda:
# 3
None
)
(
lambda: # 1
# 2
# 3
# 4
None # 5
)
(
lambda
# comment
*x: x
)
(
lambda
# comment
*x,
**y: x
)
(
lambda
# comment 1
# comment 2
*x:
# comment 3
x
)
(
lambda
# comment 1
# comment 2
*x,
**y:
# comment 3
x
)
(
lambda # comment 1
# comment 2
*x: # comment 3
x
)
(
lambda # comment 1
# comment 2
*x,
y: # comment 3
x
)
lambda *x: x
(
lambda
# comment
*x: x
)
lambda: ( # comment
x
)
(
lambda: # comment
x
)
(
lambda:
# comment
x
)
(
lambda: # comment
x
)
(
lambda:
# comment
x
)
(
lambda: # comment
( # comment
x
)
)
(
lambda # 1
# 2
x: # 3
# 4
# 5
# 6
x
)
(
lambda # 1
# 2
x, # 3
# 4
y: # 5
# 6
x
)
(
lambda
x,
# comment
y: z
)
# Leading
lambda x: (
lambda y: lambda z: x
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ z # Trailing
) # Trailing
# Leading
lambda x: lambda y: lambda z: [
x,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
z,
] # Trailing
# Trailing
lambda self, araa, kkkwargs=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(
*args, **kwargs
), e=1, f=2, g=2: d
# Regression tests for https://github.com/astral-sh/ruff/issues/8179
def a():
return b(
c,
d,
e,
f=lambda
self,
*args,
**kwargs: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs),
)
def a():
return b(
c,
d,
e,
f=lambda
self,
f=lambda self,
araa,
kkkwargs,
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,

View File

@@ -265,12 +265,10 @@ Similarly, for an `__init__.pyi` (stub) file, importing a non-exported name shou
but the inference would be `Unknown`.
```py
# error: 15 "Module `a` has no member `Foo`"
# error: 20 "Module `a` has no member `c`"
from a import Foo, c, foo
reveal_type(Foo) # revealed: Unknown
reveal_type(c) # revealed: Unknown
reveal_type(Foo) # revealed: <class 'Foo'>
reveal_type(c) # revealed: <module 'a.b.c'>
reveal_type(foo) # revealed: <module 'a.foo'>
```

View File

@@ -25,7 +25,7 @@ This file currently covers the following details:
wild. Equivalent imports like `from whatever.thispackage import a` also introduce a re-export
(this has essentially zero ecosystem impact, we just felt it was more consistent). The only way
to opt out of this is to rename the import to something else (`from . import a as b`).
`from .a import b` and equivalent does *not* introduce a re-export.
`from .a import b` and equivalent also introduces a re-export, yes this is chaos.
Note: almost all tests in here have a stub and non-stub version, because we're interested in both
defining symbols *at all* and re-exporting them.
@@ -247,10 +247,8 @@ reveal_type(mypackage.submodule) # revealed: Unknown
reveal_type(mypackage.submodule.nested) # revealed: Unknown
# error: "has no member `submodule`"
reveal_type(mypackage.submodule.nested.X) # revealed: Unknown
# error: "has no member `nested`"
reveal_type(mypackage.nested) # revealed: Unknown
# error: "has no member `nested`"
reveal_type(mypackage.nested.X) # revealed: Unknown
reveal_type(mypackage.nested) # revealed: <module 'mypackage.submodule.nested'>
reveal_type(mypackage.nested.X) # revealed: int
```
### In Non-Stub
@@ -325,10 +323,8 @@ reveal_type(mypackage.submodule) # revealed: Unknown
reveal_type(mypackage.submodule.nested) # revealed: Unknown
# error: "has no member `submodule`"
reveal_type(mypackage.submodule.nested.X) # revealed: Unknown
# error: "has no member `nested`"
reveal_type(mypackage.nested) # revealed: Unknown
# error: "has no member `nested`"
reveal_type(mypackage.nested.X) # revealed: Unknown
reveal_type(mypackage.nested) # revealed: <module 'mypackage.submodule.nested'>
reveal_type(mypackage.nested.X) # revealed: int
```
### In Non-Stub

View File

@@ -1484,6 +1484,9 @@ impl<'ast> Visitor<'ast> for SemanticIndexBuilder<'_, 'ast> {
&& !self.seen_submodule_imports.contains(direct_submodule)
&& self.current_scope().is_global()
{
// Record that this is equivalent to `from .a import ...`
is_self_import = true;
self.seen_submodule_imports
.insert(direct_submodule.to_owned());