Bug Description
Description
When attempting to import recipes that depend on ifcopenshell.util.shape_builder (such as OffsetObjectPlacements), a circular import error occurs. This prevents these recipes from being loaded or executed.
Environment
- ifcopenshell version: 0.8.4.post1 (also affects 0.8.4)
- ifcpatch version: 0.8.4
- Python version: 3.11
- OS: Linux (Docker container)
Minimal Reproduction
# This fails with circular import error
from ifcpatch.recipes.OffsetObjectPlacements import Patcher
Or when using ifcpatch:
import ifcopenshell
import ifcpatch
ifc_file = ifcopenshell.open("model.ifc")
# This fails when it tries to import the recipe
output = ifcpatch.execute({
"input": "model.ifc",
"file": ifc_file,
"recipe": "OffsetObjectPlacements",
"arguments": ["0", "0", "1000", "true", "0", "0", "90"]
})
Attachments
No response
Debug and Error Output
## Error Traceback
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/lib/python3.11/site-packages/ifcpatch/recipes/OffsetObjectPlacements.py", line 24, in <module>
from ifcopenshell.util.shape_builder import ShapeBuilder
File "/usr/local/lib/python3.11/site-packages/ifcopenshell/util/shape_builder.py", line 26, in <module>
import ifcopenshell.util.element
File "/usr/local/lib/python3.11/site-packages/ifcopenshell/util/element.py", line 22, in <module>
import ifcopenshell.util.representation
File "/usr/local/lib/python3.11/site-packages/ifcopenshell/util/representation.py", line 24, in <module>
import ifcopenshell.util.shape
File "/usr/local/lib/python3.11/site-packages/ifcopenshell/util/shape.py", line 27, in <module>
from ifcopenshell.util.shape_builder import VectorType
ImportError: cannot import name 'VectorType' from partially initialized module 'ifcopenshell.util.shape_builder' (most likely due to a circular import) (/usr/local/lib/python3.11/site-packages/ifcopenshell/util/shape_builder.py)
## Analysis
The circular import chain is:
1. `shape_builder.py` imports `ifcopenshell.util.element`
2. `element.py` imports `ifcopenshell.util.representation`
3. `representation.py` imports `ifcopenshell.util.shape`
4. `shape.py` imports `VectorType` from `ifcopenshell.util.shape_builder`
5. But `shape_builder.py` hasn't finished initializing yet → **ImportError**
## Affected Recipes
At minimum:
- `OffsetObjectPlacements` (confirmed)
- Potentially any other recipe that imports from `ifcopenshell.util.shape_builder`
## Possible Solutions
1. **Use `TYPE_CHECKING` for type hints**: Move the `VectorType` import in `shape.py` inside an `if TYPE_CHECKING:` block since it's only used for type annotations
2. **Move type definitions**: Create a separate `types.py` module for shared type definitions like `VectorType`
3. **Lazy imports**: Defer the import of `shape_builder` in `shape.py` until it's actually needed at runtime
## Workaround
As a temporary workaround, you can pre-initialize `shape_builder` with a mock `VectorType` before importing the recipe:
import sys
import types
from typing import Any
# Create mock shape_builder with VectorType
mock_shape_builder = types.ModuleType('ifcopenshell.util.shape_builder')
mock_shape_builder.VectorType = Any
sys.modules['ifcopenshell.util.shape_builder'] = mock_shape_builder
# Import base modules (shape.py will use mock VectorType)
import ifcopenshell
import ifcopenshell.util.shape
# Remove mock and import real module
del sys.modules['ifcopenshell.util.shape_builder']
import ifcopenshell.util.shape_builder
# Now recipes work
from ifcpatch.recipes.OffsetObjectPlacements import Patcher # Success!
Bug Description
Description
When attempting to import recipes that depend on
ifcopenshell.util.shape_builder(such asOffsetObjectPlacements), a circular import error occurs. This prevents these recipes from being loaded or executed.Environment
Minimal Reproduction
Or when using ifcpatch:
Attachments
No response
Debug and Error Output