params-proto 3.2.2__py3-none-any.whl → 3.2.4__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/proto.py CHANGED
@@ -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
- # Recreate the class with ptype as its metaclass
860
- # Collect class namespace (attributes and methods)
861
- namespace = {}
862
- for key in dir(obj):
863
- if not key.startswith("__") or key in ("__annotations__", "__module__", "__qualname__", "__doc__"):
864
- try:
865
- # Use __dict__ to preserve classmethod/staticmethod descriptors
866
- # getattr() would return bound methods instead of descriptors
867
- if key in obj.__dict__:
868
- namespace[key] = obj.__dict__[key]
869
- else:
870
- namespace[key] = getattr(obj, key)
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
- # Replace _EnvVar objects with resolved values from defaults
875
- # This ensures the descriptor doesn't interfere with class attribute access
876
- for key, value in defaults.items():
877
- namespace[key] = value
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 with metaclass
880
- # IMPORTANT: Use (obj,) as bases to make new class a SUBCLASS of original.
881
- # This ensures super() works correctly - the original class is in the MRO,
882
- # so Python's super() validation passes when checking isinstance(self, original_class).
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,),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: params-proto
3
- Version: 3.2.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
@@ -3,7 +3,7 @@ params_proto/app.py,sha256=UySpd1op3M44Szk6Ekyn0fJcnZsQvMTMPdaEybwWsLE,19
3
3
  params_proto/documentation.py,sha256=mIqmcwGWo8tM1BuNzLIwVTzdbQ3qyPus7yWTaOce4dM,8091
4
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=B3TqH9nPQgq9sXWrwpPnbcGiiWMR9eNS_0gXnWw_QGc,39557
6
+ params_proto/proto.py,sha256=9l_WFj3yfKbW74Jo-247rnJzNsinQHZ2wqW9K158Zeo,38081
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=-BTTwFOhJsaPnujwFIDh14QMB8r_ZdridK9I2Jkqd_U,19228
22
22
  params_proto/v2/utils.py,sha256=5EWvwboZDTsCYfzSED_J6RVFyNLIlf95nIu4p_ZSVxA,3540
23
- params_proto-3.2.2.dist-info/METADATA,sha256=EvdIaWolnBuaF6bU2orZOozwzDgGNVNipF4wYYw_CIU,8959
24
- params_proto-3.2.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
25
- params_proto-3.2.2.dist-info/licenses/LICENSE.md,sha256=c2qSYi9tUMZtzj9SEsMeKhub5LJUmHwBtDLiIMM5b6U,1526
26
- params_proto-3.2.2.dist-info/RECORD,,
23
+ params_proto-3.2.4.dist-info/METADATA,sha256=zHg8HnFEU7IQrSZLUZOOLi5WVfBUVkk__jKGgJDoh-s,8959
24
+ params_proto-3.2.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
25
+ params_proto-3.2.4.dist-info/licenses/LICENSE.md,sha256=c2qSYi9tUMZtzj9SEsMeKhub5LJUmHwBtDLiIMM5b6U,1526
26
+ params_proto-3.2.4.dist-info/RECORD,,