mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-22 11:25:26 +00:00
Preserve trailing semicolon for Notebooks (#8590)
## Summary This PR updates the formatter to preserve trailing semicolon for Jupyter Notebooks. The motivation behind the change is that semicolons in notebooks are typically used to hide the output, for example when plotting. This is highlighted in the linked issue. The conditions required as to when the trailing semicolon should be preserved are: 1. It should be a top-level statement which is last in the module. 2. For statement, it can be either assignment, annotated assignment, or augmented assignment. Here, the target should only be a single identifier i.e., multiple assignments or tuple unpacking isn't considered. 3. For expression, it can be any. ## Test Plan Add a new integration test in `ruff_cli`. The test notebook basically acts as a document as to which trailing semicolons are to be preserved. fixes: #8254
This commit is contained in:
parent
a7dbe9d670
commit
3e00ddce38
11 changed files with 945 additions and 25 deletions
|
@ -19,7 +19,7 @@ impl<'a> PyFormatContext<'a> {
|
|||
options,
|
||||
contents,
|
||||
comments,
|
||||
node_level: NodeLevel::TopLevel,
|
||||
node_level: NodeLevel::TopLevel(TopLevelStatementPosition::Other),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,12 +68,21 @@ impl Debug for PyFormatContext<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
/// What's the enclosing level of the outer node.
|
||||
/// The position of a top-level statement in the module.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
|
||||
pub(crate) enum TopLevelStatementPosition {
|
||||
/// This is the last top-level statement in the module.
|
||||
Last,
|
||||
/// Any other top-level statement.
|
||||
#[default]
|
||||
Other,
|
||||
}
|
||||
|
||||
/// What's the enclosing level of the outer node.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub(crate) enum NodeLevel {
|
||||
/// Formatting statements on the module level.
|
||||
#[default]
|
||||
TopLevel,
|
||||
TopLevel(TopLevelStatementPosition),
|
||||
|
||||
/// Formatting the body statements of a [compound statement](https://docs.python.org/3/reference/compound_stmts.html#compound-statements)
|
||||
/// (`if`, `while`, `match`, etc.).
|
||||
|
@ -86,6 +95,12 @@ pub(crate) enum NodeLevel {
|
|||
ParenthesizedExpression,
|
||||
}
|
||||
|
||||
impl Default for NodeLevel {
|
||||
fn default() -> Self {
|
||||
Self::TopLevel(TopLevelStatementPosition::Other)
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeLevel {
|
||||
/// Returns `true` if the expression is in a parenthesized context.
|
||||
pub(crate) const fn is_parenthesized(self) -> bool {
|
||||
|
@ -94,6 +109,11 @@ impl NodeLevel {
|
|||
NodeLevel::Expression(Some(_)) | NodeLevel::ParenthesizedExpression
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns `true` if this is the last top-level statement in the module.
|
||||
pub(crate) const fn is_last_top_level_statement(self) -> bool {
|
||||
matches!(self, NodeLevel::TopLevel(TopLevelStatementPosition::Last))
|
||||
}
|
||||
}
|
||||
|
||||
/// Change the [`NodeLevel`] of the formatter for the lifetime of this struct
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue