qnty 0.0.7__py3-none-any.whl → 0.0.9__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 (76) hide show
  1. qnty/__init__.py +140 -58
  2. qnty/_backup/problem_original.py +1251 -0
  3. qnty/_backup/quantity.py +63 -0
  4. qnty/codegen/cli.py +125 -0
  5. qnty/codegen/generators/data/unit_data.json +8807 -0
  6. qnty/codegen/generators/data_processor.py +345 -0
  7. qnty/codegen/generators/dimensions_gen.py +434 -0
  8. qnty/codegen/generators/doc_generator.py +141 -0
  9. qnty/codegen/generators/out/dimension_mapping.json +974 -0
  10. qnty/codegen/generators/out/dimension_metadata.json +123 -0
  11. qnty/codegen/generators/out/units_metadata.json +223 -0
  12. qnty/codegen/generators/quantities_gen.py +159 -0
  13. qnty/codegen/generators/setters_gen.py +178 -0
  14. qnty/codegen/generators/stubs_gen.py +167 -0
  15. qnty/codegen/generators/units_gen.py +295 -0
  16. qnty/codegen/generators/utils/__init__.py +0 -0
  17. qnty/equations/__init__.py +4 -0
  18. qnty/equations/equation.py +257 -0
  19. qnty/equations/system.py +127 -0
  20. qnty/expressions/__init__.py +61 -0
  21. qnty/expressions/cache.py +94 -0
  22. qnty/expressions/functions.py +96 -0
  23. qnty/expressions/nodes.py +546 -0
  24. qnty/generated/__init__.py +0 -0
  25. qnty/generated/dimensions.py +514 -0
  26. qnty/generated/quantities.py +6003 -0
  27. qnty/generated/quantities.pyi +4192 -0
  28. qnty/generated/setters.py +12210 -0
  29. qnty/generated/units.py +9798 -0
  30. qnty/problem/__init__.py +91 -0
  31. qnty/problem/base.py +142 -0
  32. qnty/problem/composition.py +385 -0
  33. qnty/problem/composition_mixin.py +382 -0
  34. qnty/problem/equations.py +413 -0
  35. qnty/problem/metaclass.py +302 -0
  36. qnty/problem/reconstruction.py +1016 -0
  37. qnty/problem/solving.py +180 -0
  38. qnty/problem/validation.py +64 -0
  39. qnty/problem/variables.py +239 -0
  40. qnty/quantities/__init__.py +6 -0
  41. qnty/quantities/expression_quantity.py +314 -0
  42. qnty/quantities/quantity.py +428 -0
  43. qnty/quantities/typed_quantity.py +215 -0
  44. qnty/solving/__init__.py +0 -0
  45. qnty/solving/manager.py +90 -0
  46. qnty/solving/order.py +355 -0
  47. qnty/solving/solvers/__init__.py +20 -0
  48. qnty/solving/solvers/base.py +92 -0
  49. qnty/solving/solvers/iterative.py +185 -0
  50. qnty/solving/solvers/simultaneous.py +547 -0
  51. qnty/units/__init__.py +0 -0
  52. qnty/{prefixes.py → units/prefixes.py} +54 -33
  53. qnty/{unit.py → units/registry.py} +73 -32
  54. qnty/utils/__init__.py +0 -0
  55. qnty/utils/logging.py +40 -0
  56. qnty/validation/__init__.py +0 -0
  57. qnty/validation/registry.py +0 -0
  58. qnty/validation/rules.py +167 -0
  59. qnty-0.0.9.dist-info/METADATA +199 -0
  60. qnty-0.0.9.dist-info/RECORD +63 -0
  61. qnty/dimension.py +0 -186
  62. qnty/equation.py +0 -216
  63. qnty/expression.py +0 -492
  64. qnty/unit_types/base.py +0 -47
  65. qnty/units.py +0 -8113
  66. qnty/variable.py +0 -263
  67. qnty/variable_types/base.py +0 -58
  68. qnty/variable_types/expression_variable.py +0 -68
  69. qnty/variable_types/typed_variable.py +0 -87
  70. qnty/variables.py +0 -2298
  71. qnty/variables.pyi +0 -6148
  72. qnty-0.0.7.dist-info/METADATA +0 -355
  73. qnty-0.0.7.dist-info/RECORD +0 -19
  74. /qnty/{unit_types → codegen}/__init__.py +0 -0
  75. /qnty/{variable_types → codegen/generators}/__init__.py +0 -0
  76. {qnty-0.0.7.dist-info → qnty-0.0.9.dist-info}/WHEEL +0 -0
