Skip to content

Conversation

@ShaharNaveh
Copy link
Contributor

Summary

At RustPython we want to fully replace https://github.com/RustPython/RustPython/blob/153d0eef51ea109d8a322fd351678847b2fb8fe2/compiler/codegen/src/unparse.rs.

Currently our only regression when using Ruff's unparsing, is forcing tuple parentheses.

Test Plan

Added tests

@github-actions
Copy link
Contributor

github-actions bot commented Oct 23, 2025

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

/// Like [`round_trip`] but configure the [`Generator`] with the requested
/// `indentation`, `line_ending` and `preferred_quote` settings.
/// `indentation`, `line_ending`, `preferred_quote` and `forced_tuple_parentheses` settings.
fn round_trip_with(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The signature here becomes a bit awkward. Should we introduce a GeneratorOptions struct with:

  • indentation
  • line_ending
  • preferred_quote: Option
  • forced_tuple_parentheses

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good

@ShaharNaveh ShaharNaveh changed the title Optionally force tuple parentheses for ruff_python_codegen::Generator Configurable "unparse mode" for ruff_python_codegen::Generator Oct 24, 2025
Comment on lines 68 to 72
pub enum UnparseMode {
#[default]
Default,
Ast,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think just Mode is enough. I'd rename Ast to AstUnparse and document that the intent is to emit the same output as Python's ast.unparse method

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

np, would you prefer this documented at the enum variant, or the Generator::with_unparse_mode?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest documenting it at the variant level

Comment on lines 185 to 188
let quote_style = match self.unparse_mode {
UnparseMode::Default => flags.quote_style(),
UnparseMode::Ast => Quote::Single,
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could make this a method on Mode insteada of repeating it at every call site

impl Mode {
	const fn quote_style(self, flags: AnyStringFlags) -> QuoteStyle {
		...
	}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that it would make sense to move the tuple precedence value to it's own method as well, right? although it's only used once it kind of makes more sense to me for some reason. I'll do that if you think it's a good idea

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm less concerned about the tuple case because it's used exactly once.

/// - [`Default`](`Mode::Default`): Output of `[AnyStringFlags.quote_style`].
/// - [`AstUnparse`](`Mode::AstUnparse`): Always return [`Quote::Single`].
#[must_use]
fn quote_style(&self, flags: impl StringFlags) -> Quote {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

had to use generics because this gets called with either AnyStringFlags or BytesLiteralFlags

use crate::stylist::Indentation;

use super::Generator;
use super::{Generator, Mode as UnparseMode};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to UnparsedMode here because the name collides with

use ruff_python_parser::{..., Mode, ...};

@MichaReiser MichaReiser added the internal An internal refactor or improvement label Oct 24, 2025
@MichaReiser MichaReiser enabled auto-merge (squash) October 24, 2025 15:41
@MichaReiser MichaReiser merged commit a2d0d39 into astral-sh:main Oct 24, 2025
37 checks passed
@ShaharNaveh
Copy link
Contributor Author

tysm @MichaReiser <3 !

@ShaharNaveh ShaharNaveh deleted the generator-force-tup-parenth branch October 25, 2025 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal An internal refactor or improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants