openepd 5.0.0__py3-none-any.whl → 5.1.1__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 +39 -0
- openepd/model/declaration.py +7 -2
- openepd/model/geography.py +1 -1
- openepd/model/lcia.py +6 -3
- openepd/model/org.py +0 -1
- 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 +13 -0
- 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 +440 -52
- {openepd-5.0.0.dist-info → openepd-5.1.1.dist-info}/METADATA +6 -1
- {openepd-5.0.0.dist-info → openepd-5.1.1.dist-info}/RECORD +61 -26
- {openepd-5.0.0.dist-info → openepd-5.1.1.dist-info}/LICENSE +0 -0
- {openepd-5.0.0.dist-info → openepd-5.1.1.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):
|
@@ -104,42 +103,42 @@ class ExternalValidationConfig:
|
|
104
103
|
|
105
104
|
|
106
105
|
def validate_unit_factory(dimensionality: OpenEPDUnit | str) -> "QuantityValidatorType":
|
107
|
-
"""Create validator for
|
106
|
+
"""Create validator for units (not quantities) to check for dimensionality."""
|
108
107
|
|
109
|
-
def validator(cls:
|
108
|
+
def validator(cls: type | None, value: str) -> str:
|
110
109
|
if ExternalValidationConfig.QUANTITY_VALIDATOR is not None:
|
111
|
-
ExternalValidationConfig.QUANTITY_VALIDATOR.
|
110
|
+
ExternalValidationConfig.QUANTITY_VALIDATOR.validate_same_dimensionality(value, dimensionality)
|
112
111
|
return value
|
113
112
|
|
114
113
|
return validator
|
115
114
|
|
116
115
|
|
117
|
-
def
|
118
|
-
"""Create validator
|
116
|
+
def validate_quantity_unit_factory(dimensionality: OpenEPDUnit | str) -> "QuantityValidatorType":
|
117
|
+
"""Create validator for quantity field to check unit matching."""
|
119
118
|
|
120
|
-
def validator(cls:
|
119
|
+
def validator(cls: type | None, value: str) -> str:
|
121
120
|
if ExternalValidationConfig.QUANTITY_VALIDATOR is not None:
|
122
|
-
ExternalValidationConfig.QUANTITY_VALIDATOR.
|
121
|
+
ExternalValidationConfig.QUANTITY_VALIDATOR.validate_unit_correctness(value, dimensionality)
|
123
122
|
return value
|
124
123
|
|
125
124
|
return validator
|
126
125
|
|
127
126
|
|
128
|
-
def
|
129
|
-
"""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."""
|
130
129
|
|
131
|
-
def validator(cls:
|
130
|
+
def validator(cls: type | None, value: str) -> str:
|
132
131
|
if ExternalValidationConfig.QUANTITY_VALIDATOR is not None:
|
133
|
-
ExternalValidationConfig.QUANTITY_VALIDATOR.
|
132
|
+
ExternalValidationConfig.QUANTITY_VALIDATOR.validate_quantity_greater_or_equal(value, min_value)
|
134
133
|
return value
|
135
134
|
|
136
135
|
return validator
|
137
136
|
|
138
137
|
|
139
|
-
def
|
138
|
+
def validate_quantity_le_factory(max_value: str) -> "QuantityValidatorType":
|
140
139
|
"""Create validator to check that quantity is less than or equal to max_value."""
|
141
140
|
|
142
|
-
def validator(value: str) -> str:
|
141
|
+
def validator(cls: type | None, value: str) -> str:
|
143
142
|
if ExternalValidationConfig.QUANTITY_VALIDATOR is not None:
|
144
143
|
ExternalValidationConfig.QUANTITY_VALIDATOR.validate_quantity_less_or_equal(value, max_value)
|
145
144
|
return value
|
@@ -151,38 +150,6 @@ def validate_quantity_for_new_validator(max_value: str) -> Callable:
|
|
151
150
|
# todo these types should be replaced by Annotated[str, AfterValidator...] as we move completely to pydantic 2
|
152
151
|
|
153
152
|
|
154
|
-
class AmountWithDimensionality(Amount, ABC):
|
155
|
-
"""Class for dimensionality-validated amounts."""
|
156
|
-
|
157
|
-
dimensionality_unit: ClassVar[str | None] = None
|
158
|
-
|
159
|
-
# Unit for dimensionality to validate against, for example "kg"
|
160
|
-
|
161
|
-
@pyd.root_validator
|
162
|
-
def check_dimensionality_matches(cls, values: dict[str, Any]) -> dict[str, Any]:
|
163
|
-
"""Check that this amount conforms to the same dimensionality as dimensionality_unit."""
|
164
|
-
if not cls.dimensionality_unit:
|
165
|
-
return values
|
166
|
-
|
167
|
-
from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
|
168
|
-
|
169
|
-
str_repr = f"{values['qty']} {values['unit']}"
|
170
|
-
validate_unit_factory(cls.dimensionality_unit)(BaseOpenEpdHierarchicalSpec, str_repr)
|
171
|
-
return values
|
172
|
-
|
173
|
-
|
174
|
-
class AmountMass(AmountWithDimensionality):
|
175
|
-
"""Amount of mass, measured in kg, t, etc."""
|
176
|
-
|
177
|
-
dimensionality_unit = OpenEPDUnit.kg
|
178
|
-
|
179
|
-
|
180
|
-
class AmountGWP(AmountWithDimensionality):
|
181
|
-
"""Amount of Global Warming Potential, measured in kgCO2e."""
|
182
|
-
|
183
|
-
dimensionality_unit = OpenEPDUnit.kg_co2
|
184
|
-
|
185
|
-
|
186
153
|
class QuantityStr(str):
|
187
154
|
"""
|
188
155
|
Quantity string type.
|
@@ -196,8 +163,10 @@ class QuantityStr(str):
|
|
196
163
|
|
197
164
|
@classmethod
|
198
165
|
def __get_validators__(cls):
|
199
|
-
|
200
|
-
|
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}")
|
201
170
|
|
202
171
|
@classmethod
|
203
172
|
def __modify_schema__(cls, field_schema):
|
@@ -245,7 +214,7 @@ class LengthMmStr(QuantityStr):
|
|
245
214
|
class LengthInchStr(QuantityStr):
|
246
215
|
"""Length (inch) quantity type."""
|
247
216
|
|
248
|
-
unit =
|
217
|
+
unit = "inch"
|
249
218
|
|
250
219
|
@classmethod
|
251
220
|
def __modify_schema__(cls, field_schema):
|
@@ -336,3 +305,422 @@ class AreaPerVolumeStr(QuantityStr):
|
|
336
305
|
"""Area per unit of volume quantity type."""
|
337
306
|
|
338
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: 5.
|
3
|
+
Version: 5.1.1
|
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/).
|