dataclass-args 1.4.2__tar.gz → 1.4.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/PKG-INFO +1 -1
  2. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args/__init__.py +1 -1
  3. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args/builder.py +12 -4
  4. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args.egg-info/PKG-INFO +1 -1
  5. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args.egg-info/SOURCES.txt +1 -0
  6. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/pyproject.toml +1 -1
  7. dataclass_args-1.4.3/tests/test_nested_help_text.py +151 -0
  8. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/LICENSE +0 -0
  9. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/README.md +0 -0
  10. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args/annotations.py +0 -0
  11. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args/append_action.py +0 -0
  12. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args/config_applicator.py +0 -0
  13. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args/exceptions.py +0 -0
  14. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args/file_loading.py +0 -0
  15. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args/formatter.py +0 -0
  16. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args/nested_processor.py +0 -0
  17. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args/type_inspector.py +0 -0
  18. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args/utils.py +0 -0
  19. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args.egg-info/dependency_links.txt +0 -0
  20. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args.egg-info/requires.txt +0 -0
  21. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/dataclass_args.egg-info/top_level.txt +0 -0
  22. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/setup.cfg +0 -0
  23. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_annotations.py +0 -0
  24. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_basic.py +0 -0
  25. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_boolean_base_configs.py +0 -0
  26. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_boolean_flags.py +0 -0
  27. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_builder_advanced.py +0 -0
  28. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_cli_append.py +0 -0
  29. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_cli_choices.py +0 -0
  30. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_cli_nested.py +0 -0
  31. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_cli_short.py +0 -0
  32. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_collisions.py +0 -0
  33. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_combine_annotations.py +0 -0
  34. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_config_applicator.py +0 -0
  35. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_config_merging_simple.py +0 -0
  36. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_description.py +0 -0
  37. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_file_loading.py +0 -0
  38. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_nested_dict_override.py +0 -0
  39. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_nested_property_override_bug.py +0 -0
  40. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_positional.py +0 -0
  41. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_type_inspector.py +0 -0
  42. {dataclass_args-1.4.2 → dataclass_args-1.4.3}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dataclass-args
3
- Version: 1.4.2
3
+ Version: 1.4.3
4
4
  Summary: Zero-boilerplate CLI generation from Python dataclasses with advanced type support and file loading
5
5
  Author-email: Martin Bartlett <martin.j.bartlett@gmail.com>
6
6
  License: MIT
@@ -91,7 +91,7 @@ from .exceptions import ConfigBuilderError, ConfigurationError, FileLoadingError
91
91
  from .file_loading import is_file_loadable_value, load_file_content
92
92
  from .utils import load_structured_file
93
93
 
94
- __version__ = "1.4.2"
94
+ __version__ = "1.4.3"
95
95
 
96
96
  __all__ = [
97
97
  # Main API
@@ -450,7 +450,10 @@ class GenericConfigBuilder:
450
450
  info = mapping["nested_info"]
451
451
  prefix = mapping["prefix"]
452
452
  if not is_cli_positional(info):
453
- self._add_argument(parser, nested_field, info, cli_name, prefix)
453
+ parent = mapping["parent_field"]
454
+ self._add_argument(
455
+ parser, nested_field, info, cli_name, prefix, parent
456
+ )
454
457
  else:
455
458
  # Regular field - skip if nested dataclass
456
459
  field_name = mapping["field_name"]
@@ -520,6 +523,7 @@ class GenericConfigBuilder:
520
523
  info: Dict[str, Any],
521
524
  cli_name: Optional[str] = None,
522
525
  prefix: str = "",
526
+ parent_field: Optional[str] = None,
523
527
  ) -> None:
524
528
  """
525
529
  Add CLI argument for a field (unified handler for flat and nested fields).
@@ -530,6 +534,7 @@ class GenericConfigBuilder:
530
534
  info: Field info dict
531
535
  cli_name: Pre-computed CLI name (for nested fields), uses info["cli_name"] if None
532
536
  prefix: Prefix for nested fields (empty string = no prefix)
537
+ parent_field: Parent field name for nested fields (for help text context)
533
538
  """
534
539
  # Boolean fields handled separately
535
540
  if info["type"] == bool:
@@ -553,9 +558,12 @@ class GenericConfigBuilder:
553
558
 
554
559
  # Build help text
555
560
  custom_help = get_cli_help(info)
556
- help_text = (
557
- custom_help if custom_help else ("nested field" if prefix else field_name)
558
- )
561
+ if custom_help:
562
+ help_text = custom_help
563
+ elif parent_field:
564
+ help_text = f"{parent_field}.{field_name}"
565
+ else:
566
+ help_text = field_name
559
567
  choices = get_cli_choices(info)
560
568
 
561
569
  # Handle append fields
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dataclass-args
3
- Version: 1.4.2
3
+ Version: 1.4.3
4
4
  Summary: Zero-boilerplate CLI generation from Python dataclasses with advanced type support and file loading
5
5
  Author-email: Martin Bartlett <martin.j.bartlett@gmail.com>
6
6
  License: MIT
@@ -33,6 +33,7 @@ tests/test_config_merging_simple.py
33
33
  tests/test_description.py
34
34
  tests/test_file_loading.py
35
35
  tests/test_nested_dict_override.py
36
+ tests/test_nested_help_text.py
36
37
  tests/test_nested_property_override_bug.py
37
38
  tests/test_positional.py
38
39
  tests/test_type_inspector.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dataclass-args"
