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 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)
@@ -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._find_user_frame(getattr(ScopeDiscoveryService, '_get_current_frame', lambda: None)()) # type: ignore[misc]
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: