openepd 4.2.0__tar.gz → 4.4.0__tar.gz

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 (95) hide show
  1. {openepd-4.2.0 → openepd-4.4.0}/PKG-INFO +8 -1
  2. {openepd-4.2.0 → openepd-4.4.0}/README.md +7 -0
  3. {openepd-4.2.0 → openepd-4.4.0}/pyproject.toml +1 -1
  4. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/__version__.py +1 -1
  5. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/lcia.py +1 -0
  6. openepd-4.4.0/src/openepd/mypy/__init__.py +15 -0
  7. openepd-4.4.0/src/openepd/mypy/custom_pydantic_plugin.py +91 -0
  8. {openepd-4.2.0 → openepd-4.4.0}/LICENSE +0 -0
  9. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/__init__.py +0 -0
  10. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/__init__.py +0 -0
  11. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/base_sync_client.py +0 -0
  12. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/category/__init__.py +0 -0
  13. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/category/dto.py +0 -0
  14. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/category/sync_api.py +0 -0
  15. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/common.py +0 -0
  16. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/dto/__init__.py +0 -0
  17. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/dto/base.py +0 -0
  18. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/dto/common.py +0 -0
  19. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/dto/meta.py +0 -0
  20. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/dto/mf.py +0 -0
  21. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/dto/params.py +0 -0
  22. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/epd/__init__.py +0 -0
  23. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/epd/dto.py +0 -0
  24. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/epd/sync_api.py +0 -0
  25. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/errors.py +0 -0
  26. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/pcr/__init__.py +0 -0
  27. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/pcr/sync_api.py +0 -0
  28. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/sync_client.py +0 -0
  29. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/test/__init__.py +0 -0
  30. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/api/utils.py +0 -0
  31. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/bundle/__init__.py +0 -0
  32. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/bundle/base.py +0 -0
  33. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/bundle/model.py +0 -0
  34. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/bundle/reader.py +0 -0
  35. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/bundle/writer.py +0 -0
  36. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/compat/__init__.py +0 -0
  37. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/compat/compat_functional_validators.py +0 -0
  38. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/compat/pydantic.py +0 -0
  39. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/__init__.py +0 -0
  40. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/base.py +0 -0
  41. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/category.py +0 -0
  42. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/common.py +0 -0
  43. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/epd.py +0 -0
  44. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/factory.py +0 -0
  45. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/org.py +0 -0
  46. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/pcr.py +0 -0
  47. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/README.md +0 -0
  48. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/__init__.py +0 -0
  49. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/asphalt.py +0 -0
  50. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/base.py +0 -0
  51. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/concrete.py +0 -0
  52. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/__init__.py +0 -0
  53. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/accessories.py +0 -0
  54. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/aggregates.py +0 -0
  55. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/aluminium.py +0 -0
  56. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/asphalt.py +0 -0
  57. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/bulk_materials.py +0 -0
  58. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/cast_decks_and_underlayment.py +0 -0
  59. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/cladding.py +0 -0
  60. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/cmu.py +0 -0
  61. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/common.py +0 -0
  62. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/concrete.py +0 -0
  63. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/conveying_equipment.py +0 -0
  64. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/electrical.py +0 -0
  65. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/electrical_transmission_and_distribution_equipment.py +0 -0
  66. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/electricity.py +0 -0
  67. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/enums.py +0 -0
  68. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/finishes.py +0 -0
  69. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/fire_and_smoke_protection.py +0 -0
  70. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/furnishings.py +0 -0
  71. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/grouting.py +0 -0
  72. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/manufacturing_inputs.py +0 -0
  73. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/masonry.py +0 -0
  74. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/material_handling.py +0 -0
  75. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/mechanical.py +0 -0
  76. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/mechanical_insulation.py +0 -0
  77. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/network_infrastructure.py +0 -0
  78. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/openings.py +0 -0
  79. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/other_electrical_equipment.py +0 -0
  80. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/other_materials.py +0 -0
  81. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/plumbing.py +0 -0
  82. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/precast_concrete.py +0 -0
  83. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/sheathing.py +0 -0
  84. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/steel.py +0 -0
  85. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/thermal_moisture_protection.py +0 -0
  86. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/utility_piping.py +0 -0
  87. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/wood.py +0 -0
  88. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/specs/generated/wood_joists.py +0 -0
  89. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/standard.py +0 -0
  90. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/validation/__init__.py +0 -0
  91. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/validation/common.py +0 -0
  92. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/validation/numbers.py +0 -0
  93. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/validation/quantity.py +0 -0
  94. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/model/versioning.py +0 -0
  95. {openepd-4.2.0 → openepd-4.4.0}/src/openepd/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openepd
