wry 0.1.8.dev1__tar.gz → 0.1.9.dev2__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 (118) hide show
  1. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/CHANGELOG.md +11 -1
  2. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/PKG-INFO +1 -3
  3. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/README.md +0 -2
  4. wry-0.1.9.dev2/RELEASE_PROCESS.md +80 -0
  5. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry/_version.py +3 -3
  6. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry/click_integration.py +2 -2
  7. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry/core/model.py +5 -2
  8. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry.egg-info/PKG-INFO +1 -3
  9. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry.egg-info/SOURCES.txt +1 -0
  10. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/.github/workflows/ci-cd.yml +0 -0
  11. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/.gitignore +0 -0
  12. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/.markdownlint.json +0 -0
  13. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/.pre-commit-config.yaml +0 -0
  14. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/LICENSE +0 -0
  15. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/TODO.md +0 -0
  16. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/check.sh +0 -0
  17. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/examples/auto_model_example.py +0 -0
  18. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/examples/config.json +0 -0
  19. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/examples/intermediate_example.py +0 -0
  20. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/examples/multi_model_example.py +0 -0
  21. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/examples/simple_cli.py +0 -0
  22. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/examples/source_tracking_example.py +0 -0
  23. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/pyproject.toml +0 -0
  24. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/scripts/README.md +0 -0
  25. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/scripts/extract_release_notes.py +0 -0
  26. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/scripts/test_all_versions.sh +0 -0
  27. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/scripts/test_ci_locally.sh +0 -0
  28. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/scripts/test_with_act.sh +0 -0
  29. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/setup.cfg +0 -0
  30. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/README.md +0 -0
  31. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/__init__.py +0 -0
  32. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/features/__init__.py +0 -0
  33. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/features/test_auto_model.py +0 -0
  34. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/features/test_multi_model.py +0 -0
  35. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/features/test_source_precedence.py +0 -0
  36. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/integration/__init__.py +0 -0
  37. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/integration/test_click_edge_cases.py +0 -0
  38. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/integration/test_click_integration.py +0 -0
  39. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/integration/test_click_integration_extended.py +0 -0
  40. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/integration/test_context_handling.py +0 -0
  41. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/__init__.py +0 -0
  42. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/auto_model/__init__.py +0 -0
  43. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/auto_model/test_auto_model_annotation_inference.py +0 -0
  44. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/auto_model/test_auto_model_field_processing.py +0 -0
  45. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/auto_model/test_field_annotation_handling.py +0 -0
  46. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/auto_model/test_field_annotations.py +0 -0
  47. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/auto_model/test_type_inference.py +0 -0
  48. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/README_TESTING_STRATEGY.md +0 -0
  49. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/__init__.py +0 -0
  50. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_bool_flag_handling.py +0 -0
  51. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_click_config_building.py +0 -0
  52. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_click_constraint_formatting.py +0 -0
  53. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_click_decorator_edge_cases.py +0 -0
  54. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_click_interval_constraints.py +0 -0
  55. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_click_lambda_parsing.py +0 -0
  56. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_click_length_constraints.py +0 -0
  57. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_click_parameter_generation.py +0 -0
  58. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_click_predicate_handling.py +0 -0
  59. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_closure_extraction_errors.py +0 -0
  60. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_closure_handling.py +0 -0
  61. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_constraint_behavior.py +0 -0
  62. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_constraint_edge_cases.py +0 -0
  63. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_env_vars_option.py +0 -0
  64. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_json_config_loading.py +0 -0
  65. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_lambda_behavior.py +0 -0
  66. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_lambda_error_handling.py +0 -0
  67. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_predicate_source_errors.py +0 -0
  68. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_strict_mode_errors.py +0 -0
  69. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/click/test_type_handling.py +0 -0
  70. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/core/__init__.py +0 -0
  71. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/core/test_accessors.py +0 -0
  72. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/core/test_advanced_features.py +0 -0
  73. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/core/test_core.py +0 -0
  74. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/core/test_edge_cases.py +0 -0
  75. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/core/test_env_utils.py +0 -0
  76. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/core/test_field_constraint_extraction.py +0 -0
  77. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/core/test_field_utils.py +0 -0
  78. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/core/test_field_utils_edge_cases.py +0 -0
  79. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/core/test_sources.py +0 -0
  80. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/core/test_type_checking_blocks.py +0 -0
  81. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/model/__init__.py +0 -0
  82. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/model/test_accessor_caching.py +0 -0
  83. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/model/test_extract_edge_cases.py +0 -0
  84. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/model/test_model_click_context_handling.py +0 -0
  85. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/model/test_model_data_extraction.py +0 -0
  86. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/model/test_model_default_handling.py +0 -0
  87. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/model/test_model_environment_integration.py +0 -0
  88. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/model/test_model_extract_subset_edge_cases.py +0 -0
  89. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/model/test_model_extraction_methods.py +0 -0
  90. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/model/test_model_field_errors.py +0 -0
  91. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/model/test_model_object_extraction.py +0 -0
  92. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/model/test_non_dict_object_extraction.py +0 -0
  93. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/model/test_object_attribute_extraction.py +0 -0
  94. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/multi_model/__init__.py +0 -0
  95. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/multi_model/test_multi_model.py +0 -0
  96. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/multi_model/test_type_checking.py +0 -0
  97. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/test_auto_model_field_processing.py +0 -0
  98. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/test_comprehensive_imports.py +0 -0
  99. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/test_generate_click_classmethod.py +0 -0
  100. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/test_init.py +0 -0
  101. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/test_init_edge_cases.py +0 -0
  102. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/test_init_version_edge_cases.py +0 -0
  103. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/test_model_extraction_methods.py +0 -0
  104. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/test_type_checking_imports.py +0 -0
  105. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/test_version_fallback.py +0 -0
  106. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/tests/unit/test_version_parsing.py +0 -0
  107. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry/__init__.py +0 -0
  108. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry/auto_model.py +0 -0
  109. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry/core/__init__.py +0 -0
  110. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry/core/accessors.py +0 -0
  111. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry/core/env_utils.py +0 -0
  112. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry/core/field_utils.py +0 -0
  113. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry/core/sources.py +0 -0
  114. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry/multi_model.py +0 -0
  115. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry/py.typed +0 -0
  116. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry.egg-info/dependency_links.txt +0 -0
  117. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry.egg-info/requires.txt +0 -0
  118. {wry-0.1.8.dev1 → wry-0.1.9.dev2}/wry.egg-info/top_level.txt +0 -0
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.8] - 2025-09-10
11
+
12
+ ### Fixed
13
+
14
+ - Improved type annotations for `generate_click_parameters` decorator
15
+ - Now uses Click's `FC` TypeVar to preserve function types through decorator chain
16
+ - Fixes pyright `reportUntypedFunctionDecorator` warnings
17
+ - Maintains proper type inference for decorated functions
18
+
10
19
  ## [0.1.7] - 2025-09-09
