params-proto 3.1.0__py3-none-any.whl → 3.1.1__py3-none-any.whl
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/envvar.py +32 -18
- params_proto/proto.py +18 -3
- {params_proto-3.1.0.dist-info → params_proto-3.1.1.dist-info}/METADATA +1 -1
- {params_proto-3.1.0.dist-info → params_proto-3.1.1.dist-info}/RECORD +6 -6
- {params_proto-3.1.0.dist-info → params_proto-3.1.1.dist-info}/WHEEL +0 -0
- {params_proto-3.1.0.dist-info → params_proto-3.1.1.dist-info}/licenses/LICENSE.md +0 -0
params_proto/envvar.py
CHANGED
|
@@ -153,24 +153,44 @@ class _EnvVar:
|
|
|
153
153
|
return os.environ[name], True
|
|
154
154
|
return None, False
|
|
155
155
|
|
|
156
|
-
def
|
|
156
|
+
def invalidate_cache(self):
|
|
157
|
+
"""Clear the cached value, forcing re-read from environment on next access."""
|
|
158
|
+
self._cached_value = None
|
|
159
|
+
self._is_cached = False
|
|
160
|
+
|
|
161
|
+
def __get__(self, obj, objtype=None):
|
|
157
162
|
"""
|
|
158
|
-
|
|
163
|
+
Descriptor protocol: auto-resolve EnvVar when accessed as a class attribute.
|
|
164
|
+
|
|
165
|
+
This enables EnvVar to work in plain classes (not decorated with @ParamsProto):
|
|
166
|
+
|
|
167
|
+
class MyConfig:
|
|
168
|
+
api_key: str = EnvVar @ "API_KEY" | "default"
|
|
169
|
+
|
|
170
|
+
# Accessing MyConfig.api_key returns the resolved value, not the _EnvVar object
|
|
171
|
+
print(MyConfig.api_key) # "default" or value of $API_KEY
|
|
159
172
|
|
|
160
|
-
|
|
161
|
-
|
|
173
|
+
Values are cached after first resolution. Use invalidate_cache() to force re-read:
|
|
174
|
+
|
|
175
|
+
envvar = MyConfig.__dict__['api_key'] # Get the _EnvVar object
|
|
176
|
+
envvar.invalidate_cache()
|
|
177
|
+
print(MyConfig.api_key) # Re-reads from environment
|
|
162
178
|
|
|
163
179
|
Args:
|
|
164
|
-
|
|
165
|
-
|
|
180
|
+
obj: Instance (None if accessed on class)
|
|
181
|
+
objtype: The class being accessed
|
|
166
182
|
|
|
167
183
|
Returns:
|
|
168
|
-
|
|
184
|
+
The resolved environment variable value
|
|
169
185
|
"""
|
|
170
186
|
from params_proto.type_utils import _convert_type
|
|
171
187
|
|
|
172
|
-
#
|
|
173
|
-
if
|
|
188
|
+
# Don't resolve the singleton EnvVar instance itself (has no templates)
|
|
189
|
+
if not self.templates:
|
|
190
|
+
return self
|
|
191
|
+
|
|
192
|
+
# Return cached value if available
|
|
193
|
+
if self._is_cached:
|
|
174
194
|
return self._cached_value
|
|
175
195
|
|
|
176
196
|
# No templates means return default
|
|
@@ -192,18 +212,12 @@ class _EnvVar:
|
|
|
192
212
|
if result is not None and self.dtype is not None:
|
|
193
213
|
result = _convert_type(result, self.dtype)
|
|
194
214
|
|
|
195
|
-
# Cache the result
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
self._is_cached = True
|
|
215
|
+
# Cache the result
|
|
216
|
+
self._cached_value = result
|
|
217
|
+
self._is_cached = True
|
|
199
218
|
|
|
200
219
|
return result
|
|
201
220
|
|
|
202
|
-
def invalidate_cache(self):
|
|
203
|
-
"""Clear the cached value, forcing re-read from environment on next get()."""
|
|
204
|
-
self._cached_value = None
|
|
205
|
-
self._is_cached = False
|
|
206
|
-
|
|
207
221
|
def __repr__(self):
|
|
208
222
|
if self.templates:
|
|
209
223
|
if len(self.templates) == 1:
|
params_proto/proto.py
CHANGED
|
@@ -177,7 +177,7 @@ class ProtoWrapper:
|
|
|
177
177
|
if is_env_var:
|
|
178
178
|
# Resolve env var at decoration time
|
|
179
179
|
# NO auto-inference from parameter name for security reasons
|
|
180
|
-
env_value = default.
|
|
180
|
+
env_value = default.__get__(None, None)
|
|
181
181
|
|
|
182
182
|
# Apply type conversion based on dtype (if provided) or annotation
|
|
183
183
|
if env_value is not None:
|
|
@@ -801,7 +801,17 @@ def proto(
|
|
|
801
801
|
|
|
802
802
|
for name in annotations.keys():
|
|
803
803
|
if hasattr(obj, name):
|
|
804
|
-
value
|
|
804
|
+
# Look up value in class dict hierarchy to bypass descriptors like _EnvVar.__get__
|
|
805
|
+
value = None
|
|
806
|
+
for klass in obj.__mro__:
|
|
807
|
+
if klass is object:
|
|
808
|
+
continue
|
|
809
|
+
if name in vars(klass):
|
|
810
|
+
value = vars(klass)[name]
|
|
811
|
+
break
|
|
812
|
+
else:
|
|
813
|
+
value = getattr(obj, name)
|
|
814
|
+
|
|
805
815
|
# Check for EnvVar first (before callable check, since _EnvVar has __call__)
|
|
806
816
|
is_env_var = (
|
|
807
817
|
hasattr(value, "__class__") and value.__class__.__name__ == "_EnvVar"
|
|
@@ -809,7 +819,7 @@ def proto(
|
|
|
809
819
|
|
|
810
820
|
if is_env_var:
|
|
811
821
|
# Resolve env var at decoration time
|
|
812
|
-
env_value = value.
|
|
822
|
+
env_value = value.__get__(None, None)
|
|
813
823
|
annotation = annotations.get(name, str)
|
|
814
824
|
|
|
815
825
|
# Apply type conversion based on dtype (if provided) or annotation
|
|
@@ -848,6 +858,11 @@ def proto(
|
|
|
848
858
|
except AttributeError:
|
|
849
859
|
pass
|
|
850
860
|
|
|
861
|
+
# Replace _EnvVar objects with resolved values from defaults
|
|
862
|
+
# This ensures the descriptor doesn't interfere with class attribute access
|
|
863
|
+
for key, value in defaults.items():
|
|
864
|
+
namespace[key] = value
|
|
865
|
+
|
|
851
866
|
# Create new class with metaclass
|
|
852
867
|
new_cls = metaclass(
|
|
853
868
|
obj.__name__,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: params-proto
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.1
|
|
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
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
params_proto/__init__.py,sha256=JJfjHf6dpkNpLDGOyH0KBWFo44nQoxSIzmwfGZb36ZU,114
|
|
2
2
|
params_proto/app.py,sha256=UySpd1op3M44Szk6Ekyn0fJcnZsQvMTMPdaEybwWsLE,19
|
|
3
3
|
params_proto/documentation.py,sha256=mIqmcwGWo8tM1BuNzLIwVTzdbQ3qyPus7yWTaOce4dM,8091
|
|
4
|
-
params_proto/envvar.py,sha256=
|
|
4
|
+
params_proto/envvar.py,sha256=A87jxSAQ2tjbKLbrm96lblV90zNdtBGCSV6QRe2DrgA,8398
|
|
5
5
|
params_proto/parse_env_template.py,sha256=mXTvKpNhT2jGr3HpwKw42shd18O0QACmSJn6yWMDdKA,1298
|
|
6
|
-
params_proto/proto.py,sha256=
|
|
6
|
+
params_proto/proto.py,sha256=81q5EyPYtH7uHCT0L2ydiin5Na2kfJ2VO3LmDfu8AXM,38386
|
|
7
7
|
params_proto/type_utils.py,sha256=x68rL5m76ZFRKsCRgH_i_4vLpt6ldWEsEAalgacFIH8,7364
|
|
8
8
|
params_proto/cli/__init__.py,sha256=sLpN3GmaBqd_d0J0nvUNOeGlV74_-jQGW0nDUU34tjA,493
|
|
9
9
|
params_proto/cli/ansi_help.py,sha256=-1gzbvOpi9GjPlqgiINOYQAfIstzg0-ukv1se88TYCQ,10967
|
|
@@ -20,7 +20,7 @@ params_proto/v2/hyper.py,sha256=onBAkT8Ja8IkeHEOq1AwCdTuBzAnthIe766ZE0lAy-M,1146
|
|
|
20
20
|
params_proto/v2/partial.py,sha256=_ovi4NY8goYgHurfYt1OV0E9DSMXGYucjMVIyG1Q_xc,983
|
|
21
21
|
params_proto/v2/proto.py,sha256=KvinzgzwRQr2bHDNtrU7App2kgAyB-SEfBe4SNYceh0,18995
|
|
22
22
|
params_proto/v2/utils.py,sha256=5EWvwboZDTsCYfzSED_J6RVFyNLIlf95nIu4p_ZSVxA,3540
|
|
23
|
-
params_proto-3.1.
|
|
24
|
-
params_proto-3.1.
|
|
25
|
-
params_proto-3.1.
|
|
26
|
-
params_proto-3.1.
|
|
23
|
+
params_proto-3.1.1.dist-info/METADATA,sha256=Z8W21Wa1zInNKFoeY7TVXu2OQNo3TCQWjtX_RzmjgWM,8991
|
|
24
|
+
params_proto-3.1.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
25
|
+
params_proto-3.1.1.dist-info/licenses/LICENSE.md,sha256=c2qSYi9tUMZtzj9SEsMeKhub5LJUmHwBtDLiIMM5b6U,1526
|
|
26
|
+
params_proto-3.1.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|