params-proto 3.2.2__tar.gz → 3.2.4__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.
- {params_proto-3.2.2 → params_proto-3.2.4}/.idea/workspace.xml +8 -3
- {params_proto-3.2.2 → params_proto-3.2.4}/PKG-INFO +1 -1
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/release_notes.md +19 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/pyproject.toml +1 -1
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/proto.py +25 -60
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_class_level_methods.py +7 -5
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_nested_cli.py +8 -7
- params_proto-3.2.4/tests/test_v3/test_proto_context_manager.py +179 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_proto_core.py +2 -1
- {params_proto-3.2.2 → params_proto-3.2.4}/.claude-plugin/marketplace.json +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.claude-plugin/plugin.json +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.editorconfig +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.gitignore +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.idea/.gitignore +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.idea/codeStyles/codeStyleConfig.xml +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.idea/inspectionProfiles/Project_Default.xml +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.idea/markdown.xml +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.idea/misc.xml +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.idea/modules.xml +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.idea/params-proto.iml +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.idea/ruff.xml +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.idea/vcs.xml +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.readthedocs.yaml +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.run/pytest for test_neo_proto_cli.run.xml +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/.run/pytest in test_params_proto.run.xml +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/ANSI_HELP_CONSIDERATIONS.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/CLAUDE.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/LICENSE.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/Makefile +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/README +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/README.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/Makefile +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/_archive_v2/api/hyper.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/_archive_v2/api/proto.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/_archive_v2/api/utils.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/_archive_v2/examples/advanced_features.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/_archive_v2/examples/basic_usage.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/_archive_v2/examples/environment_variables.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/_archive_v2/examples/hyperparameter_sweeps.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/_archive_v2/examples/index.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/_archive_v2/examples/nested_configs.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/_archive_v2/quick_start.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/_static/ansi.css +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/_static/custom.css +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/api/index.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/api/proto.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/conf.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/examples/basic_usage.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/examples/cli_applications.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/examples/ml_training.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/examples/rl_agent.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/index.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/advanced_patterns.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/ansi_formatting.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/cli-fundamentals.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/cli-patterns.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/configuration-patterns.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/core-concepts.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/environment_variables.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/help-generation.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/hyperparameter_sweeps.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/naming-conventions.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/parameter-iteration.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/parameter-overrides.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/type-system.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/union_types.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/key_concepts/welcome.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/migration.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/quick_start.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/docs/requirements.txt +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/examples/union_subcommands.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/figures/man-page.png +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/figures/params-proto-autocompletion.gif +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/figures/spec_files.png +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/scratch/demo_params_proto.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/scratch/demo_v3.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/scratch/proto_DAT_scratch.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/scratch/proto_dependency_tree_pattern.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/scratch/test_super.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/scratch/test_super_minimal.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/skills/params-proto/SKILL.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/skills/params-proto/references/cli-and-types.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/skills/params-proto/references/environment-vars.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/skills/params-proto/references/patterns.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/skills/params-proto/references/sweeps.md +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/skills/params-proto.skill +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/__init__.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/app.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/cli/__init__.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/cli/ansi_help.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/cli/cli_parse.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/cli/help_gen.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/documentation.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/envvar.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/hyper/__init__.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/hyper/proxies.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/hyper/sweep.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/parse_env_template.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/type_utils.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/v1/__init__.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/v1/hyper.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/v1/params_proto.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/v2/__init__.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/v2/hyper.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/v2/partial.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/v2/proto.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/src/params_proto/v2/utils.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v1/__init__.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v1/test_hyper.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v1/test_params_proto.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v2/test_Eval.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v2/test_neo_hyper.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v2/test_neo_proto.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v2/test_neo_proto_cli.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v2/test_neo_proto_partial.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v2/test_utils.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/conftest.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/samples/train.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_advanced_types.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_cli_parsing.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_help_strings.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_method_self_param.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_parse_env_template.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_piter.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_positional_example.sh +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_proto_comments.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_proto_envvar.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_proto_linebreaking.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_proto_partial.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_proto_required.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_strings.py +0 -0
- {params_proto-3.2.2 → params_proto-3.2.4}/tests/test_v3/test_sweep.py +0 -0
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
<option name="autoReloadType" value="SELECTIVE" />
|
|
5
5
|
</component>
|
|
6
6
|
<component name="ChangeListManager">
|
|
7
|
-
<list default="true" id="7a053ece-f497-4c97-ac58-a86c807155ac" name="Changes" comment="add design specs"
|
|
7
|
+
<list default="true" id="7a053ece-f497-4c97-ac58-a86c807155ac" name="Changes" comment="add design specs">
|
|
8
|
+
<change beforePath="$PROJECT_DIR$/src/params_proto/proto.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/params_proto/proto.py" afterDir="false" />
|
|
9
|
+
<change beforePath="$PROJECT_DIR$/tests/test_v3/test_class_level_methods.py" beforeDir="false" afterPath="$PROJECT_DIR$/tests/test_v3/test_class_level_methods.py" afterDir="false" />
|
|
10
|
+
</list>
|
|
8
11
|
<option name="SHOW_DIALOG" value="false" />
|
|
9
12
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
10
13
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
@@ -224,8 +227,8 @@
|
|
|
224
227
|
<component name="SharedIndexes">
|
|
225
228
|
<attachedChunks>
|
|
226
229
|
<set>
|
|
227
|
-
<option value="bundled-js-predefined-d6986cc7102b-9b0f141eb926-JavaScript-PY-253.30387.
|
|
228
|
-
<option value="bundled-python-sdk-
|
|
230
|
+
<option value="bundled-js-predefined-d6986cc7102b-9b0f141eb926-JavaScript-PY-253.30387.173" />
|
|
231
|
+
<option value="bundled-python-sdk-4762d8aabb82-6d6dccd035ac-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-253.30387.173" />
|
|
229
232
|
</set>
|
|
230
233
|
</attachedChunks>
|
|
231
234
|
</component>
|
|
@@ -260,6 +263,8 @@
|
|
|
260
263
|
<workItem from="1769933004821" duration="4284000" />
|
|
261
264
|
<workItem from="1770101044881" duration="1209000" />
|
|
262
265
|
<workItem from="1770110071925" duration="622000" />
|
|
266
|
+
<workItem from="1770163240415" duration="5903000" />
|
|
267
|
+
<workItem from="1770274540569" duration="373000" />
|
|
263
268
|
</task>
|
|
264
269
|
<task id="LOCAL-00001" summary="add design specs">
|
|
265
270
|
<option name="closed" value="true" />
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: params-proto
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.4
|
|
4
4
|
Summary: Modern Hyper Parameter Management for Machine Learning
|
|
5
5
|
Project-URL: Homepage, https://github.com/geyang/params-proto
|
|
6
6
|
Project-URL: Documentation, https://params-proto.readthedocs.io
|
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
This page contains the release history and changelog for params-proto.
|
|
4
4
|
|
|
5
|
+
## Version 3.2.4 (2025-02-04)
|
|
6
|
+
|
|
7
|
+
### 🐛 Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **Context Manager Protocol**: Fixed regression where `__enter__` and `__exit__` methods were stripped from `@proto` and `@proto.prefix` decorated classes
|
|
10
|
+
- Classes implementing context managers now work correctly with `with` statements
|
|
11
|
+
- Also preserves all user-defined protocol methods: `__call__`, `__iter__`, `__next__`, `__getitem__`, `__len__`, etc.
|
|
12
|
+
|
|
13
|
+
- **Simplified Implementation**: Removed method wrapping that caused issues
|
|
14
|
+
- Decorated class is now a proper subclass of the original, so methods are inherited naturally
|
|
15
|
+
- No more wrapping of methods to return `self` - use explicit `return self` if needed
|
|
16
|
+
- Standard Python semantics: classmethods receive `cls`, not bound to instance
|
|
17
|
+
|
|
18
|
+
### 🧪 Testing
|
|
19
|
+
|
|
20
|
+
- Added comprehensive tests for context manager and other Python protocol preservation
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
5
24
|
## Version 3.2.2 (2025-02-03)
|
|
6
25
|
|
|
7
26
|
### 🐛 Bug Fixes
|
|
@@ -694,46 +694,9 @@ class ptype(type):
|
|
|
694
694
|
|
|
695
695
|
# Update the instance's class to the decorated class
|
|
696
696
|
# This allows isinstance(instance, DecoratedClass) to work
|
|
697
|
+
# Since cls is a subclass of original_cls, methods are inherited naturally
|
|
697
698
|
object.__setattr__(instance, "__class__", cls)
|
|
698
699
|
|
|
699
|
-
# Copy methods from original class and wrap to return self
|
|
700
|
-
for name in dir(original_cls):
|
|
701
|
-
# Skip dunder methods and proto fields (fields are handled above)
|
|
702
|
-
if name.startswith("__") or name in annotations:
|
|
703
|
-
continue
|
|
704
|
-
|
|
705
|
-
# Check raw descriptor in MRO to detect staticmethod/classmethod (handles inheritance)
|
|
706
|
-
raw_attr = None
|
|
707
|
-
for klass in original_cls.__mro__:
|
|
708
|
-
if name in klass.__dict__:
|
|
709
|
-
raw_attr = klass.__dict__[name]
|
|
710
|
-
break
|
|
711
|
-
|
|
712
|
-
attr = getattr(original_cls, name)
|
|
713
|
-
|
|
714
|
-
# Only process actual methods (staticmethod, classmethod, or function)
|
|
715
|
-
if isinstance(raw_attr, staticmethod):
|
|
716
|
-
# For staticmethod, use directly (no binding needed)
|
|
717
|
-
method = attr
|
|
718
|
-
elif isinstance(raw_attr, classmethod) or inspect.isfunction(raw_attr) or inspect.ismethod(attr):
|
|
719
|
-
# For instance methods and classmethods, bind to instance
|
|
720
|
-
# Note: classmethods bound to instance is intentional for @proto
|
|
721
|
-
# semantics where instances have all attributes accessible
|
|
722
|
-
method = attr.__get__(instance, original_cls)
|
|
723
|
-
else:
|
|
724
|
-
# Not a method (e.g., _EnvVar, property, or other callable), skip
|
|
725
|
-
continue
|
|
726
|
-
|
|
727
|
-
# Wrap it to return self if it returns None
|
|
728
|
-
def make_wrapper(m):
|
|
729
|
-
def wrapper(*args, **kwargs):
|
|
730
|
-
result = m(*args, **kwargs)
|
|
731
|
-
return instance if result is None else result
|
|
732
|
-
|
|
733
|
-
return wrapper
|
|
734
|
-
|
|
735
|
-
setattr(instance, name, make_wrapper(method))
|
|
736
|
-
|
|
737
700
|
return instance
|
|
738
701
|
|
|
739
702
|
|
|
@@ -856,30 +819,32 @@ def proto(
|
|
|
856
819
|
else:
|
|
857
820
|
metaclass = ptype
|
|
858
821
|
|
|
859
|
-
#
|
|
860
|
-
#
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
except AttributeError:
|
|
872
|
-
pass
|
|
822
|
+
# Create new class with metaclass as subclass of original
|
|
823
|
+
# Since new class inherits from obj, methods are inherited naturally.
|
|
824
|
+
# We only need to provide:
|
|
825
|
+
# - Module/qualname metadata
|
|
826
|
+
# - Annotations (so annotated fields are visible on the class)
|
|
827
|
+
# - Resolved default values (with EnvVars resolved)
|
|
828
|
+
namespace = {
|
|
829
|
+
"__module__": obj.__module__,
|
|
830
|
+
"__qualname__": obj.__qualname__,
|
|
831
|
+
"__doc__": obj.__doc__,
|
|
832
|
+
"__annotations__": annotations,
|
|
833
|
+
}
|
|
873
834
|
|
|
874
|
-
#
|
|
875
|
-
#
|
|
876
|
-
for key
|
|
877
|
-
|
|
835
|
+
# Add resolved default values (EnvVars are already resolved in defaults dict)
|
|
836
|
+
# Also set None for annotated fields without defaults so they're accessible
|
|
837
|
+
for key in annotations.keys():
|
|
838
|
+
if key in defaults:
|
|
839
|
+
namespace[key] = defaults[key]
|
|
840
|
+
else:
|
|
841
|
+
namespace[key] = None
|
|
878
842
|
|
|
879
|
-
# Create new class
|
|
880
|
-
#
|
|
881
|
-
#
|
|
882
|
-
#
|
|
843
|
+
# Create new class as SUBCLASS of original.
|
|
844
|
+
# This ensures:
|
|
845
|
+
# 1. super() works correctly (original class is in MRO)
|
|
846
|
+
# 2. Methods, staticmethods, classmethods are inherited naturally
|
|
847
|
+
# 3. isinstance(instance, DecoratedClass) works
|
|
883
848
|
new_cls = metaclass(
|
|
884
849
|
obj.__name__,
|
|
885
850
|
(obj,),
|
|
@@ -150,13 +150,15 @@ class TestProtoPrefixWithMethods:
|
|
|
150
150
|
|
|
151
151
|
obj = Config()
|
|
152
152
|
|
|
153
|
-
# Classmethod should have access to config attributes via
|
|
153
|
+
# Classmethod should have access to config attributes via class
|
|
154
154
|
assert obj.get_lr() == 0.01
|
|
155
155
|
|
|
156
|
-
# Note: classmethods
|
|
157
|
-
# so they see
|
|
158
|
-
obj.lr = 0.001
|
|
159
|
-
assert obj.get_lr() == 0.
|
|
156
|
+
# Note: classmethods receive the class (cls), not instance,
|
|
157
|
+
# so they see class-level values (standard Python behavior)
|
|
158
|
+
obj.lr = 0.001 # Instance attribute
|
|
159
|
+
assert obj.get_lr() == 0.01 # Still sees class default
|
|
160
|
+
Config.lr = 0.002 # Class attribute
|
|
161
|
+
assert obj.get_lr() == 0.002 # Now sees class update
|
|
160
162
|
|
|
161
163
|
def test_proto_prefix_with_instance_method(self):
|
|
162
164
|
"""Test @proto.prefix on class with regular instance method."""
|
|
@@ -172,19 +172,20 @@ class TestThreeLayerNesting:
|
|
|
172
172
|
""")
|
|
173
173
|
|
|
174
174
|
# Try to override nested model config via deep dot notation
|
|
175
|
-
#
|
|
175
|
+
# Plain dataclasses use unprefixed syntax (--epochs, not --config.epochs)
|
|
176
|
+
# Only @proto.prefix decorated classes require prefixed syntax
|
|
176
177
|
result = run_cli(
|
|
177
178
|
script,
|
|
178
179
|
[
|
|
179
|
-
"
|
|
180
|
-
"--
|
|
180
|
+
"train-config", # subcommand name (kebab-case)
|
|
181
|
+
"--epochs",
|
|
181
182
|
"200",
|
|
182
|
-
"--
|
|
183
|
+
"--model.hidden_size",
|
|
183
184
|
"512",
|
|
184
|
-
"--
|
|
185
|
+
"--model.num_layers",
|
|
185
186
|
"8",
|
|
186
187
|
],
|
|
187
|
-
expect_error=True, #
|
|
188
|
+
expect_error=True, # Deep nested dot notation may not be supported yet
|
|
188
189
|
)
|
|
189
190
|
|
|
190
191
|
# Check if it succeeded or failed
|
|
@@ -196,7 +197,7 @@ class TestThreeLayerNesting:
|
|
|
196
197
|
else:
|
|
197
198
|
# If it failed, this documents the current limitation
|
|
198
199
|
pytest.skip(
|
|
199
|
-
"Deep nested dot notation (--
|
|
200
|
+
"Deep nested dot notation (--model.hidden_size) not yet supported"
|
|
200
201
|
)
|
|
201
202
|
|
|
202
203
|
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"""Test that @proto and @proto.prefix preserve context manager protocol."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from params_proto import proto
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TestContextManager:
|
|
8
|
+
"""Test context manager protocol preservation."""
|
|
9
|
+
|
|
10
|
+
def test_proto_prefix_context_manager(self):
|
|
11
|
+
"""Test that @proto.prefix preserves __enter__ and __exit__."""
|
|
12
|
+
|
|
13
|
+
@proto.prefix
|
|
14
|
+
class RUN:
|
|
15
|
+
prefix: str = "test"
|
|
16
|
+
entered: bool = False
|
|
17
|
+
exited: bool = False
|
|
18
|
+
|
|
19
|
+
def __enter__(self):
|
|
20
|
+
self.entered = True
|
|
21
|
+
return self
|
|
22
|
+
|
|
23
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
24
|
+
self.exited = True
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
run = RUN()
|
|
28
|
+
|
|
29
|
+
# Check methods exist
|
|
30
|
+
assert hasattr(run, "__enter__"), "Should have __enter__ method"
|
|
31
|
+
assert hasattr(run, "__exit__"), "Should have __exit__ method"
|
|
32
|
+
|
|
33
|
+
# Test actual context manager usage
|
|
34
|
+
with run as r:
|
|
35
|
+
assert r.entered, "Should have called __enter__"
|
|
36
|
+
assert not r.exited, "Should not have called __exit__ yet"
|
|
37
|
+
|
|
38
|
+
assert run.exited, "Should have called __exit__"
|
|
39
|
+
|
|
40
|
+
def test_proto_context_manager(self):
|
|
41
|
+
"""Test that @proto preserves __enter__ and __exit__."""
|
|
42
|
+
|
|
43
|
+
@proto
|
|
44
|
+
class Session:
|
|
45
|
+
name: str = "session"
|
|
46
|
+
active: bool = False
|
|
47
|
+
|
|
48
|
+
def __enter__(self):
|
|
49
|
+
self.active = True
|
|
50
|
+
return self
|
|
51
|
+
|
|
52
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
53
|
+
self.active = False
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
session = Session()
|
|
57
|
+
|
|
58
|
+
with session as s:
|
|
59
|
+
assert s.active, "Should be active inside context"
|
|
60
|
+
|
|
61
|
+
assert not session.active, "Should be inactive after context"
|
|
62
|
+
|
|
63
|
+
def test_context_manager_with_exception(self):
|
|
64
|
+
"""Test context manager handles exceptions correctly."""
|
|
65
|
+
|
|
66
|
+
@proto.prefix
|
|
67
|
+
class RUN:
|
|
68
|
+
prefix: str = "test"
|
|
69
|
+
exc_info: tuple = None
|
|
70
|
+
|
|
71
|
+
def __enter__(self):
|
|
72
|
+
return self
|
|
73
|
+
|
|
74
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
75
|
+
self.exc_info = (exc_type, exc_val, exc_tb)
|
|
76
|
+
return True # Suppress exception
|
|
77
|
+
|
|
78
|
+
run = RUN()
|
|
79
|
+
|
|
80
|
+
with run:
|
|
81
|
+
raise ValueError("test error")
|
|
82
|
+
|
|
83
|
+
# Exception should have been captured
|
|
84
|
+
assert run.exc_info[0] is ValueError
|
|
85
|
+
assert str(run.exc_info[1]) == "test error"
|
|
86
|
+
|
|
87
|
+
def test_context_manager_inheritance(self):
|
|
88
|
+
"""Test context manager works with inheritance."""
|
|
89
|
+
|
|
90
|
+
class BaseContext:
|
|
91
|
+
def __enter__(self):
|
|
92
|
+
self.entered = True
|
|
93
|
+
return self
|
|
94
|
+
|
|
95
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
96
|
+
self.exited = True
|
|
97
|
+
return False
|
|
98
|
+
|
|
99
|
+
@proto.prefix
|
|
100
|
+
class ChildRUN(BaseContext):
|
|
101
|
+
prefix: str = "child"
|
|
102
|
+
entered: bool = False
|
|
103
|
+
exited: bool = False
|
|
104
|
+
|
|
105
|
+
run = ChildRUN()
|
|
106
|
+
|
|
107
|
+
with run as r:
|
|
108
|
+
assert r.entered
|
|
109
|
+
|
|
110
|
+
assert run.exited
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class TestOtherProtocols:
|
|
114
|
+
"""Test other Python protocol methods are preserved."""
|
|
115
|
+
|
|
116
|
+
def test_callable_protocol(self):
|
|
117
|
+
"""Test __call__ is preserved."""
|
|
118
|
+
|
|
119
|
+
@proto.prefix
|
|
120
|
+
class Callable:
|
|
121
|
+
value: int = 0
|
|
122
|
+
call_count: int = 0
|
|
123
|
+
|
|
124
|
+
def __call__(self, x):
|
|
125
|
+
self.call_count += 1
|
|
126
|
+
return self.value + x
|
|
127
|
+
|
|
128
|
+
c = Callable()
|
|
129
|
+
c.value = 10
|
|
130
|
+
|
|
131
|
+
result = c(5)
|
|
132
|
+
assert result == 15
|
|
133
|
+
assert c.call_count == 1
|
|
134
|
+
|
|
135
|
+
def test_iterator_protocol(self):
|
|
136
|
+
"""Test __iter__ and __next__ are preserved."""
|
|
137
|
+
|
|
138
|
+
@proto.prefix
|
|
139
|
+
class Counter:
|
|
140
|
+
start: int = 0
|
|
141
|
+
end: int = 3
|
|
142
|
+
_current: int = 0
|
|
143
|
+
|
|
144
|
+
def __iter__(self):
|
|
145
|
+
self._current = self.start
|
|
146
|
+
return self
|
|
147
|
+
|
|
148
|
+
def __next__(self):
|
|
149
|
+
if self._current >= self.end:
|
|
150
|
+
raise StopIteration
|
|
151
|
+
value = self._current
|
|
152
|
+
self._current += 1
|
|
153
|
+
return value
|
|
154
|
+
|
|
155
|
+
counter = Counter()
|
|
156
|
+
result = list(counter)
|
|
157
|
+
assert result == [0, 1, 2]
|
|
158
|
+
|
|
159
|
+
def test_container_protocol(self):
|
|
160
|
+
"""Test __getitem__ and __len__ are preserved."""
|
|
161
|
+
|
|
162
|
+
@proto.prefix
|
|
163
|
+
class Container:
|
|
164
|
+
items: list = None
|
|
165
|
+
|
|
166
|
+
def __post_init__(self):
|
|
167
|
+
if self.items is None:
|
|
168
|
+
self.items = [1, 2, 3]
|
|
169
|
+
|
|
170
|
+
def __getitem__(self, index):
|
|
171
|
+
return self.items[index]
|
|
172
|
+
|
|
173
|
+
def __len__(self):
|
|
174
|
+
return len(self.items)
|
|
175
|
+
|
|
176
|
+
c = Container()
|
|
177
|
+
assert len(c) == 3
|
|
178
|
+
assert c[0] == 1
|
|
179
|
+
assert c[1] == 2
|
|
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
|
|
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
|
{params_proto-3.2.2 → params_proto-3.2.4}/docs/_archive_v2/examples/environment_variables.md
RENAMED
|
File without changes
|
{params_proto-3.2.2 → params_proto-3.2.4}/docs/_archive_v2/examples/hyperparameter_sweeps.md
RENAMED
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{params_proto-3.2.2 → params_proto-3.2.4}/skills/params-proto/references/environment-vars.md
RENAMED
|
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
|
|
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
|
|
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
|