qnty 0.1.1__py3-none-any.whl → 0.1.3__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.
- qnty/problems/problem.py +14 -0
- qnty/quantities/field_qnty.py +14 -2
- qnty/quantities/field_setter.pyi +6620 -0
- qnty/quantities/field_vars.py +4395 -389
- qnty/quantities/field_vars.pyi +2255 -2034
- {qnty-0.1.1.dist-info → qnty-0.1.3.dist-info}/METADATA +1 -1
- {qnty-0.1.1.dist-info → qnty-0.1.3.dist-info}/RECORD +8 -7
- {qnty-0.1.1.dist-info → qnty-0.1.3.dist-info}/WHEEL +0 -0
qnty/problems/problem.py
CHANGED
@@ -714,6 +714,20 @@ class Problem(ValidationMixin):
|
|
714
714
|
|
715
715
|
super().__setattr__(name, value)
|
716
716
|
|
717
|
+
def __getattr__(self, name: str) -> Any:
|
718
|
+
"""Dynamic attribute access for composed variables and other attributes."""
|
719
|
+
# Avoid recursion by checking the dict directly instead of using hasattr
|
720
|
+
try:
|
721
|
+
variables = object.__getattribute__(self, "variables")
|
722
|
+
if name in variables:
|
723
|
+
return variables[name]
|
724
|
+
except AttributeError:
|
725
|
+
# variables attribute doesn't exist yet (during initialization)
|
726
|
+
pass
|
727
|
+
|
728
|
+
# If not found, raise AttributeError
|
729
|
+
raise AttributeError(f"'{type(self).__name__}' object has no attribute '{name}'")
|
730
|
+
|
717
731
|
def __getitem__(self, key: str):
|
718
732
|
"""Allow dict-like access to variables."""
|
719
733
|
return self.get_variable(key)
|
qnty/quantities/field_qnty.py
CHANGED
@@ -738,7 +738,7 @@ class ExpressionMixin:
|
|
738
738
|
continue
|
739
739
|
|
740
740
|
# Strategy 2: Look for Equation objects in scope (created with .equals())
|
741
|
-
frame = ScopeDiscoveryService.
|
741
|
+
frame = ScopeDiscoveryService._get_cached_user_frame()
|
742
742
|
if frame:
|
743
743
|
for obj in list(frame.f_locals.values()) + list(frame.f_globals.values()):
|
744
744
|
if isinstance(obj, Equation):
|
@@ -775,8 +775,20 @@ class SetterCompatibilityMixin:
|
|
775
775
|
if not hasattr(self, "_setter_class"):
|
776
776
|
self._setter_class: type | None = None
|
777
777
|
|
778
|
-
def set(self, value: float) -> TypeSafeSetter:
|
778
|
+
def set(self, value: float, unit: str | None = None) -> 'Self | TypeSafeSetter':
|
779
779
|
"""Create setter object for fluent API compatibility."""
|
780
|
+
if unit is not None:
|
781
|
+
# Handle direct unit setting using the specialized setter
|
782
|
+
if hasattr(self, "_setter_class") and self._setter_class:
|
783
|
+
setter = self._setter_class(self, value)
|
784
|
+
if hasattr(setter, unit):
|
785
|
+
getattr(setter, unit)
|
786
|
+
return self
|
787
|
+
else:
|
788
|
+
raise ValueError(f"Unknown unit: {unit}")
|
789
|
+
else:
|
790
|
+
raise ValueError("Unit parameter not supported for this variable type")
|
791
|
+
|
780
792
|
if hasattr(self, "_setter_class") and self._setter_class:
|
781
793
|
return self._setter_class(self, value) # Correct parameter order
|
782
794
|
else:
|