qnty 0.0.9__py3-none-any.whl → 0.1.0__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.
Files changed (92) hide show
  1. qnty/__init__.py +2 -3
  2. qnty/constants/__init__.py +10 -0
  3. qnty/constants/numerical.py +18 -0
  4. qnty/constants/solvers.py +6 -0
  5. qnty/constants/tests.py +6 -0
  6. qnty/dimensions/__init__.py +23 -0
  7. qnty/dimensions/base.py +97 -0
  8. qnty/dimensions/field_dims.py +126 -0
  9. qnty/dimensions/field_dims.pyi +128 -0
  10. qnty/dimensions/signature.py +111 -0
  11. qnty/equations/__init__.py +1 -1
  12. qnty/equations/equation.py +118 -155
  13. qnty/equations/system.py +68 -65
  14. qnty/expressions/__init__.py +25 -46
  15. qnty/expressions/formatter.py +188 -0
  16. qnty/expressions/functions.py +46 -68
  17. qnty/expressions/nodes.py +539 -384
  18. qnty/expressions/types.py +70 -0
  19. qnty/problems/__init__.py +145 -0
  20. qnty/problems/composition.py +1031 -0
  21. qnty/problems/problem.py +695 -0
  22. qnty/problems/rules.py +145 -0
  23. qnty/problems/solving.py +1216 -0
  24. qnty/problems/validation.py +127 -0
  25. qnty/quantities/__init__.py +28 -5
  26. qnty/quantities/base_qnty.py +677 -0
  27. qnty/quantities/field_converters.py +24004 -0
  28. qnty/quantities/field_qnty.py +1012 -0
  29. qnty/{generated/setters.py → quantities/field_setter.py} +3071 -2961
  30. qnty/{generated/quantities.py → quantities/field_vars.py} +754 -432
  31. qnty/{generated/quantities.pyi → quantities/field_vars.pyi} +1289 -1290
  32. qnty/solving/manager.py +50 -44
  33. qnty/solving/order.py +181 -133
  34. qnty/solving/solvers/__init__.py +2 -9
  35. qnty/solving/solvers/base.py +27 -37
  36. qnty/solving/solvers/iterative.py +115 -135
  37. qnty/solving/solvers/simultaneous.py +93 -165
  38. qnty/units/__init__.py +1 -0
  39. qnty/{generated/units.py → units/field_units.py} +1700 -991
  40. qnty/units/field_units.pyi +2461 -0
  41. qnty/units/prefixes.py +58 -105
  42. qnty/units/registry.py +76 -89
  43. qnty/utils/__init__.py +16 -0
  44. qnty/utils/caching/__init__.py +23 -0
  45. qnty/utils/caching/manager.py +401 -0
  46. qnty/utils/error_handling/__init__.py +66 -0
  47. qnty/utils/error_handling/context.py +39 -0
  48. qnty/utils/error_handling/exceptions.py +96 -0
  49. qnty/utils/error_handling/handlers.py +171 -0
  50. qnty/utils/logging.py +4 -4
  51. qnty/utils/protocols.py +164 -0
  52. qnty/utils/scope_discovery.py +420 -0
  53. {qnty-0.0.9.dist-info → qnty-0.1.0.dist-info}/METADATA +1 -1
  54. qnty-0.1.0.dist-info/RECORD +60 -0
  55. qnty/_backup/problem_original.py +0 -1251
  56. qnty/_backup/quantity.py +0 -63
  57. qnty/codegen/cli.py +0 -125
  58. qnty/codegen/generators/data/unit_data.json +0 -8807
  59. qnty/codegen/generators/data_processor.py +0 -345
  60. qnty/codegen/generators/dimensions_gen.py +0 -434
  61. qnty/codegen/generators/doc_generator.py +0 -141
  62. qnty/codegen/generators/out/dimension_mapping.json +0 -974
  63. qnty/codegen/generators/out/dimension_metadata.json +0 -123
  64. qnty/codegen/generators/out/units_metadata.json +0 -223
  65. qnty/codegen/generators/quantities_gen.py +0 -159
  66. qnty/codegen/generators/setters_gen.py +0 -178
  67. qnty/codegen/generators/stubs_gen.py +0 -167
  68. qnty/codegen/generators/units_gen.py +0 -295
  69. qnty/expressions/cache.py +0 -94
  70. qnty/generated/dimensions.py +0 -514
  71. qnty/problem/__init__.py +0 -91
  72. qnty/problem/base.py +0 -142
  73. qnty/problem/composition.py +0 -385
  74. qnty/problem/composition_mixin.py +0 -382
  75. qnty/problem/equations.py +0 -413
  76. qnty/problem/metaclass.py +0 -302
  77. qnty/problem/reconstruction.py +0 -1016
  78. qnty/problem/solving.py +0 -180
  79. qnty/problem/validation.py +0 -64
  80. qnty/problem/variables.py +0 -239
  81. qnty/quantities/expression_quantity.py +0 -314
  82. qnty/quantities/quantity.py +0 -428
  83. qnty/quantities/typed_quantity.py +0 -215
  84. qnty/validation/__init__.py +0 -0
  85. qnty/validation/registry.py +0 -0
  86. qnty/validation/rules.py +0 -167
  87. qnty-0.0.9.dist-info/RECORD +0 -63
  88. /qnty/{codegen → extensions}/__init__.py +0 -0
  89. /qnty/{codegen/generators → extensions/integration}/__init__.py +0 -0
  90. /qnty/{codegen/generators/utils → extensions/plotting}/__init__.py +0 -0
  91. /qnty/{generated → extensions/reporting}/__init__.py +0 -0
  92. {qnty-0.0.9.dist-info → qnty-0.1.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,127 @@
1
+ """
2
+ Problem-validation integration for Problem class.
3
+
4
+ This module provides validation functionality through a mixin pattern,
5
+ allowing Problems to run validation checks and collect warnings.
6
+
7
+ Key features:
8
+ - Type-safe validation check management
9
+ - Robust error handling for validation failures
10
+ - Integration with Problem metaclass system
11
+ - Proper closure handling to avoid late binding issues
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import logging
17
+ from collections.abc import Callable
18
+ from typing import Any, Protocol
19
+
20
+
21
+ class ValidationResult(Protocol):
22
+ """Protocol for validation check results."""
23
+
24
+ def evaluate(self, variables: dict[str, Any]) -> dict[str, Any] | None:
25
+ """Evaluate the validation check."""
26
+ ...
27
+
28
+
29
+ class ProblemAttributes(Protocol):
30
+ """Protocol defining expected attributes for validation mixin."""
31
+
32
+ logger: logging.Logger
33
+ warnings: list[dict[str, Any]]
34
+ validation_checks: list[Callable[[Any], dict[str, Any] | None]]
35
+ variables: dict[str, Any]
36
+
37
+
38
+ class ValidationMixin:
39
+ """Mixin class providing validation functionality."""
40
+
41
+ # These attributes will be provided by other mixins in the final Problem class
42
+ logger: logging.Logger
43
+ warnings: list[dict[str, Any]]
44
+ validation_checks: list[Callable[[Any], dict[str, Any] | None]]
45
+ variables: dict[str, Any]
46
+
47
+ def add_validation_check(self, check_function: Callable[[Any], dict[str, Any] | None]) -> None:
48
+ """Add a validation check function."""
49
+ if not callable(check_function):
50
+ raise TypeError("check_function must be callable")
51
+ self.validation_checks.append(check_function)
52
+
53
+ def validate(self) -> list[dict[str, Any]]:
54
+ """Run all validation checks and return any warnings."""
55
+ validation_warnings: list[dict[str, Any]] = []
56
+
57
+ for check in self.validation_checks:
58
+ if not callable(check):
59
+ self.logger.warning(f"Skipping non-callable validation check: {check}")
60
+ continue
61
+
62
+ try:
63
+ result = check(self)
64
+ if result is not None and isinstance(result, dict):
65
+ validation_warnings.append(result)
66
+ elif result is not None:
67
+ self.logger.warning(f"Validation check returned non-dict result: {type(result)}")
68
+ except Exception as e:
69
+ self.logger.debug(f"Validation check failed: {e}")
70
+
71
+ return validation_warnings
72
+
73
+ def get_warnings(self) -> list[dict[str, Any]]:
74
+ """Get all warnings from the problem."""
75
+ try:
76
+ warnings = self.warnings.copy() if hasattr(self, "warnings") and self.warnings else []
77
+ except (AttributeError, TypeError):
78
+ warnings = []
79
+ self.logger.warning("Problem warnings attribute is not properly initialized")
80
+
81
+ try:
82
+ validation_warnings = self.validate()
83
+ warnings.extend(validation_warnings)
84
+ except Exception as e:
85
+ self.logger.error(f"Failed to run validation: {e}")
86
+
87
+ return warnings
88
+
89
+ def _recreate_validation_checks(self) -> None:
90
+ """Collect and integrate validation checks from class-level Check objects."""
91
+ # Clear existing checks
92
+ self.validation_checks = []
93
+
94
+ # Safely get class checks
95
+ try:
96
+ class_checks: dict[str, ValidationResult] = getattr(self.__class__, "_class_checks", {})
97
+ except AttributeError:
98
+ self.logger.debug("No class checks found")
99
+ return
100
+
101
+ if not isinstance(class_checks, dict):
102
+ self.logger.warning(f"Expected dict for _class_checks, got {type(class_checks)}")
103
+ return
104
+
105
+ # Create validation functions from Check objects
106
+ for check_name, check_obj in class_checks.items():
107
+ if not hasattr(check_obj, "evaluate"):
108
+ self.logger.warning(f"Check object '{check_name}' missing 'evaluate' method")
109
+ continue
110
+
111
+ validation_function = self._create_validation_function(check_obj)
112
+ self.validation_checks.append(validation_function)
113
+
114
+ def _create_validation_function(self, check_obj: ValidationResult) -> Callable[[Any], dict[str, Any] | None]:
115
+ """Create a validation function from a check object, avoiding closure issues."""
116
+
117
+ def check_function(problem_instance: Any) -> dict[str, Any] | None:
118
+ try:
119
+ if not hasattr(problem_instance, "variables"):
120
+ return None
121
+ return check_obj.evaluate(problem_instance.variables)
122
+ except Exception as e:
123
+ if hasattr(problem_instance, "logger"):
124
+ problem_instance.logger.debug(f"Validation check evaluation failed: {e}")
125
+ return None
126
+
127
+ return check_function
@@ -1,6 +1,29 @@
1
- from .quantity import Quantity, TypeSafeVariable
1
+ """
2
+ Core Quantities Package
3
+ =====================
2
4
 
3
- __all__ = [
4
- "Quantity",
5
- "TypeSafeVariable"
6
- ]
5
+ High-performance quantity and variable systems.
6
+ """
7
+
8
+ from .base_qnty import Quantity
9
+ from .field_qnty import *
10
+ from .field_qnty import FieldQnty
11
+ from .field_vars import *
12
+
13
+ # Register types with TypeRegistry for performance optimization
14
+ try:
15
+ from ..utils.protocols import register_variable_type
16
+
17
+ register_variable_type(FieldQnty)
18
+ # Also register all generated field variable types
19
+ import inspect
20
+ import sys
21
+
22
+ current_module = sys.modules[__name__]
23
+ for _name, obj in inspect.getmembers(current_module, inspect.isclass):
24
+ if hasattr(obj, "_dimension") and issubclass(obj, FieldQnty):
25
+ register_variable_type(obj)
26
+ except ImportError:
27
+ pass # Handle import ordering gracefully
28
+
29
+ __all__ = ["Quantity", "FieldQnty"]