From c0f25e93e4a9d0a7d3cdb4ed3d2ad6fe5ed78b21 Mon Sep 17 00:00:00 2001 From: Tristan Simas Date: Sat, 3 Oct 2026 20:56:33 -0400 Subject: [PATCH] Keep authored nominal subtypes in clean nested source (#1) --- src/pycodify/formatters.py | 6 +++++- tests/test_core.py | 32 +++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/pycodify/formatters.py b/src/pycodify/formatters.py index fb90c68..b58290a 100644 --- a/src/pycodify/formatters.py +++ b/src/pycodify/formatters.py @@ -328,7 +328,11 @@ def _format_dataclass_expression( current_value, field_ctx, ) - if context.clean_mode and not nested_has_fields: + if ( + context.clean_mode + and not nested_has_fields + and type(current_value) is type(default_value) + ): continue imports |= nested_imports lines.append(f"{field_name}={nested_code}") diff --git a/tests/test_core.py b/tests/test_core.py index 31a8e1f..e703a4e 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1,7 +1,7 @@ """Tests for pycodify.core module.""" import pytest -from dataclasses import dataclass +from dataclasses import dataclass, field from enum import Enum from types import MappingProxyType @@ -29,6 +29,36 @@ class SimpleConfig: enabled: bool = True +@dataclass +class VolumeConfig(SimpleConfig): + depth: int = 60 + + +@dataclass +class NominalConfig(SimpleConfig): + pass + + +@dataclass +class NestedConfig: + image: SimpleConfig = field(default_factory=SimpleConfig) + + +@pytest.mark.parametrize("image_type", [VolumeConfig, NominalConfig]) +def test_clean_nested_defaults_preserve_authored_nominal_owner(image_type): + config = NestedConfig(image=image_type()) + source = generate_python_source(Assignment("config", config), clean_mode=True) + namespace = {} + exec(source, namespace) + assert type(namespace["config"].image) is image_type + assert namespace["config"] == config + + +def test_clean_nested_unchanged_default_remains_omitted(): + source = generate_python_source(Assignment("config", NestedConfig()), clean_mode=True) + assert "image=" not in source + + class ExtensionProbe: pass