3
- Version: 4.2.0
3
+ Version: 4.4.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
@@ -144,6 +144,13 @@ with DefaultBundleWriter("my-bundle.epb") as writer, open("test-pcr.pdf", "rb")
144
144
  writer.write_blob_asset(pcr_pdf_file, "application/pdf", pcr_asset, RelType.Pdf)
145
145
  ```
146
146
 
147
+ ### Mypy
148
+
149
+ OpenEPD uses a small modification to standard pydantic models (see PydanticClassAttributeExposeModelMetaclass). Mypy,
150
+ in order to work correctly, requires a modified pydantic plugin. To enable it, add an
151
+ `openepd.mypy.custom_pydantic_plugin` to list of mypy plugins in your `pyproject.toml` or other mypy-related config
152
+ file. See [Mypy configuration](https://mypy.readthedocs.io/en/stable/extending_mypy.html)
153
+
147
154
  # Credits
148
155
 
149
156
  This library has been written and maintained by [C-Change Labs](https://c-change-labs.com/).
@@ -118,6 +118,13 @@ with DefaultBundleWriter("my-bundle.epb") as writer, open("test-pcr.pdf", "rb")
118
118
  writer.write_blob_asset(pcr_pdf_file, "application/pdf", pcr_asset, RelType.Pdf)
119
119
  ```
120
120
 