11
20
 
12
21
  ### Added
@@ -135,7 +144,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
135
144
 
136
145
  - Initial version as `drycli` package (before rename to `wry`)
137
146
 
138
- [Unreleased]: https://github.com/tahouse/wry/compare/v0.1.7...HEAD
147
+ [Unreleased]: https://github.com/tahouse/wry/compare/v0.1.8...HEAD
148
+ [0.1.8]: https://github.com/tahouse/wry/compare/v0.1.7...v0.1.8
139
149
  [0.1.7]: https://github.com/tahouse/wry/compare/v0.1.6...v0.1.7
140
150
  [0.1.6]: https://github.com/tahouse/wry/compare/v0.1.5...v0.1.6
141
151
  [0.1.5]: https://github.com/tahouse/wry/compare/v0.1.4...v0.1.5
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wry
3
- Version: 0.1.8.dev1
3
+ Version: 0.1.9.dev2
4
4
  Summary: Why Repeat Yourself? - Define your CLI once with Pydantic models
5
5
  Author-email: Tyler House <26489166+tahouse@users.noreply.github.com>
6
6
  License: MIT
@@ -243,8 +243,6 @@ class QuickConfig(AutoWryModel):
243
243
  age: int = Field(default=30, ge=0, le=120)
244
244
  email: str = Field(description="Your email")
245
245
 
246
- # No need for Annotated[..., AutoOption]!
247
-
248
246
  @click.command()
249
247
  @generate_click_parameters(QuickConfig)
250
248
  def quickstart(config: QuickConfig):
@@ -197,8 +197,6 @@ class QuickConfig(AutoWryModel):
197
197
  age: int = Field(default=30, ge=0, le=120)
198
198
  email: str = Field(description="Your email")
199
199
 
200
- # No need for Annotated[..., AutoOption]!
201
-
202
200
  @click.command()
203
201
  @generate_click_parameters(QuickConfig)
204
202
  def quickstart(config: QuickConfig):
