wry 0.5.1.dev5__tar.gz → 0.5.3.dev1__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.
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/AI_KNOWLEDGE_BASE.md +80 -18
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/CHANGELOG.md +165 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/CONTRIBUTING.md +24 -12
- wry-0.5.3.dev1/DEPRECATION.md +189 -0
- {wry-0.5.1.dev5/wry.egg-info → wry-0.5.3.dev1}/PKG-INFO +128 -1
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/README.md +127 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/examples/autowrymodel_comprehensive.py +33 -5
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/examples/multimodel_comprehensive.py +9 -9
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/examples/wrymodel_comprehensive.py +24 -12
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/features/test_inheritance.py +2 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/features/test_multi_model.py +5 -0
- wry-0.5.3.dev1/tests/integration/test_boolean_flags_integration.py +172 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/integration/test_click_integration_extended.py +1 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/integration/test_context_handling.py +3 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/auto_model/test_auto_model_annotation_inference.py +5 -5
- wry-0.5.3.dev1/tests/unit/auto_model/test_boolean_on_off_flags.py +327 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/auto_model/test_field_annotation_handling.py +4 -4
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/auto_model/test_field_annotations.py +5 -5
- wry-0.5.3.dev1/tests/unit/auto_model/test_new_marker_api.py +266 -0
- wry-0.5.3.dev1/tests/unit/auto_model/test_optional_list_comma_separated.py +388 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/auto_model/test_type_inference.py +5 -5
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_bool_flag_handling.py +3 -3
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_explicit_argument_help_injection.py +2 -2
- wry-0.5.3.dev1/tests/unit/core/test_classvar_migration.py +147 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_argument_help_injection.py +6 -6
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_init.py +12 -4
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_multiple_option_bug.py +2 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/__init__.py +12 -5
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/_version.py +3 -3
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/auto_model.py +16 -11
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/click_integration.py +250 -47
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/comma_separated.py +33 -6
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/core/env_utils.py +1 -1
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/core/model.py +42 -1
- {wry-0.5.1.dev5 → wry-0.5.3.dev1/wry.egg-info}/PKG-INFO +128 -1
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry.egg-info/SOURCES.txt +6 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/.cursorrules +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/.github/workflows/ci-cd.yml +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/.gitignore +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/.markdownlint.json +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/.pre-commit-config.yaml +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/LICENSE +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/RELEASE_PROCESS.md +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/TODO.md +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/check.sh +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/examples/config.json +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/examples/sample_config.json +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/pyproject.toml +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/scripts/README.md +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/scripts/extract_release_notes.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/scripts/test_all_versions.sh +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/scripts/test_ci_locally.sh +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/scripts/test_with_act.sh +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/scripts/update-dependencies.sh +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/setup.cfg +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/README.md +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/__init__.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/features/__init__.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/features/test_auto_model.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/features/test_source_precedence.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/integration/__init__.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/integration/test_click_edge_cases.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/integration/test_click_integration.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/__init__.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/auto_model/__init__.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/auto_model/test_auto_model_edge_cases.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/auto_model/test_auto_model_field_processing.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/auto_model/test_auto_model_list_fields.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/auto_model/test_comma_separated_lists.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/README_TESTING_STRATEGY.md +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/__init__.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_argument_types.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_click_config_building.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_click_constraint_formatting.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_click_decorator_edge_cases.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_click_interval_constraints.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_click_lambda_parsing.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_click_length_constraints.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_click_parameter_generation.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_click_predicate_handling.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_closure_extraction_errors.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_closure_handling.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_constraint_behavior.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_constraint_edge_cases.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_env_vars_option.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_field_alias_with_click_options.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_format_constraint_text.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_json_config_loading.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_lambda_behavior.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_lambda_error_handling.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_predicate_source_errors.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_strict_mode_errors.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/click/test_type_handling.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/core/__init__.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/core/test_accessors.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/core/test_advanced_features.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/core/test_core.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/core/test_edge_cases.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/core/test_env_utils.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/core/test_field_constraint_extraction.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/core/test_field_utils.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/core/test_field_utils_edge_cases.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/core/test_sources.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/core/test_type_checking_blocks.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/__init__.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_accessor_caching.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_extract_edge_cases.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_extract_subset_edge_cases.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_model_click_context_handling.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_model_data_extraction.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_model_default_handling.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_model_edge_cases.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_model_environment_integration.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_model_extract_subset_edge_cases.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_model_extraction_methods.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_model_field_errors.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_model_object_extraction.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_non_dict_object_extraction.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/model/test_object_attribute_extraction.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/multi_model/__init__.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/multi_model/test_multi_model.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/multi_model/test_type_checking.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_auto_model_field_processing.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_comprehensive_imports.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_exclude_enum.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_generate_click_classmethod.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_help_system.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_init_edge_cases.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_init_version_edge_cases.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_model_extraction_methods.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_type_checking_imports.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_variadic_argument_bug.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_version_fallback.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/tests/unit/test_version_parsing.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/core/__init__.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/core/accessors.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/core/field_utils.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/core/sources.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/help_system.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/multi_model.py +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry/py.typed +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry.egg-info/dependency_links.txt +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry.egg-info/requires.txt +0 -0
- {wry-0.5.1.dev5 → wry-0.5.3.dev1}/wry.egg-info/top_level.txt +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# wry - Comprehensive AI/LLM Knowledge Base
|
|
2
2
|
|
|
3
|
-
**Last Updated**: 2025-10-
|
|
4
|
-
**Version**: 0.
|
|
3
|
+
**Last Updated**: 2025-10-19
|
|
4
|
+
**Version**: 0.6.0+
|
|
5
5
|
**Purpose**: Complete reference for AI assistants and LLMs to understand wry without reading the entire codebase
|
|
6
6
|
|
|
7
7
|
**Related Documentation**:
|
|
8
|
+
|
|
8
9
|
- 📖 **`CONTRIBUTING.md`** - Comprehensive contributor guide (referenced by `.cursorrules`)
|
|
9
10
|
- 🤖 **`.cursorrules`** - AI assistant quick reference (references this file and CONTRIBUTING.md)
|
|
10
11
|
- 📘 **`README.md`** - User-facing documentation
|
|
@@ -23,10 +24,13 @@
|
|
|
23
24
|
4. Tracking exactly where each value came from
|
|
24
25
|
5. Enforcing strict precedence: CLI > JSON > ENV > DEFAULT
|
|
25
26
|
6. **NEW v0.3.2**: Automatic alias-based CLI option generation
|
|
27
|
+
7. **NEW v0.6.0**: Boolean on/off flags (`--option/--no-option` pattern)
|
|
28
|
+
8. **NEW v0.6.0**: Callable marker API with parameters (`AutoOption()`, `AutoArgument()`, `AutoExclude()`)
|
|
29
|
+
9. **NEW v0.6.0**: wry-prefixed ClassVars for future-proof configuration
|
|
26
30
|
|
|
27
31
|
**Key Innovation**: Single source of truth for configuration with comprehensive source tracking.
|
|
28
32
|
|
|
29
|
-
**Stats**:
|
|
33
|
+
**Stats**: 535 tests (all passing), 88%+ coverage, supports Python 3.10-3.12, Pydantic v2.11+ compatible
|
|
30
34
|
|
|
31
35
|
**For Contributors**: See `CONTRIBUTING.md` for development guidelines and `.cursorrules` for AI assistant rules
|
|
32
36
|
|
|
@@ -878,26 +882,42 @@ def eager_json_config(ctx, param, value):
|
|
|
878
882
|
|
|
879
883
|
## Edge Cases & Gotchas
|
|
880
884
|
|
|
881
|
-
### 1.
|
|
885
|
+
### 1. wry_ Prefixed ClassVars (v0.6.0+) ⚠️
|
|
886
|
+
|
|
887
|
+
**NEW v0.6.0**: Use `wry_` prefixed ClassVars for configuration.
|
|
882
888
|
|
|
883
889
|
```python
|
|
884
|
-
#
|
|
890
|
+
# OLD (deprecated but still works):
|
|
885
891
|
class Config(AutoWryModel):
|
|
886
|
-
env_prefix: str = "MYAPP_" #
|
|
892
|
+
env_prefix: ClassVar[str] = "MYAPP_" # ⚠️ Deprecated
|
|
893
|
+
comma_separated_lists: ClassVar[bool] = True # ⚠️ Deprecated
|
|
887
894
|
|
|
888
|
-
#
|
|
895
|
+
# NEW (recommended):
|
|
889
896
|
class Config(AutoWryModel):
|
|
890
|
-
|
|
897
|
+
wry_env_prefix: ClassVar[str] = "MYAPP_" # ✅ New naming
|
|
898
|
+
wry_comma_separated_lists: ClassVar[bool] = True # ✅ New naming
|
|
899
|
+
wry_boolean_off_prefix: ClassVar[str] = "no" # ✅ New feature
|
|
900
|
+
|
|
901
|
+
# WRONG - Not using ClassVar:
|
|
902
|
+
class Config(AutoWryModel):
|
|
903
|
+
wry_env_prefix: str = "MYAPP_" # ❌ Still wrong!
|
|
891
904
|
```
|
|
892
905
|
|
|
893
|
-
**Why
|
|
906
|
+
**Why ClassVar matters**:
|
|
894
907
|
|
|
895
908
|
- Without `ClassVar`, Pydantic treats it as a field
|
|
896
909
|
- Field appears in `model_fields`, gets CLI option generated
|
|
897
|
-
- Shadows `WryModel
|
|
898
|
-
-
|
|
910
|
+
- Shadows `WryModel` class attributes
|
|
911
|
+
- Configuration breaks
|
|
912
|
+
|
|
913
|
+
**Why wry_ prefix?**
|
|
899
914
|
|
|
900
|
-
|
|
915
|
+
- Avoids namespace collisions with user fields
|
|
916
|
+
- Makes wry configuration explicit
|
|
917
|
+
- Future-proof for new configuration options
|
|
918
|
+
- Old names auto-migrate with deprecation warnings
|
|
919
|
+
|
|
920
|
+
**Migration**: Old names still work (auto-migrated) but emit `DeprecationWarning`.
|
|
901
921
|
|
|
902
922
|
### 2. Source Tracking Requires Context
|
|
903
923
|
|
|
@@ -1125,18 +1145,36 @@ timeout: Optional[int] = Field(default=None)
|
|
|
1125
1145
|
# Generates: click.option("--timeout", type=click.INT, default=None)
|
|
1126
1146
|
```
|
|
1127
1147
|
|
|
1128
|
-
### 7. Boolean Fields
|
|
1148
|
+
### 7. Boolean Fields Use On/Off Pattern (NEW v0.6.0)
|
|
1149
|
+
|
|
1150
|
+
**Changed in v0.6.0**: Boolean fields now generate `--option/--no-option` pattern by default.
|
|
1129
1151
|
|
|
1130
1152
|
```python
|
|
1131
1153
|
debug: bool = Field(default=False)
|
|
1132
1154
|
|
|
1133
|
-
# Auto-generates:
|
|
1134
|
-
click.option("--debug",
|
|
1155
|
+
# Auto-generates (NEW):
|
|
1156
|
+
click.option("--debug/--no-debug", default=False)
|
|
1157
|
+
|
|
1158
|
+
# Usage:
|
|
1159
|
+
# --debug (sets to True)
|
|
1160
|
+
# --no-debug (sets to False)
|
|
1135
1161
|
|
|
1136
|
-
#
|
|
1137
|
-
|
|
1162
|
+
# Customization:
|
|
1163
|
+
verbose: Annotated[bool, AutoOption(flag_off_option="quiet")] = Field(default=False)
|
|
1164
|
+
# → --verbose/--quiet
|
|
1165
|
+
|
|
1166
|
+
# Opt-out to single flag (old behavior):
|
|
1167
|
+
simple: Annotated[bool, AutoOption(flag_enable_on_off=False)] = Field(default=False)
|
|
1168
|
+
# → --simple (single flag)
|
|
1138
1169
|
```
|
|
1139
1170
|
|
|
1171
|
+
**Why the change?**
|
|
1172
|
+
|
|
1173
|
+
- More explicit: users can clearly specify both on and off states
|
|
1174
|
+
- Follows Click best practices
|
|
1175
|
+
- Better UX: `--no-debug` is clearer than absence of `--debug`
|
|
1176
|
+
- Backwards compatible via opt-out
|
|
1177
|
+
|
|
1140
1178
|
### 8. Arguments Are Always Optional (For --config)
|
|
1141
1179
|
|
|
1142
1180
|
```python
|
|
@@ -1705,8 +1743,32 @@ class TrackedValue
|
|
|
1705
1743
|
class FieldWithSource
|
|
1706
1744
|
"""Value wrapper exposing .source attribute."""
|
|
1707
1745
|
|
|
1746
|
+
# NEW v0.6.0: Callable marker classes
|
|
1747
|
+
class WryOption
|
|
1748
|
+
"""Marker for auto-generated Click options with customization.
|
|
1749
|
+
|
|
1750
|
+
Parameters:
|
|
1751
|
+
required: bool = False
|
|
1752
|
+
flag_enable_on_off: bool = True (for bool fields)
|
|
1753
|
+
flag_off_prefix: str | None = None (for bool fields)
|
|
1754
|
+
flag_off_option: str | None = None (for bool fields)
|
|
1755
|
+
"""
|
|
1756
|
+
|
|
1757
|
+
class WryArgument
|
|
1758
|
+
"""Marker for auto-generated Click arguments."""
|
|
1759
|
+
|
|
1760
|
+
class WryExclude
|
|
1761
|
+
"""Marker to exclude field from CLI generation."""
|
|
1762
|
+
|
|
1763
|
+
# Public API aliases
|
|
1764
|
+
AutoOption = WryOption # Backwards-compatible name
|
|
1765
|
+
AutoArgument = WryArgument # Backwards-compatible name
|
|
1766
|
+
AutoExclude = WryExclude # Backwards-compatible name
|
|
1767
|
+
|
|
1768
|
+
# DEPRECATED v0.6.0: Old enum-based API
|
|
1708
1769
|
class AutoClickParameter(Enum)
|
|
1709
|
-
"""
|
|
1770
|
+
"""Deprecated: Use AutoOption(), AutoArgument(), AutoExclude() instead.
|
|
1771
|
+
OPTION, REQUIRED_OPTION, ARGUMENT, EXCLUDE"""
|
|
1710
1772
|
|
|
1711
1773
|
# Accessors (returned by @property)
|
|
1712
1774
|
class SourceAccessor
|
|
@@ -9,6 +9,159 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
11
|
|
|
12
|
+
- **Boolean on/off flags** - Boolean fields now generate `--option/--no-option` pattern by default 🎚️
|
|
13
|
+
- Makes CLI interfaces more explicit - users can explicitly set false: `--no-debug`
|
|
14
|
+
- Default behavior: `debug: bool = Field(default=False)` → `--debug/--no-debug`
|
|
15
|
+
- Custom off-option: `AutoOption(flag_off_option="quiet")` → `--verbose/--quiet`
|
|
16
|
+
- Custom prefix: `AutoOption(flag_off_prefix="skip")` → `--check/--skip-check`
|
|
17
|
+
- Single flag opt-out: `AutoOption(flag_enable_on_off=False)` → `--debug` (old behavior)
|
|
18
|
+
- Model-wide customization: `wry_boolean_off_prefix: ClassVar[str] = "disable"`
|
|
19
|
+
- Collision detection: warns and falls back to single flag if off-option conflicts with existing field
|
|
20
|
+
- Works with aliases: `debug: bool = Field(alias="verbose")` → `--verbose/--no-verbose`
|
|
21
|
+
- Full source tracking support (CLI/ENV/JSON/DEFAULT)
|
|
22
|
+
- Follows Click best practices: <https://click.palletsprojects.com/en/stable/options/#boolean>
|
|
23
|
+
- **39 new tests** covering all scenarios
|
|
24
|
+
|
|
25
|
+
- **Callable marker API** - Refactored Auto* markers from Enum to callable classes 🔧
|
|
26
|
+
- `AutoOption()` replaces `AutoClickParameter.OPTION`
|
|
27
|
+
- `AutoOption(required=True)` replaces `AutoClickParameter.REQUIRED_OPTION`
|
|
28
|
+
- `AutoArgument()` replaces `AutoClickParameter.ARGUMENT`
|
|
29
|
+
- `AutoExclude()` replaces `AutoClickParameter.EXCLUDE`
|
|
30
|
+
- All markers now support parameters for future extensibility
|
|
31
|
+
- Boolean-specific parameters: `flag_enable_on_off`, `flag_off_prefix`, `flag_off_option`
|
|
32
|
+
- List-specific parameter: `comma_separated` - replaces standalone `CommaSeparated` marker
|
|
33
|
+
- Example: `AutoOption(comma_separated=True)` replaces `Annotated[list[str], CommaSeparated]`
|
|
34
|
+
- Internal: Uses Wry-specific naming (WryOption, WryArgument, WryExclude classes)
|
|
35
|
+
- Public API: AutoOption, AutoArgument, AutoExclude are aliases to Wry* classes
|
|
36
|
+
- Follows PEP 593 Annotated pattern: <https://peps.python.org/pep-0593/>
|
|
37
|
+
|
|
38
|
+
- **wry_ prefixed ClassVars** - New naming convention for class-level configuration 🏷️
|
|
39
|
+
- `wry_env_prefix: ClassVar[str]` replaces `env_prefix`
|
|
40
|
+
- `wry_comma_separated_lists: ClassVar[bool]` replaces `comma_separated_lists`
|
|
41
|
+
- `wry_boolean_off_prefix: ClassVar[str]` - new feature for boolean flags
|
|
42
|
+
- Avoids namespace collisions with user fields
|
|
43
|
+
- Future-proof for additional configuration options
|
|
44
|
+
- **10 new tests** for migration and new features
|
|
45
|
+
|
|
46
|
+
### Deprecated
|
|
47
|
+
|
|
48
|
+
- `AutoClickParameter` enum - Use `AutoOption()`, `AutoArgument()`, `AutoExclude()` instead
|
|
49
|
+
- Old enum values still work but emit `DeprecationWarning`
|
|
50
|
+
- Will be removed in next major version (v1.0.0)
|
|
51
|
+
|
|
52
|
+
- `CommaSeparated` standalone marker - Use `AutoOption(comma_separated=True)` instead
|
|
53
|
+
- Old standalone marker still works but emits `DeprecationWarning`
|
|
54
|
+
- Will be removed in next major version (v1.0.0)
|
|
55
|
+
|
|
56
|
+
- `env_prefix` ClassVar - Use `wry_env_prefix` instead
|
|
57
|
+
- Auto-migrates with `DeprecationWarning`
|
|
58
|
+
- Will be removed in next major version (v1.0.0)
|
|
59
|
+
|
|
60
|
+
- `comma_separated_lists` ClassVar - Use `wry_comma_separated_lists` instead
|
|
61
|
+
- Auto-migrates with `DeprecationWarning`
|
|
62
|
+
- Will be removed in next major version (v1.0.0)
|
|
63
|
+
|
|
64
|
+
### Migration Guide
|
|
65
|
+
|
|
66
|
+
**From Enum to Callable API:**
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
# Old (deprecated):
|
|
70
|
+
field: Annotated[str, AutoClickParameter.OPTION] = Field(default="value")
|
|
71
|
+
required: Annotated[str, AutoClickParameter.REQUIRED_OPTION] = Field(...)
|
|
72
|
+
|
|
73
|
+
# New (recommended):
|
|
74
|
+
field: Annotated[str, AutoOption()] = Field(default="value")
|
|
75
|
+
required: Annotated[str, AutoOption(required=True)] = Field(...)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**ClassVar Migration:**
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
# Old (deprecated):
|
|
82
|
+
class Config(AutoWryModel):
|
|
83
|
+
env_prefix: ClassVar[str] = "MYAPP_"
|
|
84
|
+
comma_separated_lists: ClassVar[bool] = True
|
|
85
|
+
|
|
86
|
+
# New (recommended):
|
|
87
|
+
class Config(AutoWryModel):
|
|
88
|
+
wry_env_prefix: ClassVar[str] = "MYAPP_"
|
|
89
|
+
wry_comma_separated_lists: ClassVar[bool] = True
|
|
90
|
+
wry_boolean_off_prefix: ClassVar[str] = "no" # Optional, "no" is default
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Comma-Separated Lists:**
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
# Old (deprecated):
|
|
97
|
+
tags: Annotated[list[str], CommaSeparated] = Field(default_factory=list)
|
|
98
|
+
|
|
99
|
+
# New (recommended):
|
|
100
|
+
tags: Annotated[list[str], AutoOption(comma_separated=True)] = Field(default_factory=list)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Boolean On/Off Examples:**
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
# Default on/off pattern
|
|
107
|
+
debug: bool = Field(default=False) # --debug/--no-debug
|
|
108
|
+
|
|
109
|
+
# Custom off-option
|
|
110
|
+
verbose: Annotated[bool, AutoOption(flag_off_option="quiet")] = Field(default=False)
|
|
111
|
+
# → --verbose/--quiet
|
|
112
|
+
|
|
113
|
+
# Opt-out to single flag
|
|
114
|
+
simple: Annotated[bool, AutoOption(flag_enable_on_off=False)] = Field(default=False)
|
|
115
|
+
# → --simple (old behavior)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Internal Changes
|
|
119
|
+
|
|
120
|
+
- Updated all internal code to use `wry_*` prefixed ClassVars
|
|
121
|
+
- Metadata processing loop refactored to support multiple marker types
|
|
122
|
+
- Boolean flag generation supports on/off pattern with customization
|
|
123
|
+
- Comprehensive backwards compatibility layer with migration warnings
|
|
124
|
+
- **Total test count: 535 tests (all passing)** ✨
|
|
125
|
+
- Coverage: 88.5%+ (slight drop due to new features, will improve with more usage)
|
|
126
|
+
|
|
127
|
+
## [0.5.2] - 2025-10-14
|
|
128
|
+
|
|
129
|
+
### Fixed
|
|
130
|
+
|
|
131
|
+
- **Optional list fields with comma-separated parsing** 🐛
|
|
132
|
+
**THE BIG ONE:** Fixed critical bug where `list[str] | None` and `Optional[list[str]]` fields didn't work with comma-separated parsing
|
|
133
|
+
- **Root cause**: Nested `Annotated` types created by `AutoWryModel` (e.g., `Annotated[Optional[Annotated[list[str], CommaSeparated]], AutoOption]`) weren't being properly unwrapped
|
|
134
|
+
- **Fix 1**: Extract metadata from inner `Annotated` types within `Optional`/`Union` wrappers
|
|
135
|
+
- **Fix 2**: Unwrap `Annotated` types after unwrapping `Optional` to get to the base list type
|
|
136
|
+
- Works with both model-wide `comma_separated_lists` ClassVar and per-field `CommaSeparated` annotation
|
|
137
|
+
- Works with `list[str] | None`, `Optional[list[T]]`, and all numeric types (int, float)
|
|
138
|
+
|
|
139
|
+
### Added
|
|
140
|
+
|
|
141
|
+
- **Comprehensive tests for optional comma-separated lists** ✅
|
|
142
|
+
Added 13 test cases covering all use cases and edge cases:
|
|
143
|
+
- MVP bug: `list[str] | None` with model-wide `comma_separated_lists`
|
|
144
|
+
- Per-field `Annotated[list[T], CommaSeparated] | None`
|
|
145
|
+
- Old-style `Optional[list[T]]` syntax
|
|
146
|
+
- Multiple types: str, int, float
|
|
147
|
+
- Required vs optional lists
|
|
148
|
+
- Source tracking verification
|
|
149
|
+
- Default values: `None`, `[]`, `default_factory`
|
|
150
|
+
- Space handling in comma-separated input
|
|
151
|
+
- Double-nested `Annotated` types (the actual bug pattern)
|
|
152
|
+
- **Total test count: 507 tests (all passing)** ✨
|
|
153
|
+
|
|
154
|
+
## [0.5.1] - 2025-10-14
|
|
155
|
+
|
|
156
|
+
### Fixed
|
|
157
|
+
|
|
158
|
+
- **Comma-separated lists with `default_factory`** 🐛
|
|
159
|
+
- Fixed bug where fields with `default_factory=list` would receive `None` instead of empty list when not provided
|
|
160
|
+
- Added proper handling in `click_integration.py` to call `default_factory()` for default values
|
|
161
|
+
- All comma-separated list tests now pass without validation errors
|
|
162
|
+
|
|
163
|
+
### Added
|
|
164
|
+
|
|
12
165
|
- **Development guidelines** 📚
|
|
13
166
|
- Created `.cursorrules` as AI assistant's quick reference guide
|
|
14
167
|
- Created `CONTRIBUTING.md` as comprehensive contributor guide
|
|
@@ -17,6 +170,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
17
170
|
|
|
18
171
|
### Changed
|
|
19
172
|
|
|
173
|
+
- **Test quality improvements** ✨
|
|
174
|
+
- Fixed Pydantic shadow warnings by renaming `source` field to `source_path`/`source_file` in test cases
|
|
175
|
+
- Added `@pytest.mark.filterwarnings` to suppress intentional warnings in tests
|
|
176
|
+
- Tests that validate warning behavior no longer pollute test output
|
|
177
|
+
- All 494 tests pass cleanly with zero warnings
|
|
178
|
+
|
|
179
|
+
- **Test quality improvements** ✨
|
|
180
|
+
- Fixed Pydantic shadow warnings by renaming `source` field to `source_path`/`source_file` in test cases
|
|
181
|
+
- Added `@pytest.mark.filterwarnings` to suppress intentional warnings in tests
|
|
182
|
+
- Tests that validate warning behavior no longer pollute test output
|
|
183
|
+
- All 494 tests pass cleanly with zero warnings
|
|
184
|
+
|
|
20
185
|
- **Documentation cross-references** 🔗
|
|
21
186
|
- README.md: Added Contributing section with links to CONTRIBUTING.md, .cursorrules, AI_KNOWLEDGE_BASE.md
|
|
22
187
|
- AI_KNOWLEDGE_BASE.md: Updated header with related documentation links
|
|
@@ -228,11 +228,13 @@ def test_your_feature_with_click():
|
|
|
228
228
|
- If an ignore directive is truly necessary, add a detailed comment explaining why
|
|
229
229
|
|
|
230
230
|
**Example - Bad**:
|
|
231
|
+
|
|
231
232
|
```python
|
|
232
233
|
result = some_function() # type: ignore # ❌ Don't do this
|
|
233
234
|
```
|
|
234
235
|
|
|
235
236
|
**Example - Good**:
|
|
237
|
+
|
|
236
238
|
```python
|
|
237
239
|
# Fix the type annotation properly
|
|
238
240
|
def some_function() -> dict[str, Any]: # ✅ Proper return type
|
|
@@ -289,9 +291,10 @@ from wry import AutoWryModel, AutoOption
|
|
|
289
291
|
class MyConfig(AutoWryModel):
|
|
290
292
|
"""Configuration for my CLI tool."""
|
|
291
293
|
|
|
292
|
-
# Class-level configuration (NOT a field)
|
|
293
|
-
|
|
294
|
-
|
|
294
|
+
# Class-level configuration (NOT a field) - use wry_ prefix (v0.6.0+)
|
|
295
|
+
wry_env_prefix: ClassVar[str] = "MYAPP_"
|
|
296
|
+
wry_comma_separated_lists: ClassVar[bool] = False # Optional
|
|
297
|
+
wry_boolean_off_prefix: ClassVar[str] = "no" # Optional, customize boolean off-options
|
|
295
298
|
|
|
296
299
|
# Fields become CLI options automatically
|
|
297
300
|
host: str = Field(
|
|
@@ -324,7 +327,8 @@ def main(ctx: click.Context, **kwargs: Any) -> None:
|
|
|
324
327
|
**Key Points**:
|
|
325
328
|
|
|
326
329
|
- Extend `AutoWryModel` for automatic option generation
|
|
327
|
-
- Use `ClassVar` for class-level config (`
|
|
330
|
+
- Use `ClassVar` for class-level config (`wry_env_prefix`, `wry_comma_separated_lists`, `wry_boolean_off_prefix`)
|
|
331
|
+
- Use new callable API: `AutoOption()`, `AutoArgument()`, `AutoExclude()`
|
|
328
332
|
- Use `generate_click_parameters()` decorator
|
|
329
333
|
- Load config with `from_click_context(ctx, **kwargs)` for source tracking
|
|
330
334
|
- Access sources with `config.source.field_name`
|
|
@@ -343,7 +347,7 @@ class Config(AutoWryModel):
|
|
|
343
347
|
|
|
344
348
|
# Or model-wide comma-separated:
|
|
345
349
|
class CommaSepConfig(AutoWryModel):
|
|
346
|
-
|
|
350
|
+
wry_comma_separated_lists: ClassVar[bool] = True # All lists use comma-separated
|
|
347
351
|
|
|
348
352
|
tags: list[str] = Field(default_factory=list) # Now: --tags python,rust,go
|
|
349
353
|
```
|
|
@@ -449,6 +453,7 @@ def test_feature_with_clear_name():
|
|
|
449
453
|
- [ ] **Examples**: Add or update examples if demonstrating new features
|
|
450
454
|
|
|
451
455
|
**Documentation Management**:
|
|
456
|
+
|
|
452
457
|
- **Do not create excessive markdown files** unless explicitly needed
|
|
453
458
|
- If markdown files exist, add content to the appropriate existing file
|
|
454
459
|
- If unsure which file is appropriate, consider whether the content belongs in README.md, AI_KNOWLEDGE_BASE.md, or CHANGELOG.md
|
|
@@ -460,7 +465,7 @@ def test_feature_with_clear_name():
|
|
|
460
465
|
- [ ] **Docstrings**: All public functions/classes/modules have comprehensive docstrings (Google style)
|
|
461
466
|
- [ ] **No dead code**: Remove unused imports, variables, commented code
|
|
462
467
|
- [ ] **DRY principle**: No duplicate code - extract common logic
|
|
463
|
-
- [ ] **ClassVar for class config**: Use `ClassVar` for `
|
|
468
|
+
- [ ] **ClassVar for class config**: Use `ClassVar` for `wry_env_prefix`, `wry_comma_separated_lists`, `wry_boolean_off_prefix`
|
|
464
469
|
|
|
465
470
|
### 3. Tests
|
|
466
471
|
|
|
@@ -497,7 +502,7 @@ mypy wry/
|
|
|
497
502
|
|
|
498
503
|
- [ ] **Source tracking works**: If touching config/model code, verify source tracking
|
|
499
504
|
- [ ] **Precedence correct**: CLI > JSON > ENV > DEFAULT (verify if changing)
|
|
500
|
-
- [ ] **ClassVar not in fields**: Ensure `
|
|
505
|
+
- [ ] **ClassVar not in fields**: Ensure `wry_env_prefix`, `wry_comma_separated_lists`, `wry_boolean_off_prefix` use `ClassVar`
|
|
501
506
|
- [ ] **Examples still work**: Run examples if you changed core functionality
|
|
502
507
|
- [ ] **Help text clear**: Generated --help output is helpful
|
|
503
508
|
|
|
@@ -529,7 +534,7 @@ Use [Conventional Commits](https://www.conventionalcommits.org/) format:
|
|
|
529
534
|
feat: add comma-separated list support
|
|
530
535
|
|
|
531
536
|
- Add CommaSeparated marker for per-field annotation
|
|
532
|
-
- Add
|
|
537
|
+
- Add wry_comma_separated_lists ClassVar for model-wide setting
|
|
533
538
|
- Per-field annotation takes priority over model-wide
|
|
534
539
|
- Full Pydantic validation preserved
|
|
535
540
|
|
|
@@ -547,6 +552,7 @@ Closes #42
|
|
|
547
552
|
- Always pass `--yes` or appropriate non-interactive flags to avoid user prompts
|
|
548
553
|
|
|
549
554
|
**Example**:
|
|
555
|
+
|
|
550
556
|
```bash
|
|
551
557
|
# Bad - Git sees this as delete + add
|
|
552
558
|
rm old_file.py
|
|
@@ -576,16 +582,20 @@ git mv old_file.py new_file.py
|
|
|
576
582
|
## Pull Request Process
|
|
577
583
|
|
|
578
584
|
1. **Branch**: Create feature branch from `main`
|
|
585
|
+
|
|
579
586
|
```bash
|
|
580
587
|
git checkout -b feature/your-feature-name
|
|
581
588
|
```
|
|
589
|
+
|
|
582
590
|
2. **Complete checklist**: Follow Pre-Commit Checklist above
|
|
583
591
|
3. **Commit**: Make your commit with conventional commit message
|
|
584
592
|
4. **Test**: Pre-commit hook will run checks automatically
|
|
585
593
|
5. **Push**: Push to remote
|
|
594
|
+
|
|
586
595
|
```bash
|
|
587
596
|
git push -u origin feature/your-feature-name
|
|
588
597
|
```
|
|
598
|
+
|
|
589
599
|
6. **PR**: Submit with clear description referencing checklist items
|
|
590
600
|
|
|
591
601
|
## Critical Rules
|
|
@@ -614,9 +624,10 @@ If pre-commit hooks are failing:
|
|
|
614
624
|
2. **DRY everywhere**: Configuration defined once, used everywhere
|
|
615
625
|
3. **Examples are crucial**: Users learn from examples - keep them clear and comprehensive
|
|
616
626
|
4. **Test all 4 sources**: When adding config features, test CLI/ENV/JSON/DEFAULT
|
|
617
|
-
5. **ClassVar correctness**: `
|
|
618
|
-
6. **
|
|
619
|
-
7. **
|
|
627
|
+
5. **ClassVar correctness**: `wry_env_prefix`, `wry_comma_separated_lists`, `wry_boolean_off_prefix` must be ClassVar
|
|
628
|
+
6. **New callable API**: Use `AutoOption()`, `AutoArgument()`, `AutoExclude()` not old enum
|
|
629
|
+
7. **Explicit decorators work**: Users can always use explicit `click.option()` - preserve this
|
|
630
|
+
8. **No surprises**: Behavior should match documentation exactly
|
|
620
631
|
|
|
621
632
|
## Guidelines
|
|
622
633
|
|
|
@@ -633,7 +644,7 @@ If pre-commit hooks are failing:
|
|
|
633
644
|
### DON'T
|
|
634
645
|
|
|
635
646
|
❌ Break source precedence (CLI > JSON > ENV > DEFAULT)
|
|
636
|
-
❌ Make `
|
|
647
|
+
❌ Make `wry_env_prefix`, `wry_comma_separated_lists`, or `wry_boolean_off_prefix` regular fields
|
|
637
648
|
❌ Skip testing source tracking
|
|
638
649
|
❌ Bypass pre-commit hooks
|
|
639
650
|
❌ Create duplicate functionality
|
|
@@ -645,6 +656,7 @@ If pre-commit hooks are failing:
|
|
|
645
656
|
For information about creating releases, see **`RELEASE_PROCESS.md`**.
|
|
646
657
|
|
|
647
658
|
**Key points**:
|
|
659
|
+
|
|
648
660
|
- During development: Add all changes to `[Unreleased]` in CHANGELOG.md
|
|
649
661
|
- When releasing: Convert `[Unreleased]` to `[X.Y.Z] - YYYY-MM-DD`
|
|
650
662
|
- Tag the release commit: `git tag -s vX.Y.Z`
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Deprecation Tracking
|
|
2
|
+
|
|
3
|
+
This document tracks all deprecated features for easy removal in future versions.
|
|
4
|
+
|
|
5
|
+
## Deprecated in v0.6.0 → Remove in v1.0.0
|
|
6
|
+
|
|
7
|
+
### 1. AutoClickParameter Enum
|
|
8
|
+
|
|
9
|
+
**Location**: `wry/click_integration.py:97-115`
|
|
10
|
+
**Deprecated**: v0.6.0
|
|
11
|
+
**Remove**: v1.0.0
|
|
12
|
+
**Replacement**: `AutoOption()`, `AutoArgument()`, `AutoExclude()`
|
|
13
|
+
|
|
14
|
+
**Code markers**:
|
|
15
|
+
|
|
16
|
+
- Class definition: `wry/click_integration.py:97` (marked with `# DEPRECATED v0.6.0`)
|
|
17
|
+
- Detection logic: `wry/click_integration.py:492-517` (marked with `# DEPRECATED v0.6.0` and `# TODO: Remove in v1.0.0`)
|
|
18
|
+
|
|
19
|
+
**Migration**:
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
# Old:
|
|
23
|
+
field: Annotated[str, AutoClickParameter.OPTION]
|
|
24
|
+
|
|
25
|
+
# New:
|
|
26
|
+
field: Annotated[str, AutoOption()]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 2. Standalone CommaSeparated Marker
|
|
30
|
+
|
|
31
|
+
**Location**: `wry/comma_separated.py:171-203`
|
|
32
|
+
**Deprecated**: v0.6.0
|
|
33
|
+
**Remove**: v1.0.0
|
|
34
|
+
**Replacement**: `AutoOption(comma_separated=True)`
|
|
35
|
+
|
|
36
|
+
**Code markers**:
|
|
37
|
+
|
|
38
|
+
- Class definition: `wry/comma_separated.py:171` (marked with `# DEPRECATED v0.6.0`)
|
|
39
|
+
- Detection logic: `wry/click_integration.py:463-480` (marked with `# DEPRECATED v0.6.0` and `# TODO: Remove in v1.0.0`)
|
|
40
|
+
|
|
41
|
+
**Migration**:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
# Old:
|
|
45
|
+
tags: Annotated[list[str], CommaSeparated]
|
|
46
|
+
|
|
47
|
+
# New:
|
|
48
|
+
tags: Annotated[list[str], AutoOption(comma_separated=True)]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 3. Unprefixed env_prefix ClassVar
|
|
52
|
+
|
|
53
|
+
**Location**: `wry/core/model.py:67`
|
|
54
|
+
**Deprecated**: v0.6.0
|
|
55
|
+
**Remove**: v1.0.0
|
|
56
|
+
**Replacement**: `wry_env_prefix`
|
|
57
|
+
|
|
58
|
+
**Code markers**:
|
|
59
|
+
|
|
60
|
+
- ClassVar definition: `wry/core/model.py:67` (marked with `# DEPRECATED v0.6.0`)
|
|
61
|
+
- Migration logic: `wry/core/model.py:77-88` (marked with `# DEPRECATED v0.6.0` and `# TODO: Remove in v1.0.0`)
|
|
62
|
+
|
|
63
|
+
**Migration**:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
# Old:
|
|
67
|
+
class Config(AutoWryModel):
|
|
68
|
+
env_prefix: ClassVar[str] = "MYAPP_"
|
|
69
|
+
|
|
70
|
+
# New:
|
|
71
|
+
class Config(AutoWryModel):
|
|
72
|
+
wry_env_prefix: ClassVar[str] = "MYAPP_"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 4. Unprefixed comma_separated_lists ClassVar
|
|
76
|
+
|
|
77
|
+
**Location**: `wry/core/model.py:68`
|
|
78
|
+
**Deprecated**: v0.6.0
|
|
79
|
+
**Remove**: v1.0.0
|
|
80
|
+
**Replacement**: `wry_comma_separated_lists`
|
|
81
|
+
|
|
82
|
+
**Code markers**:
|
|
83
|
+
|
|
84
|
+
- ClassVar definition: `wry/core/model.py:68` (marked with `# DEPRECATED v0.6.0`)
|
|
85
|
+
- Migration logic: `wry/core/model.py:90-101` (marked with `# DEPRECATED v0.6.0` and `# TODO: Remove in v1.0.0`)
|
|
86
|
+
|
|
87
|
+
**Migration**:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
# Old:
|
|
91
|
+
class Config(AutoWryModel):
|
|
92
|
+
comma_separated_lists: ClassVar[bool] = True
|
|
93
|
+
|
|
94
|
+
# New:
|
|
95
|
+
class Config(AutoWryModel):
|
|
96
|
+
wry_comma_separated_lists: ClassVar[bool] = True
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 5. Using Wry Marker Classes Without Calling Them
|
|
100
|
+
|
|
101
|
+
**Location**: `wry/click_integration.py:481-491`
|
|
102
|
+
**Deprecated**: v0.6.0
|
|
103
|
+
**Remove**: v1.0.0
|
|
104
|
+
**Replacement**: Call the class (add parentheses)
|
|
105
|
+
|
|
106
|
+
**Code markers**:
|
|
107
|
+
|
|
108
|
+
- Detection logic: `wry/click_integration.py:481-491` (marked with `# DEPRECATED v0.6.0` and `# TODO: Remove in v1.0.0`)
|
|
109
|
+
|
|
110
|
+
**Migration**:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
# Old (works but not recommended):
|
|
114
|
+
field: Annotated[str, AutoOption]
|
|
115
|
+
|
|
116
|
+
# New:
|
|
117
|
+
field: Annotated[str, AutoOption()]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Removal Checklist for v1.0.0
|
|
121
|
+
|
|
122
|
+
When removing deprecated features in v1.0.0:
|
|
123
|
+
|
|
124
|
+
### Code Removal
|
|
125
|
+
|
|
126
|
+
- [ ] Remove `AutoClickParameter` enum class (`wry/click_integration.py:97-115`)
|
|
127
|
+
- [ ] Remove AutoClickParameter detection block (`wry/click_integration.py:492-517`)
|
|
128
|
+
- [ ] Remove `CommaSeparated` marker class (`wry/comma_separated.py:171-203`)
|
|
129
|
+
- [ ] Remove CommaSeparated detection block (`wry/click_integration.py:463-480`)
|
|
130
|
+
- [ ] Remove `env_prefix` ClassVar (`wry/core/model.py:67`)
|
|
131
|
+
- [ ] Remove env_prefix migration block (`wry/core/model.py:77-88`)
|
|
132
|
+
- [ ] Remove `comma_separated_lists` ClassVar (`wry/core/model.py:68`)
|
|
133
|
+
- [ ] Remove comma_separated_lists migration block (`wry/core/model.py:90-101`)
|
|
134
|
+
- [ ] Remove uncalled marker class detection (`wry/click_integration.py:481-491`)
|
|
135
|
+
|
|
136
|
+
### Test Updates
|
|
137
|
+
|
|
138
|
+
- [ ] Remove or update tests using `AutoClickParameter` enum
|
|
139
|
+
- [ ] Remove or update tests using standalone `CommaSeparated`
|
|
140
|
+
- [ ] Remove or update tests using `env_prefix` without deprecation expectations
|
|
141
|
+
- [ ] Remove or update tests using `comma_separated_lists` without deprecation expectations
|
|
142
|
+
- [ ] Update `test_classvar_migration.py` - these tests won't be needed
|
|
143
|
+
|
|
144
|
+
### Documentation Updates
|
|
145
|
+
|
|
146
|
+
- [ ] Remove deprecation sections from `CHANGELOG.md`
|
|
147
|
+
- [ ] Remove migration guide from `CHANGELOG.md`
|
|
148
|
+
- [ ] Remove deprecated patterns from examples
|
|
149
|
+
- [ ] Update `AI_KNOWLEDGE_BASE.md` to remove old API references
|
|
150
|
+
- [ ] Update `README.md` to remove old patterns
|
|
151
|
+
- [ ] Archive this `DEPRECATION.md` file
|
|
152
|
+
|
|
153
|
+
## Search Commands for Finding Deprecated Code
|
|
154
|
+
|
|
155
|
+
Use these to find all deprecated code for removal:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Find all TODO: Remove in v1.0.0 markers
|
|
159
|
+
grep -r "TODO: Remove in v1.0.0" wry/
|
|
160
|
+
|
|
161
|
+
# Find all DEPRECATED v0.6.0 markers
|
|
162
|
+
grep -r "DEPRECATED v0.6.0" wry/
|
|
163
|
+
|
|
164
|
+
# Find AutoClickParameter usage
|
|
165
|
+
grep -r "AutoClickParameter" wry/ tests/
|
|
166
|
+
|
|
167
|
+
# Find CommaSeparated standalone usage
|
|
168
|
+
grep -r "CommaSeparated" wry/ tests/ | grep -v "comma_separated"
|
|
169
|
+
|
|
170
|
+
# Find old ClassVar names
|
|
171
|
+
grep -r "env_prefix:" wry/ tests/ | grep -v "wry_env_prefix"
|
|
172
|
+
grep -r "comma_separated_lists:" wry/ tests/ | grep -v "wry_comma_separated_lists"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Testing Deprecated Features
|
|
176
|
+
|
|
177
|
+
Before removal, ensure all deprecated features have:
|
|
178
|
+
|
|
179
|
+
1. ✅ Deprecation warnings in place
|
|
180
|
+
2. ✅ Backwards compatibility tests
|
|
181
|
+
3. ✅ Migration documented in CHANGELOG
|
|
182
|
+
4. ✅ Clear TODO markers in code
|
|
183
|
+
|
|
184
|
+
After removal in v1.0.0:
|
|
185
|
+
|
|
186
|
+
1. Run full test suite
|
|
187
|
+
2. Update all examples
|
|
188
|
+
3. Create migration guide
|
|
189
|
+
4. Update version compatibility matrix
|