@@ -0,0 +1,63 @@
1
+ """
2
+ Public facade for quantity dimension classes.
3
+
4
+ End users import:
5
+ from qnty.quantity import Pressure, Length
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import TYPE_CHECKING, Any
11
+
12
+ # Explicit public API (trim as needed)
13
+ __all__ = [
14
+ "AbsorbedDose",
15
+ "Pressure",
16
+ "Length",
17
+ "Temperature",
18
+ "Force",
19
+ "Area",
20
+ "Volume",
21
+ # ... add remaining exported dimension classes ...
22
+ ]
23
+
24
+ # Internal lazy module cache
25
+ __generated_module: Any | None = None
26
+
27
+
28
+ def _load():
29
+ global __generated_module
30
+ if __generated_module is None:
31
+ from ..generated import quantities # local import for speed on cold start
32
+ __generated_module = quantities
33
+ return __generated_module
34
+
35
+
36
+ # Inject attributes lazily
37
+ def __getattr__(name: str):
38
+ if name in __all__:
39
+ mod = _load()
40
+ try:
41
+ return getattr(mod, name)
42
+ except AttributeError:
43
+ raise AttributeError(f"{name} not found in generated quantities") from None
44
+ raise AttributeError(f"module 'qnty.quantities' has no attribute '{name}'")
45
+
46
+
47
+ # Support dir() so tooling/REPLs see symbols
48
+ def __dir__():
49
+ return sorted(set(globals().keys()) | set(__all__))
50
+
51
+
52
+ # Static type checking: directly import symbols so type checkers see them.
53
+ if TYPE_CHECKING: # pragma: no cover
54
+ from ..generated.quantities import (
55
+ AbsorbedDose,
56
+ Area,
57
+ Force,
58
+ Length,
59
+ Pressure,
60
+ Temperature,
61
+ Volume,
62
+ # ... mirror list in __all__ ...
63
+ )
qnty/codegen/cli.py ADDED
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Code Generation CLI
4
+ ==================
5
+
6
+ Command-line interface for generating all qnty files in the correct dependency order:
7
+ 1. dimensions.py - Base dimensional constants
8
+ 2. units.py - Unit class definitions
9
+ 3. setters.py - Setter classes with unit properties
10
+ 4. quantities.py - Quantity classes
11
+ 5. quantities.pyi - Type stubs for IDE support
12
+
13
+ Can be run from IDE or command line:
14
+ - From command line: python cli.py
15
+ - From IDE: Run this file directly
16
+ """
17
+
18
+ import subprocess
19
+ import sys
20
+ from pathlib import Path
21
+
22
+
23
+ def run_generator(generator_name: str, script_path: Path) -> tuple[bool, str]:
24
+ """Run a single generator script and return success status with output."""
25
+ try:
26
+ print(f"\n{'='*60}")
27
+ print(f"Running {generator_name}...")
28
+ print(f"{'='*60}")
29
+
30
+ # Run the generator script as a module to allow relative imports
31
+ module_name = f"qnty.codegen.generators.{script_path.stem}"
32
+ result = subprocess.run(
33
+ [sys.executable, "-m", module_name],
34
+ capture_output=True,
35
+ text=True,
36
+ cwd=script_path.parents[4] # Run from project root
37
+ )
38
+
39
+ # Print the output
40
+ if result.stdout:
41
+ print(result.stdout)
42
+
43
+ if result.stderr:
44
+ print(f"STDERR: {result.stderr}")
45
+
46
+ if result.returncode == 0:
47
+ print(f"✓ {generator_name} completed successfully")
48
+ return True, result.stdout
49
+ else:
50
+ print(f"✗ {generator_name} failed with return code {result.returncode}")
51
+ return False, result.stderr
52
+
53
+ except Exception as e:
54
+ error_msg = f"Error running {generator_name}: {str(e)}"
55
+ print(error_msg)
56
+ return False, error_msg
57
+
58
+
59
+ def main() -> int:
60
+ """Main CLI function that runs all generators in dependency order."""
61
+ print("Qnty Code Generation Pipeline")
62
+ print("============================")
63
+ print("Generating all files in dependency order...")
64
+
65
+ # Get the generators subdirectory
66
+ script_dir = Path(__file__).parent / "generators"
67
+
68
+ # Define generators in dependency order
69
+ generators: list[tuple[str, str]] = [
70
+ ("Dimensions Generator", "dimensions_gen.py"),
71
+ ("Units Generator", "units_gen.py"),
72
+ ("Setters Generator", "setters_gen.py"),
73
+ ("Quantities Generator", "quantities_gen.py"),
74
+ ("Type Stubs Generator", "stubs_gen.py"),
75
+ ]
76
+
77
+ # Track results
78
+ success_count = 0
79
+ total_count = len(generators)
80
+ failed_generators = []
81
+
82
+ # Run each generator in order
83
+ for generator_name, script_name in generators:
84
+ script_path = script_dir / script_name
85
+
86
+ if not script_path.exists():
87
+ print(f"✗ {generator_name}: Script not found at {script_path}")
88
+ failed_generators.append(generator_name)
89
+ continue
90
+
91
+ success, output = run_generator(generator_name, script_path)
92
+ if success:
93
+ success_count += 1
94
+ else:
95
+ failed_generators.append(generator_name)
96
+ print(f"Output: {output}")
97
+
98
+ # Print final summary
99
+ print(f"\n{'='*60}")
100
+ print("GENERATION SUMMARY")
101
+ print(f"{'='*60}")
102
+ print(f"Successful: {success_count}/{total_count}")
103
+
104
+ if failed_generators:
105
+ print(f"Failed: {', '.join(failed_generators)}")
106
+ return 1
107
+ else:
108
+ print("✓ All generators completed successfully!")
109
+ print("\nGenerated files:")
110
+ print(" - src/qnty/generated/dimensions.py")
111
+ print(" - src/qnty/generated/units.py")
112
+ print(" - src/qnty/generated/setters.py")
113
+ print(" - src/qnty/generated/quantities.py")
114
+ print(" - src/qnty/generated/quantities.pyi")
115
+ return 0
116
+
117
+
118
+ if __name__ == "__main__":
119
+ exit_code = main()
120
+
121
+ # If running from IDE, pause so user can see results
122
+ if hasattr(sys, 'ps1') or 'idlelib' in sys.modules or 'IPython' in sys.modules:
123
+ input("\nPress Enter to continue...")
124
+
125
+ sys.exit(exit_code)