@@ -0,0 +1,80 @@
1
+ # Release Process for Wry
2
+
3
+ This document outlines the correct process for creating a new release.
4
+
5
+ ## Release Checklist
6
+
7
+ Follow these steps IN ORDER for each release:
8
+
9
+ 1. **Make all code changes**
10
+ - Implement features/fixes
11
+ - Ensure all tests pass (`./check.sh`)
12
+ - Fix any linting issues
13
+
14
+ 2. **Update documentation**
15
+ - Update README.md if needed
16
+ - Update any affected documentation
17
+
18
+ 3. **Update CHANGELOG.md**
19
+ - Add a new version section under `## [Unreleased]`
20
+ - Document all changes following [Keep a Changelog](https://keepachangelog.com/) format
21
+ - Update the comparison links at the bottom of the file
22
+
23
+ 4. **Commit all changes**
24
+ ```bash
25
+ git add -A
26
+ git commit -m "chore: prepare for vX.Y.Z release"
27
+ ```
28
+
29
+ 5. **Create signed tag**
30
+ ```bash
31
+ git tag -s vX.Y.Z -m "Release vX.Y.Z: brief description"
32
+ ```
33
+
34
+ 6. **Push changes and tag**
35
+ ```bash
36
+ git push origin main
37
+ git push origin vX.Y.Z
38
+ ```
39
+
40
+ ## Example
41
+
42
+ For v0.1.8 release:
43
+
44
+ ```bash
45
+ # 1. Make code changes
46
+ # ... implement type annotation improvements ...
47
+
48
+ # 2. Update CHANGELOG.md
49
+ # Add new section:
50
+ ## [0.1.8] - 2025-09-10
51
+
52
+ ### Fixed
53
+ - Improved type annotations for `generate_click_parameters` decorator
54
+
55
+ # 3. Commit everything
56
+ git add -A
57
+ git commit -m "chore: prepare for v0.1.8 release"
58
+
59
+ # 4. Create tag
60
+ git tag -s v0.1.8 -m "Release v0.1.8: improve type annotations"
61
+
62
+ # 5. Push
63
+ git push origin main
64
+ git push origin v0.1.8
65
+ ```
66
+
67
+ ## Common Mistakes to Avoid
68
+
69
+ - ❌ Creating the tag before updating CHANGELOG.md
70
+ - ❌ Forgetting to update comparison links in CHANGELOG.md
71
+ - ❌ Not running `./check.sh` before tagging
72
+ - ❌ Creating unsigned tags (always use `-s` for signed tags)
73
+
74
+ ## CI/CD Pipeline
75
+
76
+ Once a tag is pushed, the GitHub Actions workflow will:
77
+ 1. Run all tests across Python 3.10, 3.11, and 3.12
78
+ 2. Build the distribution packages
79
+ 3. Publish to PyPI (for tags) or TestPyPI (for main branch)
80
+ 4. Create a GitHub release with notes from CHANGELOG.md
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.1.8.dev1'
32
- __version_tuple__ = version_tuple = (0, 1, 8, 'dev1')
31
+ __version__ = version = '0.1.9.dev2'
32
+ __version_tuple__ = version_tuple = (0, 1, 9, 'dev2')
33
33
 
34
- __commit_id__ = commit_id = 'g4e1c76e68'
34
+ __commit_id__ = commit_id = 'g47bf3b2fc'
@@ -314,7 +314,7 @@ def generate_click_parameters(
314
314
  model_class: type[BaseModel],
315
315
  add_config_option: bool = True,
316
316
  strict: bool = True,
317
- ) -> Callable[..., Any]:
317
+ ) -> Callable[[FC], FC]:
318
318
  """Generate Click options and arguments with smart auto-generation.
319
319
 
320
320
  This decorator automatically generates Click CLI parameters from a Pydantic
@@ -508,7 +508,7 @@ def generate_click_parameters(
508
508
  )
509
509
  )
510
510
 
511
- def decorator(func: Callable[[FC], FC]) -> Callable[[FC], FC]:
511
+ def decorator(func: FC) -> FC:
512
512
  # Check for duplicate decorator application
513
513
  if hasattr(func, "_wry_models"):
514
514
  existing_models = getattr(func, "_wry_models", [])
@@ -3,12 +3,15 @@
3
3
  import json
4
4
  from collections.abc import Callable
5
5
  from pathlib import Path
6
- from typing import Any, ClassVar, TypeVar, cast
6
+ from typing import TYPE_CHECKING, Any, ClassVar, TypeVar, cast
7
7
 
8
8
  import click
9
9
  from pydantic import BaseModel, ConfigDict
10
10
  from pydantic_core import PydanticUndefined
11
11
 
12
+ if TYPE_CHECKING:
13
+ from click.decorators import FC
14
+
12
15
  from .accessors import (
13
16
  ConstraintsAccessor,
14
17
  DefaultsAccessor,
@@ -633,7 +636,7 @@ class WryModel(BaseModel):
633
636
  return result
634
637
 
635
638
  @classmethod
636
- def generate_click_parameters(cls) -> Callable:
639
+ def generate_click_parameters(cls) -> "Callable[[FC], FC]":
637
640
  """Generate Click parameters decorator for this model.
638
641
 
639
642
  This is a convenience method that allows using the decorator
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wry
3
- Version: 0.1.8.dev1
3
+ Version: 0.1.9.dev2
4
4
  Summary: Why Repeat Yourself? - Define your CLI once with Pydantic models
5
5
  Author-email: Tyler House <26489166+tahouse@users.noreply.github.com>
6
6
  License: MIT
@@ -243,8 +243,6 @@ class QuickConfig(AutoWryModel):
243
243
  age: int = Field(default=30, ge=0, le=120)
244
244
  email: str = Field(description="Your email")
245
245
 
246
- # No need for Annotated[..., AutoOption]!
247
-
248
246
  @click.command()
249
247
  @generate_click_parameters(QuickConfig)
250
248
  def quickstart(config: QuickConfig):
@@ -4,6 +4,7 @@
4
4
  CHANGELOG.md
5
5
  LICENSE
6
6
  README.md
7
+ RELEASE_PROCESS.md
7
8
  TODO.md
8
9
  check.sh
9
10
  pyproject.toml
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes