Skip to content
This repository was archived by the owner on Oct 17, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ repos:
- id: tox-ini-fmt
args: [ "-p", "fix" ]
- repo: https://github.com/tox-dev/pyproject-fmt
rev: "1.8.0"
rev: "2.0.1"
hooks:
- id: pyproject-fmt
additional_dependencies: [ "tox>=4.15" ]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.4.4"
hooks:
Expand Down
66 changes: 33 additions & 33 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ keywords = [
]
license.file = "LICENSE.txt"
authors = [
{ name = "Bernat Gabor", email = "[email protected]" },
{ name = "Bernat Gabor", email = "[email protected]" },
]
requires-python = ">=3.8"
classifiers = [
Expand Down Expand Up @@ -51,35 +51,35 @@ module-name = "pyproject_fmt_rust._lib"
python-source = "src"
strip = true
include = [
"rust-toolchain.toml",
"rust-toolchain.toml",
]

[tool.cibuildwheel]
skip = [
"pp*",
"*musl*",
"pp*",
"*musl*",
]

[tool.ruff]
line-length = 120
target-version = "py38"
lint.isort = { known-first-party = [
"pyproject_fmt_rust",
"pyproject_fmt_rust",
], required-imports = [
"from __future__ import annotations",
"from __future__ import annotations",
] }
lint.select = [
"ALL",
"ALL",
]
lint.ignore = [
"ANN101", # no type annotation for self
"ANN401", # allow Any as type annotation
"COM812", # Conflict with formatter
"CPY", # No copyright statements
"D203", # `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible
"D212", # `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible
"ISC001", # Conflict with formatter
"S104", # Possible binding to all interface
"ANN101", # no type annotation for self
"ANN401", # allow Any as type annotation
"COM812", # Conflict with formatter
"CPY", # No copyright statements
"D203", # `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible
"D212", # `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible
"ISC001", # Conflict with formatter
"S104", # Possible binding to all interface
]
lint.preview = true
format.preview = true
Expand All @@ -88,15 +88,15 @@ format.docstring-code-line-length = 100

[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = [
"D", # don"t care about documentation in tests
"FBT", # don"t care about booleans as positional arguments in tests
"INP001", # no implicit namespace
"PLC2701", # private import
"PLR0913", # any number of arguments in tests
"PLR0917", # any number of arguments in tests
"PLR2004", # Magic value used in comparison, consider replacing with a constant variable
"S101", # asserts allowed in tests...
"S603", # `subprocess` call: check for execution of untrusted input
"D", # don"t care about documentation in tests
"FBT", # don"t care about booleans as positional arguments in tests
"INP001", # no implicit namespace
"PLC2701", # private import
"PLR0913", # any number of arguments in tests
"PLR0917", # any number of arguments in tests
"PLR2004", # Magic value used in comparison, consider replacing with a constant variable
"S101", # asserts allowed in tests...
"S603", # `subprocess` call: check for execution of untrusted input
]

[tool.codespell]
Expand All @@ -105,25 +105,25 @@ count = true

[tool.pytest]
ini_options.testpaths = [
"tests",
"tests",
]

[tool.coverage]
html.show_contexts = true
html.skip_covered = false
paths.source = [
"src",
".tox/*/.venv/lib/*/site-packages",
".tox\\*\\.venv\\Lib\\site-packages",
".tox/*/lib/*/site-packages",
".tox\\*\\Lib\\site-packages",
"**/src",
"**\\src",
"src",
".tox/*/.venv/lib/*/site-packages",
".tox\\*\\.venv\\Lib\\site-packages",
".tox/*/lib/*/site-packages",
".tox\\*\\Lib\\site-packages",
"**/src",
"**\\src",
]
report.fail_under = 100
run.parallel = true
run.plugins = [
"covdefaults",
"covdefaults",
]

[tool.mypy]
Expand Down
81 changes: 57 additions & 24 deletions rust/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::string::String;

use pyo3::prelude::PyModule;
use pyo3::{pyfunction, pymodule, wrap_pyfunction, Bound, PyResult};
use pyo3::{pyclass, pyfunction, pymethods, pymodule, wrap_pyfunction, Bound, PyResult};
use taplo::formatter::{format_syntax, Options};
use taplo::parser::parse;

Expand All @@ -16,46 +16,69 @@ mod project;
mod global;
mod helpers;

/// Format toml file
#[pyfunction]
#[must_use]
pub fn format_toml(
content: &str,
#[pyclass(frozen, get_all)]
pub struct Settings {
column_width: usize,
indent: usize,
keep_full_version: bool,
max_supported_python: (u8, u8),
min_supported_python: (u8, u8),
) -> String {
}

#[pymethods]
impl Settings {
#[new]
#[pyo3(signature = (*, column_width, indent, keep_full_version, max_supported_python, min_supported_python ))]
const fn new(
column_width: usize,
indent: usize,
keep_full_version: bool,
max_supported_python: (u8, u8),
min_supported_python: (u8, u8),
) -> Self {
Self {
column_width,
indent,
keep_full_version,
max_supported_python,
min_supported_python,
}
}
}

/// Format toml file
#[must_use]
#[pyfunction]
pub fn format_toml(content: &str, opt: &Settings) -> String {
let root_ast = parse(content).into_syntax().clone_for_update();
let mut tables = Tables::from_ast(&root_ast);

fix_build(&mut tables, keep_full_version);
fix_build(&mut tables, opt.keep_full_version);
fix_project_table(
&mut tables,
keep_full_version,
max_supported_python,
min_supported_python,
opt.keep_full_version,
opt.max_supported_python,
opt.min_supported_python,
);
reorder_tables(&root_ast, &mut tables);

let options = Options {
align_entries: false, // do not align by =
align_comments: true, // align inline comments
align_single_comments: true, // align comments after entries
array_trailing_comma: true, // ensure arrays finish with trailing comma
array_auto_expand: true, // arrays go to multi line for easier diffs
array_auto_collapse: false, // do not collapse for easier diffs
compact_arrays: false, // do not compact for easier diffs
compact_inline_tables: false, // do not compact for easier diffs
compact_entries: false, // do not compact for easier diffs
column_width, // always expand arrays per https://github.com/tamasfe/taplo/issues/390
align_entries: false, // do not align by =
align_comments: true, // align inline comments
align_single_comments: true, // align comments after entries
array_trailing_comma: true, // ensure arrays finish with trailing comma
array_auto_expand: true, // arrays go to multi line for easier diffs
array_auto_collapse: false, // do not collapse for easier diffs
compact_arrays: false, // do not compact for easier diffs
compact_inline_tables: false, // do not compact for easier diffs
compact_entries: false, // do not compact for easier diffs
column_width: opt.column_width, // always expand arrays per https://github.com/tamasfe/taplo/issues/390
indent_tables: false,
indent_entries: false,
inline_table_expand: true,
trailing_newline: true,
allowed_blank_lines: 1, // one blank line to separate
indent_string: " ".repeat(indent),
indent_string: " ".repeat(opt.indent),
reorder_keys: false, // respect custom order
reorder_arrays: false, // for natural sorting we need to this ourselves
crlf: false,
Expand All @@ -71,6 +94,7 @@ pub fn format_toml(
#[cfg(not(tarpaulin_include))]
pub fn _lib(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(format_toml, m)?)?;
m.add_class::<Settings>()?;
Ok(())
}

Expand All @@ -79,7 +103,7 @@ mod tests {
use indoc::indoc;
use rstest::rstest;

use crate::format_toml;
use crate::{format_toml, Settings};

#[rstest]
#[case::simple(
Expand Down Expand Up @@ -160,7 +184,16 @@ mod tests {
#[case] keep_full_version: bool,
#[case] max_supported_python: (u8, u8),
) {
let got = format_toml(start, 1, indent, keep_full_version, max_supported_python, (3, 8));
let got = format_toml(
start,
&Settings {
column_width: 1,
indent,
keep_full_version,
max_supported_python,
min_supported_python: (3, 8),
},
);
assert_eq!(got, expected);
}
}
3 changes: 2 additions & 1 deletion src/pyproject_fmt_rust/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

from __future__ import annotations

from ._lib import format_toml
from ._lib import Settings, format_toml

__all__ = [
"Settings",
"format_toml",
]
31 changes: 22 additions & 9 deletions src/pyproject_fmt_rust/_lib.pyi
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
def format_toml( # noqa: PLR0913
content: str,
*,
column_width: int,
indent: int,
keep_full_version: bool,
max_supported_python: tuple[int, int],
min_supported_python: tuple[int, int],
) -> str: ...
class Settings:
def __init__( # noqa: PLR0913
self,
*,
column_width: int,
indent: int,
keep_full_version: bool,
max_supported_python: tuple[int, int],
min_supported_python: tuple[int, int],
) -> None: ...
@property
def column_width(self) -> int: ...
@property
def indent(self) -> int: ...
@property
def keep_full_version(self) -> bool: ...
@property
def max_supported_python(self) -> tuple[int, int]: ...
@property
def min_supported_python(self) -> tuple[int, int]: ...

def format_toml(content: str, settings: Settings) -> str: ...
6 changes: 3 additions & 3 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from textwrap import dedent

from pyproject_fmt_rust import format_toml
from pyproject_fmt_rust import Settings, format_toml


def test_format_toml() -> None:
Expand All @@ -22,14 +22,14 @@ def test_format_toml() -> None:
]
"""

res = format_toml(
dedent(txt),
settings = Settings(
column_width=120,
indent=4,
keep_full_version=True,
min_supported_python=(3, 7),
max_supported_python=(3, 8),
)
res = format_toml(dedent(txt), settings)

expected = """\
[project]
Expand Down