121
+ ### Mypy
122
+
123
+ OpenEPD uses a small modification to standard pydantic models (see PydanticClassAttributeExposeModelMetaclass). Mypy,
124
+ in order to work correctly, requires a modified pydantic plugin. To enable it, add an
125
+ `openepd.mypy.custom_pydantic_plugin` to list of mypy plugins in your `pyproject.toml` or other mypy-related config
126
+ file. See [Mypy configuration](https://mypy.readthedocs.io/en/stable/extending_mypy.html)
127
+
121
128
  # Credits
122
129
 
123
130
  This library has been written and maintained by [C-Change Labs](https://c-change-labs.com/).
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "openepd"
3
- version = "4.2.0"
3
+ version = "4.4.0"
4
4
  license = "Apache-2.0"
5
5
  description = "Python library to work with OpenEPD format"
6
6
  authors = ["C-Change Labs <support@c-change-labs.com>"]
@@ -13,4 +13,4 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- VERSION = "4.2.0"
16
+ VERSION = "4.4.0"
@@ -268,6 +268,7 @@ class LCIAMethod(StrEnum):
268
268
  CML_1992 = "CML 1992"
269
269
  RECIPE_2016 = "ReCiPe 2016"
270
270
  RECIPE_2008 = "ReCiPe 2008"
271
+ LIME2 = "LIME2"
271
272
 
272
273
  @classmethod
273
274
  def is_method_supported(cls, method_name: str | None) -> bool:
@@ -0,0 +1,15 @@
1
+ #
2
+ # Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
@@ -0,0 +1,91 @@
1
+ #
2
+ # Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ from collections.abc import Callable
18
+
19
+ from mypy.nodes import AssignmentStmt, CallExpr, MemberExpr, TypeInfo
20
+ from mypy.plugin import ClassDefContext
21
+ import pydantic.mypy
22
+ from pydantic.mypy import (
23
+ MODEL_METACLASS_FULLNAME,
24
+ ModelConfigData,
25
+ PydanticModelClassVar,
26
+ PydanticModelField,
27
+ PydanticModelTransformer,
28
+ PydanticPlugin,
29
+ )
30
+
31
+ # Using this plugin fixes the issue.
32
+
33
+ CUSTOM_OPENEPD_MODEL_METACLASS_FULLNAME = "openepd.model.base.PydanticClassAttributeExposeModelMetaclass"
34
+ MODEL_METACLASSES_FULL_NAMES = (MODEL_METACLASS_FULLNAME, CUSTOM_OPENEPD_MODEL_METACLASS_FULLNAME)
35
+
36
+ DECORATOR_FULLNAMES = pydantic.mypy.DECORATOR_FULLNAMES | {
37
+ "pydantic.v1.class_validators.validator",
38
+ }
39
+
40
+
41
+ class CustomPydanticModelTransformer(PydanticModelTransformer):
42
+ """Extension of the mypy/pydantic model transformer which also understands validator definitions via v1 compat."""
43
+
44
+ def collect_field_or_class_var_from_stmt(
45
+ self, stmt: AssignmentStmt, model_config: ModelConfigData, class_vars: dict[str, PydanticModelClassVar]
46
+ ) -> PydanticModelField | PydanticModelClassVar | None:
47
+ """Extend implementation of the original Pydantic method with one more case for validator."""
48
+ if not stmt.new_syntax and (
49
+ isinstance(stmt.rvalue, CallExpr)
50
+ and isinstance(stmt.rvalue.callee, CallExpr)
51
+ and isinstance(stmt.rvalue.callee.callee, MemberExpr)
52
+ and stmt.rvalue.callee.callee.fullname in DECORATOR_FULLNAMES
53
+ ):
54
+ # Required to detect compat-imported v1 validators and not treat them as fields.
55
+ return None
56
+ return super().collect_field_or_class_var_from_stmt(stmt, model_config, class_vars)
57
+
58
+
59
+ class CustomMetaclassPydanticPlugin(PydanticPlugin):
60
+ """
61
+ Custom metaclass pydantic plugin.
62
+
63
+ Extends a standard pydantic mypy plugin, and adds certain behaviours required for us:
64
+ 1. Support for a non-standard metaclass for pydantic models. We use it allow for access via Class.field notation
65
+ 2. Support for our modified compat import of pydantic v1 when using this metaclass.
66
+ """
67
+
68
+ def get_metaclass_hook(self, fullname: str) -> Callable[[ClassDefContext], None] | None:
69
+ """Update Pydantic `ModelMetaclass` definition."""
70
+ if fullname in MODEL_METACLASSES_FULL_NAMES:
71
+ return self._pydantic_model_metaclass_marker_callback
72
+ return None
73
+
74
+ def get_base_class_hook(self, fullname: str) -> Callable[[ClassDefContext], bool] | None: # type: ignore
75
+ """Update Pydantic model class."""
76
+ sym = self.lookup_fully_qualified(fullname)
77
+ if sym and isinstance(sym.node, TypeInfo): # pragma: no branch
78
+ # No branching may occur if the mypy cache has not been cleared
79
+ if any(base.fullname in ["pydantic.main.BaseModel", "pydantic.v1.main.BaseModel"] for base in sym.node.mro):
80
+ return self._pydantic_model_class_maker_callback
81
+ return None
82
+
83
+ def _pydantic_model_class_maker_callback(self, ctx: ClassDefContext) -> bool:
84
+ # extended to replace the mypy-pydantic transformer with our custom transformer - see validator note.
85
+ transformer = CustomPydanticModelTransformer(ctx.cls, ctx.reason, ctx.api, self.plugin_config)
86
+ return transformer.transform()
87
+
88
+
89
+ def plugin(version: str):
90
+ """Entry point to the mypy plugin."""
91
+ return CustomMetaclassPydanticPlugin
File without changes
File without changes
File without changes