7
- version = "1.4.2"
7
+ version = "1.4.3"
8
8
  description = "Zero-boilerplate CLI generation from Python dataclasses with advanced type support and file loading"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -0,0 +1,151 @@
1
+ """Test that nested field help text shows parent.field context."""
2
+
3
+ import argparse
4
+ from dataclasses import dataclass
5
+
6
+ from dataclass_args import GenericConfigBuilder, cli_help, cli_nested
7
+
8
+
9
+ class TestNestedHelpText:
10
+ """Test nested field help text generation."""
11
+
12
+ def test_nested_with_prefix_shows_parent_field_in_help(self):
13
+ """Nested fields with prefix should show 'parent.field' in help text."""
14
+
15
+ @dataclass
16
+ class AgentConfig:
17
+ name: str = "default"
18
+ timeout: int = 30
19
+
20
+ @dataclass
21
+ class Config:
22
+ agent: AgentConfig = cli_nested(prefix="a2a")
23
+
24
+ builder = GenericConfigBuilder(Config)
25
+ parser = argparse.ArgumentParser()
26
+ builder.add_arguments(parser)
27
+
28
+ # Get help text
29
+ help_text = parser.format_help()
30
+
31
+ # Should show parent.field in help text
32
+ assert "agent.name" in help_text
33
+ assert "agent.timeout" in help_text
34
+
35
+ # Should NOT show generic "nested field"
36
+ assert "nested field" not in help_text
37
+
38
+ def test_nested_with_custom_help_uses_custom(self):
39
+ """Custom help text should override parent.field format."""
40
+
41
+ @dataclass
42
+ class Inner:
43
+ value: str = cli_help("Custom help text", default="test")
44
+
45
+ @dataclass
46
+ class Outer:
47
+ inner: Inner = cli_nested(prefix="i")
48
+
49
+ builder = GenericConfigBuilder(Outer)
50
+ parser = argparse.ArgumentParser()
51
+ builder.add_arguments(parser)
52
+
53
+ help_text = parser.format_help()
54
+
55
+ # Should use custom help text
56
+ assert "Custom help text" in help_text
57
+
58
+ # Should NOT show parent.field format
59
+ assert "inner.value" not in help_text
60
+
61
+ def test_nested_empty_prefix_shows_field_name(self):
62
+ """Nested fields with empty prefix should show just the field name."""
63
+
64
+ @dataclass
65
+ class Inner:
66
+ count: int = 5
67
+
68
+ @dataclass
69
+ class Outer:
70
+ inner: Inner = cli_nested(prefix="")
71
+
72
+ builder = GenericConfigBuilder(Outer)
73
+ parser = argparse.ArgumentParser()
74
+ builder.add_arguments(parser)
75
+
76
+ help_text = parser.format_help()
77
+
78
+ # With empty prefix, should show field name
79
+ assert "--count" in help_text
80
+ # Should show just "count" not "inner.count" since prefix is empty
81
+ lines = help_text.split("\n")
82
+ count_help = [line for line in lines if "--count" in line]
83
+ assert any("count" in line for line in count_help)
84
+
85
+ def test_multiple_nested_fields_all_show_parent(self):
86
+ """Multiple nested fields should all show parent.field format."""
87
+
88
+ @dataclass
89
+ class DatabaseConfig:
90
+ host: str = "localhost"
91
+ port: int = 5432
92
+ user: str = "admin"
93
+
94
+ @dataclass
95
+ class CacheConfig:
96
+ host: str = "localhost"
97
+ port: int = 6379
98
+
99
+ @dataclass
100
+ class AppConfig:
101
+ database: DatabaseConfig = cli_nested(prefix="db")
102
+ cache: CacheConfig = cli_nested(prefix="cache")
103
+
104
+ builder = GenericConfigBuilder(AppConfig)
105
+ parser = argparse.ArgumentParser()
106
+ builder.add_arguments(parser)
107
+
108
+ help_text = parser.format_help()
109
+
110
+ # Database fields
111
+ assert "database.host" in help_text
112
+ assert "database.port" in help_text
113
+ assert "database.user" in help_text
114
+
115
+ # Cache fields
116
+ assert "cache.host" in help_text
117
+ assert "cache.port" in help_text
118
+
119
+ # CLI names should have prefixes
120
+ assert "--db-host" in help_text
121
+ assert "--db-port" in help_text
122
+ assert "--cache-host" in help_text
123
+ assert "--cache-port" in help_text
124
+
125
+ def test_nested_dataclass_field_shows_parent_context(self):
126
+ """Nested dataclass fields (not fully flattened) show parent context."""
127
+
128
+ @dataclass
129
+ class Level3:
130
+ value: str = "deep"
131
+
132
+ @dataclass
133
+ class Level2:
134
+ level3: Level3 = cli_nested(prefix="l3")
135
+
136
+ @dataclass
137
+ class Level1:
138
+ level2: Level2 = cli_nested(prefix="l2")
139
+
140
+ builder = GenericConfigBuilder(Level1)
141
+ parser = argparse.ArgumentParser()
142
+ builder.add_arguments(parser)
143
+
144
+ help_text = parser.format_help()
145
+
146
+ # Level2.level3 is not fully flattened (requires recursive flattening)
147
+ # So it shows as level2.level3
148
+ assert "level2.level3" in help_text
149
+
150
+ # CLI name has the l2 prefix
151
+ assert "--l2-level3" in help_text
File without changes
File without changes
File without changes