openepd 4.13.1__py3-none-any.whl → 5.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.
- openepd/__version__.py +1 -1
- openepd/model/common.py +40 -1
- openepd/model/declaration.py +7 -2
- openepd/model/geography.py +1 -1
- openepd/model/lcia.py +191 -19
- openepd/model/pcr.py +2 -2
- openepd/model/specs/README.md +34 -8
- openepd/model/specs/asphalt.py +2 -2
- openepd/model/specs/base.py +15 -5
- openepd/model/specs/generated/__init__.py +80 -0
- openepd/model/specs/generated/cladding.py +4 -4
- openepd/model/specs/generated/concrete.py +8 -7
- openepd/model/specs/generated/electrical.py +2 -2
- openepd/model/specs/generated/finishes.py +10 -6
- openepd/model/specs/generated/masonry.py +6 -2
- openepd/model/specs/generated/network_infrastructure.py +7 -2
- openepd/model/specs/generated/openings.py +10 -6
- openepd/model/specs/generated/sheathing.py +8 -4
- openepd/model/specs/generated/steel.py +10 -5
- openepd/model/specs/range/__init__.py +101 -0
- openepd/model/specs/range/accessories.py +97 -0
- openepd/model/specs/range/aggregates.py +57 -0
- openepd/model/specs/range/aluminium.py +92 -0
- openepd/model/specs/range/asphalt.py +61 -0
- openepd/model/specs/range/bulk_materials.py +31 -0
- openepd/model/specs/range/cast_decks_and_underlayment.py +34 -0
- openepd/model/specs/range/cladding.py +275 -0
- openepd/model/specs/range/cmu.py +44 -0
- openepd/model/specs/range/concrete.py +179 -0
- openepd/model/specs/range/conveying_equipment.py +86 -0
- openepd/model/specs/range/electrical.py +422 -0
- openepd/model/specs/range/electrical_transmission_and_distribution_equipment.py +96 -0
- openepd/model/specs/range/electricity.py +31 -0
- openepd/model/specs/range/finishes.py +585 -0
- openepd/model/specs/range/fire_and_smoke_protection.py +108 -0
- openepd/model/specs/range/furnishings.py +137 -0
- openepd/model/specs/range/grouting.py +34 -0
- openepd/model/specs/range/manufacturing_inputs.py +190 -0
- openepd/model/specs/range/masonry.py +87 -0
- openepd/model/specs/range/material_handling.py +50 -0
- openepd/model/specs/range/mechanical.py +307 -0
- openepd/model/specs/range/mechanical_insulation.py +42 -0
- openepd/model/specs/range/network_infrastructure.py +208 -0
- openepd/model/specs/range/openings.py +512 -0
- openepd/model/specs/range/other_electrical_equipment.py +31 -0
- openepd/model/specs/range/other_materials.py +194 -0
- openepd/model/specs/range/plumbing.py +200 -0
- openepd/model/specs/range/precast_concrete.py +115 -0
- openepd/model/specs/range/sheathing.py +86 -0
- openepd/model/specs/range/steel.py +332 -0
- openepd/model/specs/range/thermal_moisture_protection.py +336 -0
- openepd/model/specs/range/utility_piping.py +75 -0
- openepd/model/specs/range/wood.py +228 -0
- openepd/model/specs/range/wood_joists.py +44 -0
- openepd/model/validation/numbers.py +11 -5
- openepd/model/validation/quantity.py +469 -58
- {openepd-4.13.1.dist-info → openepd-5.1.0.dist-info}/METADATA +6 -1
- {openepd-4.13.1.dist-info → openepd-5.1.0.dist-info}/RECORD +60 -25
- {openepd-4.13.1.dist-info → openepd-5.1.0.dist-info}/LICENSE +0 -0
- {openepd-4.13.1.dist-info → openepd-5.1.0.dist-info}/WHEEL +0 -0
@@ -17,12 +17,11 @@ from abc import ABC, abstractmethod
|
|
17
17
|
from typing import TYPE_CHECKING, Any, Callable, ClassVar
|
18
18
|
|
19
19
|
from openepd.compat.pydantic import pyd
|
20
|
-
from openepd.model.
|
20
|
+
from openepd.model.base import BaseOpenEpdSchema
|
21
|
+
from openepd.model.common import Amount, OpenEPDUnit, RangeAmount
|
21
22
|
|
22
23
|
if TYPE_CHECKING:
|
23
|
-
|
24
|
-
|
25
|
-
QuantityValidatorType = Callable[[type[BaseOpenEpdHierarchicalSpec], str], str]
|
24
|
+
QuantityValidatorType = Callable[[type, str], str]
|
26
25
|
|
27
26
|
|
28
27
|
class QuantityValidator(ABC):
|
@@ -33,6 +32,19 @@ class QuantityValidator(ABC):
|
|
33
32
|
and set it with `set_unit_validator` function.
|
34
33
|
"""
|
35
34
|
|
35
|
+
@abstractmethod
|
36
|
+
def validate_same_dimensionality(self, unit: str | None, dimensionality_unit: str) -> None:
|
37
|
+
"""
|
38
|
+
Validate that a given unit ('kg') has the same dimesnionality as provided dimensionality_unit ('g').
|
39
|
+
|
40
|
+
:param unit: unit to validate, not quantity
|
41
|
+
:param dimensionality_unit: unit to check against
|
42
|
+
:raise:
|
43
|
+
ValueError if dimensionality is different
|
44
|
+
:return: None
|
45
|
+
"""
|
46
|
+
pass
|
47
|
+
|
36
48
|
@abstractmethod
|
37
49
|
def validate_unit_correctness(self, value: str, dimensionality: str) -> None:
|
38
50
|
"""
|
@@ -79,46 +91,56 @@ class QuantityValidator(ABC):
|
|
79
91
|
pass
|
80
92
|
|
81
93
|
|
94
|
+
class ExternalValidationConfig:
|
95
|
+
"""
|
96
|
+
Configuration holder for external validator.
|
97
|
+
|
98
|
+
Since openEPD library does not provide any facility for working with quantities/units, users should do this
|
99
|
+
by implementing the protocol for this validator and setting it with setup_external_validators function.
|
100
|
+
"""
|
101
|
+
|
102
|
+
QUANTITY_VALIDATOR: ClassVar[QuantityValidator | None] = None
|
103
|
+
|
104
|
+
|
82
105
|
def validate_unit_factory(dimensionality: OpenEPDUnit | str) -> "QuantityValidatorType":
|
83
|
-
"""Create validator for
|
106
|
+
"""Create validator for units (not quantities) to check for dimensionality."""
|
84
107
|
|
85
|
-
def validator(cls:
|
86
|
-
if
|
87
|
-
|
108
|
+
def validator(cls: type | None, value: str) -> str:
|
109
|
+
if ExternalValidationConfig.QUANTITY_VALIDATOR is not None:
|
110
|
+
ExternalValidationConfig.QUANTITY_VALIDATOR.validate_same_dimensionality(value, dimensionality)
|
88
111
|
return value
|
89
112
|
|
90
113
|
return validator
|
91
114
|
|
92
115
|
|
93
|
-
def
|
94
|
-
"""Create validator
|
116
|
+
def validate_quantity_unit_factory(dimensionality: OpenEPDUnit | str) -> "QuantityValidatorType":
|
117
|
+
"""Create validator for quantity field to check unit matching."""
|
95
118
|
|
96
|
-
def validator(cls:
|
97
|
-
if
|
98
|
-
|
119
|
+
def validator(cls: type | None, value: str) -> str:
|
120
|
+
if ExternalValidationConfig.QUANTITY_VALIDATOR is not None:
|
121
|
+
ExternalValidationConfig.QUANTITY_VALIDATOR.validate_unit_correctness(value, dimensionality)
|
99
122
|
return value
|
100
123
|
|
101
124
|
return validator
|
102
125
|
|
103
126
|
|
104
|
-
def
|
105
|
-
"""Create validator to check that quantity is
|
127
|
+
def validate_quantity_ge_factory(min_value: str) -> "QuantityValidatorType":
|
128
|
+
"""Create validator to check that quantity is greater than or equal to min_value."""
|
106
129
|
|
107
|
-
def validator(cls:
|
108
|
-
if
|
109
|
-
|
130
|
+
def validator(cls: type | None, value: str) -> str:
|
131
|
+
if ExternalValidationConfig.QUANTITY_VALIDATOR is not None:
|
132
|
+
ExternalValidationConfig.QUANTITY_VALIDATOR.validate_quantity_greater_or_equal(value, min_value)
|
110
133
|
return value
|
111
134
|
|
112
135
|
return validator
|
113
136
|
|
114
137
|
|
115
|
-
def
|
138
|
+
def validate_quantity_le_factory(max_value: str) -> "QuantityValidatorType":
|
116
139
|
"""Create validator to check that quantity is less than or equal to max_value."""
|
117
140
|
|
118
|
-
def validator(value: str) -> str:
|
119
|
-
|
120
|
-
|
121
|
-
cls._QUANTITY_VALIDATOR.validate_quantity_less_or_equal(value, max_value)
|
141
|
+
def validator(cls: type | None, value: str) -> str:
|
142
|
+
if ExternalValidationConfig.QUANTITY_VALIDATOR is not None:
|
143
|
+
ExternalValidationConfig.QUANTITY_VALIDATOR.validate_quantity_less_or_equal(value, max_value)
|
122
144
|
return value
|
123
145
|
|
124
146
|
return validator
|
@@ -128,38 +150,6 @@ def validate_quantity_for_new_validator(max_value: str) -> Callable:
|
|
128
150
|
# todo these types should be replaced by Annotated[str, AfterValidator...] as we move completely to pydantic 2
|
129
151
|
|
130
152
|
|
131
|
-
class AmountWithDimensionality(Amount, ABC):
|
132
|
-
"""Class for dimensionality-validated amounts."""
|
133
|
-
|
134
|
-
dimensionality_unit: ClassVar[str | None] = None
|
135
|
-
|
136
|
-
# Unit for dimensionality to validate against, for example "kg"
|
137
|
-
|
138
|
-
@pyd.root_validator
|
139
|
-
def check_dimensionality_matches(cls, values: dict[str, Any]) -> dict[str, Any]:
|
140
|
-
"""Check that this amount conforms to the same dimensionality as dimensionality_unit."""
|
141
|
-
if not cls.dimensionality_unit:
|
142
|
-
return values
|
143
|
-
|
144
|
-
from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
|
145
|
-
|
146
|
-
str_repr = f"{values['qty']} {values['unit']}"
|
147
|
-
validate_unit_factory(cls.dimensionality_unit)(BaseOpenEpdHierarchicalSpec, str_repr)
|
148
|
-
return values
|
149
|
-
|
150
|
-
|
151
|
-
class AmountMass(AmountWithDimensionality):
|
152
|
-
"""Amount of mass, measured in kg, t, etc."""
|
153
|
-
|
154
|
-
dimensionality_unit = OpenEPDUnit.kg
|
155
|
-
|
156
|
-
|
157
|
-
class AmountGWP(AmountWithDimensionality):
|
158
|
-
"""Amount of Global Warming Potential, measured in kgCO2e."""
|
159
|
-
|
160
|
-
dimensionality_unit = OpenEPDUnit.kg_co2
|
161
|
-
|
162
|
-
|
163
153
|
class QuantityStr(str):
|
164
154
|
"""
|
165
155
|
Quantity string type.
|
@@ -173,8 +163,10 @@ class QuantityStr(str):
|
|
173
163
|
|
174
164
|
@classmethod
|
175
165
|
def __get_validators__(cls):
|
176
|
-
|
177
|
-
|
166
|
+
unit = getattr(cls, "unit", None)
|
167
|
+
if unit:
|
168
|
+
yield validate_quantity_unit_factory(cls.unit)
|
169
|
+
yield validate_quantity_ge_factory(f"0 {cls.unit}")
|
178
170
|
|
179
171
|
@classmethod
|
180
172
|
def __modify_schema__(cls, field_schema):
|
@@ -222,7 +214,7 @@ class LengthMmStr(QuantityStr):
|
|
222
214
|
class LengthInchStr(QuantityStr):
|
223
215
|
"""Length (inch) quantity type."""
|
224
216
|
|
225
|
-
unit =
|
217
|
+
unit = "inch"
|
226
218
|
|
227
219
|
@classmethod
|
228
220
|
def __modify_schema__(cls, field_schema):
|
@@ -313,3 +305,422 @@ class AreaPerVolumeStr(QuantityStr):
|
|
313
305
|
"""Area per unit of volume quantity type."""
|
314
306
|
|
315
307
|
unit = "m2 / l"
|
308
|
+
|
309
|
+
|
310
|
+
class WithDimensionalityMixin(BaseOpenEpdSchema):
|
311
|
+
"""Class for dimensionality-validated amounts."""
|
312
|
+
|
313
|
+
dimensionality_unit: ClassVar[str | None] = None
|
314
|
+
|
315
|
+
# Unit for dimensionality to validate against, for example "kg"
|
316
|
+
|
317
|
+
@pyd.root_validator
|
318
|
+
def check_dimensionality_matches(cls, values: dict[str, Any]) -> dict[str, Any]:
|
319
|
+
"""Check that this amount conforms to the same dimensionality as dimensionality_unit."""
|
320
|
+
if not cls.dimensionality_unit:
|
321
|
+
return values
|
322
|
+
|
323
|
+
validate_unit_factory(cls.dimensionality_unit)(BaseOpenEpdSchema, values.get("unit")) # type:ignore [arg-type]
|
324
|
+
return values
|
325
|
+
|
326
|
+
|
327
|
+
class AmountRangeWithDimensionality(RangeAmount, WithDimensionalityMixin):
|
328
|
+
"""Mass amount, range."""
|
329
|
+
|
330
|
+
class Config:
|
331
|
+
"""Pydantic config."""
|
332
|
+
|
333
|
+
@staticmethod
|
334
|
+
def schema_extra(schema: dict[str, Any], model: type["AmountRangeWithDimensionality"]) -> None:
|
335
|
+
"""Modify json schema."""
|
336
|
+
schema["example"] = {"min": 1.2, "max": 3.4, "unit": str(model.dimensionality_unit) or None}
|
337
|
+
|
338
|
+
|
339
|
+
class WithMassKgMixin(WithDimensionalityMixin):
|
340
|
+
"""Unit validation mixin."""
|
341
|
+
|
342
|
+
dimensionality_unit = MassKgStr.unit
|
343
|
+
|
344
|
+
|
345
|
+
class AmountMass(Amount, WithMassKgMixin):
|
346
|
+
"""Amount of mass, measured in kg, t, etc."""
|
347
|
+
|
348
|
+
pass
|
349
|
+
|
350
|
+
|
351
|
+
class AmountRangeMass(AmountRangeWithDimensionality, WithMassKgMixin):
|
352
|
+
"""Range of masses."""
|
353
|
+
|
354
|
+
pass
|
355
|
+
|
356
|
+
|
357
|
+
class WithGwpMixin(WithDimensionalityMixin):
|
358
|
+
"""Unit validation mixin."""
|
359
|
+
|
360
|
+
dimensionality_unit = GwpKgCo2eStr.unit
|
361
|
+
|
362
|
+
|
363
|
+
class AmountGWP(Amount, WithGwpMixin):
|
364
|
+
"""Amount of Global Warming Potential, measured in kgCO2e."""
|
365
|
+
|
366
|
+
pass
|
367
|
+
|
368
|
+
|
369
|
+
class AmountRangeGWP(AmountRangeWithDimensionality, WithGwpMixin):
|
370
|
+
"""Range of masses."""
|
371
|
+
|
372
|
+
pass
|
373
|
+
|
374
|
+
|
375
|
+
class WithLengthMMixin(WithDimensionalityMixin):
|
376
|
+
"""Unit validation mixin."""
|
377
|
+
|
378
|
+
pass
|
379
|
+
|
380
|
+
|
381
|
+
class AmountRangeLengthM(AmountRangeWithDimensionality, WithLengthMMixin):
|
382
|
+
"""Range of lengths (m)."""
|
383
|
+
|
384
|
+
pass
|
385
|
+
|
386
|
+
|
387
|
+
class AmountLengthM(Amount, WithLengthMMixin):
|
388
|
+
"""Length (m)."""
|
389
|
+
|
390
|
+
pass
|
391
|
+
|
392
|
+
|
393
|
+
class WithLengthMmMixin(WithDimensionalityMixin):
|
394
|
+
"""Unit validation mixin."""
|
395
|
+
|
396
|
+
dimensionality_unit = LengthMmStr.unit
|
397
|
+
|
398
|
+
|
399
|
+
class AmountLengthMm(Amount, WithLengthMMixin):
|
400
|
+
"""Length (mm)."""
|
401
|
+
|
402
|
+
pass
|
403
|
+
|
404
|
+
|
405
|
+
class AmountRangeLengthMm(AmountRangeWithDimensionality, WithLengthMmMixin):
|
406
|
+
"""Range of lengths (mm)."""
|
407
|
+
|
408
|
+
pass
|
409
|
+
|
410
|
+
|
411
|
+
class WithPressureMpaMixin(WithDimensionalityMixin):
|
412
|
+
"""Unit validation mixin."""
|
413
|
+
|
414
|
+
dimensionality_unit = PressureMPaStr.unit
|
415
|
+
|
416
|
+
|
417
|
+
class AmountPressureMpa(Amount, WithPressureMpaMixin):
|
418
|
+
"""Length (mm)."""
|
419
|
+
|
420
|
+
pass
|
421
|
+
|
422
|
+
|
423
|
+
class AmountRangePressureMpa(AmountRangeWithDimensionality, WithPressureMpaMixin):
|
424
|
+
"""Range of lengths (mm)."""
|
425
|
+
|
426
|
+
pass
|
427
|
+
|
428
|
+
|
429
|
+
class WithAreaM2Mixin(WithDimensionalityMixin):
|
430
|
+
"""Unit validation mixin."""
|
431
|
+
|
432
|
+
dimensionality_unit = AreaM2Str.unit
|
433
|
+
|
434
|
+
|
435
|
+
class AmountAreaM2(Amount, WithAreaM2Mixin):
|
436
|
+
"""Area (m2)."""
|
437
|
+
|
438
|
+
pass
|
439
|
+
|
440
|
+
|
441
|
+
class AmountRangeAreaM2(AmountRangeWithDimensionality, WithAreaM2Mixin):
|
442
|
+
"""Range of Area (m2)."""
|
443
|
+
|
444
|
+
pass
|
445
|
+
|
446
|
+
|
447
|
+
class WithLengthInchStr(WithDimensionalityMixin):
|
448
|
+
"""Unit validation mixin."""
|
449
|
+
|
450
|
+
dimensionality_unit = LengthInchStr.unit
|
451
|
+
|
452
|
+
|
453
|
+
class AmountLengthInch(Amount, WithLengthInchStr):
|
454
|
+
"""Length (inch)."""
|
455
|
+
|
456
|
+
pass
|
457
|
+
|
458
|
+
|
459
|
+
class AmountRangeLengthInch(AmountRangeWithDimensionality, WithLengthInchStr):
|
460
|
+
"""Range of Length (inch)."""
|
461
|
+
|
462
|
+
pass
|
463
|
+
|
464
|
+
|
465
|
+
class WithTemperatureCMixin(WithDimensionalityMixin):
|
466
|
+
"""Unit validation mixin."""
|
467
|
+
|
468
|
+
dimensionality_unit = TemperatureCStr.unit
|
469
|
+
|
470
|
+
|
471
|
+
class AmountTemperatureC(Amount, WithTemperatureCMixin):
|
472
|
+
"""Temperature (degrees C)."""
|
473
|
+
|
474
|
+
pass
|
475
|
+
|
476
|
+
|
477
|
+
class AmountRangeTemperatureC(AmountRangeWithDimensionality, WithTemperatureCMixin):
|
478
|
+
"""Range of Temperature (degrees C)."""
|
479
|
+
|
480
|
+
pass
|
481
|
+
|
482
|
+
|
483
|
+
class WithCapacityPerHourMixin(WithDimensionalityMixin):
|
484
|
+
"""Unit validation mixin."""
|
485
|
+
|
486
|
+
dimensionality_unit = CapacityPerHourStr.unit
|
487
|
+
|
488
|
+
|
489
|
+
class AmountCapacityPerHour(Amount, WithCapacityPerHourMixin):
|
490
|
+
"""Capacity per hour."""
|
491
|
+
|
492
|
+
pass
|
493
|
+
|
494
|
+
|
495
|
+
class AmountRangeCapacityPerHour(AmountRangeWithDimensionality, WithCapacityPerHourMixin):
|
496
|
+
"""Capacity per hour range."""
|
497
|
+
|
498
|
+
pass
|
499
|
+
|
500
|
+
|
501
|
+
class WithRValueMixin(WithDimensionalityMixin):
|
502
|
+
"""Unit validation mixin."""
|
503
|
+
|
504
|
+
dimensionality_unit = RValueStr.unit
|
505
|
+
|
506
|
+
|
507
|
+
class AmountRValue(Amount, WithRValueMixin):
|
508
|
+
"""R-Value."""
|
509
|
+
|
510
|
+
pass
|
511
|
+
|
512
|
+
|
513
|
+
class AmountRangeRValue(AmountRangeWithDimensionality, WithRValueMixin):
|
514
|
+
"""R-Value range."""
|
515
|
+
|
516
|
+
pass
|
517
|
+
|
518
|
+
|
519
|
+
class WithSpeedMixin(WithDimensionalityMixin):
|
520
|
+
"""Unit validation mixin."""
|
521
|
+
|
522
|
+
dimensionality_unit = SpeedStr.unit
|
523
|
+
|
524
|
+
|
525
|
+
class AmountSpeed(Amount, WithSpeedMixin):
|
526
|
+
"""Speed."""
|
527
|
+
|
528
|
+
pass
|
529
|
+
|
530
|
+
|
531
|
+
class AmountRangeSpeed(AmountRangeWithDimensionality, WithSpeedMixin):
|
532
|
+
"""Speed range."""
|
533
|
+
|
534
|
+
pass
|
535
|
+
|
536
|
+
|
537
|
+
class WithColorTemperatureMixin(WithDimensionalityMixin):
|
538
|
+
"""Unit validation mixin."""
|
539
|
+
|
540
|
+
dimensionality_unit = ColorTemperatureStr.unit
|
541
|
+
|
542
|
+
|
543
|
+
class AmountColorTemperature(Amount, WithColorTemperatureMixin):
|
544
|
+
"""Color temperature."""
|
545
|
+
|
546
|
+
pass
|
547
|
+
|
548
|
+
|
549
|
+
class AmountRangeColorTemperature(AmountRangeWithDimensionality, WithColorTemperatureMixin):
|
550
|
+
"""Color temperature range."""
|
551
|
+
|
552
|
+
pass
|
553
|
+
|
554
|
+
|
555
|
+
class WithLuminosityMixin(WithDimensionalityMixin):
|
556
|
+
"""Unit validation mixin."""
|
557
|
+
|
558
|
+
dimensionality_unit = LuminosityStr.unit
|
559
|
+
|
560
|
+
|
561
|
+
class AmountLuminosity(Amount, WithLuminosityMixin):
|
562
|
+
"""Luminosity."""
|
563
|
+
|
564
|
+
pass
|
565
|
+
|
566
|
+
|
567
|
+
class AmountRangeLuminosity(AmountRangeWithDimensionality, WithLuminosityMixin):
|
568
|
+
"""Luminosity range."""
|
569
|
+
|
570
|
+
pass
|
571
|
+
|
572
|
+
|
573
|
+
class WithPowerMixin(WithDimensionalityMixin):
|
574
|
+
"""Unit validation mixin."""
|
575
|
+
|
576
|
+
dimensionality_unit = PowerStr.unit
|
577
|
+
|
578
|
+
|
579
|
+
class AmountPower(Amount, WithPowerMixin):
|
580
|
+
"""Power."""
|
581
|
+
|
582
|
+
pass
|
583
|
+
|
584
|
+
|
585
|
+
class AmountRangePower(AmountRangeWithDimensionality, WithPowerMixin):
|
586
|
+
"""Power range."""
|
587
|
+
|
588
|
+
pass
|
589
|
+
|
590
|
+
|
591
|
+
class WithElectricalCurrentMixin(WithDimensionalityMixin):
|
592
|
+
"""Unit validation mixin."""
|
593
|
+
|
594
|
+
dimensionality_unit = ElectricalCurrentStr.unit
|
595
|
+
|
596
|
+
|
597
|
+
class AmountElectricalCurrent(Amount, WithElectricalCurrentMixin):
|
598
|
+
"""Current."""
|
599
|
+
|
600
|
+
pass
|
601
|
+
|
602
|
+
|
603
|
+
class AmountRangeElectricalCurrent(AmountRangeWithDimensionality, WithElectricalCurrentMixin):
|
604
|
+
"""Current range."""
|
605
|
+
|
606
|
+
pass
|
607
|
+
|
608
|
+
|
609
|
+
class WithVolumeMixin(WithDimensionalityMixin):
|
610
|
+
"""Unit validation mixin."""
|
611
|
+
|
612
|
+
dimensionality_unit = VolumeStr.unit
|
613
|
+
|
614
|
+
|
615
|
+
class AmountVolume(Amount, WithVolumeMixin):
|
616
|
+
"""Volume."""
|
617
|
+
|
618
|
+
pass
|
619
|
+
|
620
|
+
|
621
|
+
class AmountRangeVolume(AmountRangeWithDimensionality, WithVolumeMixin):
|
622
|
+
"""Volume range."""
|
623
|
+
|
624
|
+
pass
|
625
|
+
|
626
|
+
|
627
|
+
class WithAirflowMixin(WithDimensionalityMixin):
|
628
|
+
"""Unit validation mixin."""
|
629
|
+
|
630
|
+
dimensionality_unit = AirflowStr.unit
|
631
|
+
|
632
|
+
|
633
|
+
class AmountAirflow(Amount, WithAirflowMixin):
|
634
|
+
"""Airflow."""
|
635
|
+
|
636
|
+
pass
|
637
|
+
|
638
|
+
|
639
|
+
class AmountRangeAirflow(AmountRangeWithDimensionality, WithAirflowMixin):
|
640
|
+
"""Airflow range."""
|
641
|
+
|
642
|
+
pass
|
643
|
+
|
644
|
+
|
645
|
+
class WithFlowRateMixin(WithDimensionalityMixin):
|
646
|
+
"""Unit validation mixin."""
|
647
|
+
|
648
|
+
dimensionality_unit = FlowRateStr.unit
|
649
|
+
|
650
|
+
|
651
|
+
class AmountFlowRate(Amount, WithFlowRateMixin):
|
652
|
+
"""Flow Rate."""
|
653
|
+
|
654
|
+
pass
|
655
|
+
|
656
|
+
|
657
|
+
class AmountRangeFlowRate(AmountRangeWithDimensionality, WithFlowRateMixin):
|
658
|
+
"""Flow Rate range."""
|
659
|
+
|
660
|
+
pass
|
661
|
+
|
662
|
+
|
663
|
+
class WithMassPerLengthMixin(WithDimensionalityMixin):
|
664
|
+
"""Unit validation mixin."""
|
665
|
+
|
666
|
+
dimensionality_unit = MassPerLengthStr.unit
|
667
|
+
|
668
|
+
|
669
|
+
class AmountMassPerLength(Amount, WithFlowRateMixin):
|
670
|
+
"""Mass per length."""
|
671
|
+
|
672
|
+
pass
|
673
|
+
|
674
|
+
|
675
|
+
class AmountRangeMassPerLength(AmountRangeWithDimensionality, WithFlowRateMixin):
|
676
|
+
"""Mass per length range."""
|
677
|
+
|
678
|
+
pass
|
679
|
+
|
680
|
+
|
681
|
+
class WithAreaPerVolumeMixin(WithDimensionalityMixin):
|
682
|
+
"""Unit validation mixin."""
|
683
|
+
|
684
|
+
dimensionality_unit = AreaPerVolumeStr.unit
|
685
|
+
|
686
|
+
|
687
|
+
class AmountAreaPerVolume(Amount, WithFlowRateMixin):
|
688
|
+
"""Area per volume."""
|
689
|
+
|
690
|
+
pass
|
691
|
+
|
692
|
+
|
693
|
+
class AmountRangeAreaPerVolume(AmountRangeWithDimensionality, WithFlowRateMixin):
|
694
|
+
"""Area per volume range."""
|
695
|
+
|
696
|
+
pass
|
697
|
+
|
698
|
+
|
699
|
+
# known range amounts
|
700
|
+
SUPPORTED_RANGE_TYPES: tuple[type[AmountRangeWithDimensionality], ...] = (
|
701
|
+
AmountRangeMass,
|
702
|
+
AmountRangeGWP,
|
703
|
+
AmountRangeLengthM,
|
704
|
+
AmountRangeLengthMm,
|
705
|
+
AmountRangePressureMpa,
|
706
|
+
AmountRangeAreaM2,
|
707
|
+
AmountRangeLengthInch,
|
708
|
+
AmountRangeTemperatureC,
|
709
|
+
AmountRangeCapacityPerHour,
|
710
|
+
AmountRangeRValue,
|
711
|
+
AmountRangeSpeed,
|
712
|
+
AmountRangeColorTemperature,
|
713
|
+
AmountRangeLuminosity,
|
714
|
+
AmountRangePower,
|
715
|
+
AmountRangeElectricalCurrent,
|
716
|
+
AmountRangeVolume,
|
717
|
+
AmountRangeAirflow,
|
718
|
+
AmountRangeFlowRate,
|
719
|
+
AmountRangeMassPerLength,
|
720
|
+
AmountRangeAreaPerVolume,
|
721
|
+
)
|
722
|
+
|
723
|
+
# known range amount mapping by unit
|
724
|
+
SUPPORTED_RANGES_BY_UNIT: dict[str, type[AmountRangeWithDimensionality]] = {
|
725
|
+
str(t.dimensionality_unit): t for t in SUPPORTED_RANGE_TYPES
|
726
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: openepd
|
3
|
-
Version:
|
3
|
+
Version: 5.1.0
|
4
4
|
Summary: Python library to work with OpenEPD format
|
5
5
|
Home-page: https://github.com/cchangelabs/openepd
|
6
6
|
License: Apache-2.0
|
@@ -170,6 +170,11 @@ codes, UN m49 codification, and special regions. To update the enums, first upda
|
|
170
170
|
Windows is not supported for development. You can use WSL2 with Ubuntu 20.04 or higher.
|
171
171
|
Instructions are the same as for regular GNU/Linux installation.
|
172
172
|
|
173
|
+
### Commit messages
|
174
|
+
|
175
|
+
Commit messages should follow [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/#specification)
|
176
|
+
specification as we use automatic version with [commitizen](https://commitizen-tools.github.io/commitizen/).
|
177
|
+
|
173
178
|
# Credits
|
174
179
|
|
175
180
|
This library has been written and maintained by [C-Change Labs](https://c-change-labs.com/).
|