diff --git a/.github/workflows/black_to_github_annotations.py b/.github/workflows/black_to_github_annotations.py
new file mode 100644
index 0000000000..074eedf6b7
--- /dev/null
+++ b/.github/workflows/black_to_github_annotations.py
@@ -0,0 +1,41 @@
+from __future__ import annotations
+
+import json
+import os
+import sys
+from typing import TypedDict
+
+import github_action_utils as gha_utils
+
+
+class Entry(TypedDict):
+ location: Location
+
+
+class Location(TypedDict):
+ path: str
+ lines: Lines
+
+
+class Lines(TypedDict):
+ begin: int
+ end: int
+
+
+json_data: list[Entry] = json.load(sys.stdin)
+
+if os.getenv("RUNNER_DEBUG"):
+ print("Debug: Black formatting JSON data:")
+ print(json.dumps(json_data, indent=2))
+
+for change in json_data:
+ location = change["location"]
+ path = location["path"]
+ lines = location["lines"]
+ gha_utils.error(
+ f"Black formatting issue in {path}",
+ title="Black Format Issue",
+ file=path,
+ line=lines["begin"],
+ end_line=lines["end"],
+ )
diff --git a/.github/workflows/build_osx.yml b/.github/workflows/build_osx.yml
index 6732a29761..f53d91b98d 100644
--- a/.github/workflows/build_osx.yml
+++ b/.github/workflows/build_osx.yml
@@ -21,12 +21,12 @@ jobs:
steps:
- name: Checkout Repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
submodules: recursive
- name: Checkout Build Repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
repository: IfcOpenShell/build-outputs
path: ./build
@@ -81,7 +81,7 @@ jobs:
- name: Upload Build Logs
if: always()
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: build-logs-osx-${{ matrix.arch }}
path: |
diff --git a/.github/workflows/build_pyodide.yml b/.github/workflows/build_pyodide.yml
index 1119893c8d..b5692b18f4 100644
--- a/.github/workflows/build_pyodide.yml
+++ b/.github/workflows/build_pyodide.yml
@@ -9,13 +9,13 @@ jobs:
steps:
- name: Checkout Repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
submodules: recursive
path: IfcOpenShell
- name: Checkout Build Repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
repository: IfcOpenShell/build-outputs
path: ifcopenshell_build
@@ -42,7 +42,7 @@ jobs:
- name: Upload Build Logs
if: always()
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: build-logs-pyodide
path: |
diff --git a/.github/workflows/build_rocky.yml b/.github/workflows/build_rocky.yml
index 292e386a8b..6a21a9dfc3 100644
--- a/.github/workflows/build_rocky.yml
+++ b/.github/workflows/build_rocky.yml
@@ -29,12 +29,12 @@ jobs:
aws --version
- name: Checkout Repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
submodules: recursive
- name: Checkout Build Repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
repository: IfcOpenShell/build-outputs
path: ./build
@@ -61,7 +61,7 @@ jobs:
- name: Upload Build Logs
if: always()
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: build-logs-rocky
path: |
diff --git a/.github/workflows/build_rocky_arm.yml b/.github/workflows/build_rocky_arm.yml
index a149af42c8..c595c63676 100644
--- a/.github/workflows/build_rocky_arm.yml
+++ b/.github/workflows/build_rocky_arm.yml
@@ -29,12 +29,12 @@ jobs:
aws --version
- name: Checkout Repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
submodules: recursive
- name: Checkout Build Repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
repository: IfcOpenShell/build-outputs
path: ./build
@@ -61,7 +61,7 @@ jobs:
- name: Upload Build Logs
if: always()
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
name: build-logs-rocky-arm64
path: |
diff --git a/.github/workflows/build_win.yml b/.github/workflows/build_win.yml
index 508f4278bd..6ef112da61 100644
--- a/.github/workflows/build_win.yml
+++ b/.github/workflows/build_win.yml
@@ -12,12 +12,12 @@ jobs:
arch: ['x64']
steps:
- name: Checkout Repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
submodules: recursive
- name: Checkout Build Repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
repository: IfcOpenShell/build-outputs
path: _deps-vs2022-x64-installed
diff --git a/.github/workflows/check_repo_ci_jobs.py b/.github/workflows/check_repo_ci_jobs.py
index 3a78b8e911..7bf7ed13e1 100644
--- a/.github/workflows/check_repo_ci_jobs.py
+++ b/.github/workflows/check_repo_ci_jobs.py
@@ -1,9 +1,9 @@
+import os
import pathlib
import shutil
+import zipfile
import requests
-import zipfile
-import os
# To test this locally, set these environment variables
REPO_OWNER = os.environ.get("REPO_OWNER", "IfcOpenShell/IfcOpenShell")
diff --git a/.github/workflows/ci-bcf-pypi.yml b/.github/workflows/ci-bcf-pypi.yml
index 91be42e97d..349b071740 100644
--- a/.github/workflows/ci-bcf-pypi.yml
+++ b/.github/workflows/ci-bcf-pypi.yml
@@ -19,7 +19,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5 # https://github.com/actions/checkout
+ - uses: actions/checkout@v6 # https://github.com/actions/checkout
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
python-version: '3.11' # Version range or exact version of a Python version to use, using SemVer's version range syntax
diff --git a/.github/workflows/ci-black-formatting.yaml b/.github/workflows/ci-black-formatting.yaml
index 37c9081538..90a0b95431 100644
--- a/.github/workflows/ci-black-formatting.yaml
+++ b/.github/workflows/ci-black-formatting.yaml
@@ -9,12 +9,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Action - checkout repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
- name: Action - install python
uses: actions/setup-python@v6
with:
- python-version: "3.9"
+ python-version: "3.10"
- name: Action - install python
uses: actions/setup-python@v6
@@ -33,23 +33,58 @@ jobs:
id: syntax-errors
run: |
ERROR=0
- python3.9 -W error -m compileall -q src/ifcopenshell-python || ERROR=1
+ python3.10 -W error -m compileall -q src/ifcopenshell-python || ERROR=1
python3.11 -W error -m compileall -q src/bonsai || ERROR=1
exit $ERROR
continue-on-error: true
- name: Black formatter
id: black
+ uses: psf/black@stable
+ continue-on-error: true
+
+ # Same check as above, but just for creating github annotations.
+ - name: Black formatter annotations
+ id: black-annotations
run: |
- black --diff --check .
+ uv tool install black-codeclimate
+ pip install github_action_utils
+ black --diff --check . | black-codeclimate | python .github/workflows/black_to_github_annotations.py
continue-on-error: true
- name: Ruff check
id: ruff
run: |
+ # Ensure execution continues, since we need to cache the output.
+ set +e
+
ERROR=0
- poe ruff-main || ERROR=1
- poe ruff-old || ERROR=1
+ # Keep colored output inside action logs, strip it from color codes for summary.
+ uv tool install ansi2txt
+ # `ruff` disables color output in CI by default.
+ export FORCE_COLOR="1"
+
+ run_check() {
+ local out
+ out="$("$@" 2>&1)"
+ local exit_code=$?
+
+ if [ "$exit_code" -ne 0 ]; then
+ ERROR=1
+ fi
+
+ # Rerun just for GitHub annotations.
+ "$@" --output-format=github || true
+
+ echo "$out"
+ echo "\`\`\`python" >> $GITHUB_STEP_SUMMARY
+ echo "$out" | ansi2txt >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ }
+
+ run_check poe ruff-main
+ run_check poe ruff-old
+
exit $ERROR
continue-on-error: true
@@ -60,9 +95,9 @@ jobs:
echo "::error::Syntax errors check failed, see 'syntax-errors' step for the details." && ERROR=1
fi
if [ "${{ steps.black.outcome }}" != "success" ]; then
- echo "::error::Black formatting check failed, see 'black' step for the details." && ERROR=1
+ echo "::error::Black formatting check failed, see Summary or 'black' step for the details." && ERROR=1
fi
if [ "${{ steps.ruff.outcome }}" != "success" ]; then
- echo "::error::Ruff check failed, see 'ruff' step for the details." && ERROR=1
+ echo "::error::Ruff check failed, see Summary or 'ruff' step for the details." && ERROR=1
fi
exit $ERROR
diff --git a/.github/workflows/ci-bonsai-choco.yml b/.github/workflows/ci-bonsai-choco.yml
index 5240304b85..c4204f7d02 100644
--- a/.github/workflows/ci-bonsai-choco.yml
+++ b/.github/workflows/ci-bonsai-choco.yml
@@ -34,7 +34,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
with:
fetch-tags: true
fetch-depth: 0
diff --git a/.github/workflows/ci-bonsai-daily.yml b/.github/workflows/ci-bonsai-daily.yml
index 49e59f9474..4185574b2d 100644
--- a/.github/workflows/ci-bonsai-daily.yml
+++ b/.github/workflows/ci-bonsai-daily.yml
@@ -54,7 +54,7 @@ jobs:
short_name: macosm1,
}
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
@@ -93,7 +93,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout bonsai_unstable_repo repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
repository: IfcOpenShell/bonsai_unstable_repo
token: ${{ secrets.IFCOPENBOT_TOKEN }}
diff --git a/.github/workflows/ci-bonsai.yml b/.github/workflows/ci-bonsai.yml
index 7f90d1ad25..4c8364a958 100644
--- a/.github/workflows/ci-bonsai.yml
+++ b/.github/workflows/ci-bonsai.yml
@@ -43,7 +43,7 @@ jobs:
short_name: macosm1,
}
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
diff --git a/.github/workflows/ci-bsdd-pypi.yaml b/.github/workflows/ci-bsdd-pypi.yaml
index b563d1fa74..e7c326a59a 100644
--- a/.github/workflows/ci-bsdd-pypi.yaml
+++ b/.github/workflows/ci-bsdd-pypi.yaml
@@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
python-version: '3.11' # Version range or exact version of a Python version to use, using SemVer's version range syntax
diff --git a/.github/workflows/ci-ifc4d-pypi.yaml b/.github/workflows/ci-ifc4d-pypi.yaml
index 161ea22651..c08b26d9c0 100644
--- a/.github/workflows/ci-ifc4d-pypi.yaml
+++ b/.github/workflows/ci-ifc4d-pypi.yaml
@@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
python-version: '3.11' # Version range or exact version of a Python version to use, using SemVer's version range syntax
diff --git a/.github/workflows/ci-ifc5d-pypi.yaml b/.github/workflows/ci-ifc5d-pypi.yaml
index 48b36f8b8f..635f60c985 100644
--- a/.github/workflows/ci-ifc5d-pypi.yaml
+++ b/.github/workflows/ci-ifc5d-pypi.yaml
@@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
python-version: '3.11' # Version range or exact version of a Python version to use, using SemVer's version range syntax
diff --git a/.github/workflows/ci-ifccityjson-pypi.yaml b/.github/workflows/ci-ifccityjson-pypi.yaml
index 5bf5a8bda8..f16a57cffd 100644
--- a/.github/workflows/ci-ifccityjson-pypi.yaml
+++ b/.github/workflows/ci-ifccityjson-pypi.yaml
@@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
python-version: '3.11' # Version range or exact version of a Python version to use, using SemVer's version range syntax
diff --git a/.github/workflows/ci-ifcclash-pypi.yaml b/.github/workflows/ci-ifcclash-pypi.yaml
index 9075b2138d..bbde274804 100644
--- a/.github/workflows/ci-ifcclash-pypi.yaml
+++ b/.github/workflows/ci-ifcclash-pypi.yaml
@@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
python-version: '3.11' # Version range or exact version of a Python version to use, using SemVer's version range syntax
diff --git a/.github/workflows/ci-ifcconvert.yml b/.github/workflows/ci-ifcconvert.yml
index 181f5a0d77..d4cd7fc55a 100644
--- a/.github/workflows/ci-ifcconvert.yml
+++ b/.github/workflows/ci-ifcconvert.yml
@@ -37,7 +37,7 @@ jobs:
short_name: macosm164
}
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
python-version: '3.11' # Version range or exact version of a Python version to use, using SemVer's version range syntax
diff --git a/.github/workflows/ci-ifccsv-pypi.yaml b/.github/workflows/ci-ifccsv-pypi.yaml
index 8dab393cc3..04d7a76937 100644
--- a/.github/workflows/ci-ifccsv-pypi.yaml
+++ b/.github/workflows/ci-ifccsv-pypi.yaml
@@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
python-version: '3.11' # Version range or exact version of a Python version to use, using SemVer's version range syntax
diff --git a/.github/workflows/ci-ifcdiff-pypi.yaml b/.github/workflows/ci-ifcdiff-pypi.yaml
index 4abb170932..eba7ad237f 100644
--- a/.github/workflows/ci-ifcdiff-pypi.yaml
+++ b/.github/workflows/ci-ifcdiff-pypi.yaml
@@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
python-version: '3.11' # Version range or exact version of a Python version to use, using SemVer's version range syntax
diff --git a/.github/workflows/ci-ifcfm-pypi.yaml b/.github/workflows/ci-ifcfm-pypi.yaml
index 5de093bfb2..c658bbf3ef 100644
--- a/.github/workflows/ci-ifcfm-pypi.yaml
+++ b/.github/workflows/ci-ifcfm-pypi.yaml
@@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
python-version: '3.11' # Version range or exact version of a Python version to use, using SemVer's version range syntax
diff --git a/.github/workflows/ci-ifcopenshell-conda-daily.yml b/.github/workflows/ci-ifcopenshell-conda-daily.yml
index 07916435d8..b648538ed7 100644
--- a/.github/workflows/ci-ifcopenshell-conda-daily.yml
+++ b/.github/workflows/ci-ifcopenshell-conda-daily.yml
@@ -21,7 +21,7 @@ jobs:
date: ${{ steps.date.outputs.date }}
verdate: ${{ steps.verdate.outputs.verdate }}
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- name: Set env
run: echo ok go
@@ -54,8 +54,7 @@ jobs:
platform: [
{ name: win, distver: windows-latest, pkg_dir: 'win-64' },
{ name: linux, distver: ubuntu-latest, pkg_dir: 'linux-64' },
- { name: macOS-arm, distver: macos-latest, pkg_dir: 'osx-arm64' },
- { name: macOS-x86, distver: macos-13, pkg_dir: 'osx-64' }
+ { name: macOS-arm, distver: macos-latest, pkg_dir: 'osx-arm64' }
]
steps:
- name: Set Swap Space
@@ -76,7 +75,7 @@ jobs:
echo "ARTIFACTS_DIR=/home/runner/work/artifacts" >> $GITHUB_ENV
fi
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
with:
submodules: recursive
diff --git a/.github/workflows/ci-ifcopenshell-docker.yml b/.github/workflows/ci-ifcopenshell-docker.yml
index d6663ff198..d5691ecfce 100644
--- a/.github/workflows/ci-ifcopenshell-docker.yml
+++ b/.github/workflows/ci-ifcopenshell-docker.yml
@@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-22.04
needs: activate
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
with:
submodules: recursive
@@ -73,7 +73,7 @@ jobs:
make package
working-directory: build
- name: Upload
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v6
with:
# Artifact name
name: ifcos-artifacts
@@ -86,12 +86,12 @@ jobs:
name: Docker Build, Tag, Push
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
with:
lfs: true
- name: Download
- uses: actions/download-artifact@v6.0.0
+ uses: actions/download-artifact@v7.0.0
with:
# Artifact name
name: ifcos-artifacts
diff --git a/.github/workflows/ci-ifcopenshell-python-pypi.yml b/.github/workflows/ci-ifcopenshell-python-pypi.yml
index 10ad9b6e61..526aa09b64 100644
--- a/.github/workflows/ci-ifcopenshell-python-pypi.yml
+++ b/.github/workflows/ci-ifcopenshell-python-pypi.yml
@@ -47,7 +47,7 @@ jobs:
short_name: macosm164
}
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
with:
submodules: recursive
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
diff --git a/.github/workflows/ci-ifcopenshell-python.yml b/.github/workflows/ci-ifcopenshell-python.yml
index bd8182d63e..5d34335ada 100644
--- a/.github/workflows/ci-ifcopenshell-python.yml
+++ b/.github/workflows/ci-ifcopenshell-python.yml
@@ -38,7 +38,7 @@ jobs:
short_name: macosm164
}
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
with:
submodules: recursive
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
diff --git a/.github/workflows/ci-ifcpatch-pypi.yaml b/.github/workflows/ci-ifcpatch-pypi.yaml
index 5c5d8fc583..79692933ce 100644
--- a/.github/workflows/ci-ifcpatch-pypi.yaml
+++ b/.github/workflows/ci-ifcpatch-pypi.yaml
@@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
python-version: '3.11' # Version range or exact version of a Python version to use, using SemVer's version range syntax
diff --git a/.github/workflows/ci-ifcsverchok-daily.yml b/.github/workflows/ci-ifcsverchok-daily.yml
index c117ec57a4..ac3edc546b 100644
--- a/.github/workflows/ci-ifcsverchok-daily.yml
+++ b/.github/workflows/ci-ifcsverchok-daily.yml
@@ -25,7 +25,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
diff --git a/.github/workflows/ci-ifcsverchok.yml b/.github/workflows/ci-ifcsverchok.yml
index 1ff610989f..f3c8aba0a2 100644
--- a/.github/workflows/ci-ifcsverchok.yml
+++ b/.github/workflows/ci-ifcsverchok.yml
@@ -19,7 +19,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
diff --git a/.github/workflows/ci-ifctester-org.yml b/.github/workflows/ci-ifctester-org.yml
index 99e97ef8f9..7ec6cbdc46 100644
--- a/.github/workflows/ci-ifctester-org.yml
+++ b/.github/workflows/ci-ifctester-org.yml
@@ -10,9 +10,9 @@ jobs:
publish_website:
runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- name: Checkout ifctester_org_static_html
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
repository: IfcOpenShell/ifctester_org_static_html
token: ${{ secrets.IFCOPENBOT_TOKEN }}
diff --git a/.github/workflows/ci-ifctester-pypi.yml b/.github/workflows/ci-ifctester-pypi.yml
index d8acf9615e..b024d7685d 100644
--- a/.github/workflows/ci-ifctester-pypi.yml
+++ b/.github/workflows/ci-ifctester-pypi.yml
@@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6 # https://github.com/actions/setup-python
with:
python-version: '3.11' # Version range or exact version of a Python version to use, using SemVer's version range syntax
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ad00406ed8..d2392ecb2e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -34,8 +34,12 @@ jobs:
compile-and-test:
runs-on: ubuntu-22.04
needs: activate
+ env:
+ # Colored output for cmake.
+ CLICOLOR_FORCE: "1"
+ CMAKE_COLOR_DIAGNOSTICS: "ON"
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
with:
submodules: recursive
diff --git a/.github/workflows/docs-deployment-unstable.yml b/.github/workflows/docs-deployment-unstable.yml
index 7f191838eb..55e2fd5518 100644
--- a/.github/workflows/docs-deployment-unstable.yml
+++ b/.github/workflows/docs-deployment-unstable.yml
@@ -11,7 +11,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
diff --git a/.github/workflows/docs-deployment.yml b/.github/workflows/docs-deployment.yml
index 4a65e161d9..3ff50b575e 100644
--- a/.github/workflows/docs-deployment.yml
+++ b/.github/workflows/docs-deployment.yml
@@ -9,7 +9,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
diff --git a/.github/workflows/publish-pyodide-demo-app.yml b/.github/workflows/publish-pyodide-demo-app.yml
index 91bab31cb5..4aebe4266e 100644
--- a/.github/workflows/publish-pyodide-demo-app.yml
+++ b/.github/workflows/publish-pyodide-demo-app.yml
@@ -26,7 +26,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout (recursive)
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
submodules: recursive
fetch-depth: 0
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index b5cbb4f28c..4880ed8177 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
submodules: recursive
- name: Install C++ dependencies
diff --git a/aws/lambda/example_handler/__init__.py b/aws/lambda/example_handler/__init__.py
index 5256cb90a2..a6e3fe0212 100644
--- a/aws/lambda/example_handler/__init__.py
+++ b/aws/lambda/example_handler/__init__.py
@@ -1,6 +1,6 @@
+import boto3
import ifcopenshell
import ifcopenshell.util.element
-import boto3
s3 = boto3.client('s3')
diff --git a/choco/bonsai/choco_release.py b/choco/bonsai/choco_release.py
index b63ee3bf89..681e6c58e5 100644
--- a/choco/bonsai/choco_release.py
+++ b/choco/bonsai/choco_release.py
@@ -13,9 +13,10 @@ import hashlib
import os
import pathlib
import re
-from urllib import request
-from github import Github
from typing import NoReturn
+from urllib import request
+
+from github import Github
def get_repo_tag_names() -> list[str]:
diff --git a/choco/bonsai/tools/disable_blenderbim_addon.py b/choco/bonsai/tools/disable_blenderbim_addon.py
index c7355eb7d9..644be2623f 100644
--- a/choco/bonsai/tools/disable_blenderbim_addon.py
+++ b/choco/bonsai/tools/disable_blenderbim_addon.py
@@ -1,6 +1,5 @@
import bpy
-
bpy.ops.preferences.addon_disable(module='blenderbim')
bpy.ops.wm.save_userpref()
diff --git a/choco/bonsai/tools/enable_blenderbim_addon.py b/choco/bonsai/tools/enable_blenderbim_addon.py
index eae588e5f8..2b767dea03 100644
--- a/choco/bonsai/tools/enable_blenderbim_addon.py
+++ b/choco/bonsai/tools/enable_blenderbim_addon.py
@@ -1,6 +1,5 @@
import bpy
-
bpy.ops.preferences.addon_enable(module='blenderbim')
bpy.ops.wm.save_userpref()
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index 742ef0d6b8..2c197240d9 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -104,6 +104,7 @@ option(USERSPACE_PYTHON_PREFIX "Installs IfcPython for the current user only ins
option(USE_DEBUG_PYTHON "Use debug binaries when building Debug IfcPython on Windows." OFF)
option(ADD_COMMIT_SHA "Add commit sha and branch in version number, requires git" OFF)
option(VERSION_OVERRIDE "Override the version defined in buildinfo.cpp with the file VERSION in the repository root" OFF)
+option(USE_CCACHE "Enable use of ccache if it's available from PATH." ON)
set(
PYTHON_MODULE_INSTALL_DIR
@@ -132,7 +133,7 @@ if((BUILD_CONVERT OR BUILD_GEOMSERVER OR BUILD_IFCPYTHON) AND(NOT BUILD_IFCGEOM)
endif()
find_program(CCACHE_FOUND ccache)
-if(CCACHE_FOUND)
+if(USE_CCACHE AND CCACHE_FOUND)
message(STATUS "`ccache` is found, using it as a compiler launcher.")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_FOUND}")
if(MSVC)
diff --git a/cmake/IfcOpenShellConfig.cmake.in b/cmake/IfcOpenShellConfig.cmake.in
index afdfe838bc..414066668d 100644
--- a/cmake/IfcOpenShellConfig.cmake.in
+++ b/cmake/IfcOpenShellConfig.cmake.in
@@ -4,7 +4,42 @@
set(IFCOPENSHELL_SCHEMA_VERSIONS @SCHEMA_VERSIONS@)
set(IFCOPENSHELL_WITH_OPENCASCADE @WITH_OPENCASCADE@)
+set(IFCOPENSHELL_WITH_CGAL @WITH_CGAL@)
+set(IFCOPENSHELL_IFCXML @IFCXML_SUPPORT@)
+set(IFCOPENSHELL_WITH_ROCKSDB @WITH_ROCKSDB@)
+include(CMakeFindDependencyMacro)
+
+set(Boost_USE_STATIC_LIBS ON)
+set(Boost_USE_STATIC_RUNTIME OFF)
+set(Boost_USE_MULTITHREADED ON)
+set(Boost_COMPONENTS system program_options regex thread date_time iostreams)
+find_dependency(Boost CONFIG COMPONENTS ${Boost_COMPONENTS})
+find_dependency(Eigen3 CONFIG)
+
+if(IFCOPENSHELL_WITH_ROCKSDB)
+ find_dependency(zstd CONFIG)
+ find_dependency(RocksDB CONFIG)
+endif()
+
+if(IFCOPENSHELL_IFCXML)
+ find_dependency(LibXml2 CONFIG)
+endif()
+
+
+if(IFCOPENSHELL_WITH_CGAL)
+ find_dependency(CGAL CONFIG)
+endif()
+
+if(IFCOPENSHELL_WITH_OPENCASCADE)
+ find_dependency(OpenCASCADE CONFIG)
+ if(OpenCASCADE_VERSION VERSION_LESS "7.7.0")
+ # cmake configs < 7.7.0 were not adding include directories to targets automatically.
+ set_target_properties(TKernel PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${OpenCASCADE_INCLUDE_DIR}"
+ )
+ endif()
+endif()
include("${CMAKE_CURRENT_LIST_DIR}/@CONFIG_TARGETS_FILENAME@")
diff --git a/conda/update_version_init.py b/conda/update_version_init.py
index e5a7a6fd22..cbcf0df1f9 100644
--- a/conda/update_version_init.py
+++ b/conda/update_version_init.py
@@ -1,7 +1,8 @@
-import re
import argparse
+import re
from pathlib import Path
+
def update_version(file_path: str, version: str) -> None:
"""Update the version string in the given __init__.py file."""
file_path = Path(file_path)
diff --git a/docs/conf.py b/docs/conf.py
index 4583e85a43..5f4b91a23e 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,4 +1,5 @@
import textwrap
+
# The `extensions` list should already be in here from `sphinx-quickstart`
extensions = [
# there may be others here already, e.g. 'sphinx.ext.mathjax'
diff --git a/docs/generate_docs.py b/docs/generate_docs.py
index 09f3683c82..8b3e60140d 100644
--- a/docs/generate_docs.py
+++ b/docs/generate_docs.py
@@ -1,10 +1,10 @@
# This program requires doxygen, sphinx, breathe and exhale.
+import multiprocessing
import os
-import sys
import shutil
import subprocess
-import multiprocessing
+import sys
# some extra check to see if we can find sphinx in pypy bin dir
sphinx_build = os.path.join(os.path.dirname(sys.executable), 'sphinx-build')
diff --git a/nix/build-all.py b/nix/build-all.py
index 3bd12885c3..a76a53862c 100644
--- a/nix/build-all.py
+++ b/nix/build-all.py
@@ -99,35 +99,36 @@ Used environment variables:
"""
-import logging
-import os
-import re
-import sys
import glob
-import subprocess as sp
-import shutil
-import tarfile
+import logging
import multiprocessing
+import os
import platform
-import threading
-import sysconfig
-from datetime import datetime
+import re
+import shutil
# @todo temporary for expired mpfr.org certificate on 2023-04-08
import ssl
+import subprocess as sp
+import sys
+import sysconfig
+import tarfile
+import threading
+from datetime import datetime
ssl._create_default_https_context = ssl._create_unverified_context
import time
-from urllib.request import urlretrieve
from collections.abc import Generator, Sequence
from pathlib import Path
+from urllib.request import urlretrieve
try:
- from typing import Union, Literal
+ from typing import Literal, Union
except:
# python 3.6 compatibility for rocky 8
from typing import Union
+
from typing_extensions import Literal
logger = logging.getLogger(__name__)
@@ -139,7 +140,7 @@ PROJECT_NAME = "IfcOpenShell"
USE_CURRENT_PYTHON_VERSION = os.getenv("USE_CURRENT_PYTHON_VERSION")
ADD_COMMIT_SHA = os.getenv("ADD_COMMIT_SHA")
-PYTHON_VERSIONS = ["3.9.11", "3.10.3", "3.11.8", "3.12.1", "3.13.6", "3.14.0"]
+PYTHON_VERSIONS = ["3.10.3", "3.11.8", "3.12.1", "3.13.6", "3.14.0"]
JSON_VERSION = "3.11.3"
OCE_VERSION = "0.18.3"
OCCT_VERSION = "7.8.1"
diff --git a/pyodide/cache_dependencies.py b/pyodide/cache_dependencies.py
index 0ac2c8a600..5800cba067 100644
--- a/pyodide/cache_dependencies.py
+++ b/pyodide/cache_dependencies.py
@@ -8,12 +8,11 @@ or unpacks existing archives.
Usage: python cache_dependencies.py [pack|unpack]
"""
-import tarfile
import sys
+import tarfile
from pathlib import Path
from typing import Literal
-
CACHE_PREFIX = "cache-"
diff --git a/pyodide/test/test_wheel.py b/pyodide/test/test_wheel.py
index 1204c3d532..f241776d02 100644
--- a/pyodide/test/test_wheel.py
+++ b/pyodide/test/test_wheel.py
@@ -1,6 +1,5 @@
from pathlib import Path
-
WHEEL_FILENAME = next(
p.name for p in (Path.cwd() / "pyodide").iterdir() if p.name.startswith("ifcopenshell-") and p.suffix == ".whl"
)
diff --git a/pyproject.toml b/pyproject.toml
index edd328321e..13abb08d76 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -47,6 +47,7 @@ select = [
"UP", # pyupgrade
"RUF015", # next() > list_comprehension[0]
"RUF022", # sort __all__
+ "I", # import sorting
]
ignore = [
"FA100", # Conflicts with Blender using annotations for props definitions.
diff --git a/src/bcf/bcf/agnostic/extensions.py b/src/bcf/bcf/agnostic/extensions.py
index 20ecd621d8..16e7283c1a 100644
--- a/src/bcf/bcf/agnostic/extensions.py
+++ b/src/bcf/bcf/agnostic/extensions.py
@@ -1,7 +1,8 @@
+from dataclasses import fields
+from typing import NamedTuple, Union
+
import bcf.v2.model.extensions
import bcf.v3.model.extensions
-from typing import NamedTuple, Union
-from dataclasses import fields
class AttributeData(NamedTuple):
diff --git a/src/bcf/bcf/agnostic/model.py b/src/bcf/bcf/agnostic/model.py
index 4afd25d1bc..e511c07656 100644
--- a/src/bcf/bcf/agnostic/model.py
+++ b/src/bcf/bcf/agnostic/model.py
@@ -1,6 +1,7 @@
+from typing import Union
+
import bcf.v2.model
import bcf.v3.model
-from typing import Union
BimSnippet = Union[bcf.v2.model.BimSnippet, bcf.v3.model.BimSnippet]
BitMap = Union[bcf.v2.model.VisualizationInfoBitmap, bcf.v3.model.Bitmap]
diff --git a/src/bcf/bcf/agnostic/topic.py b/src/bcf/bcf/agnostic/topic.py
index 1493d44bd7..1e77f40e97 100644
--- a/src/bcf/bcf/agnostic/topic.py
+++ b/src/bcf/bcf/agnostic/topic.py
@@ -1,13 +1,14 @@
import tempfile
+from pathlib import Path
+from typing import Optional, Union
+
+import bcf.agnostic.model as mdl
import bcf.v2.bcfxml
import bcf.v2.model
import bcf.v2.topic
import bcf.v3.bcfxml
import bcf.v3.model
import bcf.v3.topic
-import bcf.agnostic.model as mdl
-from pathlib import Path
-from typing import Union, Optional
from typing_extensions import assert_never
TopicHandler = Union[bcf.v2.topic.TopicHandler, bcf.v3.topic.TopicHandler]
diff --git a/src/bcf/bcf/agnostic/visinfo.py b/src/bcf/bcf/agnostic/visinfo.py
index 27adf56bdf..a2b248b085 100644
--- a/src/bcf/bcf/agnostic/visinfo.py
+++ b/src/bcf/bcf/agnostic/visinfo.py
@@ -1,5 +1,6 @@
-import bcf.v2.visinfo
-import bcf.v3.visinfo
from typing import Union
+import bcf.v2.visinfo
+import bcf.v3.visinfo
+
VisualizationInfoHandler = Union[bcf.v2.visinfo.VisualizationInfoHandler, bcf.v3.visinfo.VisualizationInfoHandler]
diff --git a/src/bcf/bcf/bcfxml.py b/src/bcf/bcf/bcfxml.py
index 073e50af39..07b1fb5cb0 100644
--- a/src/bcf/bcf/bcfxml.py
+++ b/src/bcf/bcf/bcfxml.py
@@ -29,7 +29,6 @@ from bcf.v3.bcfxml import BcfXml as BcfXml3
from bcf.v3.model import Version as Version3
from bcf.xml_parser import AbstractXmlParserSerializer, XmlParserSerializer
-
BcfXml = Union[BcfXml2, BcfXml3]
diff --git a/src/bcf/bcf/inmemory_zipfile.py b/src/bcf/bcf/inmemory_zipfile.py
index 413da4fcfa..bac4b47c7b 100644
--- a/src/bcf/bcf/inmemory_zipfile.py
+++ b/src/bcf/bcf/inmemory_zipfile.py
@@ -7,6 +7,7 @@ original idea from https://stackoverflow.com/a/19722365/1307905
"""
from __future__ import annotations
+
import zipfile
from io import BytesIO
from os import PathLike
diff --git a/src/bcf/bcf/v2/bcfxml.py b/src/bcf/bcf/v2/bcfxml.py
index 039f1cbe09..ad9f8e7679 100644
--- a/src/bcf/bcf/v2/bcfxml.py
+++ b/src/bcf/bcf/v2/bcfxml.py
@@ -1,6 +1,7 @@
"""BCF XML V2 handler."""
from __future__ import annotations
+
import uuid
import warnings
import zipfile
diff --git a/src/bcf/bcf/v2/model/extensions.py b/src/bcf/bcf/v2/model/extensions.py
index bf28512100..e50277570e 100644
--- a/src/bcf/bcf/v2/model/extensions.py
+++ b/src/bcf/bcf/v2/model/extensions.py
@@ -14,15 +14,11 @@
# Currently extensions support for v2 is only read-only.
-import sys
from dataclasses import dataclass, field, fields
from typing import Optional
-DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
-
-
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsPriorities:
class Meta:
global_type = False
@@ -39,7 +35,7 @@ class ExtensionsPriorities:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsSnippetTypes:
class Meta:
global_type = False
@@ -56,7 +52,7 @@ class ExtensionsSnippetTypes:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsStages:
class Meta:
global_type = False
@@ -73,7 +69,7 @@ class ExtensionsStages:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsTopicLabels:
class Meta:
global_type = False
@@ -90,7 +86,7 @@ class ExtensionsTopicLabels:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsTopicStatuses:
class Meta:
global_type = False
@@ -107,7 +103,7 @@ class ExtensionsTopicStatuses:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsTopicTypes:
class Meta:
global_type = False
@@ -124,7 +120,7 @@ class ExtensionsTopicTypes:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsUsers:
class Meta:
global_type = False
@@ -141,7 +137,7 @@ class ExtensionsUsers:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Extensions:
topic_types: Optional[ExtensionsTopicTypes] = field(
default=None,
diff --git a/src/bcf/bcf/v2/model/markup.py b/src/bcf/bcf/v2/model/markup.py
index f91d8fe8dc..9027d5b280 100644
--- a/src/bcf/bcf/v2/model/markup.py
+++ b/src/bcf/bcf/v2/model/markup.py
@@ -1,13 +1,10 @@
-import sys
from dataclasses import dataclass, field
from typing import Optional
from xsdata.models.datatype import XmlDateTime
-DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
-
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class BimSnippet:
reference: str = field(
metadata={
@@ -41,7 +38,7 @@ class BimSnippet:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class CommentViewpoint:
class Meta:
global_type = False
@@ -56,7 +53,7 @@ class CommentViewpoint:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class HeaderFile:
class Meta:
global_type = False
@@ -112,7 +109,7 @@ class HeaderFile:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class TopicDocumentReference:
class Meta:
global_type = False
@@ -150,7 +147,7 @@ class TopicDocumentReference:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class TopicRelatedTopic:
class Meta:
global_type = False
@@ -165,7 +162,7 @@ class TopicRelatedTopic:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ViewPoint:
viewpoint: Optional[str] = field(
default=None,
@@ -201,7 +198,7 @@ class ViewPoint:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Comment:
date: XmlDateTime = field(
metadata={
@@ -261,7 +258,7 @@ class Comment:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Header:
file: list[HeaderFile] = field(
default_factory=list,
@@ -274,7 +271,7 @@ class Header:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Topic:
reference_link: list[str] = field(
default_factory=list,
@@ -428,7 +425,7 @@ class Topic:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Markup:
header: Optional[Header] = field(
default=None,
diff --git a/src/bcf/bcf/v2/model/project.py b/src/bcf/bcf/v2/model/project.py
index a27afb7cd6..e86fb9b009 100644
--- a/src/bcf/bcf/v2/model/project.py
+++ b/src/bcf/bcf/v2/model/project.py
@@ -1,11 +1,8 @@
-import sys
from dataclasses import dataclass, field
from typing import Optional
-DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
-
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Project:
name: Optional[str] = field(
default=None,
@@ -24,7 +21,7 @@ class Project:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ProjectExtension:
project: Optional[Project] = field(
default=None,
diff --git a/src/bcf/bcf/v2/model/version.py b/src/bcf/bcf/v2/model/version.py
index ea9331bc36..9f55ad5bf9 100644
--- a/src/bcf/bcf/v2/model/version.py
+++ b/src/bcf/bcf/v2/model/version.py
@@ -1,11 +1,8 @@
-import sys
from dataclasses import dataclass, field
from typing import Optional
-DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
-
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Version:
detailed_version: Optional[str] = field(
default=None,
diff --git a/src/bcf/bcf/v2/model/visinfo.py b/src/bcf/bcf/v2/model/visinfo.py
index 3615609881..3d4debbcbd 100644
--- a/src/bcf/bcf/v2/model/visinfo.py
+++ b/src/bcf/bcf/v2/model/visinfo.py
@@ -1,17 +1,14 @@
-import sys
from dataclasses import dataclass, field
from enum import Enum
from typing import Optional
-DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
-
class BitmapFormat(Enum):
PNG = "PNG"
JPG = "JPG"
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Component:
originating_system: Optional[str] = field(
default=None,
@@ -38,7 +35,7 @@ class Component:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Direction:
x: float = field(
metadata={
@@ -63,7 +60,7 @@ class Direction:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Point:
x: float = field(
metadata={
@@ -88,7 +85,7 @@ class Point:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ViewSetupHints:
spaces_visible: Optional[bool] = field(
default=None,
@@ -113,7 +110,7 @@ class ViewSetupHints:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ClippingPlane:
location: Point = field(
metadata={
@@ -131,7 +128,7 @@ class ClippingPlane:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ComponentColoringColor:
class Meta:
global_type = False
@@ -154,7 +151,7 @@ class ComponentColoringColor:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ComponentSelection:
component: list[Component] = field(
default_factory=list,
@@ -166,7 +163,7 @@ class ComponentSelection:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ComponentVisibilityExceptions:
class Meta:
global_type = False
@@ -181,7 +178,7 @@ class ComponentVisibilityExceptions:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Line:
start_point: Point = field(
metadata={
@@ -199,7 +196,7 @@ class Line:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class OrthogonalCamera:
"""
Attributes
@@ -239,7 +236,7 @@ class OrthogonalCamera:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class PerspectiveCamera:
"""
Attributes
@@ -284,7 +281,7 @@ class PerspectiveCamera:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class VisualizationInfoBitmap:
class Meta:
global_type = False
@@ -333,7 +330,7 @@ class VisualizationInfoBitmap:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ComponentColoring:
color: list[ComponentColoringColor] = field(
default_factory=list,
@@ -345,7 +342,7 @@ class ComponentColoring:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ComponentVisibility:
exceptions: Optional[ComponentVisibilityExceptions] = field(
default=None,
@@ -363,7 +360,7 @@ class ComponentVisibility:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class VisualizationInfoClippingPlanes:
class Meta:
global_type = False
@@ -377,7 +374,7 @@ class VisualizationInfoClippingPlanes:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class VisualizationInfoLines:
class Meta:
global_type = False
@@ -392,7 +389,7 @@ class VisualizationInfoLines:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Components:
view_setup_hints: Optional[ViewSetupHints] = field(
default=None,
@@ -424,7 +421,7 @@ class Components:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class VisualizationInfo:
"""
VisualizationInfo documentation.
diff --git a/src/bcf/bcf/v2/topic.py b/src/bcf/bcf/v2/topic.py
index 7ee4c50b60..30506d734d 100644
--- a/src/bcf/bcf/v2/topic.py
+++ b/src/bcf/bcf/v2/topic.py
@@ -1,6 +1,7 @@
"""BCF XML V2 Topic handler."""
from __future__ import annotations
+
import datetime
import tempfile
import uuid
diff --git a/src/bcf/bcf/v2/visinfo.py b/src/bcf/bcf/v2/visinfo.py
index 46d274ea1d..1d081ae782 100644
--- a/src/bcf/bcf/v2/visinfo.py
+++ b/src/bcf/bcf/v2/visinfo.py
@@ -1,12 +1,12 @@
import uuid
import zipfile
-from typing import Any, Optional, Literal, Union
from collections.abc import Iterable
+from typing import Any, Literal, Optional, Union
+import ifcopenshell.util.placement
+import ifcopenshell.util.unit
import numpy as np
from ifcopenshell import entity_instance
-import ifcopenshell.util.unit
-import ifcopenshell.util.placement
from numpy.typing import NDArray
import bcf.v2.model as mdl
diff --git a/src/bcf/bcf/v3/bcfxml.py b/src/bcf/bcf/v3/bcfxml.py
index 872efe5db9..7d5ca0de1f 100644
--- a/src/bcf/bcf/v3/bcfxml.py
+++ b/src/bcf/bcf/v3/bcfxml.py
@@ -1,6 +1,7 @@
"""BCF XML V3 handlers."""
from __future__ import annotations
+
import uuid
import warnings
import zipfile
diff --git a/src/bcf/bcf/v3/model/documents.py b/src/bcf/bcf/v3/model/documents.py
index 2e2de1f5ea..65a3615e7c 100644
--- a/src/bcf/bcf/v3/model/documents.py
+++ b/src/bcf/bcf/v3/model/documents.py
@@ -1,11 +1,8 @@
-import sys
from dataclasses import dataclass, field
from typing import Optional
-DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
-
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Document:
filename: str = field(
metadata={
@@ -37,7 +34,7 @@ class Document:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class DocumentInfoDocuments:
class Meta:
global_type = False
@@ -52,7 +49,7 @@ class DocumentInfoDocuments:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class DocumentInfo:
documents: Optional[DocumentInfoDocuments] = field(
default=None,
diff --git a/src/bcf/bcf/v3/model/extensions.py b/src/bcf/bcf/v3/model/extensions.py
index 12d3d4dbfd..48aef2243b 100644
--- a/src/bcf/bcf/v3/model/extensions.py
+++ b/src/bcf/bcf/v3/model/extensions.py
@@ -1,11 +1,8 @@
-import sys
from dataclasses import dataclass, field
from typing import Optional
-DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
-
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsPriorities:
class Meta:
global_type = False
@@ -22,7 +19,7 @@ class ExtensionsPriorities:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsSnippetTypes:
class Meta:
global_type = False
@@ -39,7 +36,7 @@ class ExtensionsSnippetTypes:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsStages:
class Meta:
global_type = False
@@ -56,7 +53,7 @@ class ExtensionsStages:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsTopicLabels:
class Meta:
global_type = False
@@ -73,7 +70,7 @@ class ExtensionsTopicLabels:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsTopicStatuses:
class Meta:
global_type = False
@@ -90,7 +87,7 @@ class ExtensionsTopicStatuses:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsTopicTypes:
class Meta:
global_type = False
@@ -107,7 +104,7 @@ class ExtensionsTopicTypes:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ExtensionsUsers:
class Meta:
global_type = False
@@ -124,7 +121,7 @@ class ExtensionsUsers:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Extensions:
topic_types: Optional[ExtensionsTopicTypes] = field(
default=None,
diff --git a/src/bcf/bcf/v3/model/markup.py b/src/bcf/bcf/v3/model/markup.py
index 96b656b09d..bcd985af34 100644
--- a/src/bcf/bcf/v3/model/markup.py
+++ b/src/bcf/bcf/v3/model/markup.py
@@ -1,13 +1,10 @@
-import sys
from dataclasses import dataclass, field
from typing import Optional
from xsdata.models.datatype import XmlDateTime
-DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
-
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class BimSnippet:
reference: str = field(
metadata={
@@ -47,7 +44,7 @@ class BimSnippet:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class CommentViewpoint:
class Meta:
global_type = False
@@ -62,7 +59,7 @@ class CommentViewpoint:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class DocumentReference:
document_guid: Optional[str] = field(
default=None,
@@ -103,7 +100,7 @@ class DocumentReference:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class File:
filename: Optional[str] = field(
default=None,
@@ -160,7 +157,7 @@ class File:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class TopicLabels:
class Meta:
global_type = False
@@ -177,7 +174,7 @@ class TopicLabels:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class TopicReferenceLinks:
class Meta:
global_type = False
@@ -194,7 +191,7 @@ class TopicReferenceLinks:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class TopicRelatedTopicsRelatedTopic:
class Meta:
global_type = False
@@ -209,7 +206,7 @@ class TopicRelatedTopicsRelatedTopic:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ViewPoint:
viewpoint: Optional[str] = field(
default=None,
@@ -249,7 +246,7 @@ class ViewPoint:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Comment:
date: XmlDateTime = field(
metadata={
@@ -315,7 +312,7 @@ class Comment:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class HeaderFiles:
class Meta:
global_type = False
@@ -330,7 +327,7 @@ class HeaderFiles:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class TopicDocumentReferences:
class Meta:
global_type = False
@@ -345,7 +342,7 @@ class TopicDocumentReferences:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class TopicRelatedTopics:
class Meta:
global_type = False
@@ -360,7 +357,7 @@ class TopicRelatedTopics:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class TopicViewpoints:
class Meta:
global_type = False
@@ -375,7 +372,7 @@ class TopicViewpoints:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Header:
files: Optional[HeaderFiles] = field(
default=None,
@@ -387,7 +384,7 @@ class Header:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class TopicComments:
class Meta:
global_type = False
@@ -402,7 +399,7 @@ class TopicComments:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Topic:
reference_links: Optional[TopicReferenceLinks] = field(
default=None,
@@ -599,7 +596,7 @@ class Topic:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Markup:
header: Optional[Header] = field(
default=None,
diff --git a/src/bcf/bcf/v3/model/project.py b/src/bcf/bcf/v3/model/project.py
index ff07fa2c08..76a6922925 100644
--- a/src/bcf/bcf/v3/model/project.py
+++ b/src/bcf/bcf/v3/model/project.py
@@ -1,11 +1,8 @@
-import sys
from dataclasses import dataclass, field
from typing import Optional
-DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
-
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Project:
name: Optional[str] = field(
default=None,
@@ -28,7 +25,7 @@ class Project:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ProjectInfo:
project: Project = field(
metadata={
diff --git a/src/bcf/bcf/v3/model/version.py b/src/bcf/bcf/v3/model/version.py
index dd8cc713e3..f3a44d2ab3 100644
--- a/src/bcf/bcf/v3/model/version.py
+++ b/src/bcf/bcf/v3/model/version.py
@@ -1,10 +1,7 @@
-import sys
from dataclasses import dataclass, field
-DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
-
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Version:
version_id: str = field(
metadata={
diff --git a/src/bcf/bcf/v3/model/visinfo.py b/src/bcf/bcf/v3/model/visinfo.py
index 43a00f33d3..e2fa3d06d7 100644
--- a/src/bcf/bcf/v3/model/visinfo.py
+++ b/src/bcf/bcf/v3/model/visinfo.py
@@ -1,18 +1,14 @@
-import sys
from dataclasses import dataclass, field
from enum import Enum
from typing import Optional
-DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
-
-
class BitmapFormat(Enum):
PNG = "png"
JPG = "jpg"
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Component:
originating_system: Optional[str] = field(
default=None,
@@ -43,7 +39,7 @@ class Component:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Direction:
x: float = field(
metadata={
@@ -68,7 +64,7 @@ class Direction:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Point:
x: float = field(
metadata={
@@ -93,7 +89,7 @@ class Point:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ViewSetupHints:
spaces_visible: bool = field(
default=False,
@@ -118,7 +114,7 @@ class ViewSetupHints:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Bitmap:
format: BitmapFormat = field(
metadata={
@@ -166,7 +162,7 @@ class Bitmap:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ClippingPlane:
location: Point = field(
metadata={
@@ -184,7 +180,7 @@ class ClippingPlane:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ComponentColoringColorComponents:
class Meta:
global_type = False
@@ -199,7 +195,7 @@ class ComponentColoringColorComponents:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ComponentSelection:
component: list[Component] = field(
default_factory=list,
@@ -210,7 +206,7 @@ class ComponentSelection:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ComponentVisibilityExceptions:
class Meta:
global_type = False
@@ -224,7 +220,7 @@ class ComponentVisibilityExceptions:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Line:
start_point: Point = field(
metadata={
@@ -242,7 +238,7 @@ class Line:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class OrthogonalCamera:
"""
Attributes
@@ -292,7 +288,7 @@ class OrthogonalCamera:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class PerspectiveCamera:
"""
Attributes
@@ -348,7 +344,7 @@ class PerspectiveCamera:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ComponentColoringColor:
class Meta:
global_type = False
@@ -370,7 +366,7 @@ class ComponentColoringColor:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ComponentVisibility:
view_setup_hints: Optional[ViewSetupHints] = field(
default=None,
@@ -395,7 +391,7 @@ class ComponentVisibility:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class VisualizationInfoBitmaps:
class Meta:
global_type = False
@@ -409,7 +405,7 @@ class VisualizationInfoBitmaps:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class VisualizationInfoClippingPlanes:
class Meta:
global_type = False
@@ -423,7 +419,7 @@ class VisualizationInfoClippingPlanes:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class VisualizationInfoLines:
class Meta:
global_type = False
@@ -437,7 +433,7 @@ class VisualizationInfoLines:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class ComponentColoring:
color: list[ComponentColoringColor] = field(
default_factory=list,
@@ -448,7 +444,7 @@ class ComponentColoring:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class Components:
selection: Optional[ComponentSelection] = field(
default=None,
@@ -473,7 +469,7 @@ class Components:
)
-@dataclass(**DATACLASS_KWARGS)
+@dataclass(slots=True, kw_only=True)
class VisualizationInfo:
"""
VisualizationInfo documentation.
diff --git a/src/bcf/bcf/v3/topic.py b/src/bcf/bcf/v3/topic.py
index 04753c006e..d82e4ed0f1 100644
--- a/src/bcf/bcf/v3/topic.py
+++ b/src/bcf/bcf/v3/topic.py
@@ -1,6 +1,7 @@
"""BCF XML V3 Topic handler."""
from __future__ import annotations
+
import datetime
import uuid
import zipfile
diff --git a/src/bcf/bcf/v3/visinfo.py b/src/bcf/bcf/v3/visinfo.py
index 7880ddb10f..050641ed23 100644
--- a/src/bcf/bcf/v3/visinfo.py
+++ b/src/bcf/bcf/v3/visinfo.py
@@ -1,12 +1,12 @@
import uuid
import zipfile
-from typing import Any, Optional, Literal, Union
from collections.abc import Iterable
+from typing import Any, Literal, Optional, Union
+import ifcopenshell.util.placement
+import ifcopenshell.util.unit
import numpy as np
from ifcopenshell import entity_instance
-import ifcopenshell.util.unit
-import ifcopenshell.util.placement
from numpy.typing import NDArray
import bcf.v3.model as mdl
diff --git a/src/bcf/tests/conftest.py b/src/bcf/tests/conftest.py
index ea1b2aee8b..f19792122a 100644
--- a/src/bcf/tests/conftest.py
+++ b/src/bcf/tests/conftest.py
@@ -1,5 +1,4 @@
import pytest
-
from bcf.xml_parser import XmlParserSerializer
diff --git a/src/bcf/tests/v2/test_bcf_xml.py b/src/bcf/tests/v2/test_bcf_xml.py
index fed1428e73..1b5128e96f 100644
--- a/src/bcf/tests/v2/test_bcf_xml.py
+++ b/src/bcf/tests/v2/test_bcf_xml.py
@@ -4,9 +4,8 @@ import uuid
from pathlib import Path
from tempfile import TemporaryDirectory
-import pytest
-
import bcf.v2.model as mdl
+import pytest
from bcf.v2.bcfxml import BcfXml
from bcf.v2.topic import TopicHandler
from bcf.v2.visinfo import (
diff --git a/src/bcf/tests/v2/test_example_files.py b/src/bcf/tests/v2/test_example_files.py
index 3821569c28..6d964bd0e9 100644
--- a/src/bcf/tests/v2/test_example_files.py
+++ b/src/bcf/tests/v2/test_example_files.py
@@ -3,11 +3,10 @@ import os
import zipfile
from pathlib import Path
-from xsdata.models.datatype import XmlDateTime
-
import bcf.v2.model as mdl
from bcf.v2.bcfxml import BcfXml
from bcf.v2.topic import TopicHandler
+from xsdata.models.datatype import XmlDateTime
def test_maximum_information() -> None:
diff --git a/src/bcf/tests/v2/test_ifcclash_api.py b/src/bcf/tests/v2/test_ifcclash_api.py
index 14945e8392..34c3a493e4 100644
--- a/src/bcf/tests/v2/test_ifcclash_api.py
+++ b/src/bcf/tests/v2/test_ifcclash_api.py
@@ -1,6 +1,5 @@
import numpy as np
import pytest
-
from bcf.v2.bcfxml import BcfXml
diff --git a/src/bcf/tests/v3/test_bcf_xml.py b/src/bcf/tests/v3/test_bcf_xml.py
index 50664b98c7..ae658ca55f 100644
--- a/src/bcf/tests/v3/test_bcf_xml.py
+++ b/src/bcf/tests/v3/test_bcf_xml.py
@@ -4,9 +4,8 @@ import uuid
from pathlib import Path
from tempfile import TemporaryDirectory
-import pytest
-
import bcf.v3.model as mdl
+import pytest
from bcf.v3.bcfxml import BcfXml
from bcf.v3.topic import TopicHandler
from bcf.v3.visinfo import (
diff --git a/src/bcf/tests/v3/test_example_files.py b/src/bcf/tests/v3/test_example_files.py
index e385b8634f..6774c49982 100644
--- a/src/bcf/tests/v3/test_example_files.py
+++ b/src/bcf/tests/v3/test_example_files.py
@@ -3,11 +3,10 @@ import os
import zipfile
from pathlib import Path
-from xsdata.models.datatype import XmlDateTime
-
import bcf.v3.model as mdl
from bcf.v3.bcfxml import BcfXml
from bcf.v3.topic import TopicHandler
+from xsdata.models.datatype import XmlDateTime
def test_doc_ref_internal() -> None:
diff --git a/src/bcf/tests/v3/test_ifcclash_api.py b/src/bcf/tests/v3/test_ifcclash_api.py
index d470f1ffb8..faea9b6a1a 100644
--- a/src/bcf/tests/v3/test_ifcclash_api.py
+++ b/src/bcf/tests/v3/test_ifcclash_api.py
@@ -1,6 +1,5 @@
import numpy as np
import pytest
-
from bcf.v3.bcfxml import BcfXml
diff --git a/src/bonsai/bonsai/bim/__init__.py b/src/bonsai/bonsai/bim/__init__.py
index 3d865de16e..29be20faf4 100644
--- a/src/bonsai/bonsai/bim/__init__.py
+++ b/src/bonsai/bonsai/bim/__init__.py
@@ -115,11 +115,13 @@ classes = [
operator.EditBlenderCollection,
operator.FileAssociate,
operator.FileUnassociate,
+ operator.LoadBlendMetadataAndIFC,
operator.OpenPath,
operator.OpenUpstream,
operator.OpenUri,
operator.ReloadIfcFile,
operator.RevertClippingPlaneCut,
+ operator.SaveBlendMetadataFile,
operator.SelectDir,
operator.SelectIfcFile,
operator.SelectURIAttribute,
@@ -129,12 +131,21 @@ classes = [
prop.StrProperty,
operator.BIM_OT_enum_property_search, # /!\ Register AFTER prop.StrProperty
operator.BIM_OT_attribute_search_values,
+ operator.BIM_UL_tab_panels,
+ operator.BIM_OT_toggle_panel_visibility,
+ operator.BIM_OT_bookmark_panel,
+ operator.BIM_OT_manage_tab_panels,
+ operator.BIM_OT_manage_tab_visibility,
+ operator.BIM_OT_toggle_tab_visibility,
+ operator.BIM_OT_reset_ui_layout,
prop.ObjProperty,
prop.MultipleFileSelect,
prop.Attribute,
prop.ISODuration,
prop.BIMAreaProperties,
prop.BIMTabProperties,
+ prop.BIMTabVisibility, # Must be registered before BIMProperties
+ prop.BIMPanelProperties, # Must be registered before BIMProperties
prop.BIMProperties,
prop.IfcParameter,
prop.PsetQto,
@@ -272,6 +283,7 @@ def register():
bpy.types.Curve.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.Camera.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.PointLight.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
+
if hasattr(bpy.types, "UI_MT_button_context_menu"):
bpy.types.UI_MT_button_context_menu.append(ui.draw_custom_context_menu)
bpy.types.STATUSBAR_HT_header.append(ui.draw_statusbar)
@@ -307,6 +319,10 @@ def register():
# RestrictedContext doesn't allow accessing scene attribute, postpone it for a bit.
bpy.app.timers.register(tool.Blender.setup_user_data_dir, first_interval=0.1)
+ bpy.types.Scene.active_tab_name = bpy.props.StringProperty()
+ bpy.types.Scene.tab_panels = bpy.props.CollectionProperty(type=bpy.types.PropertyGroup)
+ bpy.types.Scene.active_tab_panel_index = bpy.props.IntProperty()
+
def unregister():
global icons
@@ -348,3 +364,7 @@ def unregister():
tool.Blender.remove_scene_panel_override(panel)
bpy.app.translations.unregister("bonsai")
+
+ del bpy.types.Scene.active_tab_name
+ del bpy.types.Scene.tab_panels
+ del bpy.types.Scene.active_tab_panel_index
diff --git a/src/bonsai/bonsai/bim/helper.py b/src/bonsai/bonsai/bim/helper.py
index 49f49582b4..3b3dd502e4 100644
--- a/src/bonsai/bonsai/bim/helper.py
+++ b/src/bonsai/bonsai/bim/helper.py
@@ -498,6 +498,8 @@ def draw_filter(
if data.data["saved_searches"]:
row.operator("bim.load_search", text="", icon="IMPORT").module = module
row.operator("bim.save_search", text="", icon="EXPORT").module = module
+ if data.data["saved_searches"]:
+ row.operator("bim.remove_search", text="", icon="REMOVE").module = module
if module != "search":
if module == "drawing_include":
row.operator("bim.edit_element_filter", icon="CHECKMARK", text="").filter_mode = "INCLUDE"
@@ -505,8 +507,17 @@ def draw_filter(
row.operator("bim.edit_element_filter", icon="CHECKMARK", text="").filter_mode = "EXCLUDE"
row.operator("bim.enable_editing_element_filter", icon="CANCEL", text="").filter_mode = "NONE"
row = layout.row(align=True)
- row.operator("bim.add_filter_group", text="Add Search Group", icon="ADD").module = module
- row.operator("bim.edit_filter_query", text="", icon="FILTER").module = module
+ if not tool.Blender.get_addon_preferences().chain_filter_with_set_operations:
+ row.operator("bim.add_filter_group", text="Add Search Group", icon="ADD").module = module
+ else:
+ if not filter_groups or not any(fg.filters for fg in filter_groups):
+ op = row.operator("bim.add_filter", text="Add Filter", icon="ADD")
+ op.type = "entity"
+ op.index = 0
+ op.module = module
+ op = row.operator("bim.edit_filter_query", text="", icon="FILTER")
+ if "module" in op.bl_rna.properties:
+ op.module = module
for i, filter_group in enumerate(filter_groups):
box = layout.box()
@@ -524,43 +535,251 @@ def draw_filter(
for j, ifc_filter in enumerate(filter_group.filters):
if ifc_filter.type == "entity":
row = box.row(align=True)
+ preferences = tool.Blender.get_addon_preferences()
+ if preferences.chain_filter_with_set_operations:
+ show_mode_toggle = j > 0
+ else:
+ show_mode_toggle = (
+ preferences.default_filter_with_set_operations_for_globalid_and_class and j > 0
+ ) # PR 7315 mode
+ if show_mode_toggle:
+ mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
+ op = row.operator(
+ "bim.toggle_filter_inclusion",
+ icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
+ text="",
+ depress=ifc_filter.filter_mode != "ADD",
+ )
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
row.prop(ifc_filter, "value", text="", icon="FILE_3D")
+ op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
+ op.filter_type = ifc_filter.type
elif ifc_filter.type == "attribute":
row = box.row(align=True)
+ if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
+ mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
+ op = row.operator(
+ "bim.toggle_filter_inclusion",
+ icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
+ text="",
+ depress=ifc_filter.filter_mode != "ADD",
+ )
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
row.prop(ifc_filter, "name", text="", icon="COPY_ID")
+ op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
+ op.filter_type = ifc_filter.type
+ op.suggestion_type = "attribute_name"
row.prop(ifc_filter, "value", text="")
+ if ifc_filter.name:
+ op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
+ op.filter_type = ifc_filter.type
+ op.suggestion_type = "attribute_value"
elif ifc_filter.type == "type":
row = box.row(align=True)
+ if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
+ mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
+ op = row.operator(
+ "bim.toggle_filter_inclusion",
+ icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
+ text="",
+ depress=ifc_filter.filter_mode != "ADD",
+ )
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
row.prop(ifc_filter, "value", text="", icon="FILE_VOLUME")
+ op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
+ op.filter_type = ifc_filter.type
elif ifc_filter.type == "material":
row = box.row(align=True)
+ if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
+ mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
+ op = row.operator(
+ "bim.toggle_filter_inclusion",
+ icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
+ text="",
+ depress=ifc_filter.filter_mode != "ADD",
+ )
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
row.prop(ifc_filter, "value", text="", icon="MATERIAL")
+ op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
+ op.filter_type = ifc_filter.type
elif ifc_filter.type == "property":
row = box.row(align=True)
+ if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
+ mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
+ op = row.operator(
+ "bim.toggle_filter_inclusion",
+ icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
+ text="",
+ depress=ifc_filter.filter_mode != "ADD",
+ )
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
row.prop(ifc_filter, "pset", text="", icon="PROPERTIES")
+ op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
+ op.filter_type = ifc_filter.type
+ op.suggestion_type = "pset"
row.prop(ifc_filter, "name", text="")
+ if ifc_filter.pset:
+ op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
+ op.filter_type = ifc_filter.type
+ op.suggestion_type = "property_name"
row.prop(ifc_filter, "comparison", text="")
row.prop(ifc_filter, "value", text="")
+ if ifc_filter.pset and ifc_filter.name:
+ op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
+ op.filter_type = ifc_filter.type
+ op.suggestion_type = "property_value"
elif ifc_filter.type == "classification":
row = box.row(align=True)
+ if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
+ mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
+ op = row.operator(
+ "bim.toggle_filter_inclusion",
+ icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
+ text="",
+ depress=ifc_filter.filter_mode != "ADD",
+ )
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
row.prop(ifc_filter, "value", text="", icon="OUTLINER")
+ op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
+ op.filter_type = ifc_filter.type
elif ifc_filter.type == "location":
row = box.row(align=True)
+ if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
+ mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
+ op = row.operator(
+ "bim.toggle_filter_inclusion",
+ icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
+ text="",
+ depress=ifc_filter.filter_mode != "ADD",
+ )
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
row.prop(ifc_filter, "value", text="", icon="PACKAGE")
+ op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
+ op.filter_type = ifc_filter.type
elif ifc_filter.type == "group":
row = box.row(align=True)
+ if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
+ mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
+ op = row.operator(
+ "bim.toggle_filter_inclusion",
+ icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
+ text="",
+ depress=ifc_filter.filter_mode != "ADD",
+ )
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
row.prop(ifc_filter, "value", text="", icon="OUTLINER_COLLECTION")
+ op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
+ op.filter_type = ifc_filter.type
elif ifc_filter.type == "parent":
row = box.row(align=True)
+ if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
+ mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
+ op = row.operator(
+ "bim.toggle_filter_inclusion",
+ icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
+ text="",
+ depress=ifc_filter.filter_mode != "ADD",
+ )
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
row.prop(ifc_filter, "value", text="", icon="FILE_PARENT")
+ op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
+ op.filter_type = ifc_filter.type
elif ifc_filter.type == "query":
row = box.row(align=True)
+ if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
+ mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
+ op = row.operator(
+ "bim.toggle_filter_inclusion",
+ icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
+ text="",
+ depress=ifc_filter.filter_mode != "ADD",
+ )
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
row.prop(ifc_filter, "name", text="", icon="POINTCLOUD_DATA")
row.prop(ifc_filter, "comparison", text="")
row.prop(ifc_filter, "value", text="")
elif ifc_filter.type == "instance":
row = box.row(align=True)
+ preferences = tool.Blender.get_addon_preferences()
+ if preferences.chain_filter_with_set_operations:
+ show_mode_toggle = j > 0
+ else:
+ show_mode_toggle = (
+ preferences.default_filter_with_set_operations_for_globalid_and_class and j > 0
+ ) # PR 7315 mode
+ if show_mode_toggle:
+ mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
+ op = row.operator(
+ "bim.toggle_filter_inclusion",
+ icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
+ text="",
+ depress=ifc_filter.filter_mode != "ADD",
+ )
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
row.prop(ifc_filter, "value", text="", icon="GRIP")
+ op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
+ op.group_index = i
+ op.filter_index = j
+ op.module = module
+ op.filter_type = ifc_filter.type
op = row.operator("bim.select_filter_elements", text="", icon="EYEDROPPER")
op.group_index = i
op.index = j
@@ -569,3 +788,149 @@ def draw_filter(
op.group_index = i
op.index = j
op.module = module
+
+
+# ============================================================================
+# UI Panel Visibility Helpers
+# ============================================================================
+
+
+def get_tab_names():
+ from bonsai.bim.prop import get_tab
+
+ enum_items = get_tab(None, None)
+ # Exclude None separators and the BLENDER tab (not part of BIM tab system)
+ return [item[0] for item in enum_items if item is not None and item[0] != "BLENDER"]
+
+
+def get_panel_tab_name(panel_class):
+ if hasattr(panel_class, "bim_tab_name"):
+ return panel_class.bim_tab_name
+ return "PROJECT" # Default fallback
+
+
+def should_show_panel(panel_id, panel_tab_name, context):
+ if tool.Blender.is_tab(context, "BOOKMARK"):
+ return is_panel_bookmarked(panel_id) and get_panel_visibility(panel_id, "BOOKMARK")
+
+ if tool.Blender.is_tab(context, panel_tab_name):
+ return get_tab_visibility(panel_tab_name) and get_panel_visibility(panel_id, panel_tab_name)
+
+ return False
+
+
+def get_tab_visibility(tab_name):
+ bim_props = tool.Blender.get_bim_props()
+ tab_vis = bim_props.tab_visibilities.get(tab_name)
+ return tab_vis.is_visible if tab_vis else True
+
+
+def set_tab_visibility(tab_name, visible):
+ bim_props = tool.Blender.get_bim_props()
+ tab_vis = bim_props.tab_visibilities.get(tab_name)
+ if tab_vis:
+ tab_vis.is_visible = visible
+ else:
+ new_tab = bim_props.tab_visibilities.add()
+ new_tab.name = tab_name
+ new_tab.is_visible = visible
+
+
+def get_panel_visibility(panel_id, current_tab=None):
+ panel_config = get_panel_config(panel_id)
+ if panel_config:
+ if current_tab == "BOOKMARK":
+ return panel_config.is_visible_in_bookmarks
+ else:
+ return panel_config.is_visible_in_tab
+ return True
+
+
+def is_panel_bookmarked(panel_id):
+ panel_config = get_panel_config(panel_id)
+ if panel_config:
+ return panel_config.is_bookmarked
+ return False
+
+
+def get_panel_config(panel_id, create_if_missing=False):
+ try:
+ bim_props = tool.Blender.get_bim_props()
+ except (AttributeError, AssertionError):
+ return None
+
+ for prop in bim_props.panel_properties:
+ if prop.name == panel_id:
+ return prop
+
+ if create_if_missing:
+ try:
+ prop = bim_props.panel_properties.add()
+ prop.name = panel_id
+ prop.is_visible_in_tab = True
+ prop.is_visible_in_bookmarks = True
+ prop.is_bookmarked = False
+ return prop
+ except AttributeError:
+ pass
+
+ return None
+
+
+def get_all_tab_panels(force_refresh=False):
+ panels = {tab_name: [] for tab_name in get_tab_names() if tab_name != "BOOKMARK"}
+ panels["BOOKMARK"] = []
+
+ bim_props = tool.Blender.get_bim_props()
+ for prop in bim_props.panel_properties:
+ panel_class = getattr(bpy.types, prop.name, None)
+ if panel_class:
+ tab_name = get_panel_tab_name(panel_class)
+ if tab_name and tab_name != "BOOKMARK":
+ bl_label = getattr(panel_class, "bl_label", prop.name)
+ panels[tab_name].append({"bl_idname": prop.name, "bl_label": bl_label})
+
+ if prop.is_bookmarked:
+ panel_class = getattr(bpy.types, prop.name, None)
+ if panel_class:
+ bl_label = getattr(panel_class, "bl_label", prop.name)
+ panels["BOOKMARK"].append({"bl_idname": prop.name, "bl_label": bl_label})
+
+ if not panels["BOOKMARK"]:
+ panels["BOOKMARK"] = [{}]
+
+ return panels
+
+
+def initialize_tab_visibilities():
+ bim_props = tool.Blender.get_bim_props()
+
+ if len(bim_props.tab_visibilities) > 0:
+ return
+
+ for tab_name in get_tab_names():
+ tab_vis = bim_props.tab_visibilities.add()
+ tab_vis.name = tab_name
+ tab_vis.is_visible = True
+
+
+def initialize_panel_properties():
+
+ bim_props = tool.Blender.get_bim_props()
+
+ if len(bim_props.panel_properties) > 0:
+ return
+
+ for attr_name in dir(bpy.types):
+ if attr_name.startswith("BIM_PT_tab_"):
+ panel_class = getattr(bpy.types, attr_name)
+ if not hasattr(panel_class, "bl_idname"):
+ continue
+
+ panel_id = panel_class.bl_idname
+
+ prop = bim_props.panel_properties.add()
+ prop.name = panel_id
+ prop.is_visible_in_tab = True
+ prop.is_visible_in_bookmarks = True
+ prop.is_bookmarked = False
diff --git a/src/bonsai/bonsai/bim/module/drawing/__init__.py b/src/bonsai/bonsai/bim/module/drawing/__init__.py
index 8b5a787ebe..eb5779d4af 100644
--- a/src/bonsai/bonsai/bim/module/drawing/__init__.py
+++ b/src/bonsai/bonsai/bim/module/drawing/__init__.py
@@ -143,6 +143,7 @@ def menu_func(self, context):
if element and element.is_a("IfcAnnotation") and element.ObjectType in ["SECTION", "ELEVATION"]:
self.layout.operator("bim.activate_drawing_by_annotation", text="Go to Drawing")
+
def register():
if not bpy.app.background:
bpy.utils.register_tool(workspace.AnnotationTool, after={"bim.bim_tool"}, separator=True, group=False)
@@ -155,7 +156,7 @@ def register():
bpy.app.handlers.load_post.append(handler.load_post)
bpy.app.handlers.depsgraph_update_pre.append(handler.depsgraph_update_pre_handler)
bpy.types.VIEW3D_MT_image_add.append(ui.add_object_button)
- bpy.types.VIEW3D_MT_object_context_menu.append(menu_func)
+ bpy.types.VIEW3D_MT_object_context_menu.append(menu_func)
def unregister():
diff --git a/src/bonsai/bonsai/bim/module/drawing/decoration.py b/src/bonsai/bonsai/bim/module/drawing/decoration.py
index 3a1d73de16..fc3b9ecbf6 100644
--- a/src/bonsai/bonsai/bim/module/drawing/decoration.py
+++ b/src/bonsai/bonsai/bim/module/drawing/decoration.py
@@ -1655,7 +1655,7 @@ class CutDecorator:
if isinstance(space, bpy.types.SpaceView3D) and space.local_view:
in_local_view = True
break
-
+
# If just entering local view (transition from False to True)
if in_local_view and not self.__class__.was_in_local_view:
self.__class__.local_view_has_annotation = False
@@ -1664,10 +1664,10 @@ class CutDecorator:
if element and element.is_a("IfcAnnotation"):
self.__class__.local_view_has_annotation = True
break
-
+
# Update the state for next time
self.__class__.was_in_local_view = in_local_view
-
+
# Skip decorations if in local view and no IfcAnnotation was selected when entering
if in_local_view and not self.__class__.local_view_has_annotation:
return
@@ -2066,7 +2066,7 @@ class DecorationsHandler:
if isinstance(space, bpy.types.SpaceView3D) and space.local_view:
in_local_view = True
break
-
+
# If just entering local view (transition from False to True)
if in_local_view and not self.__class__.was_in_local_view:
self.__class__.local_view_has_annotation = False
@@ -2075,10 +2075,10 @@ class DecorationsHandler:
if element and element.is_a("IfcAnnotation"):
self.__class__.local_view_has_annotation = True
break
-
+
# Update the state for next time
self.__class__.was_in_local_view = in_local_view
-
+
# Skip decorations if in local view and no IfcAnnotation was selected when entering
if in_local_view and not self.__class__.local_view_has_annotation:
return
@@ -2093,5 +2093,6 @@ class DecorationsHandler:
if not DecoratorData.is_loaded:
DecoratorData.load(self)
- for obj, decorator in DecoratorData.data["object_decorators"]:
+ object_decorators = DecoratorData.data.get("object_decorators", [])
+ for obj, decorator in object_decorators:
decorator.decorate(context, obj)
diff --git a/src/bonsai/bonsai/bim/module/drawing/gizmos.py b/src/bonsai/bonsai/bim/module/drawing/gizmos.py
index ef42c57dc6..3b25a0b12a 100644
--- a/src/bonsai/bonsai/bim/module/drawing/gizmos.py
+++ b/src/bonsai/bonsai/bim/module/drawing/gizmos.py
@@ -86,7 +86,7 @@ overlapping with geometry. The get_local_view_direction() helper determines if t
camera is viewing from the positive or negative side of each axis.
"""
-__all__ = [
+__all__ = [ # noqa: RUF022 (unsorted `__all__`)
"GizmoColor",
"GizmoAxis",
"TextAlignment",
diff --git a/src/bonsai/bonsai/bim/module/drawing/operator.py b/src/bonsai/bonsai/bim/module/drawing/operator.py
index 248fae5775..e874983074 100644
--- a/src/bonsai/bonsai/bim/module/drawing/operator.py
+++ b/src/bonsai/bonsai/bim/module/drawing/operator.py
@@ -296,6 +296,15 @@ class CreateDrawing(bpy.types.Operator):
self.drawing_index = drawing_i
if self.print_all:
bpy.ops.bim.activate_drawing(drawing=drawing_id, should_view_from_camera=False)
+ original_cache_setting = self.props.should_use_underlay_cache
+ self.props.should_use_underlay_cache = False
+
+ # Force Blender to process all pending operations
+ for area in context.screen.areas:
+ area.tag_redraw()
+
+ # Process events to let Blender finish internal cleanup
+ bpy.ops.wm.redraw_timer(type="DRAW_WIN_SWAP", iterations=1)
self.camera = context.scene.camera
assert (camera_element := tool.Ifc.get_entity(self.camera))
@@ -339,6 +348,23 @@ class CreateDrawing(bpy.types.Operator):
f"Failed to create drawing '{self.drawing.Name}' - drawing has underlay but there's no active drawing underlay style.",
)
return {"FINISHED"}
+
+ # Clear any local camera setup and force viewport to use scene camera
+ for area in context.screen.areas:
+ if area.type == "VIEW_3D":
+ for space in area.spaces:
+ if space.type == "VIEW_3D":
+ # Clear local camera to ensure we use scene.camera
+ space.use_local_camera = False
+ space.camera = context.scene.camera
+ space.region_3d.view_perspective = "CAMERA"
+ print(f"Set viewport camera to: {context.scene.camera.name}")
+ break
+
+ # Force complete scene update
+ context.view_layer.update()
+ context.evaluated_depsgraph_get()
+
underlay_svg = self.generate_underlay(context)
with profile("Generate linework"):
@@ -3050,9 +3076,9 @@ class AddReference(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
filter_glob: bpy.props.StringProperty(default="*.svg", options={"HIDDEN"})
use_relative_path: bpy.props.BoolProperty(name="Use Relative Path", default=True)
filename_ext = ".svg"
-
+
files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement)
- directory: bpy.props.StringProperty(subtype='DIR_PATH')
+ directory: bpy.props.StringProperty(subtype="DIR_PATH")
def _execute(self, context):
# Handle both single and multiple file selection
@@ -3661,8 +3687,12 @@ class EnableEditingElementFilter(bpy.types.Operator, tool.Ifc.Operator):
if query := ifcopenshell.util.element.get_pset(element, "EPset_Drawing", self.filter_mode.title()):
filter_groups = tool.Search.get_filter_groups(f"drawing_{self.filter_mode.lower()}")
try:
- tool.Search.import_filter_query(query, filter_groups)
- except:
+ data = json.loads(query)
+ if isinstance(data, dict) and "filter_structure" in data:
+ tool.Search.import_filter_structure(data["filter_structure"], filter_groups)
+ else:
+ tool.Search.import_filter_query(query, filter_groups)
+ except Exception:
pass
@@ -3682,12 +3712,41 @@ class EditElementFilter(bpy.types.Operator, tool.Ifc.Operator):
assert element
pset = tool.Pset.get_element_pset(element, "EPset_Drawing")
assert pset
+
if self.filter_mode == "INCLUDE":
- query = tool.Search.export_filter_query(props.include_filter_groups) or None
- ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Include": query})
+ filter_groups = props.include_filter_groups
elif self.filter_mode == "EXCLUDE":
- query = tool.Search.export_filter_query(props.exclude_filter_groups) or None
- ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Exclude": query})
+ filter_groups = props.exclude_filter_groups
+ else:
+ return
+
+ query = tool.Search.export_filter_query(filter_groups) or None
+
+ if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and query:
+ filter_structure = []
+ for filter_group in filter_groups:
+ group_data = []
+ for ifc_filter in filter_group.filters:
+ filter_data = {
+ "type": ifc_filter.type,
+ "name": ifc_filter.name,
+ "value": ifc_filter.value,
+ "pset": ifc_filter.pset,
+ "comparison": ifc_filter.comparison,
+ "filter_mode": ifc_filter.filter_mode,
+ }
+ group_data.append(filter_data)
+ filter_structure.append(group_data)
+
+ value = json.dumps({"type": "BBIM_Search", "query": query, "filter_structure": filter_structure})
+ else:
+ value = query
+
+ if self.filter_mode == "INCLUDE":
+ ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Include": value})
+ elif self.filter_mode == "EXCLUDE":
+ ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Exclude": value})
+
props.filter_mode = "NONE"
bpy.ops.bim.activate_drawing(drawing=element.id(), should_view_from_camera=False)
@@ -4015,66 +4074,66 @@ class ExcludeAnnotation(bpy.types.Operator, tool.Ifc.Operator):
tool.Drawing.exclude_annotation_from_drawing(referenced_element, drawing)
core.sync_references(tool.Ifc, tool.Collector, tool.Drawing, drawing=drawing)
+
class ActivateDrawingByAnnotation(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.activate_drawing_by_annotation"
bl_label = "Activate Drawing"
bl_description = "Activate the drawing corresponding to the selected annotation"
bl_options = {"REGISTER", "UNDO"}
-
+
@classmethod
def poll(cls, context):
# Check if an annotation object is selected
if not context.selected_objects:
cls.poll_message_set("No object selected")
return False
-
+
active_obj = context.active_object
if not active_obj:
cls.poll_message_set("No active object")
return False
-
+
element = tool.Ifc.get_entity(active_obj)
if not element:
cls.poll_message_set("Selected object is not an IFC element")
return False
-
+
# Check if it's an IfcAnnotation with ObjectType = "SECTION" or "ELEVATION"
if not element.is_a("IfcAnnotation") or element.ObjectType not in ["SECTION", "ELEVATION"]:
cls.poll_message_set("Selected object is not a drawing annotation")
return False
-
+
return True
def _execute(self, context):
active_obj = context.active_object
element = tool.Ifc.get_entity(active_obj)
-
+
if not element or not element.is_a("IfcAnnotation") or element.ObjectType not in ["SECTION", "ELEVATION"]:
self.report({"ERROR"}, "Selected object is not a drawing annotation")
return {"CANCELLED"}
-
+
# Find the drawing/camera element that this annotation references
drawing_element = self.find_drawing_from_annotation(element)
-
+
if not drawing_element:
self.report({"ERROR"}, "Could not find drawing element for this annotation")
return {"CANCELLED"}
-
+
# Use the existing ActivateDrawing operator with the drawing element's ID
bpy.ops.bim.activate_drawing(drawing=drawing_element.id())
-
+
return {"FINISHED"}
-
+
def find_drawing_from_annotation(self, annotation_element):
"""Find the drawing/camera element that this annotation references."""
ifc = tool.Ifc.get()
-
+
# Check IfcRelAssignsToProduct relationships
for rel in ifc.get_inverse(annotation_element):
if rel.is_a("IfcRelAssignsToProduct") and rel.RelatingProduct:
if rel.RelatingProduct.is_a("IfcAnnotation"):
# Found the drawing element!
return rel.RelatingProduct
-
-
- return None
\ No newline at end of file
+
+ return None
diff --git a/src/bonsai/bonsai/bim/module/drawing/ui.py b/src/bonsai/bonsai/bim/module/drawing/ui.py
index 252a3c9148..1a25b387dd 100644
--- a/src/bonsai/bonsai/bim/module/drawing/ui.py
+++ b/src/bonsai/bonsai/bim/module/drawing/ui.py
@@ -479,10 +479,12 @@ class BIM_PT_sheets(Panel):
drawingnamesvg = active_sheet.name
drawingname = drawingnamesvg.split(".svg")[0]
ifc_file = tool.Ifc.get()
- ifc_annotations = ifc_file.by_type("IfcAnnotation")
drawingid = None
- for annotation in ifc_annotations:
+ for annotation in ifc_file.by_type("IfcAnnotation"):
+ if annotation.ObjectType != "DRAWING":
+ continue
+
Annotation_Name = annotation.Name.replace(",", "") # Remove commas
if Annotation_Name == drawingname:
drawingid = annotation.id()
diff --git a/src/bonsai/bonsai/bim/module/model/opening.py b/src/bonsai/bonsai/bim/module/model/opening.py
index d028425fb2..962cec8bc2 100644
--- a/src/bonsai/bonsai/bim/module/model/opening.py
+++ b/src/bonsai/bonsai/bim/module/model/opening.py
@@ -151,23 +151,23 @@ class FilledOpeningGenerator:
existing_opening_occurrence, "Model", "Body", "MODEL_VIEW"
)
assert representation
-
+
# Check if mapped representation - preserve it
- if (representation.RepresentationType == 'MappedRepresentation' and
- len(representation.Items) == 1 and
- representation.Items[0].is_a("IfcMappedItem")):
+ if (
+ representation.RepresentationType == "MappedRepresentation"
+ and len(representation.Items) == 1
+ and representation.Items[0].is_a("IfcMappedItem")
+ ):
source_rep = representation.Items[0].MappingSource.MappedRepresentation
representation = ifcopenshell.util.element.copy_deep(
- tool.Ifc.get(),
- source_rep,
- exclude=["IfcGeometricRepresentationContext"]
+ tool.Ifc.get(), source_rep, exclude=["IfcGeometricRepresentationContext"]
)
else:
representation = ifcopenshell.util.representation.resolve_representation(representation)
else:
# Check for library template before generating from filling
template_rep = self.get_opening_template_from_type(filling)
-
+
if template_rep:
representation = template_rep
else:
@@ -222,68 +222,68 @@ class FilledOpeningGenerator:
voided_element = opening.VoidsElements[0].RelatingBuildingElement
opening_rep = ifcopenshell.util.representation.get_representation(opening, "Model", "Body", "MODEL_VIEW")
-
+
# ALWAYS preserve the existing opening representation (Tessellation, SweptSolid, etc.)
preserved_representation = None
if opening_rep:
- if (opening_rep.RepresentationType == 'MappedRepresentation' and
- len(opening_rep.Items) == 1 and
- opening_rep.Items[0].is_a("IfcMappedItem")):
+ if (
+ opening_rep.RepresentationType == "MappedRepresentation"
+ and len(opening_rep.Items) == 1
+ and opening_rep.Items[0].is_a("IfcMappedItem")
+ ):
# For mapped representations, copy the underlying representation
preserved_representation = ifcopenshell.util.element.copy_deep(
tool.Ifc.get(),
opening_rep.Items[0].MappingSource.MappedRepresentation,
- exclude=["IfcGeometricRepresentationContext"]
+ exclude=["IfcGeometricRepresentationContext"],
)
else:
# For direct representations (non-mapped), copy them too
preserved_representation = ifcopenshell.util.element.copy_deep(
- tool.Ifc.get(),
- opening_rep,
- exclude=["IfcGeometricRepresentationContext"]
+ tool.Ifc.get(), opening_rep, exclude=["IfcGeometricRepresentationContext"]
)
-
+
ifcopenshell.api.geometry.unassign_representation(tool.Ifc.get(), product=opening, representation=opening_rep)
ifcopenshell.api.geometry.remove_representation(tool.Ifc.get(), representation=opening_rep)
existing_opening_occurrence = self.get_existing_opening_occurrence_if_any(filling)
-
+
# Priority order for choosing representation:
# 1. Existing occurrence with Tessellation (best quality)
# 2. Library template with Tessellation
# 3. Preserved representation from old opening (maintain user's work)
# 4. Generate from filling (last resort)
-
+
representation_to_use = None
-
+
if existing_opening_occurrence:
representation = ifcopenshell.util.representation.get_representation(
existing_opening_occurrence, "Model", "Body", "MODEL_VIEW"
)
-
- if (representation and
- representation.RepresentationType == 'MappedRepresentation' and
- len(representation.Items) == 1 and
- representation.Items[0].is_a("IfcMappedItem")):
+
+ if (
+ representation
+ and representation.RepresentationType == "MappedRepresentation"
+ and len(representation.Items) == 1
+ and representation.Items[0].is_a("IfcMappedItem")
+ ):
source_rep = representation.Items[0].MappingSource.MappedRepresentation
# Prefer Tessellation from existing occurrence over preserved representation
- if source_rep.RepresentationType == 'Tessellation':
+ if source_rep.RepresentationType == "Tessellation":
representation_to_use = ifcopenshell.util.element.copy_deep(
- tool.Ifc.get(),
- source_rep,
- exclude=["IfcGeometricRepresentationContext"]
+ tool.Ifc.get(), source_rep, exclude=["IfcGeometricRepresentationContext"]
)
else:
representation_to_use = ifcopenshell.util.representation.resolve_representation(representation)
-
+
if not representation_to_use:
template_rep = self.get_opening_template_from_type(filling)
- if template_rep and template_rep.RepresentationType == 'Tessellation':
+ if template_rep and template_rep.RepresentationType == "Tessellation":
representation_to_use = template_rep
-
+
if not representation_to_use and preserved_representation:
representation_to_use = preserved_representation
-
+
if not representation_to_use:
opening_obj = tool.Ifc.get_object(opening)
if opening_obj:
@@ -299,7 +299,7 @@ class FilledOpeningGenerator:
ifcopenshell.api.geometry.assign_representation(
tool.Ifc.get(), product=opening, representation=mapped_representation
)
-
+
# update voided object representation...
voided_elements = ifcopenshell.util.element.get_parts(voided_element) or [voided_element]
for voided_element in voided_elements:
@@ -314,31 +314,31 @@ class FilledOpeningGenerator:
representation=representation,
)
- def get_opening_template_from_type(self, filling: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
+ def get_opening_template_from_type(
+ self, filling: ifcopenshell.entity_instance
+ ) -> Union[ifcopenshell.entity_instance, None]:
"""
Check if the filling's type has a stored opening template from library import.
"""
element_type = ifcopenshell.util.element.get_type(filling)
-
+
if not element_type:
return None
-
+
desc = element_type.Description
-
+
if not desc or "||BonsaiOpeningTemplate:" not in desc:
return None
-
+
# Extract template ID
marker = desc.split("||BonsaiOpeningTemplate:")[-1]
template_id = int(marker.split("||")[0])
-
+
try:
template_rep = tool.Ifc.get().by_id(template_id)
# Make a copy so we don't reuse the same representation instance
copied = ifcopenshell.util.element.copy_deep(
- tool.Ifc.get(),
- template_rep,
- exclude=["IfcGeometricRepresentationContext"]
+ tool.Ifc.get(), template_rep, exclude=["IfcGeometricRepresentationContext"]
)
return copied
except:
diff --git a/src/bonsai/bonsai/bim/module/project/operator.py b/src/bonsai/bonsai/bim/module/project/operator.py
index 8f22492132..94d7279daa 100644
--- a/src/bonsai/bonsai/bim/module/project/operator.py
+++ b/src/bonsai/bonsai/bim/module/project/operator.py
@@ -715,11 +715,8 @@ class AppendLibraryElement(bpy.types.Operator, tool.Ifc.Operator):
if element.is_a("IfcSurfaceStyle") and not tool.Ifc.get_object_by_identifier(element.id()):
ifc_importer.create_style(element)
-
def store_opening_template_from_library(
- self,
- element: ifcopenshell.entity_instance,
- library_file: ifcopenshell.file
+ self, element: ifcopenshell.entity_instance, library_file: ifcopenshell.file
) -> None:
"""
Find an opening representation in the library and copy it to the current file
@@ -729,36 +726,36 @@ class AppendLibraryElement(bpy.types.Operator, tool.Ifc.Operator):
library_element = library_file.by_guid(element.GlobalId)
except:
return
-
+
# Find occurrences with openings in the library
library_occurrences = ifcopenshell.util.element.get_types(library_element)
-
+
for occurrence in library_occurrences:
if not getattr(occurrence, "FillsVoids", None):
continue
-
+
library_opening = occurrence.FillsVoids[0].RelatingOpeningElement
library_opening_rep = ifcopenshell.util.representation.get_representation(
library_opening, "Model", "Body", "MODEL_VIEW"
)
-
+
if not library_opening_rep:
continue
-
+
# Check if mapped representation
- if (library_opening_rep.RepresentationType == 'MappedRepresentation' and
- len(library_opening_rep.Items) == 1 and
- library_opening_rep.Items[0].is_a("IfcMappedItem")):
-
+ if (
+ library_opening_rep.RepresentationType == "MappedRepresentation"
+ and len(library_opening_rep.Items) == 1
+ and library_opening_rep.Items[0].is_a("IfcMappedItem")
+ ):
+
mapped_rep = library_opening_rep.Items[0].MappingSource.MappedRepresentation
-
+
# Store ALL representation types (Tessellation, SweptSolid, etc.)
template_rep = ifcopenshell.util.element.copy_deep(
- self.file,
- mapped_rep,
- exclude=["IfcGeometricRepresentationContext"]
+ self.file, mapped_rep, exclude=["IfcGeometricRepresentationContext"]
)
-
+
# Store reference in type's Description
current_desc = element.Description or ""
element.Description = f"{current_desc}||BonsaiOpeningTemplate:{template_rep.id()}"
@@ -1059,6 +1056,20 @@ class LoadProject(bpy.types.Operator, IFCFileSelector, ImportHelper):
return tooltip
def execute(self, context):
+ if (
+ tool.Blender.get_addon_preferences().save_metadata_blend_file
+ and self.should_start_fresh_session
+ and not self.is_advanced
+ ):
+ filepath = self.get_filepath()
+ metadata_path = Path(str(filepath) + ".metadata.blend")
+ if metadata_path.exists() and metadata_path.is_file():
+ try:
+ bpy.ops.bim.load_blend_metadata_and_ifc(filepath=filepath)
+ return {"FINISHED"}
+ except Exception as e:
+ self.report({"WARNING"}, f"Failed to load metadata file, using regular load: {e}")
+
@persistent
def load_handler(*args):
bpy.app.handlers.load_post.remove(load_handler)
@@ -1747,15 +1758,28 @@ class ExportIFC(bpy.types.Operator, ExportHelper):
bim_props = tool.Blender.get_bim_props()
if bim_props.ifc_file != output_file and extension not in ("ifczip", "ifcjson"):
tool.Ifc.set_path(output_file)
- save_blend_file = bool(bpy.data.is_saved and bpy.data.is_dirty and bpy.data.filepath)
- if save_blend_file:
- bpy.ops.wm.save_mainfile(filepath=bpy.data.filepath)
bim_props.is_dirty = False
+
+ if tool.Blender.get_addon_preferences().save_metadata_blend_file:
+ try:
+ bpy.ops.bim.save_blend_metadata_file()
+ blendmetadata_path = output_file + ".metadata.blend"
+ self.report(
+ {"INFO"},
+ f'IFC Project "{os.path.basename(output_file)}" And Metadata File Saved to: {os.path.basename(blendmetadata_path)}',
+ )
+ except Exception as e:
+ self.report({"ERROR"}, f"Failed to save blend metadata file: {e}")
+ else:
+ save_blend_file = bool(bpy.data.is_saved and bpy.data.is_dirty and bpy.data.filepath)
+ if save_blend_file:
+ bpy.ops.wm.save_mainfile(filepath=bpy.data.filepath)
+ self.report(
+ {"INFO"},
+ f'IFC Project "{os.path.basename(output_file)}" {"" if not save_blend_file else "And Current Blend File Are"} Saved',
+ )
+
bonsai.bim.handler.refresh_ui_data()
- self.report(
- {"INFO"},
- f'IFC Project "{os.path.basename(output_file)}" {"" if not save_blend_file else "And Current Blend File Are"} Saved',
- )
@classmethod
def description(cls, context, properties):
diff --git a/src/bonsai/bonsai/bim/module/project/ui.py b/src/bonsai/bonsai/bim/module/project/ui.py
index 6fe5b55604..fa45494e0f 100644
--- a/src/bonsai/bonsai/bim/module/project/ui.py
+++ b/src/bonsai/bonsai/bim/module/project/ui.py
@@ -331,6 +331,13 @@ class BIM_PT_project(Panel):
col.prop(props, "ifc_file", text="")
row.operator("bim.select_ifc_file", icon="FILE_FOLDER", text="")
+ if tool.Blender.get_addon_preferences().save_metadata_blend_file:
+ row = self.layout.row(align=True)
+ col = row.column()
+ col.enabled = False
+ metadata_filename = os.path.basename(props.ifc_file) + ".metadata.blend"
+ col.label(text=f"Saving session data to: {metadata_filename}")
+
class BIM_PT_new_project_wizard(Panel):
bl_label = "New Project Wizard"
diff --git a/src/bonsai/bonsai/bim/module/search/__init__.py b/src/bonsai/bonsai/bim/module/search/__init__.py
index e1849c63ae..88cb2f6ed4 100644
--- a/src/bonsai/bonsai/bim/module/search/__init__.py
+++ b/src/bonsai/bonsai/bim/module/search/__init__.py
@@ -24,12 +24,15 @@ classes = (
operator.ActivateIfcClassFilter,
operator.AddFilter,
operator.AddFilterGroup,
+ operator.ApplyFilterFromText,
operator.ColourByProperty,
operator.EditFilterQuery,
+ operator.FilterValueSuggestions,
operator.LoadColourscheme,
operator.LoadSearch,
operator.RemoveFilter,
operator.RemoveFilterGroup,
+ operator.RemoveSearch,
operator.ResetObjectColours,
operator.SaveColourscheme,
operator.SaveSearch,
@@ -40,6 +43,7 @@ classes = (
operator.SelectIfcClass,
operator.SelectSimilar,
operator.ShowAllElements,
+ operator.ToggleFilterInclusion,
operator.ToggleFilterSelection,
prop.BIMColour,
prop.BIMFilterItem,
@@ -55,7 +59,9 @@ classes = (
def register():
bpy.types.Scene.BIMSearchProperties = bpy.props.PointerProperty(type=prop.BIMSearchProperties)
+ bpy.types.TEXT_HT_header.append(operator.draw_text_editor_header)
def unregister():
del bpy.types.Scene.BIMSearchProperties
+ bpy.types.TEXT_HT_header.remove(operator.draw_text_editor_header)
diff --git a/src/bonsai/bonsai/bim/module/search/operator.py b/src/bonsai/bonsai/bim/module/search/operator.py
index 1fb164047b..2c7a506e78 100644
--- a/src/bonsai/bonsai/bim/module/search/operator.py
+++ b/src/bonsai/bonsai/bim/module/search/operator.py
@@ -40,9 +40,476 @@ from bpy.props import (
FloatVectorProperty,
CollectionProperty,
)
+from bonsai.bim.prop import StrProperty
from typing import TYPE_CHECKING, Literal, get_args, assert_never
+def draw_text_editor_header(self, context):
+ if context.space_data.text and context.space_data.text.name.startswith("FilterQuery_"):
+ layout = self.layout
+ layout.separator()
+ op = layout.operator("bim.apply_filter_from_text", text="Apply Filter Configuration", icon="CHECKMARK")
+
+
+def update_filter_search_value(self: "FilterValueSuggestions", context: bpy.types.Context) -> None:
+ filter_groups = tool.Search.get_filter_groups(self.module)
+ ifc_filter = filter_groups[self.group_index].filters[self.filter_index]
+
+ value = self.search_value
+
+ if " < " in value:
+ value = value.split(" < ")[-1]
+
+ if ifc_filter.type == "entity":
+ if " (superclass)" in value:
+ value = value.replace(" (superclass)", "")
+ if " > " in value:
+ value = value.split(" > ")[-1]
+
+ elif ifc_filter.type == "instance":
+ if ": " in value:
+ value = value.split(": ")[-1]
+ elif " (" in value:
+ hierarchy_class = value.split(" (")
+ element_class = hierarchy_class[-1].rstrip(")")
+ element_name = hierarchy_class[0] if len(hierarchy_class) > 1 else None
+
+ ifc_file = tool.Ifc.get()
+ if ifc_file:
+ for element_id in IfcStore.id_map.keys():
+ try:
+ element = ifc_file.by_id(element_id)
+ if element.is_a() == element_class:
+ if element_name is None or (hasattr(element, "Name") and element.Name == element_name):
+ value = element.GlobalId
+ break
+ except:
+ continue
+
+ elif ifc_filter.type == "parent":
+ if " (" in value:
+ value = value.split(" (")[0]
+
+ if ifc_filter.type == "property":
+ if self.suggestion_type == "pset":
+ ifc_filter.pset = value
+ elif self.suggestion_type == "property_name":
+ ifc_filter.name = value
+ else:
+ ifc_filter.value = value
+ elif ifc_filter.type == "attribute":
+ if self.suggestion_type == "attribute_name":
+ ifc_filter.name = value
+ else:
+ ifc_filter.value = value
+ else:
+ ifc_filter.value = value
+
+ if self.first_launch:
+ self.first_launch = False
+ else:
+ context.window.screen = context.window.screen
+
+
+class FilterValueSuggestions(Operator):
+ bl_idname = "bim.filter_value_suggestions"
+ bl_label = "Filter Value Suggestions"
+ bl_description = "Get suggestions for filter values from the current IFC file"
+ bl_options = {"REGISTER", "UNDO"}
+
+ group_index: IntProperty()
+ filter_index: IntProperty()
+ module: StringProperty(default="search")
+ filter_type: StringProperty()
+ suggestion_type: StringProperty(default="value")
+
+ first_launch: BoolProperty(default=True, options={"SKIP_SAVE"})
+ search_value: StringProperty(
+ name="Search",
+ description="Search for filter values",
+ update=update_filter_search_value,
+ default="",
+ options={"SKIP_SAVE"},
+ )
+ collection_values: CollectionProperty(type=StrProperty, options={"SKIP_SAVE"})
+
+ def execute(self, context):
+ return {"FINISHED"}
+
+ def invoke(self, context, event):
+ ifc_file = tool.Ifc.get()
+ if not ifc_file:
+ self.report({"WARNING"}, "No IFC file loaded")
+ return {"CANCELLED"}
+
+ filter_groups = tool.Search.get_filter_groups(self.module)
+ ifc_filter = filter_groups[self.group_index].filters[self.filter_index]
+
+ string_suggestions = self.get_suggestions(ifc_file, ifc_filter)
+ if not string_suggestions:
+ self.report({"INFO"}, f"No suggestions available")
+ return {"CANCELLED"}
+
+ self.collection_values.clear()
+ for suggestion in natsorted(string_suggestions):
+ self.collection_values.add().name = suggestion
+
+ return context.window_manager.invoke_props_dialog(self, width=800)
+
+ def draw(self, context):
+ layout = self.layout
+
+ filter_groups = tool.Search.get_filter_groups(self.module)
+ ifc_filter = filter_groups[self.group_index].filters[self.filter_index]
+
+ label_map = {
+ "entity": "Select Class",
+ "type": "Select Type",
+ "material": "Select Material",
+ "location": "Select Location",
+ "group": "Select Group",
+ "classification": "Select Classification",
+ "parent": "Select Parent",
+ "instance": "Select GlobalId",
+ }
+
+ if ifc_filter.type == "attribute":
+ if self.suggestion_type == "attribute_value":
+ label = f"Select Value for {ifc_filter.name}"
+ else:
+ label = "Select Attribute Name"
+ elif ifc_filter.type == "property":
+ if self.suggestion_type == "property_value":
+ label = f"Select Value for {ifc_filter.pset}.{ifc_filter.name}"
+ elif self.suggestion_type == "property_name":
+ label = f"Select Property from {ifc_filter.pset}"
+ else:
+ label = "Select Property Set"
+ else:
+ label = label_map.get(ifc_filter.type, "Select Value")
+
+ row = layout.row()
+ row.label(text=label)
+ row = layout.row()
+ row.prop_search(
+ self,
+ "search_value",
+ self,
+ "collection_values",
+ text="",
+ results_are_suggestions=True,
+ )
+
+ def get_suggestions(self, ifc_file, ifc_filter):
+ suggestions = set()
+
+ if ifc_filter.type == "entity":
+ suggestions = self.get_entity_suggestions(ifc_file)
+ elif ifc_filter.type == "type":
+ suggestions = self.get_type_suggestions(ifc_file)
+ elif ifc_filter.type == "material":
+ suggestions = self.get_material_suggestions(ifc_file)
+ elif ifc_filter.type == "location":
+ suggestions = self.get_location_suggestions(ifc_file)
+ elif ifc_filter.type == "group":
+ suggestions = self.get_group_suggestions(ifc_file)
+ elif ifc_filter.type == "classification":
+ suggestions = self.get_classification_suggestions(ifc_file)
+ elif ifc_filter.type == "parent":
+ suggestions = self.get_parent_suggestions(ifc_file)
+ elif ifc_filter.type == "instance":
+ suggestions = self.get_instance_suggestions(ifc_file)
+ elif ifc_filter.type == "attribute":
+ if self.suggestion_type == "attribute_name":
+ suggestions = self.get_attribute_names(ifc_file)
+ else:
+ suggestions = self.get_attribute_values(ifc_file, ifc_filter.name)
+ elif ifc_filter.type == "property":
+ if self.suggestion_type == "pset":
+ suggestions = self.get_property_sets(ifc_file)
+ elif self.suggestion_type == "property_name":
+ suggestions = self.get_property_names(ifc_file, ifc_filter.pset)
+ else:
+ suggestions = self.get_property_values(ifc_file, ifc_filter.pset, ifc_filter.name)
+
+ return suggestions
+
+ def build_hierarchy_path(self, element):
+ path = []
+ current = element
+
+ while current:
+ if hasattr(current, "Name") and current.Name:
+ path.insert(0, current.Name)
+
+ parent = None
+
+ if hasattr(current, "Decomposes") and current.Decomposes:
+ for rel in current.Decomposes:
+ if hasattr(rel, "RelatingObject"):
+ parent = rel.RelatingObject
+ break
+
+ if not parent and hasattr(current, "ContainedInStructure") and current.ContainedInStructure:
+ for rel in current.ContainedInStructure:
+ if hasattr(rel, "RelatingStructure"):
+ parent = rel.RelatingStructure
+ break
+
+ current = parent
+
+ return path
+
+ def get_entity_suggestions(self, ifc_file):
+ all_classes = set()
+ schema = tool.Ifc.schema()
+
+ for element_id in IfcStore.id_map.keys():
+ try:
+ element = ifc_file.by_id(element_id)
+ class_name = element.is_a()
+
+ try:
+ entity = schema.declaration_by_name(class_name).as_entity()
+ current = entity
+
+ chain_names = [class_name]
+ while current.supertype():
+ supertype = current.supertype()
+ chain_names.insert(0, supertype.name())
+ current = supertype
+
+ if len(chain_names) > 1:
+ all_classes.add(" > ".join(chain_names))
+ for i in range(len(chain_names) - 1):
+ superclass_chain = " > ".join(chain_names[: i + 1])
+ all_classes.add(f"{superclass_chain} (superclass)")
+ else:
+ all_classes.add(class_name)
+ except:
+ all_classes.add(class_name)
+ except:
+ continue
+
+ return all_classes
+
+ def get_type_suggestions(self, ifc_file):
+ suggestions = set()
+ for element_type in ifc_file.by_type("IfcTypeObject"):
+ if element_type.Name:
+ hierarchy_path = self.build_hierarchy_path(element_type)
+ if len(hierarchy_path) > 1:
+ suggestions.add(" < ".join(hierarchy_path))
+ else:
+ suggestions.add(element_type.Name)
+ return suggestions
+
+ def get_material_suggestions(self, ifc_file):
+ suggestions = set()
+ for material in ifc_file.by_type("IfcMaterial"):
+ if material.Name:
+ suggestions.add(material.Name)
+ return suggestions
+
+ def get_location_suggestions(self, ifc_file):
+ suggestions = set()
+ for spatial in ifc_file.by_type("IfcSpatialStructureElement"):
+ if spatial.Name:
+ hierarchy_path = self.build_hierarchy_path(spatial)
+ if len(hierarchy_path) > 1:
+ suggestions.add(" < ".join(hierarchy_path))
+ else:
+ suggestions.add(spatial.Name)
+ return suggestions
+
+ def get_group_suggestions(self, ifc_file):
+ suggestions = set()
+ for group in ifc_file.by_type("IfcGroup"):
+ if group.Name:
+ hierarchy_path = self.build_hierarchy_path(group)
+ if len(hierarchy_path) > 1:
+ suggestions.add(" < ".join(hierarchy_path))
+ else:
+ suggestions.add(group.Name)
+ return suggestions
+
+ def get_classification_suggestions(self, ifc_file):
+ suggestions = set()
+ for ref in ifc_file.by_type("IfcClassificationReference"):
+ if ref.Identification:
+ suggestions.add(ref.Identification)
+ return suggestions
+
+ def get_parent_suggestions(self, ifc_file):
+ suggestions = set()
+ for element_id in IfcStore.id_map.keys():
+ try:
+ element = ifc_file.by_id(element_id)
+ has_children = False
+
+ if hasattr(element, "IsDecomposedBy") and element.IsDecomposedBy:
+ has_children = True
+ elif hasattr(element, "ContainsElements") and element.ContainsElements:
+ has_children = True
+ elif hasattr(element, "HasOpenings") and element.HasOpenings:
+ has_children = True
+
+ if has_children:
+ hierarchy_path = self.build_hierarchy_path(element)
+ element_class = element.is_a()
+
+ if len(hierarchy_path) > 0:
+ hierarchy_str = " < ".join(hierarchy_path)
+ suggestions.add(f"{hierarchy_str} ({element_class})")
+ else:
+ element_name = element.Name if hasattr(element, "Name") and element.Name else element_class
+ suggestions.add(f"{element_name} ({element_class})")
+ except:
+ continue
+
+ return suggestions
+
+ def get_instance_suggestions(self, ifc_file):
+ suggestions = set()
+ element_data = []
+
+ for element_id in IfcStore.id_map.keys():
+ try:
+ element = ifc_file.by_id(element_id)
+ if hasattr(element, "GlobalId") and element.GlobalId:
+ hierarchy_path = self.build_hierarchy_path(element)
+ element_class = element.is_a()
+
+ if len(hierarchy_path) > 0:
+ hierarchy_str = " < ".join(hierarchy_path)
+ display_str = f"{hierarchy_str} ({element_class})"
+ else:
+ display_str = f"({element_class})"
+
+ element_data.append((display_str, element.GlobalId))
+ except:
+ continue
+
+ display_counts = {}
+ for display_str, global_id in element_data:
+ display_counts[display_str] = display_counts.get(display_str, 0) + 1
+
+ for display_str, global_id in element_data:
+ if display_counts[display_str] > 1:
+ suggestions.add(f"{display_str}: {global_id}")
+ else:
+ suggestions.add(display_str)
+
+ return suggestions
+
+ def get_property_sets(self, ifc_file):
+ psets = set()
+ for element_id in IfcStore.id_map.keys():
+ try:
+ element = ifc_file.by_id(element_id)
+ for definition in getattr(element, "IsDefinedBy", []):
+ if definition.is_a("IfcRelDefinesByProperties"):
+ pset = definition.RelatingPropertyDefinition
+ if pset.is_a("IfcPropertySet") and pset.Name:
+ psets.add(pset.Name)
+ except:
+ continue
+ return psets
+
+ def get_property_names(self, ifc_file, pset_name):
+ property_names = set()
+ for element_id in IfcStore.id_map.keys():
+ try:
+ element = ifc_file.by_id(element_id)
+ for definition in getattr(element, "IsDefinedBy", []):
+ if definition.is_a("IfcRelDefinesByProperties"):
+ pset = definition.RelatingPropertyDefinition
+ if pset.is_a("IfcPropertySet") and pset.Name == pset_name:
+ if pset.HasProperties:
+ for prop in pset.HasProperties:
+ if hasattr(prop, "Name") and prop.Name:
+ property_names.add(prop.Name)
+ except:
+ continue
+ return property_names
+
+ def get_property_values(self, ifc_file, pset_name, property_name):
+ property_values = set()
+ for element_id in IfcStore.id_map.keys():
+ try:
+ element = ifc_file.by_id(element_id)
+ for definition in getattr(element, "IsDefinedBy", []):
+ if definition.is_a("IfcRelDefinesByProperties"):
+ pset = definition.RelatingPropertyDefinition
+ if pset.is_a("IfcPropertySet") and pset.Name == pset_name:
+ if pset.HasProperties:
+ for prop in pset.HasProperties:
+ if hasattr(prop, "Name") and prop.Name == property_name:
+ if hasattr(prop, "NominalValue") and prop.NominalValue:
+ try:
+ value = prop.NominalValue.wrappedValue
+ if value is not None and value != "":
+ if not hasattr(value, "is_a") and not isinstance(
+ value, (tuple, list)
+ ):
+ str_value = str(value)
+ if not str_value.startswith("#") and not str_value.startswith(
+ "("
+ ):
+ property_values.add(str_value)
+ except:
+ continue
+ except:
+ continue
+ return property_values
+
+ def get_attribute_names(self, ifc_file):
+ attribute_names = set()
+ schema = tool.Ifc.schema()
+
+ ifc_classes = set()
+ for element_id in IfcStore.id_map.keys():
+ try:
+ element = ifc_file.by_id(element_id)
+ ifc_classes.add(element.is_a())
+ except:
+ continue
+
+ for ifc_class in ifc_classes:
+ try:
+ entity = schema.declaration_by_name(ifc_class).as_entity()
+ attributes = entity.all_attributes()
+ for attr in attributes:
+ attribute_names.add(attr.name())
+ except:
+ continue
+
+ return attribute_names
+
+ def get_attribute_values(self, ifc_file, attribute_name):
+ attribute_values = set()
+
+ for element_id in IfcStore.id_map.keys():
+ try:
+ element = ifc_file.by_id(element_id)
+
+ if element.is_a("IfcRelationship") or element.is_a("IfcTypeObject"):
+ continue
+
+ if hasattr(element, attribute_name):
+ value = getattr(element, attribute_name, None)
+
+ if value is not None and value != "":
+ if not hasattr(value, "is_a") and not isinstance(value, (tuple, list)):
+ str_value = str(value)
+ if not str_value.startswith("#") and not str_value.startswith("("):
+ attribute_values.add(str_value)
+ except:
+ continue
+
+ return attribute_values
+
+
class AddFilterGroup(Operator):
bl_idname = "bim.add_filter_group"
bl_label = "Add Filter Group"
@@ -96,11 +563,38 @@ class AddFilter(Operator):
def execute(self, context):
filter_groups = tool.Search.get_filter_groups(self.module)
+ if self.index >= len(filter_groups):
+ filter_groups.add()
new = filter_groups[self.index].filters.add()
new.type = self.type
return {"FINISHED"}
+class ToggleFilterInclusion(Operator):
+ bl_idname = "bim.toggle_filter_inclusion"
+ bl_label = "Toggle Filter Mode"
+ bl_description = "Cycle between Add (+), Subtract (-), and Filter modes for this filter"
+ bl_options = {"REGISTER", "UNDO"}
+
+ group_index: IntProperty()
+ filter_index: IntProperty()
+ module: StringProperty()
+
+ def execute(self, context):
+ filter_groups = tool.Search.get_filter_groups(self.module)
+ filter_group = filter_groups[self.group_index]
+ ifc_filter = filter_group.filters[self.filter_index]
+
+ if ifc_filter.filter_mode == "ADD":
+ ifc_filter.filter_mode = "SUBTRACT"
+ elif ifc_filter.filter_mode == "SUBTRACT":
+ ifc_filter.filter_mode = "FILTER"
+ else:
+ ifc_filter.filter_mode = "ADD"
+
+ return {"FINISHED"}
+
+
class SelectFilterElements(bpy.types.Operator):
bl_idname = "bim.select_filter_elements"
bl_label = "Select Filter Elements"
@@ -120,6 +614,47 @@ class SelectFilterElements(bpy.types.Operator):
return {"FINISHED"}
+class ApplyFilterFromText(Operator, tool.Ifc.Operator):
+ bl_idname = "bim.apply_filter_from_text"
+ bl_label = "Apply Filter Configuration"
+ bl_description = "Apply the JSON filter configuration from the current text block"
+ bl_options = {"REGISTER", "UNDO"}
+
+ @classmethod
+ def poll(cls, context):
+ if context.area and context.area.type == "TEXT_EDITOR":
+ space = context.space_data
+ if space.text and space.text.name.startswith("FilterQuery_"):
+ return True
+ return False
+
+ def execute(self, context):
+ space = context.space_data
+ text = space.text
+
+ if not text or not text.name.startswith("FilterQuery_"):
+ self.report({"ERROR"}, "No valid filter configuration text block")
+ return {"CANCELLED"}
+
+ module = text.name.replace("FilterQuery_", "")
+
+ try:
+ json_data = json.loads(text.as_string())
+ filter_structure = json_data.get("filter_structure", [])
+ filter_groups = tool.Search.get_filter_groups(module)
+ tool.Search.import_filter_structure(filter_structure, filter_groups)
+ self.report({"INFO"}, "Filter configuration applied successfully")
+
+ if len(context.window_manager.windows) > 1:
+ bpy.ops.wm.window_close()
+
+ except Exception as e:
+ self.report({"ERROR"}, f"Invalid JSON: {str(e)}")
+ return {"CANCELLED"}
+
+ return {"FINISHED"}
+
+
class EditFilterQuery(Operator, tool.Ifc.Operator):
bl_idname = "bim.edit_filter_query"
bl_label = "Edit Filter Query"
@@ -127,29 +662,82 @@ class EditFilterQuery(Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"}
query: StringProperty(name="Query")
old_query: StringProperty(name="Old Query")
- module: StringProperty()
+ module: StringProperty(default="search")
def _execute(self, context):
- if self.query == self.old_query:
- return
+ module = getattr(self, "module", "search")
- filter_groups = tool.Search.get_filter_groups(self.module)
- try:
- tool.Search.import_filter_query(self.query, filter_groups)
- except:
- return
+ if not tool.Blender.get_addon_preferences().chain_filter_with_set_operations:
+ if self.query == self.old_query:
+ return
+
+ filter_groups = tool.Search.get_filter_groups(module)
+ try:
+ tool.Search.import_filter_query(self.query, filter_groups)
+ except:
+ return
def draw(self, context):
- row = self.layout.row()
- row.prop(self, "query", text="")
+
+ if not tool.Blender.get_addon_preferences().chain_filter_with_set_operations:
+ row = self.layout.row()
+ row.prop(self, "query", text="")
def invoke(self, context, event):
- filter_groups = tool.Search.get_filter_groups(self.module)
+ module = getattr(self, "module", "search")
+ filter_groups = tool.Search.get_filter_groups(module)
- self.query = tool.Search.export_filter_query(filter_groups)
- self.old_query = self.query
+ if tool.Blender.get_addon_preferences().chain_filter_with_set_operations:
+ filter_structure = []
+ for filter_group in filter_groups:
+ group_data = []
+ for ifc_filter in filter_group.filters:
+ filter_data = {
+ "type": ifc_filter.type,
+ "name": ifc_filter.name,
+ "value": ifc_filter.value,
+ "pset": ifc_filter.pset,
+ "comparison": ifc_filter.comparison,
+ "filter_mode": ifc_filter.filter_mode,
+ }
+ group_data.append(filter_data)
+ filter_structure.append(group_data)
- return context.window_manager.invoke_props_dialog(self)
+ query = tool.Search.export_filter_query(filter_groups)
+ json_data = {"type": "BBIM_Search", "query": query, "filter_structure": filter_structure}
+
+ text_block_name = f"FilterQuery_{module}"
+ text = bpy.data.texts.get(text_block_name)
+ if not text:
+ text = bpy.data.texts.new(text_block_name)
+
+ text.clear()
+ text.write(json.dumps(json_data, indent=2))
+
+ bpy.ops.wm.window_new()
+ new_window = context.window_manager.windows[-1]
+
+ new_area = new_window.screen.areas[0]
+ new_area.type = "TEXT_EDITOR"
+
+ text_space = None
+ for space in new_area.spaces:
+ if space.type == "TEXT_EDITOR":
+ text_space = space
+ break
+
+ if text_space:
+ text_space.text = text
+
+ self.report(
+ {"INFO"}, "Compact text editor opened. Edit JSON and click 'Apply Filter Configuration' in header"
+ )
+ return {"FINISHED"}
+
+ else:
+ self.query = tool.Search.export_filter_query(filter_groups)
+ self.old_query = self.query
+ return context.window_manager.invoke_props_dialog(self, width=400)
class Search(Operator):
@@ -174,9 +762,26 @@ class Search(Operator):
else:
assert_never(self.property_group)
- results = ifcopenshell.util.selector.filter_elements(
- tool.Ifc.get(), tool.Search.export_filter_query(props.filter_groups)
- )
+ preferences = tool.Blender.get_addon_preferences()
+
+ # Migrate old ! prefix filters to new filter_mode system when preferences are enabled
+ if (
+ preferences.chain_filter_with_set_operations
+ or preferences.default_filter_with_set_operations_for_globalid_and_class
+ ):
+ for filter_group in props.filter_groups:
+ for ifc_filter in filter_group.filters:
+ if ifc_filter.type not in ["entity", "instance"]:
+ continue
+ if ifc_filter.value.startswith("!"):
+ ifc_filter.value = ifc_filter.value[1:]
+ ifc_filter.filter_mode = "SUBTRACT"
+
+ results = tool.Search.execute_filter_groups(props.filter_groups)
+ else:
+ results = ifcopenshell.util.selector.filter_elements(
+ tool.Ifc.get(), tool.Search.export_filter_query(props.filter_groups)
+ )
objs = [obj for e in results if isinstance(obj := tool.Ifc.get_object(e), bpy.types.Object)]
for obj in objs:
@@ -242,13 +847,28 @@ class SaveSearch(Operator, tool.Ifc.Operator):
try:
query = tool.Search.export_filter_query(filter_groups)
- results = ifcopenshell.util.selector.filter_elements(tool.Ifc.get(), query)
+ results = tool.Search.execute_filter_groups(filter_groups)
+
+ filter_structure = []
+ for filter_group in filter_groups:
+ group_data = []
+ for ifc_filter in filter_group.filters:
+ filter_data = {
+ "type": ifc_filter.type,
+ "name": ifc_filter.name,
+ "value": ifc_filter.value,
+ "pset": ifc_filter.pset,
+ "comparison": ifc_filter.comparison,
+ "filter_mode": ifc_filter.filter_mode,
+ }
+ group_data.append(filter_data)
+ filter_structure.append(group_data)
except:
print(traceback.format_exc())
self.report({"ERROR"}, "Error occurred trying save search.")
return
- description = json.dumps({"type": "BBIM_Search", "query": query})
+ description = json.dumps({"type": "BBIM_Search", "query": query, "filter_structure": filter_structure})
ifc_file = tool.Ifc.get()
group = next(
(
@@ -289,7 +909,12 @@ class LoadSearch(Operator, tool.Ifc.Operator):
filter_groups = tool.Search.get_filter_groups(self.module)
props = tool.Search.get_search_props()
group = tool.Ifc.get().by_id(int(props.saved_searches))
- tool.Search.import_filter_query(tool.Search.get_group_query(group), filter_groups)
+
+ group_data = tool.Search.get_group_data(group)
+ if group_data and "filter_structure" in group_data:
+ tool.Search.import_filter_structure(group_data["filter_structure"], filter_groups)
+ else:
+ tool.Search.import_filter_query(tool.Search.get_group_query(group), filter_groups)
def draw(self, context):
assert self.layout
@@ -302,6 +927,41 @@ class LoadSearch(Operator, tool.Ifc.Operator):
return context.window_manager.invoke_props_dialog(self)
+class RemoveSearch(Operator, tool.Ifc.Operator):
+ bl_idname = "bim.remove_search"
+ bl_label = "Remove Search"
+ bl_description = "Remove a saved search filter"
+ bl_options = {"REGISTER", "UNDO"}
+ module: StringProperty()
+
+ def _execute(self, context):
+ props = tool.Search.get_search_props()
+ group_id = props.saved_searches
+ if not group_id:
+ self.report({"ERROR"}, "No search selected for removal")
+ return
+
+ group = tool.Ifc.get().by_id(int(group_id))
+ group_name = group.Name or "Unnamed"
+ ifcopenshell.api.group.remove_group(tool.Ifc.get(), group=group)
+ tool.Search.patch_search_ifcgroups()
+ self.report({"INFO"}, f"Removed saved search: {group_name}")
+
+ def draw(self, context):
+ self.layout.label(text="Select search to remove:", icon="ERROR")
+ row = self.layout.row()
+ props = tool.Search.get_search_props()
+ row.prop(props, "saved_searches", text="")
+
+ def invoke(self, context, event):
+ tool.Search.patch_search_ifcgroups()
+ from bonsai.bim.module.search.data import SearchData
+
+ if not SearchData.is_loaded:
+ SearchData.load()
+ return context.window_manager.invoke_props_dialog(self)
+
+
class ColourByProperty(Operator):
bl_idname = "bim.colour_by_property"
bl_label = "Colour by Property"
diff --git a/src/bonsai/bonsai/bim/module/type/data.py b/src/bonsai/bonsai/bim/module/type/data.py
index 119456875a..3d0f506986 100644
--- a/src/bonsai/bonsai/bim/module/type/data.py
+++ b/src/bonsai/bonsai/bim/module/type/data.py
@@ -101,7 +101,7 @@ class TypeData:
element_type = ifcopenshell.util.element.get_type(element)
if not element_type:
return results
-
+
data = element_type.get_info()
if "GlobalId" in data:
excluded_keys = ["id", "type"]
diff --git a/src/bonsai/bonsai/bim/module/type/operator.py b/src/bonsai/bonsai/bim/module/type/operator.py
index b09b9fe5a8..c078d66f67 100644
--- a/src/bonsai/bonsai/bim/module/type/operator.py
+++ b/src/bonsai/bonsai/bim/module/type/operator.py
@@ -429,18 +429,18 @@ class EnableEditingTypeAttributes(bpy.types.Operator):
obj = context.active_object
if not obj:
return {"CANCELLED"}
-
+
element = tool.Ifc.get_entity(obj)
if not element:
return {"CANCELLED"}
-
+
element_type = ifcopenshell.util.element.get_type(element)
if not element_type:
return {"CANCELLED"}
-
+
props = tool.Type.get_object_type_props(obj)
props.type_attributes.clear()
-
+
bonsai.bim.helper.import_attributes(element_type, props.type_attributes)
props.is_editing_type_attributes = True
return {"FINISHED"}
@@ -456,7 +456,7 @@ class DisableEditingTypeAttributes(bpy.types.Operator):
obj = context.active_object
if not obj:
return {"CANCELLED"}
-
+
props = tool.Type.get_object_type_props(obj)
props.type_attributes.clear()
props.property_unset("is_editing_type_attributes")
@@ -473,24 +473,24 @@ class EditTypeAttributes(bpy.types.Operator, tool.Ifc.Operator):
obj = context.active_object
if not obj:
return {"CANCELLED"}
-
+
element = tool.Ifc.get_entity(obj)
if not element:
return {"CANCELLED"}
-
+
element_type = ifcopenshell.util.element.get_type(element)
if not element_type:
return {"CANCELLED"}
-
+
props = tool.Type.get_object_type_props(obj)
attributes = bonsai.bim.helper.export_attributes(props.type_attributes)
-
+
ifcopenshell.api.attribute.edit_attributes(tool.Ifc.get(), product=element_type, attributes=attributes)
-
+
type_obj = tool.Ifc.get_object(element_type)
if type_obj:
tool.Root.set_object_name(type_obj, element_type)
-
+
bpy.ops.bim.disable_editing_type_attributes()
-
+
return {"FINISHED"}
diff --git a/src/bonsai/bonsai/bim/module/type/ui.py b/src/bonsai/bonsai/bim/module/type/ui.py
index 24ffdc672e..d596997d5a 100644
--- a/src/bonsai/bonsai/bim/module/type/ui.py
+++ b/src/bonsai/bonsai/bim/module/type/ui.py
@@ -124,27 +124,28 @@ class BIM_PT_type_attributes(Panel):
def draw(self, context):
if not TypeData.is_loaded:
TypeData.load()
-
+
assert (layout := self.layout)
assert (obj := context.active_object)
-
+
if not TypeData.data.get("relating_type"):
layout.label(text="No Relating Type", icon="INFO")
return
-
+
props = tool.Type.get_object_type_props(obj)
-
+
if props.is_editing_type_attributes:
row = layout.row(align=True)
row.operator("bim.edit_type_attributes", icon="CHECKMARK", text="Save Attributes")
row.operator("bim.disable_editing_type_attributes", icon="CANCEL", text="")
-
+
import bonsai.bim.helper
+
bonsai.bim.helper.draw_attributes(props.type_attributes, layout)
else:
row = layout.row()
row.operator("bim.enable_editing_type_attributes", icon="GREASEPENCIL", text="Edit")
-
+
for attribute in TypeData.data["relating_type_attributes"]:
row = layout.row(align=True)
row.label(text=attribute["name"])
diff --git a/src/bonsai/bonsai/bim/operator.py b/src/bonsai/bonsai/bim/operator.py
index 517bfe34f1..82ac6ca185 100644
--- a/src/bonsai/bonsai/bim/operator.py
+++ b/src/bonsai/bonsai/bim/operator.py
@@ -33,6 +33,15 @@ import bonsai.bim
import bonsai.tool as tool
import bonsai.bim.handler
from enum import Enum
+from bonsai.bim.helper import (
+ get_all_tab_panels,
+ get_tab_visibility,
+ set_tab_visibility,
+ get_tab_names,
+ get_panel_config,
+ initialize_panel_properties,
+ initialize_tab_visibilities,
+)
from bpy_extras.io_utils import ImportHelper
from bonsai.bim import import_ifc
from bonsai.bim.prop import StrProperty
@@ -236,6 +245,147 @@ class SelectIfcFile(bpy.types.Operator, IFCFileSelector, ImportHelper):
return ImportHelper.invoke(self, context, event)
+class SaveBlendMetadataFile(bpy.types.Operator):
+ bl_idname = "bim.save_blend_metadata_file"
+ bl_label = "Save Blend Metadata File"
+ bl_options = {"REGISTER", "UNDO"}
+
+ def execute(self, context):
+ """
+ Save the current blend file as a metadata-only file (no geometry), preserving settings, window arrangement, geometry nodes, etc.
+ """
+ props = tool.Blender.get_bim_props()
+ ifc_file = getattr(props, "ifc_file", None)
+ if not ifc_file:
+ self.report({"WARNING"}, "No IFC file path set.")
+ return {"CANCELLED"}
+
+ blendmetadata_path = ifc_file + ".metadata.blend"
+
+ # Save a temporary copy of the current blend file
+ temp_path = bpy.path.abspath("//__temp_blendmetadata.blend")
+ bpy.ops.wm.save_as_mainfile(filepath=temp_path, copy=True)
+
+ cleanup_script = f"""
+import bpy
+
+# Ensure all styles are loaded before attempting to remove them
+try:
+ bpy.ops.bim.load_styles()
+except Exception:
+ pass
+
+# 1. Collect all IfcStyle material names
+ifcstyle_material_names = []
+try:
+ styles_props = getattr(bpy.context.scene, "BIMStylesProperties", None)
+ if styles_props is None and bpy.data.scenes:
+ styles_props = getattr(bpy.data.scenes[0], "BIMStylesProperties", None)
+ if styles_props:
+ for style in list(styles_props.styles):
+ material = getattr(style, "blender_material", None)
+ if material and material.name:
+ ifcstyle_material_names.append(material.name)
+except Exception:
+ pass
+
+# 2. Purge IfcStore
+try:
+ from bonsai.bim.ifc import IfcStore
+except ImportError:
+ IfcStore = None
+
+if IfcStore:
+ try:
+ IfcStore.purge()
+ except Exception:
+ pass
+
+# 3. Remove all collections named IfcProject*
+for collection in list(bpy.data.collections):
+ if collection.name.startswith('IfcProject'):
+ try:
+ bpy.data.collections.remove(collection, do_unlink=True)
+ except Exception:
+ pass
+
+# 4. Purge orphaned data blocks after removing IfcProject collections
+try:
+ bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True)
+except Exception:
+ pass
+
+# 5. Remove all materials corresponding to the IfcStyles we collected
+materials_removed = 0
+try:
+ for mat_name in ifcstyle_material_names:
+ if mat_name in bpy.data.materials:
+ try:
+ bpy.data.materials.remove(bpy.data.materials[mat_name], do_unlink=True)
+ materials_removed += 1
+ except Exception:
+ pass
+except Exception:
+ pass
+
+bpy.ops.wm.save_as_mainfile(filepath=r'{blendmetadata_path}')
+"""
+ import tempfile
+ with tempfile.NamedTemporaryFile("w", suffix=".py", delete=False) as script_file:
+ script_file.write(cleanup_script)
+ script_path = script_file.name
+
+ blender_exe = bpy.app.binary_path
+ import subprocess
+ result = subprocess.run(
+ [blender_exe, temp_path, "--background", "--python", script_path], capture_output=True, text=True
+ )
+
+ # Print the output from the background process (includes debug info)
+ if result.stdout:
+ print("\n=== Background Blender Output ===")
+ print(result.stdout)
+ if result.stderr:
+ print("\n=== Background Blender Errors ===")
+ print(result.stderr)
+
+ try:
+ os.remove(temp_path)
+ os.remove(script_path)
+ except Exception:
+ pass
+
+ return {"FINISHED"}
+
+
+class LoadBlendMetadataAndIFC(bpy.types.Operator):
+ bl_idname = "bim.load_blend_metadata_and_ifc"
+ bl_label = "Load Blend Metadata and IFC"
+ bl_options = {"REGISTER", "UNDO"}
+ filepath: bpy.props.StringProperty(name="IFC File Path", default="")
+
+ def execute(self, context):
+ ifc_file = self.filepath
+ if not ifc_file:
+ props = tool.Blender.get_bim_props()
+ ifc_file = getattr(props, "ifc_file", None)
+
+ if not ifc_file:
+ self.report({"WARNING"}, "No IFC file path set.")
+ return {"CANCELLED"}
+
+ metadata_path = ifc_file + ".metadata.blend"
+ # Open the metadata blend file
+ bpy.ops.wm.open_mainfile(filepath=metadata_path)
+ # After loading metadata, clear blend warning (no geometry loaded yet)
+ props = tool.Blender.get_bim_props()
+ props.has_blend_warning = False
+ # Load the IFC file into the current session (preserve layout)
+ bpy.ops.bim.load_project(filepath=ifc_file, should_start_fresh_session=False)
+ self.report({"INFO"}, f"Loaded metadata and IFC: {metadata_path}, {ifc_file}")
+ return {"FINISHED"}
+
+
# TODO: Unused operator.
# Is there a need for this or 'DIR_PATH' propety subtype does almost the same,
# but also has alt+click?
@@ -1605,3 +1755,244 @@ class BIM_OT_attribute_remove_subitem(bpy.types.Operator):
attr.is_null = True
return {"FINISHED"}
+
+
+class BIM_UL_tab_panels(bpy.types.UIList):
+ """UIList for Tab Panels"""
+
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ row = layout.row(align=True)
+ row.label(text=item["bl_label"])
+
+ row.operator(
+ "bim.toggle_panel_visibility",
+ text="",
+ icon="HIDE_OFF" if item.get("visible", True) else "HIDE_ON",
+ ).action = f"TOGGLE_VISIBILITY_{item.name}"
+
+ row.operator(
+ "bim.bookmark_panel",
+ text="",
+ icon="SOLO_ON" if item.get("bookmarked", False) else "SOLO_OFF",
+ ).action = f"BOOKMARK_{item.name}"
+
+
+class BIM_OT_toggle_panel_visibility(bpy.types.Operator):
+ """Toggle Panel Visibility"""
+
+ bl_idname = "bim.toggle_panel_visibility"
+ bl_label = "Toggle Panel Visibility"
+ bl_options = {"REGISTER", "UNDO"}
+
+ action: bpy.props.StringProperty()
+
+ def execute(self, context):
+ panel_name = self.action.replace("TOGGLE_VISIBILITY_", "")
+ active_tab = getattr(context.scene, "active_tab_name", None) or getattr(
+ tool.Blender.get_bim_props(), "tab", None
+ )
+ is_bookmark_tab = active_tab == "BOOKMARK"
+
+ panel_config = get_panel_config(panel_name, create_if_missing=True)
+ if panel_config:
+ if is_bookmark_tab:
+ panel_config.is_visible_in_bookmarks = not panel_config.is_visible_in_bookmarks
+ new_value = panel_config.is_visible_in_bookmarks
+ else:
+ panel_config.is_visible_in_tab = not panel_config.is_visible_in_tab
+ new_value = panel_config.is_visible_in_tab
+
+ for item in context.scene.tab_panels:
+ if item.name == panel_name:
+ item["visible"] = new_value
+ break
+
+ for area in bpy.context.window.screen.areas:
+ if area.type == "PROPERTIES":
+ area.tag_redraw()
+
+ tab_context = "Bookmarks" if is_bookmark_tab else "Tab"
+ self.report({"INFO"}, f"Toggled visibility for {panel_name} in {tab_context}.")
+ return {"FINISHED"}
+
+
+class BIM_OT_bookmark_panel(bpy.types.Operator):
+ """Bookmark Panel"""
+
+ bl_idname = "bim.bookmark_panel"
+ bl_label = "Bookmark Panel"
+ bl_options = {"REGISTER", "UNDO"}
+
+ action: bpy.props.StringProperty()
+
+ def execute(self, context):
+ panel_name = self.action.replace("BOOKMARK_", "")
+ panel_config = get_panel_config(panel_name, create_if_missing=True)
+
+ if panel_config:
+ panel_config.is_bookmarked = not panel_config.is_bookmarked
+
+ for item in context.scene.tab_panels:
+ if item.name == panel_name:
+ item["bookmarked"] = panel_config.is_bookmarked
+ break
+
+ for area in bpy.context.window.screen.areas:
+ if area.type == "PROPERTIES":
+ area.tag_redraw()
+
+ self.report({"INFO"}, f"Toggled bookmark for {panel_name}.")
+ return {"FINISHED"}
+
+
+class BIM_OT_manage_tab_panels(bpy.types.Operator):
+ """Manage Tab Panels"""
+
+ bl_idname = "bim.manage_tab_panels"
+ bl_label = "Manage Tab Panels"
+ bl_options = {"REGISTER", "UNDO"}
+
+ tab_name: bpy.props.StringProperty()
+
+ def invoke(self, context, event):
+
+ context.scene.active_tab_name = self.tab_name
+ context.scene.tab_panels.clear()
+
+ initialize_tab_visibilities()
+ initialize_panel_properties()
+ all_panels = get_all_tab_panels(force_refresh=True)
+
+ for panel_data in all_panels.get(self.tab_name, []):
+ panel_name = panel_data.get("bl_idname", "")
+ panel_label = panel_data.get("bl_label", "")
+ if not panel_name or not panel_label:
+ continue
+
+ item = context.scene.tab_panels.add()
+ item.name = panel_name
+ item["bl_label"] = panel_label
+
+ panel_config = get_panel_config(panel_name, create_if_missing=True)
+ if panel_config:
+ if self.tab_name == "BOOKMARK":
+ item["visible"] = panel_config.is_visible_in_bookmarks
+ else:
+ item["visible"] = panel_config.is_visible_in_tab
+ item["bookmarked"] = panel_config.is_bookmarked
+ else:
+ item["visible"] = True
+ item["bookmarked"] = False
+
+ return context.window_manager.invoke_popup(self)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label(text=f"Manage Panels for {self.tab_name} Tab")
+
+ row = layout.row()
+ row.template_list("BIM_UL_tab_panels", "", context.scene, "tab_panels", context.scene, "active_tab_panel_index")
+
+ def execute(self, context):
+ for item in context.scene.tab_panels:
+ panel_config = get_panel_config(item.name, create_if_missing=True)
+ if panel_config:
+ if self.tab_name == "BOOKMARK":
+ panel_config.is_visible_in_bookmarks = item["visible"]
+ else:
+ panel_config.is_visible_in_tab = item["visible"]
+ panel_config.is_bookmarked = item["bookmarked"]
+
+ self.report({"INFO"}, f"Panels for {self.tab_name} managed successfully.")
+ return {"FINISHED"}
+
+
+class BIM_OT_manage_tab_visibility(bpy.types.Operator):
+ """Manage Tab Visibility"""
+
+ bl_idname = "bim.manage_tab_visibility"
+ bl_label = "Manage Tab Visibility"
+ bl_options = {"REGISTER", "UNDO"}
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.row()
+ row = self.layout.row(align=True)
+ row.alignment = "RIGHT"
+
+ row.operator("bim.reset_ui_layout", icon="FILE_REFRESH", text="")
+ row = layout.row()
+ row = self.layout.row(align=True)
+ row.alignment = "CENTER"
+
+ for tab_name in get_tab_names():
+ row = layout.row()
+ row.label(text=tab_name)
+ is_visible = get_tab_visibility(tab_name)
+ icon = "HIDE_OFF" if is_visible else "HIDE_ON"
+ op = row.operator("bim.toggle_tab_visibility", text="", icon=icon)
+ op.tab_name = tab_name
+
+ def execute(self, context):
+ return {"FINISHED"}
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_popup(self)
+
+
+class BIM_OT_toggle_tab_visibility(bpy.types.Operator):
+ """Toggle Tab Visibility"""
+
+ bl_idname = "bim.toggle_tab_visibility"
+ bl_label = "Toggle Tab Visibility"
+ bl_options = {"REGISTER", "UNDO"}
+
+ tab_name: bpy.props.StringProperty()
+
+ def execute(self, context):
+ if self.tab_name in get_tab_names():
+ current_visibility = get_tab_visibility(self.tab_name)
+ set_tab_visibility(self.tab_name, not current_visibility)
+
+ for area in bpy.context.window.screen.areas:
+ if area.type == "PROPERTIES":
+ area.tag_redraw()
+
+ self.report({"INFO"}, f"Toggled visibility for {self.tab_name}.")
+ return {"FINISHED"}
+
+
+class BIM_OT_reset_ui_layout(bpy.types.Operator):
+ """Reset UI Layout to Default"""
+
+ bl_idname = "bim.reset_ui_layout"
+ bl_label = "Reset UI Layout"
+ bl_options = {"REGISTER", "UNDO"}
+
+ def execute(self, context):
+
+ for tab_name in get_tab_names():
+ set_tab_visibility(tab_name, True)
+
+ get_all_tab_panels()["BOOKMARK"] = [{}]
+
+ for tab_name, panels in get_all_tab_panels().items():
+ for panel in panels:
+ panel_name = panel.get("bl_idname", "")
+ if not panel_name:
+ continue
+
+ show_prop_name = f"show_{panel_name.lower()}"
+ if hasattr(context.scene, show_prop_name):
+ setattr(context.scene, show_prop_name, True)
+
+ bookmark_prop_name = f"bookmark_{panel_name.lower()}"
+ if hasattr(context.scene, bookmark_prop_name):
+ setattr(context.scene, bookmark_prop_name, False)
+
+ for area in bpy.context.window.screen.areas:
+ if area.type == "PROPERTIES":
+ area.tag_redraw()
+
+ self.report({"INFO"}, "UI layout reset to default.")
+ return {"FINISHED"}
diff --git a/src/bonsai/bonsai/bim/prop.py b/src/bonsai/bonsai/bim/prop.py
index 08137a133e..f9c7f57782 100644
--- a/src/bonsai/bonsai/bim/prop.py
+++ b/src/bonsai/bonsai/bim/prop.py
@@ -493,8 +493,9 @@ def get_tab(
("SCHEDULING", "Costing and Scheduling", "", "NLA", 6),
("FM", "Facility Management", "", "PACKAGE", 7),
("QUALITY", "Quality and Coordination", "", "COMMUNITY", 8),
+ ("BOOKMARK", "Bookmark", "", "SOLO_ON", 9),
None,
- ("BLENDER", "Blender Properties", "", "BLENDER", 9),
+ ("BLENDER", "Blender Properties", "", "BLENDER", 10),
]
return get_tab.enum_items
@@ -529,6 +530,26 @@ class BIMTabProperties(PropertyGroup):
inactive_tab: bool
+class BIMTabVisibility(PropertyGroup):
+ name: StringProperty(name="Tab Name")
+ is_visible: BoolProperty(name="Is Visible", default=True)
+
+ if TYPE_CHECKING:
+ name: str
+ is_visible: bool
+
+
+class BIMPanelProperties(PropertyGroup):
+ is_visible_in_tab: BoolProperty(name="Is Visible in Tab", default=True)
+ is_visible_in_bookmarks: BoolProperty(name="Is Visible in Bookmarks", default=True)
+ is_bookmarked: BoolProperty(name="Is Bookmarked", default=False)
+
+ if TYPE_CHECKING:
+ is_visible_in_tab: bool
+ is_visible_in_bookmarks: bool
+ is_bookmarked: bool
+
+
class BIMProperties(PropertyGroup):
is_dirty: BoolProperty(name="Is Dirty", default=False)
schema_dir: StringProperty(
@@ -613,6 +634,9 @@ class BIMProperties(PropertyGroup):
name="Time Unit",
default="HOUR",
)
+ tab_visibilities: CollectionProperty(type=BIMTabVisibility, name="Tab Visibilities")
+ panel_properties: CollectionProperty(type=BIMPanelProperties, name="Panel Properties")
+
if TYPE_CHECKING:
is_dirty: bool
schema_dir: str
@@ -627,6 +651,8 @@ class BIMProperties(PropertyGroup):
volume_unit: str
mass_unit: str
time_unit: str
+ tab_visibilities: bpy.types.bpy_prop_collection[BIMTabVisibility]
+ panel_properties: bpy.types.bpy_prop_collection[BIMPanelProperties]
class IfcParameter(PropertyGroup):
@@ -748,6 +774,15 @@ class BIMFacet(PropertyGroup):
pset: StringProperty(name="Pset")
value: StringProperty(name="Value")
type: StringProperty(name="Type")
+ filter_mode: EnumProperty(
+ name="Filter Mode",
+ items=[
+ ("ADD", "Add", "Add elements to the result set (query entire IFC file)", "ADD", 0),
+ ("SUBTRACT", "Subtract", "Subtract matching elements from previous results", "REMOVE", 1),
+ ("FILTER", "Filter", "Filter down previous results to matching elements", "FILTER", 2),
+ ],
+ default="ADD",
+ )
comparison: EnumProperty(
items=[
("=", "equal to", ""),
@@ -765,6 +800,7 @@ class BIMFacet(PropertyGroup):
pset: str
value: str
type: str
+ filter_mode: Literal["ADD", "SUBTRACT", "FILTER"]
comparison: Literal["=", "!=", ">=", "<=", ">", "<", "*=", "!*="]
diff --git a/src/bonsai/bonsai/bim/ui.py b/src/bonsai/bonsai/bim/ui.py
index 4a1114d831..6c2baaa0fb 100644
--- a/src/bonsai/bonsai/bim/ui.py
+++ b/src/bonsai/bonsai/bim/ui.py
@@ -36,6 +36,19 @@ import bonsai.bim
import bonsai.tool as tool
from ifcopenshell.util.file import IfcHeaderExtractor
from bonsai.bim.prop import Attribute
+from bonsai.bim.helper import (
+ get_tab_names,
+ get_panel_tab_name,
+ should_show_panel,
+ get_tab_visibility,
+ set_tab_visibility,
+ get_panel_visibility,
+ is_panel_bookmarked,
+ get_panel_config,
+ get_all_tab_panels,
+ initialize_tab_visibilities,
+ initialize_panel_properties,
+)
from bonsai.bim.module.bsdd.prop import BIMBSDDProperties, BSDDProperty
from bonsai.bim.module.pset.prop import IfcProperty
from bonsai.bim.module.model.prop import (
@@ -139,8 +152,8 @@ class IFCFileSelector:
class BIM_PT_section_plane(Panel):
- bl_label = "Temporary Section Cutaways"
bl_idname = "BIM_PT_section_plane"
+ bl_label = "Temporary Section Cutaways"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "output"
@@ -163,8 +176,8 @@ class BIM_PT_section_plane(Panel):
class BIM_PT_section_with_cappings(Panel):
- bl_label = "Section Cutaways With Cappings"
bl_idname = "BIM_PT_section_with_cappings"
+ bl_label = "Section Cutaways With Cappings"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "output"
@@ -690,6 +703,28 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
default=False,
)
+ chain_filter_with_set_operations: BoolProperty(
+ name="NEW filter mode: Enable chained filters with set operations",
+ description="Enable chaining search filters with set operations: ADD (union: combine sets), SUBTRACT (difference: remove from set), FILTER (intersection: only elements in both sets), with autocomplete suggestions for filter values",
+ default=False,
+ )
+ default_filter_with_set_operations_for_globalid_and_class: BoolProperty(
+ name="DEFAULT filter mode: Enable set operations for GlobalId/Class",
+ description="Enable ADD/SUBTRACT/FILTER toggle buttons on entity (Class) and instance (GlobalId) filters for the DEFAULT filter mode",
+ default=False,
+ )
+
+ save_metadata_blend_file: BoolProperty(
+ name="Save non ifc data to .metadata.blend File",
+ description="Save session data (window layout, settings) to a .metadata.blend file alongside the IFC file. This file is automatically loaded when opening the project.",
+ default=False,
+ )
+ user_ui_customization: BoolProperty(
+ name="User UI Customization",
+ description="Enable user interface customization features (hide/show tabs and panels, bookmark panels) and save the session settings as part of the .metadata.blend file",
+ default=False,
+ )
+
if TYPE_CHECKING:
svg2pdf_command: str
svg2dxf_command: str
@@ -727,6 +762,10 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
default_parameters: DefaultParameters
container_hide_show_isolate: bool
mass_time_units_in_wizard: bool
+ chain_filter_with_set_operations: bool
+ default_filter_with_set_operations_for_globalid_and_class: bool
+ save_metadata_blend_file: bool
+ user_ui_customization: bool
def draw(self, context: bpy.types.Context) -> None:
layout = self.layout
@@ -909,10 +948,24 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
def draw_extras_settings(self, layout: bpy.types.UILayout, context: bpy.types.Context) -> None:
layout.prop(self, "container_hide_show_isolate")
layout.prop(self, "mass_time_units_in_wizard")
+ layout.label(text="Filtering modes:")
+ box = layout.box()
+ row = box.row(align=True)
+ row.prop(self, "chain_filter_with_set_operations")
+ row.operator("bim.open_uri", text="", icon="HELP").uri = "https://community.osarch.org/discussion/3270"
+ row = box.row(align=True)
+ row.prop(self, "default_filter_with_set_operations_for_globalid_and_class")
+ row.operator("bim.open_uri", text="", icon="HELP").uri = "https://community.osarch.org/discussion/comment/27030"
+ layout.prop(self, "save_metadata_blend_file")
+ if self.save_metadata_blend_file:
+ row = layout.row()
+ row.separator()
+ row.prop(self, "user_ui_customization")
# Scene panel groups
class BIM_PT_tabs(Panel):
+ bl_idname = "BIM_PT_tabs"
bl_label = "Bonsai"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
@@ -925,51 +978,76 @@ class BIM_PT_tabs(Panel):
UIData.load()
is_ifc_project = bool(tool.Ifc.get())
aprops = tool.Blender.get_area_props(context)
+ addon_prefs = tool.Blender.get_addon_preferences()
ifc_icon = f"{UIData.data['tabs_icon_color_mode']}_ifc"
- row = self.layout.row()
- row.alignment = "CENTER"
- row.operator(
- "bim.set_tab",
- text="",
- emboss=aprops.tab == "PROJECT",
- icon_value=bonsai.bim.icons[ifc_icon].icon_id,
- ).tab = "PROJECT"
- self.draw_tab_entry(row, "FILE_3D", "OBJECT", is_ifc_project, aprops.tab == "OBJECT")
- self.draw_tab_entry(row, "MATERIAL", "GEOMETRY", is_ifc_project, aprops.tab == "GEOMETRY")
- self.draw_tab_entry(row, "DOCUMENTS", "DRAWINGS", is_ifc_project, aprops.tab == "DRAWINGS")
- self.draw_tab_entry(row, "NETWORK_DRIVE", "SERVICES", is_ifc_project, aprops.tab == "SERVICES")
- self.draw_tab_entry(row, "EDITMODE_HLT", "STRUCTURE", is_ifc_project, aprops.tab == "STRUCTURE")
- self.draw_tab_entry(row, "NLA", "SCHEDULING", is_ifc_project, aprops.tab == "SCHEDULING")
- self.draw_tab_entry(row, "PACKAGE", "FM", True, aprops.tab == "FM")
- self.draw_tab_entry(row, "COMMUNITY", "QUALITY", True, aprops.tab == "QUALITY")
- row.operator("bim.switch_tab", text="", emboss=False, icon="UV_SYNC_SELECT")
+ split = self.layout.split(factor=0.9)
+ col_left = split.column(align=True)
+ row_left = col_left.row(align=True)
+ row_left.alignment = "CENTER"
+ if get_tab_visibility("PROJECT"):
+ row_left.operator(
+ "bim.set_tab",
+ text="",
+ emboss=aprops.tab == "PROJECT",
+ icon_value=bonsai.bim.icons[ifc_icon].icon_id,
+ ).tab = "PROJECT"
+ if get_tab_visibility("OBJECT"):
+ self.draw_tab_entry(row_left, "FILE_3D", "OBJECT", is_ifc_project, aprops.tab == "OBJECT")
+ if get_tab_visibility("GEOMETRY"):
+ self.draw_tab_entry(row_left, "MATERIAL", "GEOMETRY", is_ifc_project, aprops.tab == "GEOMETRY")
+ if get_tab_visibility("DRAWINGS"):
+ self.draw_tab_entry(row_left, "DOCUMENTS", "DRAWINGS", is_ifc_project, aprops.tab == "DRAWINGS")
+ if get_tab_visibility("SERVICES"):
+ self.draw_tab_entry(row_left, "NETWORK_DRIVE", "SERVICES", is_ifc_project, aprops.tab == "SERVICES")
+ if get_tab_visibility("STRUCTURE"):
+ self.draw_tab_entry(row_left, "EDITMODE_HLT", "STRUCTURE", is_ifc_project, aprops.tab == "STRUCTURE")
+ if get_tab_visibility("SCHEDULING"):
+ self.draw_tab_entry(row_left, "NLA", "SCHEDULING", is_ifc_project, aprops.tab == "SCHEDULING")
+ if get_tab_visibility("FM"):
+ self.draw_tab_entry(row_left, "PACKAGE", "FM", True, aprops.tab == "FM")
+ if get_tab_visibility("QUALITY"):
+ self.draw_tab_entry(row_left, "COMMUNITY", "QUALITY", True, aprops.tab == "QUALITY")
+ if (
+ addon_prefs.save_metadata_blend_file
+ and addon_prefs.user_ui_customization
+ and get_tab_visibility("BOOKMARK")
+ ):
+ self.draw_tab_entry(row_left, "SOLO_ON", "BOOKMARK", True, aprops.tab == "BOOKMARK")
+ row_left.operator("bim.switch_tab", text="", emboss=False, icon="UV_SYNC_SELECT")
+ row_left = col_left.row(align=True)
# Yes, that's right.
- row = self.layout.row()
- row.alignment = "CENTER"
- row.scale_y = 0.2
- for tab in [
- "PROJECT",
- "OBJECT",
- "GEOMETRY",
- "DRAWINGS",
- "SERVICES",
- "STRUCTURE",
- "SCHEDULING",
- "FM",
- "QUALITY",
- "SWITCH",
- ]:
+ row_left.alignment = "CENTER"
+ row_left.scale_y = 0.2
+
+ if not (addon_prefs.save_metadata_blend_file and addon_prefs.user_ui_customization):
+ row_left.prop(aprops, "inactive_tab", text="", icon="BLANK1", emboss=False)
+
+ for tab in get_tab_names():
# Draw a little underscore below the active tab icon.
- if aprops.tab == tab:
- row.prop(aprops, "active_tab", text="", icon="BLANK1")
- else:
- row.prop(aprops, "inactive_tab", text="", icon="BLANK1", emboss=False)
+ if get_tab_visibility(tab):
+ if aprops.tab == tab:
+ row_left.prop(aprops, "active_tab", text="", icon="BLANK1")
+ else:
+ row_left.prop(aprops, "inactive_tab", text="", icon="BLANK1", emboss=False)
+ row_left.prop(aprops, "inactive_tab", text="", icon="BLANK1", emboss=False) # space for Switch
+ col_right = split.column(align=True)
+ row_right = col_right.row(align=True)
+ row_right.alignment = "RIGHT"
+
+ if addon_prefs.save_metadata_blend_file and addon_prefs.user_ui_customization:
+ row_right.operator("bim.manage_tab_visibility", icon="PREFERENCES", text="")
row = self.layout.row(align=True)
row.prop(aprops, "tab", text="")
+ if addon_prefs.save_metadata_blend_file and addon_prefs.user_ui_customization:
+ for tab in get_tab_names():
+ if get_tab_visibility(tab):
+ if aprops.tab == tab:
+ row.operator("bim.manage_tab_panels", text="", icon="PREFERENCES").tab_name = tab
+
if bonsai.REINSTALLED_BBIM_VERSION:
box = self.layout.box()
box.alert = True
@@ -1040,14 +1118,18 @@ class BIM_PT_tabs(Panel):
class BIM_PT_tab_new_project_wizard(Panel):
+ bl_idname = "BIM_PT_tab_new_project_wizard"
bl_label = "New Project Wizard"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "PROJECT"
@classmethod
def poll(cls, context):
- if not tool.Blender.is_tab(context, "PROJECT"):
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if not tool.Blender.is_tab(context, cls.bim_tab_name):
return False
bim_props = tool.Blender.get_bim_props()
pprops = tool.Project.get_project_props()
@@ -1062,94 +1144,128 @@ class BIM_PT_tab_new_project_wizard(Panel):
class BIM_PT_tab_project_info(Panel):
+ bl_idname = "BIM_PT_tab_project_info"
bl_label = "Project Info"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "PROJECT"
@classmethod
def poll(cls, context):
- if not tool.Blender.is_tab(context, "PROJECT"):
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
return False
- bim_props = tool.Blender.get_bim_props()
- pprops = tool.Project.get_project_props()
- if pprops.is_loading:
- return True
- elif tool.Ifc.get() or bim_props.ifc_file:
- return True
- return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name):
+ bim_props = tool.Blender.get_bim_props()
+ pprops = tool.Project.get_project_props()
+ if pprops.is_loading:
+ return True
+ elif tool.Ifc.get() or bim_props.ifc_file:
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
- pass
+ layout = self.layout
+ layout.label(text="This is the Project Info panel.")
class BIM_PT_tab_spatial(Panel):
+ bl_idname = "BIM_PT_tab_spatial"
bl_label = "Spatial"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "PROJECT"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "PROJECT") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_project_setup(Panel):
+ bl_idname = "BIM_PT_tab_project_setup"
bl_label = "Project Setup"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "PROJECT"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "PROJECT")
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name):
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_stakeholders(Panel):
+ bl_idname = "BIM_PT_tab_stakeholders"
bl_label = "Stakeholders"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_options = {"DEFAULT_CLOSED"}
+ bim_tab_name = "PROJECT"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "PROJECT") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_collaboration(Panel):
+ bl_idname = "BIM_PT_tab_collaboration"
bl_label = "Collaboration"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "QUALITY"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "QUALITY")
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name):
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_grouping_and_filtering(Panel):
+ bl_idname = "BIM_PT_tab_grouping_and_filtering"
bl_label = "Grouping and Filtering"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_options = {"HEADER_LAYOUT_EXPAND"}
+ bim_tab_name = "PROJECT"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "PROJECT") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
@@ -1164,197 +1280,281 @@ class BIM_PT_tab_grouping_and_filtering(Panel):
class BIM_PT_tab_geometry(Panel):
+ bl_idname = "BIM_PT_tab_geometry"
bl_label = "Geometry"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "PROJECT"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "PROJECT") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_status(Panel):
+ bl_idname = "BIM_PT_tab_status"
bl_label = "Status"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "SCHEDULING"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "SCHEDULING") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_qto(Panel):
+ bl_idname = "BIM_PT_tab_qto"
bl_label = "Quantity Take-off"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "SCHEDULING"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "SCHEDULING") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_resources(Panel):
+ bl_idname = "BIM_PT_tab_resources"
bl_label = "Resources"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "SCHEDULING"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "SCHEDULING") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_cost(Panel):
+ bl_idname = "BIM_PT_tab_cost"
bl_label = "Cost"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "SCHEDULING"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "SCHEDULING") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_sequence(Panel):
+ bl_idname = "BIM_PT_tab_sequence"
bl_label = "Construction Scheduling"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "SCHEDULING"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "SCHEDULING") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_structural(Panel):
+ bl_idname = "BIM_PT_tab_structural"
bl_label = "Structural"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "STRUCTURE"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "STRUCTURE") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_services(Panel):
+ bl_idname = "BIM_PT_tab_services"
bl_label = "Services"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "SERVICES"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "SERVICES") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_lighting(Panel):
+ bl_idname = "BIM_PT_tab_lighting"
bl_label = "Lighting"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "SERVICES"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "SERVICES") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_zones(Panel):
+ bl_idname = "BIM_PT_tab_zones"
bl_label = "Zones"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "SERVICES"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "SERVICES") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_solar_analysis(Panel):
+ bl_idname = "BIM_PT_tab_solar_analysis"
bl_label = "Solar Analysis"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "SERVICES"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "SERVICES") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_quality_control(Panel):
+ bl_idname = "BIM_PT_tab_quality_control"
bl_label = "Quality Control"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "QUALITY"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "QUALITY")
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name):
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_clash_detection(Panel):
+ bl_idname = "BIM_PT_tab_clash_detection"
bl_label = "Clash Detection"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
+ bim_tab_name = "QUALITY"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "QUALITY")
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name):
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_sandbox(Panel):
+ bl_idname = "BIM_PT_tab_sandbox"
bl_label = "Sandbox"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_options = {"DEFAULT_CLOSED"}
+ bim_tab_name = "QUALITY"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "QUALITY")
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name):
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
row = self.layout.row()
@@ -1363,17 +1563,21 @@ class BIM_PT_tab_sandbox(Panel):
# Object panel groups
class BIM_PT_tab_object_metadata(Panel):
+ bl_idname = "BIM_PT_tab_object_metadata"
bl_label = "Object"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
+ bim_tab_name = "OBJECT"
@classmethod
def poll(cls, context):
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
props = tool.Project.get_project_props()
- return (
- tool.Blender.is_tab(context, "OBJECT")
+ if (
+ tool.Blender.is_tab(context, cls.bim_tab_name)
and tool.Ifc.get()
and (obj := context.active_object)
# Hide links empty handles.
@@ -1382,254 +1586,326 @@ class BIM_PT_tab_object_metadata(Panel):
or not obj.instance_collection
or not any(l.empty_handle == obj for l in props.links)
)
- )
+ ):
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_placement(Panel):
+ bl_idname = "BIM_PT_tab_placement"
bl_label = "Placement"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
+ bim_tab_name = "GEOMETRY"
@classmethod
def poll(cls, context):
- return (
- tool.Blender.is_tab(context, "GEOMETRY")
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if (
+ tool.Blender.is_tab(context, cls.bim_tab_name)
and tool.Ifc.get()
and (obj := context.active_object)
and tool.Ifc.get_entity(obj)
- )
+ ):
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_representations(Panel):
+ bl_idname = "BIM_PT_tab_representations"
bl_label = "Representations"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
+ bim_tab_name = "GEOMETRY"
@classmethod
def poll(cls, context):
- return (
- tool.Blender.is_tab(context, "GEOMETRY")
- and tool.Ifc.get()
- and tool.Geometry.get_active_or_representation_obj()
- )
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_geometric_relationships(Panel):
+ bl_idname = "BIM_PT_tab_geometric_relationships"
bl_label = "Geometric Relationships"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
bl_options = {"DEFAULT_CLOSED"}
+ bim_tab_name = "GEOMETRY"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "GEOMETRY") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_parametric_geometry(Panel):
+ bl_idname = "BIM_PT_tab_parametric_geometry"
bl_label = "Parametric Geometry"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
bl_options = {"DEFAULT_CLOSED"}
+ bim_tab_name = "GEOMETRY"
@classmethod
def poll(cls, context):
- return (
- tool.Blender.is_tab(context, "GEOMETRY")
- and tool.Ifc.get()
- and (obj := context.active_object)
- and tool.Ifc.get_entity(obj)
- )
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_object_materials(Panel):
+ bl_idname = "BIM_PT_tab_object_materials"
bl_label = "Object Materials"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
+ bim_tab_name = "GEOMETRY"
@classmethod
def poll(cls, context):
- return (
- tool.Blender.is_tab(context, "GEOMETRY")
- and tool.Ifc.get()
- and (obj := context.active_object)
- and tool.Ifc.get_entity(obj)
- )
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_materials(Panel):
+ bl_idname = "BIM_PT_tab_materials"
bl_label = "Materials"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
+ bim_tab_name = "GEOMETRY"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "GEOMETRY") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_styles(Panel):
+ bl_idname = "BIM_PT_tab_styles"
bl_label = "Styles"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
+ bim_tab_name = "GEOMETRY"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "GEOMETRY") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_profiles(Panel):
+ bl_idname = "BIM_PT_tab_profiles"
bl_label = "Profiles"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
+ bim_tab_name = "GEOMETRY"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "GEOMETRY") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_sheets(Panel):
+ bl_idname = "BIM_PT_tab_sheets"
bl_label = "Sheets"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
+ bim_tab_name = "DRAWINGS"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "DRAWINGS") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_drawings(Panel):
+ bl_idname = "BIM_PT_tab_drawings"
bl_label = "Drawings"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
+ bim_tab_name = "DRAWINGS"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "DRAWINGS") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_schedules(Panel):
+ bl_idname = "BIM_PT_tab_schedules"
bl_label = "Schedules"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
+ bim_tab_name = "DRAWINGS"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "DRAWINGS") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_references(Panel):
+ bl_idname = "BIM_PT_tab_references"
bl_label = "References"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
+ bim_tab_name = "DRAWINGS"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "DRAWINGS") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_misc(Panel):
- bl_label = "Misc."
+ bl_idname = "BIM_PT_tab_misc"
+ bl_label = "Misc"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
bl_options = {"DEFAULT_CLOSED"}
+ bim_tab_name = "OBJECT"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "OBJECT") and tool.Ifc.get()
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name) and tool.Ifc.get():
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_handover(Panel):
- bl_label = "Commissioning and Handover"
+ bl_idname = "BIM_PT_tab_handover"
+ bl_label = "Handover"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 1
+ bim_tab_name = "FM"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "FM")
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name):
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
class BIM_PT_tab_operations(Panel):
- bl_label = "Operations and Maintenance"
+ bl_idname = "BIM_PT_tab_operations"
+ bl_label = "Operations"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_order = 2
+ bim_tab_name = "FM"
@classmethod
def poll(cls, context):
- return tool.Blender.is_tab(context, "FM")
+ if not should_show_panel(cls.bl_idname, cls.bim_tab_name, context):
+ return False
+ if tool.Blender.is_tab(context, cls.bim_tab_name):
+ return True
+ return tool.Blender.is_tab(context, "BOOKMARK")
def draw(self, context):
pass
diff --git a/src/bonsai/bonsai/core/drawing.py b/src/bonsai/bonsai/core/drawing.py
index f30c49974d..118fc3b69c 100644
--- a/src/bonsai/bonsai/core/drawing.py
+++ b/src/bonsai/bonsai/core/drawing.py
@@ -487,12 +487,29 @@ def sync_references(
potential_reference_elements = drawing_tool.get_potential_reference_elements(drawing)
for element in potential_reference_elements:
+ # Skip spatial elements - their IFC placement is the source of truth
+ if element.is_a("IfcSpatialElement"):
+ continue
+
+ # Skip grids - their IFC placement is the source of truth
+ if element.is_a("IfcGrid") or element.is_a("IfcGridAxis"):
+ continue
+
if (obj := ifc.get_object(element)) and ifc.is_moved(obj):
drawing_tool.sync_object_placement(obj)
for element in drawing_tool.get_group_elements(group):
if not drawing_tool.is_auto_annotation(element):
continue
+
+ # Skip spatial elements - should never sync their placement
+ if element.is_a("IfcSpatialElement"):
+ continue
+
+ # Skip grids
+ if element.is_a("IfcGrid") or element.is_a("IfcGridAxis"):
+ continue
+
if (obj := ifc.get_object(element)) and ifc.is_moved(obj):
drawing_tool.sync_object_placement(obj)
if not (reference_element := drawing_tool.get_assigned_product(element)):
diff --git a/src/bonsai/bonsai/core/unit.py b/src/bonsai/bonsai/core/unit.py
index a4c52508f1..9594c2b566 100644
--- a/src/bonsai/bonsai/core/unit.py
+++ b/src/bonsai/bonsai/core/unit.py
@@ -28,9 +28,13 @@ if TYPE_CHECKING:
def assign_scene_units(ifc: type[tool.Ifc], unit: type[tool.Unit]) -> None:
if unit.is_scene_unit_metric():
- lengthunit = ifc.run("unit.add_si_unit", unit_type="LENGTHUNIT", prefix=unit.get_scene_unit_si_prefix("LENGTHUNIT"))
+ lengthunit = ifc.run(
+ "unit.add_si_unit", unit_type="LENGTHUNIT", prefix=unit.get_scene_unit_si_prefix("LENGTHUNIT")
+ )
areaunit = ifc.run("unit.add_si_unit", unit_type="AREAUNIT", prefix=unit.get_scene_unit_si_prefix("AREAUNIT"))
- volumeunit = ifc.run("unit.add_si_unit", unit_type="VOLUMEUNIT", prefix=unit.get_scene_unit_si_prefix("VOLUMEUNIT"))
+ volumeunit = ifc.run(
+ "unit.add_si_unit", unit_type="VOLUMEUNIT", prefix=unit.get_scene_unit_si_prefix("VOLUMEUNIT")
+ )
planeangleunit = ifc.run("unit.add_conversion_based_unit", name="degree")
units = [lengthunit, areaunit, volumeunit, planeangleunit]
diff --git a/src/bonsai/bonsai/tool/drawing.py b/src/bonsai/bonsai/tool/drawing.py
index 8fc500a223..b687134afc 100644
--- a/src/bonsai/bonsai/tool/drawing.py
+++ b/src/bonsai/bonsai/tool/drawing.py
@@ -2123,7 +2123,15 @@ class Drawing(bonsai.core.tool.Drawing):
value = ifcopenshell.util.selector.get_element_value(product, variable[2:-2])
value = '"' + str(value).replace('"', '\\"') + '"'
command = command.replace(variable, value)
- text = text.replace(original_command, ifcopenshell.util.selector.format(command[2:-2]))
+ # Defensive: skip if command[2:-2] is None or 'None'
+ command_content = command[2:-2]
+ if command_content is None or str(command_content).strip().lower() == "none":
+ text = text.replace(original_command, "")
+ else:
+ try:
+ text = text.replace(original_command, ifcopenshell.util.selector.format(command_content))
+ except Exception:
+ text = text.replace(original_command, "")
for variable in re.findall("{{.*?}}", text):
value = ifcopenshell.util.selector.get_element_value(product, variable[2:-2])
if isinstance(value, (list, tuple)):
@@ -2277,7 +2285,16 @@ class Drawing(bonsai.core.tool.Drawing):
pset = ifcopenshell.util.element.get_psets(drawing).get("EPset_Drawing", {})
include = pset.get("Include", None)
if include:
- elements = ifcopenshell.util.selector.filter_elements(ifc_file, include)
+ try:
+ data = json.loads(include)
+ if isinstance(data, dict) and "filter_structure" in data:
+ elements = tool.Search.execute_filter_groups_from_json(data, ifc_file)
+ elif isinstance(data, dict) and "query" in data:
+ elements = ifcopenshell.util.selector.filter_elements(ifc_file, data["query"])
+ else:
+ elements = ifcopenshell.util.selector.filter_elements(ifc_file, include)
+ except (json.JSONDecodeError, ValueError):
+ elements = ifcopenshell.util.selector.filter_elements(ifc_file, include)
else:
if ifc_file.schema == "IFC2X3":
base_elements = set(ifc_file.by_type("IfcElement") + ifc_file.by_type("IfcSpatialStructureElement"))
@@ -2291,7 +2308,7 @@ class Drawing(bonsai.core.tool.Drawing):
if not i.is_a("IfcAnnotation"):
updated_set.add(i)
# add aggregate too, if element is host by one
- if decomposes := i.Decomposes:
+ if hasattr(i, "Decomposes") and (decomposes := i.Decomposes):
aggregate = decomposes[0].RelatingObject
# remove IfcProject for class iterator. See https://github.com/IfcOpenShell/IfcOpenShell/issues/4361#issuecomment-2081223615
if aggregate.is_a("IfcProduct"):
@@ -2304,7 +2321,18 @@ class Drawing(bonsai.core.tool.Drawing):
exclude = pset.get("Exclude", None)
if exclude:
- elements -= ifcopenshell.util.selector.filter_elements(ifc_file, exclude)
+ try:
+ data = json.loads(exclude)
+ if isinstance(data, dict) and "filter_structure" in data:
+ exclude_elements = tool.Search.execute_filter_groups_from_json(data, ifc_file)
+ elements -= exclude_elements
+ elif isinstance(data, dict) and "query" in data:
+ elements -= ifcopenshell.util.selector.filter_elements(ifc_file, data["query"])
+ else:
+ elements -= ifcopenshell.util.selector.filter_elements(ifc_file, exclude)
+ except (json.JSONDecodeError, ValueError):
+ elements -= ifcopenshell.util.selector.filter_elements(ifc_file, exclude)
+ elements -= ifcopenshell.util.selector.filter_elements(ifc_file, exclude)
elements -= set(ifc_file.by_type("IfcOpeningElement"))
return elements
@@ -2318,7 +2346,18 @@ class Drawing(bonsai.core.tool.Drawing):
# NOTE: EPset_Drawing.Include is not used to avoid adding other elements besides spaces
exclude = pset.get("Exclude", None)
if exclude:
- elements -= ifcopenshell.util.selector.filter_elements(ifc_file, exclude)
+ try:
+ data = json.loads(exclude)
+ if isinstance(data, dict) and "filter_structure" in data:
+ exclude_elements = tool.Search.execute_filter_groups_from_json(data, ifc_file)
+ elements -= exclude_elements
+ elif isinstance(data, dict) and "query" in data:
+ elements -= ifcopenshell.util.selector.filter_elements(ifc_file, data["query"])
+ else:
+ elements -= ifcopenshell.util.selector.filter_elements(ifc_file, exclude)
+ except (json.JSONDecodeError, ValueError):
+ elements -= ifcopenshell.util.selector.filter_elements(ifc_file, exclude)
+ elements -= ifcopenshell.util.selector.filter_elements(ifc_file, exclude)
return elements
@classmethod
diff --git a/src/bonsai/bonsai/tool/root.py b/src/bonsai/bonsai/tool/root.py
index 109af267d6..42bd558bd1 100644
--- a/src/bonsai/bonsai/tool/root.py
+++ b/src/bonsai/bonsai/tool/root.py
@@ -91,20 +91,21 @@ class Root(bonsai.core.tool.Root):
elif dest.is_a("IfcTypeProduct"):
if not source.RepresentationMaps:
return copied_entities
-
+
# Copy representation maps while preserving mapped representation structures
new_maps = []
for i, rep_map in enumerate(source.RepresentationMaps):
source_rep = rep_map.MappedRepresentation
-
# Copy the map itself
new_map = ifcopenshell.util.element.copy(tool.Ifc.get(), rep_map)
-
+
# Handle the mapped representation - preserve mapping structure if present
- if (source_rep.RepresentationType == 'MappedRepresentation' and
- len(source_rep.Items) == 1 and
- source_rep.Items[0].is_a("IfcMappedItem")):
+ if (
+ source_rep.RepresentationType == "MappedRepresentation"
+ and len(source_rep.Items) == 1
+ and source_rep.Items[0].is_a("IfcMappedItem")
+ ):
# This is a mapped representation - preserve the structure
new_rep = ifcopenshell.util.element.copy(tool.Ifc.get(), source_rep)
new_rep.Items = [ifcopenshell.util.element.copy(tool.Ifc.get(), item) for item in source_rep.Items]
@@ -118,9 +119,9 @@ class Root(bonsai.core.tool.Root):
exclude_callback=exclude_callback,
copied_entities=copied_entities,
)
-
+
new_maps.append(new_map)
-
+
dest.RepresentationMaps = new_maps
return copied_entities
diff --git a/src/bonsai/bonsai/tool/search.py b/src/bonsai/bonsai/tool/search.py
index 29e862b6b0..a0e2e17456 100644
--- a/src/bonsai/bonsai/tool/search.py
+++ b/src/bonsai/bonsai/tool/search.py
@@ -42,6 +42,38 @@ class Search(bonsai.core.tool.Search):
def get_group_query(cls, group: ifcopenshell.entity_instance) -> str:
return json.loads(group.Description)["query"]
+ @classmethod
+ def get_group_data(cls, group: ifcopenshell.entity_instance) -> dict:
+ return json.loads(group.Description)
+
+ @classmethod
+ def import_filter_structure(
+ cls, filter_structure: list, filter_groups: bpy.types.bpy_prop_collection_idprop[BIMFilterGroup]
+ ) -> None:
+ filter_groups.clear()
+
+ for group_data in filter_structure:
+ if not isinstance(group_data, list):
+ continue
+
+ filter_group = filter_groups.add()
+
+ for filter_data in group_data:
+ if not isinstance(filter_data, dict):
+ continue
+
+ ifc_filter = filter_group.filters.add()
+ ifc_filter.type = filter_data.get("type", "")
+ ifc_filter.name = filter_data.get("name", "")
+ ifc_filter.value = filter_data.get("value", "")
+ ifc_filter.pset = filter_data.get("pset", "")
+ ifc_filter.comparison = filter_data.get("comparison", "=")
+ filter_mode = filter_data.get("filter_mode", "ADD")
+ if filter_mode in ["ADD", "SUBTRACT", "FILTER"]:
+ ifc_filter.filter_mode = filter_mode
+ else:
+ ifc_filter.filter_mode = "ADD"
+
FilterModule = Union[Literal["search", "csv", "diff", "drawing_include", "drawing_exclude"], str]
@classmethod
@@ -80,53 +112,253 @@ class Search(bonsai.core.tool.Search):
for ifc_filter in filter_group.filters:
if not ifc_filter.value:
continue
- if ifc_filter.type == "instance":
- if "bpy.data.texts" in ifc_filter.value:
- data_name = ifc_filter.value.split("bpy.data.texts")[1][2:-2]
- filter_group_query.append(bpy.data.texts[data_name].as_string())
- else:
- filter_group_query.append(ifc_filter.value)
- elif ifc_filter.type == "entity":
- filter_group_query.append(ifc_filter.value)
- elif ifc_filter.type == "attribute":
- if not ifc_filter.name:
- continue
- comparison, value = cls.get_comparison_and_value(ifc_filter)
- filter_group_query.append(f"{ifc_filter.name}{comparison}{value}")
- elif ifc_filter.type == "type":
- comparison, value = cls.get_comparison_and_value(ifc_filter)
- filter_group_query.append(f"type{comparison}{value}")
- elif ifc_filter.type == "material":
- comparison, value = cls.get_comparison_and_value(ifc_filter)
- filter_group_query.append(f"material{comparison}{value}")
- elif ifc_filter.type == "property":
- if not ifc_filter.pset or not ifc_filter.name:
- continue
- pset = cls.wrap_value(ifc_filter, ifc_filter.pset)
- name = cls.wrap_value(ifc_filter, ifc_filter.name)
- comparison = ifc_filter.comparison
- value = cls.wrap_value(ifc_filter, ifc_filter.value)
- filter_group_query.append(f"{pset}.{name} {comparison} {value}")
- elif ifc_filter.type == "classification":
- comparison, value = cls.get_comparison_and_value(ifc_filter)
- filter_group_query.append(f"classification{comparison}{value}")
- elif ifc_filter.type == "location":
- comparison, value = cls.get_comparison_and_value(ifc_filter)
- filter_group_query.append(f"location{comparison}{value}")
- elif ifc_filter.type == "group":
- comparison, value = cls.get_comparison_and_value(ifc_filter)
- filter_group_query.append(f"group{comparison}{value}")
- elif ifc_filter.type == "parent":
- comparison, value = cls.get_comparison_and_value(ifc_filter)
- filter_group_query.append(f"parent{comparison}{value}")
- elif ifc_filter.type == "query":
- keys = cls.wrap_value(ifc_filter, ifc_filter.name)
- comparison = ifc_filter.comparison or "="
- value = cls.wrap_value(ifc_filter, ifc_filter.value)
- filter_group_query.append(f"query:{keys}{comparison}{value}")
- query.append(", ".join(filter_group_query))
+
+ query_part = cls._export_single_filter(ifc_filter)
+ if query_part:
+ filter_group_query.append(query_part)
+
+ if filter_group_query:
+ query.append(", ".join(filter_group_query))
return " + ".join(query)
+ @classmethod
+ def _export_single_filter(cls, ifc_filter: BIMFacet) -> str:
+ preferences = tool.Blender.get_addon_preferences()
+
+ if ifc_filter.type == "instance":
+ if "bpy.data.texts" in ifc_filter.value:
+ data_name = ifc_filter.value.split("bpy.data.texts")[1][2:-2]
+ value = bpy.data.texts[data_name].as_string()
+ else:
+ value = ifc_filter.value
+
+ if (
+ preferences.chain_filter_with_set_operations
+ or preferences.default_filter_with_set_operations_for_globalid_and_class
+ ):
+ value = value.lstrip("!")
+ if ifc_filter.filter_mode == "SUBTRACT":
+ value = f"!{value}"
+ return value
+
+ elif ifc_filter.type == "entity":
+ value = ifc_filter.value
+
+ if (
+ preferences.chain_filter_with_set_operations
+ or preferences.default_filter_with_set_operations_for_globalid_and_class
+ ):
+ value = value.lstrip("!")
+ if ifc_filter.filter_mode == "SUBTRACT":
+ value = f"!{value}"
+ return value
+ elif ifc_filter.type == "attribute":
+ if not ifc_filter.name:
+ return ""
+ comparison, value = cls.get_comparison_and_value(ifc_filter)
+ return f"{ifc_filter.name}{comparison}{value}"
+ elif ifc_filter.type == "type":
+ comparison, value = cls.get_comparison_and_value(ifc_filter)
+ return f"type{comparison}{value}"
+ elif ifc_filter.type == "material":
+ comparison, value = cls.get_comparison_and_value(ifc_filter)
+ return f"material{comparison}{value}"
+ elif ifc_filter.type == "property":
+ if not ifc_filter.pset or not ifc_filter.name:
+ return ""
+ pset = cls.wrap_value(ifc_filter, ifc_filter.pset)
+ name = cls.wrap_value(ifc_filter, ifc_filter.name)
+ comparison = ifc_filter.comparison
+ value = cls.wrap_value(ifc_filter, ifc_filter.value)
+ return f"{pset}.{name} {comparison} {value}"
+ elif ifc_filter.type == "classification":
+ comparison, value = cls.get_comparison_and_value(ifc_filter)
+ return f"classification{comparison}{value}"
+ elif ifc_filter.type == "location":
+ comparison, value = cls.get_comparison_and_value(ifc_filter)
+ return f"location{comparison}{value}"
+ elif ifc_filter.type == "group":
+ comparison, value = cls.get_comparison_and_value(ifc_filter)
+ return f"group{comparison}{value}"
+ elif ifc_filter.type == "parent":
+ comparison, value = cls.get_comparison_and_value(ifc_filter)
+ return f"parent{comparison}{value}"
+ elif ifc_filter.type == "query":
+ keys = cls.wrap_value(ifc_filter, ifc_filter.name)
+ comparison = ifc_filter.comparison or "="
+ value = cls.wrap_value(ifc_filter, ifc_filter.value)
+ return f"query:{keys}{comparison}{value}"
+ return ""
+
+ @classmethod
+ def execute_filter_groups(cls, filter_groups: bpy.types.bpy_prop_collection_idprop[BIMFilterGroup]) -> set:
+ """
+ Execute filter groups with simplified chaining support.
+ Within a single group chain, all filters chain sequentially with ADD/SUBTRACT/FILTER modes.
+ Groups are combined with union (same as original " + " behavior).
+ """
+ preferences = tool.Blender.get_addon_preferences()
+
+ all_group_results = []
+
+ for group_idx, filter_group in enumerate(filter_groups):
+ group_results = set()
+
+ for filter_index, ifc_filter in enumerate(filter_group.filters):
+ if not ifc_filter.value:
+ continue
+
+ query = cls._export_single_filter(ifc_filter)
+ if not query:
+ continue
+
+ if filter_index == 0:
+ mode = "ADD"
+ else:
+ if ifc_filter.type in ["entity", "instance"]:
+ if (
+ preferences.chain_filter_with_set_operations
+ or preferences.default_filter_with_set_operations_for_globalid_and_class
+ ):
+ mode = ifc_filter.filter_mode
+ else:
+ mode = "FILTER" if group_results else "ADD"
+ else:
+ if preferences.chain_filter_with_set_operations:
+ mode = ifc_filter.filter_mode
+ else:
+ mode = "FILTER" if group_results else "ADD"
+
+ if mode == "ADD":
+ results = ifcopenshell.util.selector.filter_elements(tool.Ifc.get(), query)
+ group_results.update(results)
+
+ elif mode == "SUBTRACT":
+ if group_results:
+ query_without_prefix = query[1:] if query.startswith("!") else query
+ elements_to_remove = ifcopenshell.util.selector.filter_elements(
+ tool.Ifc.get(), query_without_prefix, elements=group_results
+ )
+ group_results -= elements_to_remove
+ else:
+ results = ifcopenshell.util.selector.filter_elements(tool.Ifc.get(), query)
+ group_results.update(results)
+
+ elif mode == "FILTER":
+ if group_results:
+ results = ifcopenshell.util.selector.filter_elements(
+ tool.Ifc.get(), query, elements=group_results
+ )
+ group_results = results
+ else:
+ results = ifcopenshell.util.selector.filter_elements(tool.Ifc.get(), query)
+ group_results.update(results)
+
+ if group_results:
+ all_group_results.append(group_results)
+
+ final_results = set()
+ for group_results in all_group_results:
+ final_results.update(group_results)
+
+ return final_results
+
+ @classmethod
+ def execute_filter_groups_from_json(
+ cls, data: dict, ifc_file: ifcopenshell.file
+ ) -> set[ifcopenshell.entity_instance]:
+ """Execute filter groups from JSON data with filter_structure
+
+ This is used by drawing include/exclude to properly handle ADD/SUBTRACT/FILTER modes
+ without needing to instantiate Blender property groups.
+ """
+ filter_structure = data.get("filter_structure", [])
+
+ all_group_results = []
+ for group_data in filter_structure:
+ group_results = set()
+
+ for filter_data in group_data:
+ filter_mode = filter_data.get("filter_mode", "ADD")
+ filter_type = filter_data.get("type", "")
+ value = filter_data.get("value", "")
+
+ if not filter_type or not value:
+ continue
+
+ query_part = None
+ if filter_type == "entity":
+ query_part = value
+ elif filter_type == "attribute":
+ name = filter_data.get("name", "")
+ if not name:
+ continue
+ comparison = filter_data.get("comparison", "=")
+ query_part = f"{name}{comparison}{cls._wrap_json_value(value)}"
+ elif filter_type == "property":
+ pset = filter_data.get("pset", "")
+ name = filter_data.get("name", "")
+ if not pset or not name:
+ continue
+ comparison = filter_data.get("comparison", " = ")
+ wrapped_pset = cls._wrap_json_value(pset)
+ wrapped_name = cls._wrap_json_value(name)
+ wrapped_value = cls._wrap_json_value(value)
+ query_part = f"{wrapped_pset}.{wrapped_name} {comparison} {wrapped_value}"
+ elif filter_type == "type":
+ query_part = f"type={cls._wrap_json_value(value)}"
+ elif filter_type == "material":
+ query_part = f"material={cls._wrap_json_value(value)}"
+ elif filter_type == "classification":
+ query_part = f"classification={cls._wrap_json_value(value)}"
+ elif filter_type == "location":
+ query_part = f"location={cls._wrap_json_value(value)}"
+ elif filter_type == "group":
+ query_part = f"group={cls._wrap_json_value(value)}"
+ elif filter_type == "parent":
+ query_part = f"parent={cls._wrap_json_value(value)}"
+ elif filter_type == "query":
+ name = filter_data.get("name", "")
+ if not name:
+ continue
+ keys = cls._wrap_json_value(name)
+ comparison = filter_data.get("comparison", "=")
+ wrapped_value = cls._wrap_json_value(value)
+ query_part = f"query:{keys}{comparison}{wrapped_value}"
+ elif filter_type == "instance":
+ query_part = value
+
+ if not query_part:
+ continue
+
+ if filter_mode == "FILTER" and group_results:
+ results = ifcopenshell.util.selector.filter_elements(ifc_file, query_part, elements=group_results)
+ group_results = results
+ elif filter_mode == "SUBTRACT":
+ results = ifcopenshell.util.selector.filter_elements(ifc_file, query_part)
+ group_results -= results
+ else: # ADD
+ results = ifcopenshell.util.selector.filter_elements(ifc_file, query_part)
+ group_results.update(results)
+
+ if group_results:
+ all_group_results.append(group_results)
+
+ final_results = set()
+ for group_results in all_group_results:
+ final_results.update(group_results)
+
+ return final_results
+
+ @classmethod
+ def _wrap_json_value(cls, value: str) -> str:
+ """Wrap value for use in query string"""
+ if value.startswith("/") and value.endswith("/"):
+ return value
+ elif value in ("NULL", "TRUE", "FALSE"):
+ return value
+ return '"' + value.replace('"', '\\"') + '"'
+
@classmethod
def get_comparison_and_value(
cls, ifc_filter: BIMFacet
@@ -349,7 +581,8 @@ class ImportFilterQueryTransformer(lark.Transformer):
def facet_list(self, args):
new = self.filter_groups.add()
global_ids = []
- for arg in args:
+ is_first_group = len(self.filter_groups) == 1
+ for filter_index, arg in enumerate(args):
if arg["type"] == "instance" and global_ids:
if "bpy.data.texts" in new2.value:
data_name = new2.value.split("bpy.data.texts")[1][2:-2]
@@ -374,21 +607,26 @@ class ImportFilterQueryTransformer(lark.Transformer):
new2.pset = arg["pset"]
if "comparison" in arg:
new2.comparison = arg["comparison"] or "="
+ if "filter_mode" in arg:
+ new2.filter_mode = arg["filter_mode"]
+ elif not is_first_group and filter_index == 0 and arg["type"] in ("entity", "instance"):
+ if arg.get("filter_mode", "ADD") != "SUBTRACT":
+ new2.filter_mode = "FILTER"
def facet(self, args):
return args[0]
def instance(self, args):
if args[0].data == "not":
- return {"type": "instance", "value": "!" + args[1].children[0].value}
+ return {"type": "instance", "value": args[1].children[0].value, "filter_mode": "SUBTRACT"}
else:
- return {"type": "instance", "value": args[0].children[0].value}
+ return {"type": "instance", "value": args[0].children[0].value, "filter_mode": "ADD"}
def entity(self, args):
if args[0].data == "not":
- return {"type": "entity", "value": "!" + args[1].children[0].value}
+ return {"type": "entity", "value": args[1].children[0].value, "filter_mode": "SUBTRACT"}
else:
- return {"type": "entity", "value": args[0].children[0].value}
+ return {"type": "entity", "value": args[0].children[0].value, "filter_mode": "ADD"}
def attribute(self, args):
name, comparison, value = args
diff --git a/src/bonsai/pyproject.toml b/src/bonsai/pyproject.toml
index 3ec2cb8748..6dab8f3454 100644
--- a/src/bonsai/pyproject.toml
+++ b/src/bonsai/pyproject.toml
@@ -38,3 +38,8 @@ exclude = ["test*"]
[tool.ruff]
extend = "../../pyproject.toml"
+
+[tool.ruff.lint]
+ignore = [
+ "I", # import sorting - ignore it temporarily, still need to do some tests
+]
diff --git a/src/bonsai/test/core/test_unit.py b/src/bonsai/test/core/test_unit.py
index 2bbd783cc3..a7d73c755f 100644
--- a/src/bonsai/test/core/test_unit.py
+++ b/src/bonsai/test/core/test_unit.py
@@ -93,7 +93,6 @@ class TestAssignSceneUnits:
ifc.run("unit.assign_unit", units=["lengthunit", "areaunit", "volumeunit", "planeangleunit"]).should_be_called()
subject.assign_scene_units(ifc, unit)
-
def test_creating_metric_units_with_conversion_based_mass_and_time(self, ifc, unit):
unit.is_scene_unit_metric().should_be_called().will_return(True)
unit.get_scene_unit_si_prefix("LENGTHUNIT").should_be_called().will_return("MILLI")
diff --git a/src/bonsai/test/tool/test_drawing.py b/src/bonsai/test/tool/test_drawing.py
index 28f95614f8..960e283084 100644
--- a/src/bonsai/test/tool/test_drawing.py
+++ b/src/bonsai/test/tool/test_drawing.py
@@ -928,23 +928,24 @@ class TestAddReferenceImage(NewFile):
uv_node = material_nodes["Texture Coordinate"]
assert len(uv_node.outputs["Generated"].links[:]) == 1
+
class TestAddReference(NewFile):
def test_add_single_reference(self):
"""Test adding a single reference file (backward compatibility)"""
bpy.ops.bim.create_project()
ifc_path = Path("test/files/temp/test.ifc").absolute()
bpy.ops.bim.save_project(filepath=str(ifc_path), should_save_as=True)
-
+
# Create a temporary SVG file
svg_path = Path("test/files/temp/reference.svg").absolute()
svg_path.parent.mkdir(parents=True, exist_ok=True)
with open(svg_path, "w") as f:
f.write('')
-
+
try:
# Add single reference
bpy.ops.bim.add_reference(filepath=str(svg_path))
-
+
# Verify reference was added
ifc = tool.Ifc.get()
references = [doc for doc in ifc.by_type("IfcDocumentInformation") if doc.Scope == "REFERENCE"]
@@ -954,24 +955,24 @@ class TestAddReference(NewFile):
# Cleanup
if svg_path.exists():
svg_path.unlink()
-
+
def test_add_multiple_references(self):
"""Test adding multiple reference files at once"""
bpy.ops.bim.create_project()
ifc_path = Path("test/files/temp/test.ifc").absolute()
bpy.ops.bim.save_project(filepath=str(ifc_path), should_save_as=True)
-
+
# Create temporary SVG files
temp_dir = Path("test/files/temp").absolute()
temp_dir.mkdir(parents=True, exist_ok=True)
-
+
svg_files = []
for i in range(3):
svg_path = temp_dir / f"reference_{i}.svg"
with open(svg_path, "w") as f:
f.write('')
svg_files.append(svg_path)
-
+
try:
# Test by directly calling core.add_document multiple times
# (simulating what the operator does with multiple files)
@@ -979,12 +980,13 @@ class TestAddReference(NewFile):
for svg_file in svg_files:
uri = tool.Ifc.get_uri(str(svg_file), use_relative_path=True)
from bonsai.bim import core
+
core.drawing.add_document(tool.Ifc, tool.Drawing, "REFERENCE", uri=uri)
-
+
# Verify all references were added
references = [doc for doc in ifc.by_type("IfcDocumentInformation") if doc.Scope == "REFERENCE"]
assert len(references) == 3
-
+
reference_names = {ref.Name for ref in references}
expected_names = {f"reference_{i}" for i in range(3)}
assert reference_names == expected_names
diff --git a/src/bsdd/bsdd.py b/src/bsdd/bsdd.py
index 9a24d1dd1e..17480c87f5 100644
--- a/src/bsdd/bsdd.py
+++ b/src/bsdd/bsdd.py
@@ -17,15 +17,15 @@
# along with bSDD. If not, see .
from __future__ import annotations
-import uuid
+import http.server
import time
import urllib.parse
-import requests
+import uuid
import webbrowser
-import http.server
-from typing import TypedDict, Literal, Optional, TYPE_CHECKING, Any
-from typing_extensions import NotRequired
+from typing import TYPE_CHECKING, Any, Literal, Optional, TypedDict
+import requests
+from typing_extensions import NotRequired
if TYPE_CHECKING:
import ifcopenshell
diff --git a/src/bsdd/bsdd_json.py b/src/bsdd/bsdd_json.py
index 5edc8616fa..becaac810b 100644
--- a/src/bsdd/bsdd_json.py
+++ b/src/bsdd/bsdd_json.py
@@ -1,11 +1,13 @@
from __future__ import annotations
-from .type_hints import *
-from typing import Optional, Literal
-from datetime import datetime
-from pydantic import BaseModel, Field, PrivateAttr, model_validator, ConfigDict
import json
import weakref
+from datetime import datetime
+from typing import Literal, Optional
+
+from pydantic import BaseModel, ConfigDict, Field, PrivateAttr, model_validator
+
+from .type_hints import *
def _lower_first(s: str) -> str:
diff --git a/src/bsdd/pyproject.toml b/src/bsdd/pyproject.toml
index 76e0e5353a..d64d667a20 100644
--- a/src/bsdd/pyproject.toml
+++ b/src/bsdd/pyproject.toml
@@ -10,15 +10,16 @@ authors = [
]
description = "Library to interact with the buildingSMART Data Dictionary"
readme = "README.md"
-requires-python = ">=3.9"
+requires-python = ">=3.10"
keywords = ["IFC", "bSDD", "BIM"]
classifiers = [
"Development Status :: 4 - Beta",
"Programming Language :: Python",
- "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
+ "Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)",
diff --git a/src/bsdd/type_hints.py b/src/bsdd/type_hints.py
index b408e3b9a1..6f825cdd80 100644
--- a/src/bsdd/type_hints.py
+++ b/src/bsdd/type_hints.py
@@ -1,6 +1,5 @@
from typing import Literal
-
COUNTRY_CODE = Literal[
"AF",
"AX",
diff --git a/src/bsdd/yml_to_classes.py b/src/bsdd/yml_to_classes.py
index ba53917051..981d3c4439 100644
--- a/src/bsdd/yml_to_classes.py
+++ b/src/bsdd/yml_to_classes.py
@@ -1,8 +1,8 @@
-import yaml
import sys
from pathlib import Path
from typing import Any
+import yaml
type_to_python_type = {
"string": "str",
diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt
index be3a3e42d9..9e1e911cda 100644
--- a/src/examples/CMakeLists.txt
+++ b/src/examples/CMakeLists.txt
@@ -28,14 +28,6 @@ if(STANDALONE_PROJECT)
project(IfcOpenShellExamples)
set(CMAKE_CXX_STANDARD 17)
- set(Boost_USE_STATIC_LIBS ON)
- set(Boost_USE_STATIC_RUNTIME OFF)
- set(Boost_USE_MULTITHREADED ON)
- set(Boost_COMPONENTS system program_options regex thread date_time iostreams)
- find_package(Boost CONFIG REQUIRED COMPONENTS ${Boost_COMPONENTS})
- find_package(zstd CONFIG REQUIRED)
- find_package(RocksDB CONFIG REQUIRED)
- find_package(LibXml2 CONFIG REQUIRED)
find_package(IfcOpenShell CONFIG REQUIRED)
set(SCHEMA_VERSIONS ${IFCOPENSHELL_SCHEMA_VERSIONS})
set(WITH_OPENCASCADE ${IFCOPENSHELL_WITH_OPENCASCADE})
@@ -61,17 +53,6 @@ if(SCHEMA_VERSIONS MATCHES "2x3")
add_library(IfcHouseInterface INTERFACE)
if (STANDALONE_PROJECT)
- find_package(Eigen3 CONFIG REQUIRED)
- find_package(CGAL CONFIG REQUIRED)
- find_package(OpenCASCADE CONFIG REQUIRED)
-
- if(OpenCASCADE_VERSION VERSION_LESS "7.7.0")
- # cmake configs < 7.7.0 were not adding include directories to targets automatically.
- set_target_properties(TKernel PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${OpenCASCADE_INCLUDE_DIR}"
- )
- endif()
-
target_link_libraries(IfcHouseInterface INTERFACE IfcOpenShell::IfcParse IfcOpenShell::geometry_serializer)
else()
target_link_libraries(IfcHouseInterface INTERFACE IfcParse geometry_serializer)
diff --git a/src/ifc2ca/_deprecated/ca2ifc.py b/src/ifc2ca/_deprecated/ca2ifc.py
index 5f9115396e..0f55d9d6d3 100644
--- a/src/ifc2ca/_deprecated/ca2ifc.py
+++ b/src/ifc2ca/_deprecated/ca2ifc.py
@@ -17,11 +17,12 @@
# along with Ifc2CA. If not, see .
import json
-import ifcopenshell
-import ifcopenshell.guid
import os
from datetime import datetime
+import ifcopenshell
+import ifcopenshell.guid
+
class CA2IFC:
def __init__(self, inputFilename, outputFilename):
diff --git a/src/ifc2ca/_deprecated/scriptCodeAsterBonded.py b/src/ifc2ca/_deprecated/scriptCodeAsterBonded.py
index 005e28fa4c..0b1184453b 100644
--- a/src/ifc2ca/_deprecated/scriptCodeAsterBonded.py
+++ b/src/ifc2ca/_deprecated/scriptCodeAsterBonded.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Ifc2CA. If not, see .
-import json
-import numpy as np
import itertools
+import json
from pathlib import Path
+import numpy as np
+
flatten = itertools.chain.from_iterable
ScaleFactor = 1.0
diff --git a/src/ifc2ca/_deprecated/scriptSalomeBonded.py b/src/ifc2ca/_deprecated/scriptSalomeBonded.py
index a1c6030956..fb2bd575f9 100644
--- a/src/ifc2ca/_deprecated/scriptSalomeBonded.py
+++ b/src/ifc2ca/_deprecated/scriptSalomeBonded.py
@@ -16,15 +16,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Ifc2CA. If not, see .
+import itertools
+import json
import os
import time
-import json
+from pathlib import Path
+
+import numpy as np
import salome
import salome_notebook
import salome_version
-import numpy as np
-import itertools
-from pathlib import Path
flatten = itertools.chain.from_iterable
@@ -155,10 +156,11 @@ class MODEL:
###
### GEOM component
###
- import GEOM
- from salome.geom import geomBuilder
import math
+
+ import GEOM
import SALOMEDS
+ from salome.geom import geomBuilder
gg = salome.ImportComponentGUI("GEOM")
if NEW_SALOME:
diff --git a/src/ifc2ca/ifc2ca.py b/src/ifc2ca/ifc2ca.py
index f8908b0aa7..728df67d45 100644
--- a/src/ifc2ca/ifc2ca.py
+++ b/src/ifc2ca/ifc2ca.py
@@ -17,6 +17,7 @@
# along with Ifc2CA. If not, see .
from __future__ import annotations
+
import json
import os
import subprocess
diff --git a/src/ifc4d/__main__.py b/src/ifc4d/__main__.py
index d7e2a58307..8313ba7464 100644
--- a/src/ifc4d/__main__.py
+++ b/src/ifc4d/__main__.py
@@ -1,13 +1,12 @@
+import argparse
import os
import sys
-import argparse
+import ifcopenshell
+from ifc4d.msp2ifc import MSP2Ifc
from ifc4d.p6xer2ifc import P6XER2Ifc
from ifc4d.p62ifc import P62Ifc
-from ifc4d.msp2ifc import MSP2Ifc
from ifc4d.pp2ifc import PP2Ifc
-import ifcopenshell
-
parser = argparse.ArgumentParser()
parser.add_argument("-f", "--file", action="store", type=str, required=True, help="schedule file name to be parsed")
diff --git a/src/ifc4d/ifc4d/common.py b/src/ifc4d/ifc4d/common.py
index d13840267a..f4fd42e1d1 100644
--- a/src/ifc4d/ifc4d/common.py
+++ b/src/ifc4d/ifc4d/common.py
@@ -1,12 +1,14 @@
from __future__ import annotations
+
+from datetime import date, datetime, timedelta
+from typing import Any, TypedDict, Union
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.control
import ifcopenshell.api.resource
import ifcopenshell.api.sequence
import ifcopenshell.util.date
-from datetime import datetime, timedelta, date
-from typing import Union, Any, TypedDict
from typing_extensions import NotRequired
diff --git a/src/ifc4d/ifc4d/csv2ifc.py b/src/ifc4d/ifc4d/csv2ifc.py
index 1233734290..6efbf4fad6 100644
--- a/src/ifc4d/ifc4d/csv2ifc.py
+++ b/src/ifc4d/ifc4d/csv2ifc.py
@@ -17,23 +17,24 @@
# along with IfcResources. If not, see .
from __future__ import annotations
-import csv
+
import _csv
-import ifcopenshell.api.resource
-import isodate
+import csv
+import datetime
+from typing import Any, Literal, NamedTuple, Optional, Union, cast, get_args
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.cost
import ifcopenshell.api.pset
+import ifcopenshell.api.resource
import ifcopenshell.api.root
import ifcopenshell.api.unit
import ifcopenshell.util.date
import ifcopenshell.util.element
import ifcopenshell.util.resource
import ifcopenshell.util.unit
-import datetime
-from typing import Any, Optional, Union, Literal, get_args, NamedTuple, cast
-
+import isodate
SUPPORTED_COLUMN = Literal[
"HIERARCHY",
diff --git a/src/ifc4d/ifc4d/csv4d2ifc.py b/src/ifc4d/ifc4d/csv4d2ifc.py
index 9a33ea8198..2e519cc0ea 100644
--- a/src/ifc4d/ifc4d/csv4d2ifc.py
+++ b/src/ifc4d/ifc4d/csv4d2ifc.py
@@ -18,13 +18,14 @@
import csv
+import locale
+import re
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.root
import ifcopenshell.api.sequence
import ifcopenshell.util.date
-import locale
-import re
class Csv2Ifc:
diff --git a/src/ifc4d/ifc4d/ifc2msp.py b/src/ifc4d/ifc4d/ifc2msp.py
index e7d540dd3a..a685f689dc 100644
--- a/src/ifc4d/ifc4d/ifc2msp.py
+++ b/src/ifc4d/ifc4d/ifc2msp.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Ifc4D. If not, see .
-import uuid
import datetime
+import uuid
+import xml.etree.ElementTree as ET
+
import ifcopenshell
import ifcopenshell.util.date
import ifcopenshell.util.sequence
-import xml.etree.ElementTree as ET
class Ifc2Msp:
diff --git a/src/ifc4d/ifc4d/ifc2p6.py b/src/ifc4d/ifc4d/ifc2p6.py
index 1d4bfea195..5093f306be 100644
--- a/src/ifc4d/ifc4d/ifc2p6.py
+++ b/src/ifc4d/ifc4d/ifc2p6.py
@@ -16,12 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Ifc4D. If not, see .
-import uuid
import datetime
+import uuid
+import xml.etree.ElementTree as ET
+
import ifcopenshell
import ifcopenshell.util.date
import ifcopenshell.util.sequence
-import xml.etree.ElementTree as ET
+
from .common import ScheduleIfcGenerator
diff --git a/src/ifc4d/ifc4d/msp2ifc.py b/src/ifc4d/ifc4d/msp2ifc.py
index 2285a1a1ea..3ba14a6985 100644
--- a/src/ifc4d/ifc4d/msp2ifc.py
+++ b/src/ifc4d/ifc4d/msp2ifc.py
@@ -17,7 +17,9 @@
# along with Ifc4D. If not, see .
import datetime
-from datetime import timedelta, date
+import xml.etree.ElementTree as ET
+from datetime import date, timedelta
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.control
@@ -25,7 +27,6 @@ import ifcopenshell.api.pset
import ifcopenshell.api.root
import ifcopenshell.api.sequence
import ifcopenshell.util.date
-import xml.etree.ElementTree as ET
class MSP2Ifc:
diff --git a/src/ifc4d/ifc4d/p62ifc.py b/src/ifc4d/ifc4d/p62ifc.py
index aeb4338c07..833bf39dd3 100644
--- a/src/ifc4d/ifc4d/p62ifc.py
+++ b/src/ifc4d/ifc4d/p62ifc.py
@@ -16,12 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Ifc4D. If not, see .
-import math
import datetime
+import math
+import xml.etree.ElementTree as ET
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.date
-import xml.etree.ElementTree as ET
+
from .common import ScheduleIfcGenerator
diff --git a/src/ifc4d/ifc4d/p6xer2ifc.py b/src/ifc4d/ifc4d/p6xer2ifc.py
index 9e8bd1bfd9..ef218ade2d 100644
--- a/src/ifc4d/ifc4d/p6xer2ifc.py
+++ b/src/ifc4d/ifc4d/p6xer2ifc.py
@@ -16,11 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Ifc4D. If not, see .
-from xerparser.reader import Reader
+from datetime import date, datetime, timedelta
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.date
-from datetime import datetime, timedelta, date
+from xerparser.reader import Reader
+
from .common import ScheduleIfcGenerator
diff --git a/src/ifc4d/ifc4d/pp2ifc.py b/src/ifc4d/ifc4d/pp2ifc.py
index 5ce9b68b48..338a887e91 100644
--- a/src/ifc4d/ifc4d/pp2ifc.py
+++ b/src/ifc4d/ifc4d/pp2ifc.py
@@ -5,16 +5,17 @@ import sys
print("In module products sys.path[0], __package__ ==", sys.path[0], __package__)
sys.path.append(sys.path[0])
-import sqlite3
import datetime
-from datetime import timedelta
-import ifcopenshell.util.date
-from .wpattern import AstaCalendarWorkPattern
-from .common import ScheduleIfcGenerator, Calendar, WBSEntry, Activity
+import sqlite3
import time
from collections import defaultdict
+from datetime import timedelta
from typing import Any
+import ifcopenshell.util.date
+
+from .common import Activity, Calendar, ScheduleIfcGenerator, WBSEntry
+from .wpattern import AstaCalendarWorkPattern
list_of_tables = [
"BAR",
diff --git a/src/ifc4d/ifc4d/wpattern.py b/src/ifc4d/ifc4d/wpattern.py
index cbadad53e0..0c2cc265b9 100644
--- a/src/ifc4d/ifc4d/wpattern.py
+++ b/src/ifc4d/ifc4d/wpattern.py
@@ -6,13 +6,11 @@ for each day as a key there is a list of working times with the format
"""
-import sys
import re
-from datetime import time, datetime
+from datetime import datetime, time
from typing import Any
-from ifc4d.common import WorkSlot
-ZIP_STRICT = {} if sys.version_info < (3, 10) else {"strict": True}
+from ifc4d.common import WorkSlot
class AstaCalendarWorkPattern:
@@ -123,7 +121,7 @@ class AstaCalendarWorkPattern:
self.values = self.get_values(string)
self.dict_wp: list[WorkSlot] = []
- for value, day_name in zip(self.values[1:], self.day_names, **ZIP_STRICT):
+ for value, day_name in zip(self.values[1:], self.day_names, strict=True):
splt_data = value.strip().split(",")
workhours: list[dict[str, Any]] = []
if len(splt_data) >= 7:
diff --git a/src/ifc5d/ifc5d/csv2ifc.py b/src/ifc5d/ifc5d/csv2ifc.py
index 6e0cb7b5ea..b1edd82d88 100644
--- a/src/ifc5d/ifc5d/csv2ifc.py
+++ b/src/ifc5d/ifc5d/csv2ifc.py
@@ -17,19 +17,21 @@
# along with Ifc5D. If not, see .
from __future__ import annotations
+
import csv
+import locale
+from pathlib import Path
+from typing import Optional, TypedDict, Union
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.control
import ifcopenshell.api.cost
import ifcopenshell.api.root
-import ifcopenshell.util.unit
-import ifcopenshell.util.selector
-import ifcopenshell.util.element
import ifcopenshell.util.cost
-import locale
-from pathlib import Path
-from typing import Union, Optional, TypedDict
+import ifcopenshell.util.element
+import ifcopenshell.util.selector
+import ifcopenshell.util.unit
from typing_extensions import NotRequired
diff --git a/src/ifc5d/ifc5d/ifc2json.py b/src/ifc5d/ifc5d/ifc2json.py
index fae04126af..3b184ca1c7 100644
--- a/src/ifc5d/ifc5d/ifc2json.py
+++ b/src/ifc5d/ifc5d/ifc2json.py
@@ -1,11 +1,11 @@
-import ifcopenshell
-import ifcopenshell.util.unit
from typing import Any
+
+import ifcopenshell
import ifcopenshell.util.cost
import ifcopenshell.util.date
+import ifcopenshell.util.unit
from ifcopenshell.util.classification import get_references
-
CostItem = dict[str, Any]
diff --git a/src/ifc5d/ifc5d/ifc5Dspreadsheet.py b/src/ifc5d/ifc5d/ifc5Dspreadsheet.py
index 369232c401..324340fb1c 100644
--- a/src/ifc5d/ifc5d/ifc5Dspreadsheet.py
+++ b/src/ifc5d/ifc5d/ifc5Dspreadsheet.py
@@ -18,18 +18,20 @@
from __future__ import annotations
-import os
-import time
+
import argparse
import datetime
import logging
+import os
+import time
+from collections import Counter
+from typing import Any, Optional, TypedDict, Union
+
import ifcopenshell
-import ifcopenshell.util.element
import ifcopenshell.util.cost
import ifcopenshell.util.date
+import ifcopenshell.util.element
import ifcopenshell.util.unit
-from collections import Counter
-from typing import Union, Optional, Any, TypedDict
class CostItem(TypedDict):
@@ -418,9 +420,9 @@ class Ifc5DCsvWriter(Ifc5Dwriter):
class Ifc5DOdsWriter(Ifc5Dwriter):
def write(self) -> None:
+ from odf.number import CurrencyStyle, CurrencySymbol, Number, NumberStyle, Text
from odf.opendocument import OpenDocumentSpreadsheet
from odf.style import Style, TableCellProperties
- from odf.number import NumberStyle, CurrencyStyle, CurrencySymbol, Number, Text
super().write()
@@ -448,9 +450,9 @@ class Ifc5DOdsWriter(Ifc5Dwriter):
self.doc.save(os.path.join(self.output, file_name), True)
def write_table(self, cost_schedule):
- from odf.table import Table, TableRow, TableCell
+ from odf.number import CurrencyStyle, CurrencySymbol, Number, NumberStyle, Text
+ from odf.table import Table, TableCell, TableRow
from odf.text import P
- from odf.number import NumberStyle, CurrencyStyle, CurrencySymbol, Number, Text
def row():
return TableRow()
@@ -594,11 +596,13 @@ class Ifc5DPdfWriter(Ifc5Dwriter):
def write(self) -> None:
import os
- import ifc5d
import shutil
- import typst
import tempfile
+ import typst
+
+ import ifc5d
+
DEFAULT_OPTIONS = {
"nested_structure_depth": 0,
"parent_to_new_page_up_to_depth": 0,
diff --git a/src/ifc5d/ifc5d/qto.py b/src/ifc5d/ifc5d/qto.py
index 67e5478ef1..f7fba8d9e5 100644
--- a/src/ifc5d/ifc5d/qto.py
+++ b/src/ifc5d/ifc5d/qto.py
@@ -18,24 +18,25 @@
import functools
import itertools
+import json
+import multiprocessing
import os
import types
-import json
+from collections import defaultdict
+from collections.abc import Iterable
+from typing import Any, Literal, NamedTuple, Union, get_args
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.pset
import ifcopenshell.geom
import ifcopenshell.ifcopenshell_wrapper as W
-import ifcopenshell.util.unit
import ifcopenshell.util.element
+import ifcopenshell.util.representation
import ifcopenshell.util.selector
import ifcopenshell.util.shape
-import ifcopenshell.util.representation
import ifcopenshell.util.type
-import multiprocessing
-from collections import defaultdict
-from typing import Any, Literal, get_args, Union, NamedTuple
-from collections.abc import Iterable
+import ifcopenshell.util.unit
class Function(NamedTuple):
@@ -545,8 +546,8 @@ class Blender(QtoCalculator):
@classmethod
def calculate(cls, ifc_file, elements, qtos, results):
- import bonsai.tool as tool
import bonsai.bim.module.qto.calculator as calculator
+ import bonsai.tool as tool
unit_converter = SI2ProjectUnitConverter(ifc_file)
formula_functions: dict[str, types.FunctionType] = {}
diff --git a/src/ifc5d/test/test_csv2ifc.py b/src/ifc5d/test/test_csv2ifc.py
index 49858ba386..7dc1bbd718 100644
--- a/src/ifc5d/test/test_csv2ifc.py
+++ b/src/ifc5d/test/test_csv2ifc.py
@@ -16,17 +16,18 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import tempfile
import csv
-import pytest
+import tempfile
+from pathlib import Path
+
+import ifc5d.csv2ifc
+import ifc5d.ifc5Dspreadsheet
import ifcopenshell
import ifcopenshell.api.root
import ifcopenshell.api.unit
import ifcopenshell.util.cost
import ifcopenshell.util.element
-import ifc5d.csv2ifc
-import ifc5d.ifc5Dspreadsheet
-from pathlib import Path
+import pytest
class TestCsv2Ifc:
diff --git a/src/ifcbimtester/bimtester/__init__.py b/src/ifcbimtester/bimtester/__init__.py
index d76bea9460..180dbfaa6f 100644
--- a/src/ifcbimtester/bimtester/__init__.py
+++ b/src/ifcbimtester/bimtester/__init__.py
@@ -16,8 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with BIMTester. If not, see .
-from os.path import dirname
-from os.path import realpath
+from os.path import dirname, realpath
__version__ = version = "0.0.0"
diff --git a/src/ifcbimtester/bimtester/clean.py b/src/ifcbimtester/bimtester/clean.py
index f457da2a59..d681a9fe29 100644
--- a/src/ifcbimtester/bimtester/clean.py
+++ b/src/ifcbimtester/bimtester/clean.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with BIMTester. If not, see .
-import ifcopenshell
import os
from pathlib import Path
+import ifcopenshell
+
class TestPurger:
def __init__(self):
diff --git a/src/ifcbimtester/bimtester/features/environment.py b/src/ifcbimtester/bimtester/features/environment.py
index dc249f32d5..d9576dc885 100644
--- a/src/ifcbimtester/bimtester/features/environment.py
+++ b/src/ifcbimtester/bimtester/features/environment.py
@@ -17,15 +17,12 @@
# along with BIMTester. If not, see .
import os
-from behave.model import Scenario
+from behave.model import Scenario
from bimtester.ifc import IfcStore
from bimtester.lang import switch_locale
-from logfile import append_logfile
-from logfile import create_logfile
-from zoom_smart_view import add_smartview
-from zoom_smart_view import create_zoom_set_of_smartviews
-
+from logfile import append_logfile, create_logfile
+from zoom_smart_view import add_smartview, create_zoom_set_of_smartviews
this_path = os.path.dirname(os.path.realpath(__file__))
diff --git a/src/ifcbimtester/bimtester/features/steps/aggregation/en.py b/src/ifcbimtester/bimtester/features/steps/aggregation/en.py
index 70568d42cb..a2bbe621a1 100644
--- a/src/ifcbimtester/bimtester/features/steps/aggregation/en.py
+++ b/src/ifcbimtester/bimtester/features/steps/aggregation/en.py
@@ -16,8 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with BIMTester. If not, see .
-from behave import step, given, when, then, use_step_matcher
-
+from behave import given, step, then, use_step_matcher, when
from bimtester import util
from bimtester.ifc import IfcStore
from bimtester.table import TableModel
diff --git a/src/ifcbimtester/bimtester/features/steps/all.py b/src/ifcbimtester/bimtester/features/steps/all.py
index a525eccf00..6c46e6450d 100644
--- a/src/ifcbimtester/bimtester/features/steps/all.py
+++ b/src/ifcbimtester/bimtester/features/steps/all.py
@@ -26,7 +26,7 @@ use_step_matcher("parse")
from bimtester.features.steps.attributes_eleclasses import de, en
use_step_matcher("parse")
-from bimtester.features.steps.attributes_psets import en, de
+from bimtester.features.steps.attributes_psets import de, en
use_step_matcher("parse")
from bimtester.features.steps.attributes_qsets import en
diff --git a/src/ifcbimtester/bimtester/features/steps/application/en.py b/src/ifcbimtester/bimtester/features/steps/application/en.py
index b2dbd5ffe7..9e40eb99b4 100644
--- a/src/ifcbimtester/bimtester/features/steps/application/en.py
+++ b/src/ifcbimtester/bimtester/features/steps/application/en.py
@@ -17,7 +17,6 @@
# along with BIMTester. If not, see .
from behave import step
-
from bimtester.ifc import IfcStore
from bimtester.lang import _
diff --git a/src/ifcbimtester/bimtester/features/steps/attributes_eleclasses/en.py b/src/ifcbimtester/bimtester/features/steps/attributes_eleclasses/en.py
index f141eaee23..e032207acf 100644
--- a/src/ifcbimtester/bimtester/features/steps/attributes_eleclasses/en.py
+++ b/src/ifcbimtester/bimtester/features/steps/attributes_eleclasses/en.py
@@ -17,9 +17,7 @@
# along with BIMTester. If not, see .
import ifcopenshell.util.element as eleutils
-
from behave import step
-
from bimtester import util
from bimtester.ifc import IfcStore
from bimtester.lang import _
diff --git a/src/ifcbimtester/bimtester/features/steps/attributes_psets/en.py b/src/ifcbimtester/bimtester/features/steps/attributes_psets/en.py
index 6141213801..d9b41eb10a 100644
--- a/src/ifcbimtester/bimtester/features/steps/attributes_psets/en.py
+++ b/src/ifcbimtester/bimtester/features/steps/attributes_psets/en.py
@@ -16,9 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with BIMTester. If not, see .
-from behave import step
-from behave import use_step_matcher
-
+from behave import step, use_step_matcher
from bimtester import util
from bimtester.ifc import IfcStore
from bimtester.lang import _
@@ -48,6 +46,7 @@ def step_impl(context, ifc_class, property_path):
)
def step_impl(context, ifc_class, property_path, pattern):
import re
+
from ifcopenshell.util.element import get_psets
pset_name, property_name = property_path.split(".")
diff --git a/src/ifcbimtester/bimtester/features/steps/classification/en.py b/src/ifcbimtester/bimtester/features/steps/classification/en.py
index 356d9cfd36..461b6b91e2 100644
--- a/src/ifcbimtester/bimtester/features/steps/classification/en.py
+++ b/src/ifcbimtester/bimtester/features/steps/classification/en.py
@@ -17,8 +17,8 @@
# along with BIMTester. If not, see .
import json
-from behave import step
+from behave import step
from bimtester import util
from bimtester.ifc import IfcStore
from bimtester.lang import _
diff --git a/src/ifcbimtester/bimtester/features/steps/element_classes/en.py b/src/ifcbimtester/bimtester/features/steps/element_classes/en.py
index e41c0aad05..035ff05cf2 100644
--- a/src/ifcbimtester/bimtester/features/steps/element_classes/en.py
+++ b/src/ifcbimtester/bimtester/features/steps/element_classes/en.py
@@ -17,7 +17,6 @@
# along with BIMTester. If not, see .
from behave import step
-
from bimtester import util
from bimtester.ifc import IfcStore
from bimtester.lang import _
diff --git a/src/ifcbimtester/bimtester/features/steps/geocoding/en.py b/src/ifcbimtester/bimtester/features/steps/geocoding/en.py
index c9b4007d49..de0204ba55 100644
--- a/src/ifcbimtester/bimtester/features/steps/geocoding/en.py
+++ b/src/ifcbimtester/bimtester/features/steps/geocoding/en.py
@@ -17,7 +17,6 @@
# along with BIMTester. If not, see .
from behave import step, use_step_matcher
-
from bimtester import util
from bimtester.ifc import IfcStore
from bimtester.lang import _
diff --git a/src/ifcbimtester/bimtester/features/steps/geolocation/en.py b/src/ifcbimtester/bimtester/features/steps/geolocation/en.py
index 13aa359671..40568b6fe4 100644
--- a/src/ifcbimtester/bimtester/features/steps/geolocation/en.py
+++ b/src/ifcbimtester/bimtester/features/steps/geolocation/en.py
@@ -17,14 +17,13 @@
# along with BIMTester. If not, see .
import math
-import numpy as np
+
import ifcopenshell
import ifcopenshell.util.element
-import ifcopenshell.util.placement
import ifcopenshell.util.geolocation
-
+import ifcopenshell.util.placement
+import numpy as np
from behave import step
-
from bimtester import util
from bimtester.ifc import IfcStore
from bimtester.lang import _
diff --git a/src/ifcbimtester/bimtester/features/steps/geometric_detail/en.py b/src/ifcbimtester/bimtester/features/steps/geometric_detail/en.py
index 153cca30b5..5179a1d726 100644
--- a/src/ifcbimtester/bimtester/features/steps/geometric_detail/en.py
+++ b/src/ifcbimtester/bimtester/features/steps/geometric_detail/en.py
@@ -17,7 +17,6 @@
# along with BIMTester. If not, see .
from behave import step
-
from bimtester import util
from bimtester.ifc import IfcStore
from bimtester.lang import _
diff --git a/src/ifcbimtester/bimtester/features/steps/model_federation/en.py b/src/ifcbimtester/bimtester/features/steps/model_federation/en.py
index af0edc0975..db76d08484 100644
--- a/src/ifcbimtester/bimtester/features/steps/model_federation/en.py
+++ b/src/ifcbimtester/bimtester/features/steps/model_federation/en.py
@@ -18,9 +18,7 @@
import ifcopenshell.util.geolocation
import ifcopenshell.util.placement
-
from behave import step
-
from bimtester import util
from bimtester.ifc import IfcStore
from bimtester.lang import _
diff --git a/src/ifcbimtester/bimtester/features/steps/project_setup/en.py b/src/ifcbimtester/bimtester/features/steps/project_setup/en.py
index 84e3e84f58..c86990eb7d 100644
--- a/src/ifcbimtester/bimtester/features/steps/project_setup/en.py
+++ b/src/ifcbimtester/bimtester/features/steps/project_setup/en.py
@@ -17,7 +17,6 @@
# along with BIMTester. If not, see .
from behave import step
-
from bimtester import util
from bimtester.ifc import IfcStore
from bimtester.lang import _
diff --git a/src/ifcbimtester/bimtester/features/steps/spatial_structure/en.py b/src/ifcbimtester/bimtester/features/steps/spatial_structure/en.py
index 5eee990077..f57efa1713 100644
--- a/src/ifcbimtester/bimtester/features/steps/spatial_structure/en.py
+++ b/src/ifcbimtester/bimtester/features/steps/spatial_structure/en.py
@@ -17,7 +17,6 @@
# along with BIMTester. If not, see .
from behave import step
-
from bimtester.ifc import IfcStore
from bimtester.lang import _
diff --git a/src/ifcbimtester/bimtester/guiwidget.py b/src/ifcbimtester/bimtester/guiwidget.py
index b9b02e81af..9c41a78b7e 100644
--- a/src/ifcbimtester/bimtester/guiwidget.py
+++ b/src/ifcbimtester/bimtester/guiwidget.py
@@ -16,18 +16,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with BIMTester. If not, see .
-import os
import json
+import os
import sys
import webbrowser
+from PySide2 import QtCore, QtGui, QtWidgets
+
import bimtester.reports
import bimtester.run
-from PySide2 import QtCore
-from PySide2 import QtGui
-from PySide2 import QtWidgets
-
def run():
app = QtWidgets.QApplication(sys.argv)
diff --git a/src/ifcbimtester/bimtester/reports.py b/src/ifcbimtester/bimtester/reports.py
index df237f631b..2c250c7f85 100644
--- a/src/ifcbimtester/bimtester/reports.py
+++ b/src/ifcbimtester/bimtester/reports.py
@@ -19,8 +19,10 @@
import datetime
import json
import os
-import pystache
import sys
+
+import pystache
+
from bimtester.lang import _
diff --git a/src/ifcbimtester/bimtester/run.py b/src/ifcbimtester/bimtester/run.py
index 5f0d58bd18..f4684cfb78 100644
--- a/src/ifcbimtester/bimtester/run.py
+++ b/src/ifcbimtester/bimtester/run.py
@@ -16,27 +16,29 @@
# You should have received a copy of the GNU Lesser General Public License
# along with BIMTester. If not, see .
-import os
-import sys
import json
-import shutil
import logging
+import os
+import shutil
+import sys
import tempfile
+
import ifcopenshell
try:
import ifcopenshell.express
except:
pass # They are using an old version of IfcOpenShell. Gracefully degrade for now.
-import behave.formatter.pretty # Needed for pyinstaller to package it
-from bimtester.ifc import IfcStore
from distutils.dir_util import copy_tree
-from behave.__main__ import main as behave_main
-
# TODO: refactor when this isn't super experimental
from logging import StreamHandler
+import behave.formatter.pretty # Needed for pyinstaller to package it
+from behave.__main__ import main as behave_main
+
+from bimtester.ifc import IfcStore
+
class TestRunner:
def __init__(self, ifc_path, schema_path=None, ifc=None):
diff --git a/src/ifcbimtester/bimtester/util.py b/src/ifcbimtester/bimtester/util.py
index a9e09b0b8e..16bdf06aa6 100644
--- a/src/ifcbimtester/bimtester/util.py
+++ b/src/ifcbimtester/bimtester/util.py
@@ -16,10 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with BIMTester. If not, see .
+import json
+
import ifcopenshell
import ifcopenshell.util.element
import ifcopenshell.validate
-import json
+
from bimtester.lang import _
diff --git a/src/ifcbimtester/cli.py b/src/ifcbimtester/cli.py
index f091fc27ae..7172b62023 100644
--- a/src/ifcbimtester/cli.py
+++ b/src/ifcbimtester/cli.py
@@ -19,8 +19,9 @@
# along with BIMTester. If not, see .
-import os
import argparse
+import os
+
import bimtester.clean
import bimtester.reports
import bimtester.run
diff --git a/src/ifcbimtester/examples/steps/aggregation.py b/src/ifcbimtester/examples/steps/aggregation.py
index 67435eee62..ccf46b5e0d 100644
--- a/src/ifcbimtester/examples/steps/aggregation.py
+++ b/src/ifcbimtester/examples/steps/aggregation.py
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with BIMTester. If not, see .
-from behave import step, given, when, then, use_step_matcher
+from behave import given, step, then, use_step_matcher, when
use_step_matcher("parse")
diff --git a/src/ifcbimtester/examples/steps/attributes_eleclasses.py b/src/ifcbimtester/examples/steps/attributes_eleclasses.py
index 466eff15c2..ed5475ac65 100644
--- a/src/ifcbimtester/examples/steps/attributes_eleclasses.py
+++ b/src/ifcbimtester/examples/steps/attributes_eleclasses.py
@@ -17,10 +17,8 @@
# along with BIMTester. If not, see .
from behave import step
-
from utils import IfcFile
-
use_step_matcher("re")
diff --git a/src/ifcbimtester/gui.py b/src/ifcbimtester/gui.py
index 1fe0c6b674..6c5ada241b 100644
--- a/src/ifcbimtester/gui.py
+++ b/src/ifcbimtester/gui.py
@@ -21,5 +21,4 @@
from bimtester.guiwidget import run
-
run()
diff --git a/src/ifcblender/io_import_scene_ifc/__init__.py b/src/ifcblender/io_import_scene_ifc/__init__.py
index 29834b2356..c85864a6de 100644
--- a/src/ifcblender/io_import_scene_ifc/__init__.py
+++ b/src/ifcblender/io_import_scene_ifc/__init__.py
@@ -40,17 +40,18 @@ if "bpy" in locals():
if "ifcopenshell" in locals():
importlib.reload(ifcopenshell)
+import logging
+import os
+from collections import defaultdict
+
+import bpy
+import mathutils
from bpy.props import (
BoolProperty,
IntProperty,
StringProperty,
)
from bpy_extras.io_utils import ImportHelper
-from collections import defaultdict
-import bpy
-import logging
-import mathutils
-import os
major, minor = bpy.app.version[0:2]
transpose_matrices = minor >= 62
diff --git a/src/ifccityjson/ifccityjson/__main__.py b/src/ifccityjson/ifccityjson/__main__.py
index 284560b288..6a9e5e9881 100644
--- a/src/ifccityjson/ifccityjson/__main__.py
+++ b/src/ifccityjson/ifccityjson/__main__.py
@@ -17,7 +17,9 @@
# along with ifccityjson. If not, see .
import argparse
+
from cjio import cityjson
+
from .cityjson2ifc import Cityjson2ifc
diff --git a/src/ifccityjson/ifccityjson/cityjson2ifc/cityjson2ifc.py b/src/ifccityjson/ifccityjson/cityjson2ifc/cityjson2ifc.py
index 441855baf4..f26f5c89d6 100644
--- a/src/ifccityjson/ifccityjson/cityjson2ifc/cityjson2ifc.py
+++ b/src/ifccityjson/ifccityjson/cityjson2ifc/cityjson2ifc.py
@@ -18,6 +18,8 @@
# along with ifccityjson. If not, see .
import os
+from datetime import datetime
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.context
@@ -26,10 +28,9 @@ import ifcopenshell.api.pset
import ifcopenshell.api.root
import ifcopenshell.api.unit
import ifcopenshell.guid
-from datetime import datetime
-from .geometry import GeometryIO
from . import __version__
+from .geometry import GeometryIO
JSON_TO_IFC = {
"Building": ["IfcBuilding"],
diff --git a/src/ifcclash/ifcclash/__main__.py b/src/ifcclash/ifcclash/__main__.py
index bc81131a53..13371a1119 100644
--- a/src/ifcclash/ifcclash/__main__.py
+++ b/src/ifcclash/ifcclash/__main__.py
@@ -18,10 +18,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcClash. If not, see .
-import sys
+import argparse
import json
import logging
-import argparse
+import sys
+
from .ifcclash import Clasher, ClashSettings
parser = argparse.ArgumentParser(description="Clashes geometry between two IFC files")
diff --git a/src/ifcclash/ifcclash/ifcclash.py b/src/ifcclash/ifcclash/ifcclash.py
index 409fb914d7..6e8f05b3a8 100644
--- a/src/ifcclash/ifcclash/ifcclash.py
+++ b/src/ifcclash/ifcclash/ifcclash.py
@@ -20,15 +20,17 @@
from __future__ import annotations
+
import json
-import time
-import numpy as np
import multiprocessing
+import time
+from logging import Logger
+from typing import Literal, TypedDict, Union
+
import ifcopenshell
import ifcopenshell.geom
import ifcopenshell.util.selector
-from logging import Logger
-from typing import Literal, TypedDict, Union
+import numpy as np
from typing_extensions import NotRequired, assert_never
@@ -256,9 +258,10 @@ class Clasher:
json.dump(clash_sets, clashes_file, indent=4)
def smart_group_clashes(self, clash_sets: list[ClashSet], max_clustering_distance: float):
- from sklearn.cluster import OPTICS
from collections import defaultdict
+ from sklearn.cluster import OPTICS
+
count_of_input_clashes = 0
count_of_clash_sets = 0
count_of_smart_groups = 0
diff --git a/src/ifcclash/make.py b/src/ifcclash/make.py
index b4436f6e14..e15c972795 100644
--- a/src/ifcclash/make.py
+++ b/src/ifcclash/make.py
@@ -21,6 +21,5 @@
import os
import subprocess
-
cmd = "pyinstaller ./bootstrap.py --name ifcclash --onefile --clean"
subprocess.check_output(cmd, shell=True)
diff --git a/src/ifccsv/ifccsv.py b/src/ifccsv/ifccsv.py
index 6c87209770..341fa186e7 100755
--- a/src/ifccsv/ifccsv.py
+++ b/src/ifccsv/ifccsv.py
@@ -20,23 +20,24 @@
# This can be packaged with `pyinstaller --onefile --clean --icon=icon.ico ifccsv.py`
+import argparse
+import csv
import os
import re
-import csv
-import argparse
+from collections.abc import Iterable
+from statistics import mean
+from typing import Literal, Optional, Union
+
import ifcopenshell
-import ifcopenshell.util.selector
import ifcopenshell.util.element
import ifcopenshell.util.schema
-from statistics import mean
-from typing import Optional, Union, Literal
-from collections.abc import Iterable
+import ifcopenshell.util.selector
try:
from odf.namespaces import OFFICENS
from odf.opendocument import OpenDocumentSpreadsheet, load
from odf.style import Style, TableCellProperties
- from odf.table import Table, TableRow, TableCell
+ from odf.table import Table, TableCell, TableRow
from odf.text import P
except:
pass # No ODF support
diff --git a/src/ifcdiff/ifcdiff.py b/src/ifcdiff/ifcdiff.py
index 889f23ca37..c7d6bb5d03 100755
--- a/src/ifcdiff/ifcdiff.py
+++ b/src/ifcdiff/ifcdiff.py
@@ -20,23 +20,23 @@
# This can be packaged with `pyinstaller --onefile --clean --icon=icon.ico ifcdiff.py`
-import time
+import argparse
import json
import logging
-import argparse
-import numpy as np
import multiprocessing
+import time
+from typing import Any, Literal, Optional, Union
+
import ifcopenshell
import ifcopenshell.geom
-import ifcopenshell.util.element
-import ifcopenshell.util.selector
-import ifcopenshell.util.placement
import ifcopenshell.util.classification
+import ifcopenshell.util.element
+import ifcopenshell.util.placement
import ifcopenshell.util.representation
+import ifcopenshell.util.selector
+import numpy as np
from deepdiff import DeepDiff
from orderly_set import OrderedSet
-from typing import Optional, Union, Literal, Any
-
__version__ = version = "0.0.0"
diff --git a/src/ifcdiff/test.py b/src/ifcdiff/test.py
index c9e632091f..ca294a1ed4 100644
--- a/src/ifcdiff/test.py
+++ b/src/ifcdiff/test.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcdiff
import ifcopenshell
import ifcopenshell.api.context
import ifcopenshell.api.geometry
@@ -24,6 +23,8 @@ import ifcopenshell.api.root
import ifcopenshell.api.unit
import ifcopenshell.util.representation
+import ifcdiff
+
def setup_project() -> ifcopenshell.file:
ifc_file = ifcopenshell.file(schema="IFC4")
diff --git a/src/ifcfm/ifcfm/__init__.py b/src/ifcfm/ifcfm/__init__.py
index 14fa76146d..ced960305c 100644
--- a/src/ifcfm/ifcfm/__init__.py
+++ b/src/ifcfm/ifcfm/__init__.py
@@ -17,15 +17,17 @@
# along with IfcFM. If not, see .
from __future__ import annotations
-import os
-import re
+
import csv
import importlib
-import ifcopenshell.util.selector
-from pathlib import Path
+import os
+import re
from collections import defaultdict
-from typing import Literal, Union, Any, TYPE_CHECKING
from collections.abc import Callable
+from pathlib import Path
+from typing import TYPE_CHECKING, Any, Literal, Union
+
+import ifcopenshell.util.selector
try:
from openpyxl import Workbook
@@ -37,7 +39,7 @@ try:
import odf.namespaces as odf_ns
from odf.opendocument import OpenDocumentSpreadsheet
from odf.style import Style, TableCellProperties, TableProperties
- from odf.table import Table, TableRow, TableCell
+ from odf.table import Table, TableCell, TableRow
from odf.text import P
except:
pass # No ODF support
diff --git a/src/ifcfm/ifcfm/__main__.py b/src/ifcfm/ifcfm/__main__.py
index 9133611716..8affc93d29 100644
--- a/src/ifcfm/ifcfm/__main__.py
+++ b/src/ifcfm/ifcfm/__main__.py
@@ -16,10 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcFM. If not, see .
-import ifcfm
import argparse
+
import ifcopenshell
+import ifcfm
+
parser = argparse.ArgumentParser(description="Extracts FM data from IFC to spreadsheets")
parser.add_argument(
"-p",
diff --git a/src/ifcfm/ifcfm/basic.py b/src/ifcfm/ifcfm/basic.py
index 62fbdd47e0..7cd5801c6d 100644
--- a/src/ifcfm/ifcfm/basic.py
+++ b/src/ifcfm/ifcfm/basic.py
@@ -16,6 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcFM. If not, see .
+from typing import Any, Optional, Union
+
import ifcopenshell
import ifcopenshell.util.classification
import ifcopenshell.util.date
@@ -23,7 +25,6 @@ import ifcopenshell.util.element
import ifcopenshell.util.fm
import ifcopenshell.util.placement
import ifcopenshell.util.system
-from typing import Any, Union, Optional
def get_facilities(ifc_file: ifcopenshell.file) -> list[ifcopenshell.entity_instance]:
diff --git a/src/ifcfm/ifcfm/cobie24.py b/src/ifcfm/ifcfm/cobie24.py
index 778d49de79..f4848e1654 100644
--- a/src/ifcfm/ifcfm/cobie24.py
+++ b/src/ifcfm/ifcfm/cobie24.py
@@ -16,6 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcFM. If not, see .
+from collections.abc import Generator
+from typing import Any, Optional, Union
+
import ifcopenshell
import ifcopenshell.geom
import ifcopenshell.util.classification
@@ -26,9 +29,6 @@ import ifcopenshell.util.placement
import ifcopenshell.util.shape
import ifcopenshell.util.system
from ifcopenshell.util.shape_builder import np_matrix_to_euler
-from typing import Any, Union, Optional
-from collections.abc import Generator
-
# The original BIMServer plugin has a function called ifcToCOBie:
# https://github.com/opensourceBIM/COBie-plugins/blob/master/COBieShared/src/org/bimserver/cobie/shared/serialization/COBieTabSerializer.java#L54
diff --git a/src/ifcfm/ifcfm/cobie24legacy.py b/src/ifcfm/ifcfm/cobie24legacy.py
index 6e5eaf84c2..078529e892 100644
--- a/src/ifcfm/ifcfm/cobie24legacy.py
+++ b/src/ifcfm/ifcfm/cobie24legacy.py
@@ -16,6 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcFM. If not, see .
+from typing import Any, Optional, Union
+
import ifcopenshell
import ifcopenshell.guid
import ifcopenshell.util.classification
@@ -24,8 +26,6 @@ import ifcopenshell.util.element
import ifcopenshell.util.fm
import ifcopenshell.util.placement
import ifcopenshell.util.system
-from typing import Any, Union, Optional
-
# The original BIMServer plugin has a function called ifcToCOBie:
# https://github.com/opensourceBIM/COBie-plugins/blob/master/COBieShared/src/org/bimserver/cobie/shared/serialization/COBieTabSerializer.java#L54
diff --git a/src/ifcopenshell-python/docs/ifcopenshell-python/installation.rst b/src/ifcopenshell-python/docs/ifcopenshell-python/installation.rst
index 9ff9b917e2..8d75712f71 100644
--- a/src/ifcopenshell-python/docs/ifcopenshell-python/installation.rst
+++ b/src/ifcopenshell-python/docs/ifcopenshell-python/installation.rst
@@ -34,8 +34,6 @@ ZIP packages
+-------------+---------------------------------+-------------------------------+---------------------------------+-----------------------------------+
| | Linux 64bit | Windows 64bit | MacOS Intel 64bit | MacOS Silicon 64bit |
+=============+=================================+===============================+=================================+===================================+
- | Python 3.9 | :ios_python_url:`py39-linux64` | :ios_python_url:`py39-win64` | :ios_python_url:`py39-macos64` | :ios_python_url:`py39-macosm164` |
- +-------------+---------------------------------+-------------------------------+---------------------------------+-----------------------------------+
| Python 3.10 | :ios_python_url:`py310-linux64` | :ios_python_url:`py310-win64` | :ios_python_url:`py310-macos64` | :ios_python_url:`py310-macosm164` |
+-------------+---------------------------------+-------------------------------+---------------------------------+-----------------------------------+
| Python 3.11 | :ios_python_url:`py311-linux64` | :ios_python_url:`py311-win64` | :ios_python_url:`py311-macos64` | :ios_python_url:`py311-macosm164` |
diff --git a/src/ifcopenshell-python/ifcopenshell/__init__.py b/src/ifcopenshell-python/ifcopenshell/__init__.py
index b81db34cbc..9d472d3b1d 100644
--- a/src/ifcopenshell-python/ifcopenshell/__init__.py
+++ b/src/ifcopenshell-python/ifcopenshell/__init__.py
@@ -54,13 +54,14 @@ Example:
print(wall.Name)
"""
from __future__ import annotations
+
import os
import sys
-import zipfile
import tempfile
-from pathlib import Path
-from typing import Optional, Union, TYPE_CHECKING, Any, overload, Literal
+import zipfile
from collections.abc import Generator, Sequence
+from pathlib import Path
+from typing import TYPE_CHECKING, Any, Literal, Optional, Union, overload
if TYPE_CHECKING:
import ifcopenshell.express.schema_class
@@ -88,12 +89,10 @@ except Exception:
# `_file`, `_stream` is used only for annotations inside this file,
# see https://github.com/microsoft/pyright/discussions/9065.
-from .file import file as _file
-from .file import file
-
-from .file import rocksdb_lazy_instance
from . import guid
from .entity_instance import entity_instance, register_schema_attributes
+from .file import file, rocksdb_lazy_instance
+from .file import file as _file
from .sql import sqlite, sqlite_entity
# explicitly specify available imported symbols
@@ -110,8 +109,8 @@ __all__ = [
]
try:
- from .stream import stream as _stream, stream_entity
- from .stream import stream
+ from .stream import stream, stream_entity
+ from .stream import stream as _stream
except:
pass
diff --git a/src/ifcopenshell-python/ifcopenshell/api/__init__.py b/src/ifcopenshell-python/ifcopenshell/api/__init__.py
index 0eb95b2c65..49c3b471dd 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/__init__.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/__init__.py
@@ -38,13 +38,16 @@ Also see how to `create a simple model from scratch
`_.
"""
-import json
-import numpy
-import inspect
import importlib
-import ifcopenshell
-from typing import Callable, Any, Optional, TYPE_CHECKING
+import inspect
+import json
+from collections.abc import Callable
from functools import partial
+from typing import TYPE_CHECKING, Any, Optional
+
+import numpy
+
+import ifcopenshell
if TYPE_CHECKING:
import ifcopenshell.api
@@ -186,8 +189,8 @@ def remove_all_listeners():
def extract_docs(module: str, usecase: str) -> dict[str, Any]:
- import typing
import collections
+ import typing
inputs = collections.OrderedDict()
@@ -303,8 +306,8 @@ def wrap_usecase(usecase_path, usecase):
def wrap_usecases(path, name):
"""This developer feature wraps an API module's usecases with listeners."""
- import sys
import pkgutil
+ import sys
module_name = name.split(".")[-1]
module = sys.modules[name]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/aggregate/assign_object.py b/src/ifcopenshell-python/ifcopenshell/api/aggregate/assign_object.py
index 22d027b73b..a7e3e403d8 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/aggregate/assign_object.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/aggregate/assign_object.py
@@ -16,14 +16,15 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
+import ifcopenshell.api.geometry
import ifcopenshell.api.owner
import ifcopenshell.api.spatial
-import ifcopenshell.api.geometry
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.placement
-from typing import Union
def assign_object(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/__init__.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/__init__.py
index 563376485f..790125cb0b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/__init__.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/__init__.py
@@ -47,45 +47,48 @@ Future versions of this API may support:
5. Adding a segment at any location along a curve
"""
+from ._get_segment_start_point_label import register_referent_name_callback
from .add_stationing_referent import add_stationing_referent
from .add_vertical_layout import add_vertical_layout
from .add_zero_length_segment import add_zero_length_segment
-from .create_layout_segment import create_layout_segment
from .create import create
from .create_as_offset_curve import create_as_offset_curve
from .create_as_polyline import create_as_polyline
from .create_by_pi_method import create_by_pi_method
from .create_from_csv import create_from_csv
-from .create_segment_representations import create_segment_representations
+from .create_layout_segment import create_layout_segment
from .create_representation import create_representation
+from .create_segment_representations import create_segment_representations
from .distance_along_from_station import distance_along_from_station
from .get_alignment import get_alignment
from .get_alignment_layout_nest import get_alignment_layout_nest
+from .get_alignment_layouts import get_alignment_layouts
from .get_alignment_segment_nest import get_alignment_segment_nest
from .get_alignment_start_station import get_alignment_start_station
-from .get_curve_segment_transition_code import get_curve_segment_transition_code
-from .get_layout_segments import get_layout_segments
-from .get_horizontal_layout import get_horizontal_layout
-from .get_vertical_layout import get_vertical_layout
-from .get_cant_layout import get_cant_layout
-from .get_alignment_layouts import get_alignment_layouts
from .get_axis_subcontext import get_axis_subcontext
from .get_basis_curve import get_basis_curve
+from .get_cant_layout import get_cant_layout
from .get_child_alignments import get_child_alignments
from .get_curve import get_curve
+from .get_curve_segment_transition_code import get_curve_segment_transition_code
+from .get_horizontal_layout import get_horizontal_layout
from .get_layout_curve import get_layout_curve
+from .get_layout_segments import get_layout_segments
from .get_mapped_segments import get_mapped_segments
from .get_parent_alignment import get_parent_alignment
from .get_referent_nest import get_referent_nest
+from .get_vertical_layout import get_vertical_layout
from .has_zero_length_segment import has_zero_length_segment
-from .layout_horizontal_alignment_by_pi_method import layout_horizontal_alignment_by_pi_method
-from .layout_vertical_alignment_by_pi_method import layout_vertical_alignment_by_pi_method
+from .layout_horizontal_alignment_by_pi_method import (
+ layout_horizontal_alignment_by_pi_method,
+)
+from .layout_vertical_alignment_by_pi_method import (
+ layout_vertical_alignment_by_pi_method,
+)
from .name_segments import name_segments
from .update_fallback_position import update_fallback_position
from .util import *
-from ._get_segment_start_point_label import register_referent_name_callback
-
__all__ = [
"add_stationing_referent",
"add_vertical_layout",
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_curve.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_curve.py
index 4fcadc176e..934e456b57 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_curve.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_curve.py
@@ -16,19 +16,27 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import numpy as np
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.alignment
import ifcopenshell.geom
-import ifcopenshell.util.unit
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
-import numpy as np
+import ifcopenshell.util.unit
from ifcopenshell import entity_instance
-
-from ifcopenshell.api.alignment._update_curve_segment_transition_code import _update_curve_segment_transition_code
-from ifcopenshell.api.alignment._map_alignment_horizontal_segment import _map_alignment_horizontal_segment
-from ifcopenshell.api.alignment._map_alignment_vertical_segment import _map_alignment_vertical_segment
-from ifcopenshell.api.alignment._map_alignment_cant_segment import _map_alignment_cant_segment
+from ifcopenshell.api.alignment._map_alignment_cant_segment import (
+ _map_alignment_cant_segment,
+)
+from ifcopenshell.api.alignment._map_alignment_horizontal_segment import (
+ _map_alignment_horizontal_segment,
+)
+from ifcopenshell.api.alignment._map_alignment_vertical_segment import (
+ _map_alignment_vertical_segment,
+)
+from ifcopenshell.api.alignment._update_curve_segment_transition_code import (
+ _update_curve_segment_transition_code,
+)
def _add_curve_segment_to_composite_curve(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_layout.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_layout.py
index bb31342efb..999bf2f80f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_layout.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_segment_to_layout.py
@@ -16,6 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+from collections.abc import Sequence
+
+import numpy as np
+
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
@@ -23,14 +28,11 @@ import ifcopenshell.api.pset
import ifcopenshell.geom
import ifcopenshell.util.alignment
import ifcopenshell.util.unit
-from ifcopenshell import ifcopenshell_wrapper
-import numpy as np
-import math
-from ifcopenshell import entity_instance
-from collections.abc import Sequence
-
+from ifcopenshell import entity_instance, ifcopenshell_wrapper
from ifcopenshell.api.alignment._add_segment_to_curve import _add_segment_to_curve
-from ifcopenshell.api.alignment._get_segment_start_point_label import _get_segment_start_point_label
+from ifcopenshell.api.alignment._get_segment_start_point_label import (
+ _get_segment_start_point_label,
+)
def _add_segment_to_layout(file: ifcopenshell.file, layout: entity_instance, segment: entity_instance) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_zero_length_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_zero_length_segment.py
index 17be8ec45c..00ac9d6000 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_zero_length_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_add_zero_length_segment.py
@@ -21,8 +21,9 @@ import ifcopenshell.api.alignment
import ifcopenshell.util
import ifcopenshell.util.alignment
from ifcopenshell import entity_instance
-
-from ifcopenshell.api.alignment._get_segment_start_point_label import _get_segment_start_point_label
+from ifcopenshell.api.alignment._get_segment_start_point_label import (
+ _get_segment_start_point_label,
+)
def _add_zero_length_segment(file: ifcopenshell.file, layout: entity_instance) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_geometric_representation.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_geometric_representation.py
index d6b070af78..30b91bb0a0 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_geometric_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_geometric_representation.py
@@ -16,14 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+from collections.abc import Sequence
+
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.api.geometry
from ifcopenshell import entity_instance
-import math
-from collections.abc import Sequence
-
def _create_geometric_representation(file: ifcopenshell.file, alignment: entity_instance) -> None:
"""
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_offset_curve_representation.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_offset_curve_representation.py
index 402a6c3513..31f0c583aa 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_offset_curve_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_offset_curve_representation.py
@@ -16,14 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+from collections.abc import Sequence
+
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.api.geometry
from ifcopenshell import entity_instance
-import math
-from collections.abc import Sequence
-
def _create_offset_curve_representation(
file: ifcopenshell.file, alignment: entity_instance, offsets: Sequence[entity_instance]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_polyline_representation.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_polyline_representation.py
index e8329a5b1a..c745e6b9ac 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_polyline_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_create_polyline_representation.py
@@ -16,14 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+from collections.abc import Sequence
+
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.api.geometry
from ifcopenshell import entity_instance
-import math
-from collections.abc import Sequence
-
def _create_polyline_representation(
file: ifcopenshell.file, alignment: entity_instance, points: Sequence[entity_instance]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_cant_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_cant_segment.py
index ccf466828b..27a781c505 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_cant_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_cant_segment.py
@@ -16,14 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+from collections.abc import Sequence
+
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.api.geometry
from ifcopenshell import entity_instance
-import math
-from collections.abc import Sequence
-
def _get_cant_segment(horizontal_segment: entity_instance) -> entity_instance:
"""
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_segment_start_point_label.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_segment_start_point_label.py
index b1bddfb2e6..34b30b9f59 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_segment_start_point_label.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_get_segment_start_point_label.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-from ifcopenshell import entity_instance
from collections.abc import Sequence
+import ifcopenshell
+from ifcopenshell import entity_instance
_horizontal_callback = None
_vertical_callback = None
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_cant_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_cant_segment.py
index c86edc110e..e5b9ea0381 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_cant_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_cant_segment.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+from collections.abc import Sequence
+
import ifcopenshell
from ifcopenshell import entity_instance
from ifcopenshell.api.alignment import get_axis_subcontext
-from collections.abc import Sequence
-import math
def _get_axis(file: ifcopenshell.file, Ds: float, rail_head_distance: float) -> entity_instance:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_horizontal_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_horizontal_segment.py
index 73802f2318..17de77a7ad 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_horizontal_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_horizontal_segment.py
@@ -16,14 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+from collections.abc import Sequence
+
import ifcopenshell
-from ifcopenshell import entity_instance
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
import ifcopenshell.util
import ifcopenshell.util.unit
-from collections.abc import Sequence
-import math
-
+from ifcopenshell import entity_instance
from ifcopenshell.api.alignment._get_cant_segment import _get_cant_segment
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_vertical_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_vertical_segment.py
index 1f8a1ef5d7..e47a50d5ce 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_vertical_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_map_alignment_vertical_segment.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-from ifcopenshell import ifcopenshell_wrapper
-from ifcopenshell import entity_instance
-from collections.abc import Sequence
import math
+from collections.abc import Sequence
+
+import ifcopenshell
+from ifcopenshell import entity_instance, ifcopenshell_wrapper
def _polynomial_length(A: float, B: float, C: float, L: float) -> float:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/_update_curve_segment_transition_code.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/_update_curve_segment_transition_code.py
index 59154980dc..5e1c2d0123 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/_update_curve_segment_transition_code.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/_update_curve_segment_transition_code.py
@@ -16,13 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+
+import numpy as np
+
import ifcopenshell
import ifcopenshell.api.alignment
-from ifcopenshell import ifcopenshell_wrapper
import ifcopenshell.geom
-from ifcopenshell import entity_instance
-import numpy as np
-import math
+from ifcopenshell import entity_instance, ifcopenshell_wrapper
def _update_curve_segment_transition_code(prev_segment: entity_instance, segment: entity_instance) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/add_stationing_referent.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/add_stationing_referent.py
index 2ac08a2fbf..bccc7b0213 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/add_stationing_referent.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/add_stationing_referent.py
@@ -16,6 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import numpy as np
+
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
@@ -24,9 +26,7 @@ import ifcopenshell.geom
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.unit
-from ifcopenshell import entity_instance
-from ifcopenshell import ifcopenshell_wrapper
-import numpy as np
+from ifcopenshell import entity_instance, ifcopenshell_wrapper
def add_stationing_referent(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/add_vertical_layout.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/add_vertical_layout.py
index 06c1ef9fa8..41daef657c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/add_vertical_layout.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/add_vertical_layout.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
+import ifcopenshell.api
import ifcopenshell.api.aggregate
import ifcopenshell.api.alignment
import ifcopenshell.api.geometry
@@ -24,9 +25,7 @@ import ifcopenshell.api.nest
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.representation
-import ifcopenshell.api
from ifcopenshell import entity_instance
-
from ifcopenshell.api.alignment._add_zero_length_segment import _add_zero_length_segment
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/add_zero_length_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/add_zero_length_segment.py
index 5b36cddd75..96c3a9c1f2 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/add_zero_length_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/add_zero_length_segment.py
@@ -16,21 +16,30 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+
+import numpy as np
+
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
import ifcopenshell.geom
-import ifcopenshell.util.alignment
-from ifcopenshell import entity_instance
import ifcopenshell.ifcopenshell_wrapper as wrapper
+import ifcopenshell.util.alignment
import ifcopenshell.util.unit
-import numpy as np
-import math
-
-from ifcopenshell.api.alignment._get_segment_start_point_label import _get_segment_start_point_label
-from ifcopenshell.api.alignment._map_alignment_horizontal_segment import _map_alignment_horizontal_segment
-from ifcopenshell.api.alignment._map_alignment_vertical_segment import _map_alignment_vertical_segment
-from ifcopenshell.api.alignment._update_curve_segment_transition_code import _update_curve_segment_transition_code
+from ifcopenshell import entity_instance
+from ifcopenshell.api.alignment._get_segment_start_point_label import (
+ _get_segment_start_point_label,
+)
+from ifcopenshell.api.alignment._map_alignment_horizontal_segment import (
+ _map_alignment_horizontal_segment,
+)
+from ifcopenshell.api.alignment._map_alignment_vertical_segment import (
+ _map_alignment_vertical_segment,
+)
+from ifcopenshell.api.alignment._update_curve_segment_transition_code import (
+ _update_curve_segment_transition_code,
+)
def add_zero_length_segment(file: ifcopenshell.file, layout: entity_instance, include_referent: bool = True) -> bool:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/create.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/create.py
index cd707920c0..d2682aaad1 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/create.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/create.py
@@ -21,11 +21,11 @@ import ifcopenshell.api.aggregate
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
import ifcopenshell.util.alignment
-
from ifcopenshell import entity_instance
-
-from ifcopenshell.api.alignment._create_geometric_representation import _create_geometric_representation
from ifcopenshell.api.alignment._add_zero_length_segment import _add_zero_length_segment
+from ifcopenshell.api.alignment._create_geometric_representation import (
+ _create_geometric_representation,
+)
def create(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_as_offset_curve.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_as_offset_curve.py
index a206fda69b..f4bc35773a 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_as_offset_curve.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_as_offset_curve.py
@@ -16,17 +16,17 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from collections.abc import Sequence
+
import ifcopenshell
import ifcopenshell.api.aggregate
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
import ifcopenshell.util.alignment
-
from ifcopenshell import entity_instance
-
-from ifcopenshell.api.alignment._create_offset_curve_representation import _create_offset_curve_representation
-
-from collections.abc import Sequence
+from ifcopenshell.api.alignment._create_offset_curve_representation import (
+ _create_offset_curve_representation,
+)
def create_as_offset_curve(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_as_polyline.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_as_polyline.py
index 1048f1fa69..4988a31920 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_as_polyline.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_as_polyline.py
@@ -16,18 +16,18 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+from collections.abc import Sequence
+
import ifcopenshell
import ifcopenshell.api.aggregate
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
import ifcopenshell.util.alignment
-
from ifcopenshell import entity_instance
-
-from ifcopenshell.api.alignment._create_polyline_representation import _create_polyline_representation
-
-import math
-from collections.abc import Sequence
+from ifcopenshell.api.alignment._create_polyline_representation import (
+ _create_polyline_representation,
+)
def _create_layout(file: ifcopenshell.file, alignment: entity_instance, points: Sequence[entity_instance]):
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_by_pi_method.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_by_pi_method.py
index 55f91b5cbe..09a0f0ecb6 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_by_pi_method.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_by_pi_method.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from collections.abc import Sequence
+
import ifcopenshell
import ifcopenshell.api.aggregate
import ifcopenshell.api.alignment
import ifcopenshell.api.nest
from ifcopenshell import entity_instance
-from collections.abc import Sequence
def create_by_pi_method(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_from_csv.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_from_csv.py
index 4125f16bfc..ce7192611c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_from_csv.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_from_csv.py
@@ -16,15 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.api.alignment
-import ifcopenshell.api
-from ifcopenshell import entity_instance
-from ifcopenshell.api.alignment import get_axis_subcontext
-
+import csv
from collections.abc import Sequence
-import csv
+import ifcopenshell
+import ifcopenshell.api
+import ifcopenshell.api.alignment
+from ifcopenshell import entity_instance
+from ifcopenshell.api.alignment import get_axis_subcontext
def create_from_csv(file: ifcopenshell.file, filepath: str) -> entity_instance:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_layout_segment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_layout_segment.py
index 3f6789fd98..6fd6876e08 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_layout_segment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_layout_segment.py
@@ -16,15 +16,15 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+from typing import Union
+
+import numpy as np
+
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.geom
-from ifcopenshell import entity_instance
-import math
-from ifcopenshell import ifcopenshell_wrapper
-import numpy as np
-from typing import Union
-
+from ifcopenshell import entity_instance, ifcopenshell_wrapper
from ifcopenshell.api.alignment._add_segment_to_layout import _add_segment_to_layout
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_representation.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_representation.py
index c94ee873fa..896108367f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_representation.py
@@ -19,9 +19,10 @@
import ifcopenshell
import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
-
-from ifcopenshell.api.alignment._create_geometric_representation import _create_geometric_representation
from ifcopenshell.api.alignment._add_segment_to_curve import _add_segment_to_curve
+from ifcopenshell.api.alignment._create_geometric_representation import (
+ _create_geometric_representation,
+)
def create_representation(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_segment_representations.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_segment_representations.py
index c6f479e656..d35429ce75 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/create_segment_representations.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/create_segment_representations.py
@@ -17,9 +17,9 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
+import ifcopenshell.api.alignment
import ifcopenshell.util.element
import ifcopenshell.util.representation
-import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_layouts.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_layouts.py
index 897ab22da8..4b4a1a17d3 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_layouts.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_alignment_layouts.py
@@ -16,12 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.util
-from ifcopenshell import entity_instance
from collections.abc import Sequence
+import ifcopenshell
+import ifcopenshell.util
import ifcopenshell.util.representation
+from ifcopenshell import entity_instance
def get_alignment_layouts(alignment: entity_instance) -> Sequence[entity_instance]:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_axis_subcontext.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_axis_subcontext.py
index 033c94d9bb..98e6646cc4 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_axis_subcontext.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_axis_subcontext.py
@@ -17,8 +17,8 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.util.representation
import ifcopenshell.api.context
+import ifcopenshell.util.representation
from ifcopenshell import entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_basis_curve.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_basis_curve.py
index b96c830757..0bf28746fe 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_basis_curve.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_basis_curve.py
@@ -18,9 +18,8 @@
import ifcopenshell
import ifcopenshell.util
-from ifcopenshell import entity_instance
-
import ifcopenshell.util.representation
+from ifcopenshell import entity_instance
def get_basis_curve(alignment: entity_instance) -> entity_instance:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_child_alignments.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_child_alignments.py
index c81018ce06..ccc8f01214 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_child_alignments.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_child_alignments.py
@@ -16,12 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.util
-from ifcopenshell import entity_instance
from collections.abc import Sequence
+import ifcopenshell
+import ifcopenshell.util
import ifcopenshell.util.element
+from ifcopenshell import entity_instance
def get_child_alignments(alignment: entity_instance) -> Sequence[entity_instance]:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve.py
index aeb018976a..6b1a7172d9 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve.py
@@ -18,9 +18,8 @@
import ifcopenshell
import ifcopenshell.util
-from ifcopenshell import entity_instance
-
import ifcopenshell.util.representation
+from ifcopenshell import entity_instance
def get_curve(alignment: entity_instance) -> entity_instance:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve_segment_transition_code.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve_segment_transition_code.py
index 577b14d709..6711935e6f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve_segment_transition_code.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_curve_segment_transition_code.py
@@ -16,13 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+
+import numpy as np
+
import ifcopenshell
import ifcopenshell.api
-from ifcopenshell import ifcopenshell_wrapper
import ifcopenshell.geom
-from ifcopenshell import entity_instance
-import numpy as np
-import math
+from ifcopenshell import entity_instance, ifcopenshell_wrapper
def get_curve_segment_transition_code(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_layout_segments.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_layout_segments.py
index cae8079f53..34cfd90a1d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_layout_segments.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_layout_segments.py
@@ -16,12 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.util
-from ifcopenshell import entity_instance
from collections.abc import Sequence
+import ifcopenshell
+import ifcopenshell.util
import ifcopenshell.util.element
+from ifcopenshell import entity_instance
def get_layout_segments(layout: entity_instance) -> Sequence[entity_instance]:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_mapped_segments.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_mapped_segments.py
index 12be6d90f1..2e10aa9824 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_mapped_segments.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_mapped_segments.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from collections.abc import Sequence
+
import ifcopenshell
import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
-from collections.abc import Sequence
def _get_curve_segment_count(segment: entity_instance) -> int:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_parent_alignment.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_parent_alignment.py
index 5115f9e37a..333bfc01e5 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/get_parent_alignment.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/get_parent_alignment.py
@@ -18,9 +18,8 @@
import ifcopenshell
import ifcopenshell.util
-from ifcopenshell import entity_instance
-
import ifcopenshell.util.representation
+from ifcopenshell import entity_instance
def get_parent_alignment(alignment: entity_instance) -> entity_instance:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/layout_horizontal_alignment_by_pi_method.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/layout_horizontal_alignment_by_pi_method.py
index 3409fd761b..ed157c3c90 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/layout_horizontal_alignment_by_pi_method.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/layout_horizontal_alignment_by_pi_method.py
@@ -16,15 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.api.alignment
-from ifcopenshell import entity_instance
-
import math
from collections.abc import Sequence
+import ifcopenshell
+import ifcopenshell.api.alignment
import ifcopenshell.util
import ifcopenshell.util.unit
+from ifcopenshell import entity_instance
def layout_horizontal_alignment_by_pi_method(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/layout_vertical_alignment_by_pi_method.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/layout_vertical_alignment_by_pi_method.py
index 73470467af..542237cbc4 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/layout_vertical_alignment_by_pi_method.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/layout_vertical_alignment_by_pi_method.py
@@ -16,13 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+from collections.abc import Sequence
+
import ifcopenshell
import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
-import math
-from collections.abc import Sequence
-
def layout_vertical_alignment_by_pi_method(
file: ifcopenshell.file, layout: entity_instance, vpoints: Sequence[Sequence[float]], lengths: Sequence[float]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/update_fallback_position.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/update_fallback_position.py
index 6cc653fb52..3cd4c05907 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/update_fallback_position.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/update_fallback_position.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import numpy as np
+
import ifcopenshell
import ifcopenshell.util.placement
from ifcopenshell import entity_instance
-import numpy as np
def update_fallback_position(file: ifcopenshell.file, lp: entity_instance):
diff --git a/src/ifcopenshell-python/ifcopenshell/api/alignment/util.py b/src/ifcopenshell-python/ifcopenshell/api/alignment/util.py
index 389f94576a..144311a3df 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/alignment/util.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/alignment/util.py
@@ -16,20 +16,18 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.api.alignment
import math
import numpy as np
import ifcopenshell
+import ifcopenshell.api.alignment
import ifcopenshell.geom
import ifcopenshell.guid
import ifcopenshell.template
-from ifcopenshell import entity_instance
-from ifcopenshell import ifcopenshell_wrapper
import ifcopenshell.util
import ifcopenshell.util.alignment
+from ifcopenshell import entity_instance, ifcopenshell_wrapper
def evaluate_representation(shape_rep: entity_instance, dist_along: float) -> np.ndarray:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/attribute/edit_attributes.py b/src/ifcopenshell-python/ifcopenshell/api/attribute/edit_attributes.py
index 6199ddf3b7..2e679fd409 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/attribute/edit_attributes.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/attribute/edit_attributes.py
@@ -17,14 +17,11 @@
# along with IfcOpenShell. If not, see .
import sys
-import ifcopenshell.api.owner
-import ifcopenshell.util.element
+from types import EllipsisType
from typing import Any, Union
-if sys.version_info >= (3, 10):
- from types import EllipsisType
-else:
- EllipsisType = type(...)
+import ifcopenshell.api.owner
+import ifcopenshell.util.element
def edit_attributes(file: ifcopenshell.file, product: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/boundary/assign_connection_geometry.py b/src/ifcopenshell-python/ifcopenshell/api/boundary/assign_connection_geometry.py
index 36e55f2d00..f974ea2cd2 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/boundary/assign_connection_geometry.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/boundary/assign_connection_geometry.py
@@ -16,10 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.unit
+from typing import Optional
+
import numpy as np
import numpy.typing as npt
-from typing import Optional
+
+import ifcopenshell.util.unit
from ifcopenshell.util.shape_builder import SequenceOfVectors, V, ifc_safe_vector_type
diff --git a/src/ifcopenshell-python/ifcopenshell/api/boundary/edit_attributes.py b/src/ifcopenshell-python/ifcopenshell/api/boundary/edit_attributes.py
index 6980b1a2dd..ee11094d13 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/boundary/edit_attributes.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/boundary/edit_attributes.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Optional
+import ifcopenshell
+
def edit_attributes(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/classification/add_classification.py b/src/ifcopenshell-python/ifcopenshell/api/classification/add_classification.py
index 2932a5bb93..6642e618b4 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/classification/add_classification.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/classification/add_classification.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Union
+
import ifcopenshell
import ifcopenshell.guid
-import ifcopenshell.util.schema
import ifcopenshell.util.date
-from typing import Union, Any
+import ifcopenshell.util.schema
def add_classification(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/classification/add_reference.py b/src/ifcopenshell-python/ifcopenshell/api/classification/add_reference.py
index 7f3d46bc96..10177821b4 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/classification/add_reference.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/classification/add_reference.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Optional, Union
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.schema
-from typing import Optional, Union, Any
def add_reference(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/classification/edit_classification.py b/src/ifcopenshell-python/ifcopenshell/api/classification/edit_classification.py
index b2091c0eca..133dc1bfc2 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/classification/edit_classification.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/classification/edit_classification.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_classification(
file: ifcopenshell.file, classification: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/classification/edit_reference.py b/src/ifcopenshell-python/ifcopenshell/api/classification/edit_reference.py
index f5a85d40f9..24e670f2f3 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/classification/edit_reference.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/classification/edit_reference.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_reference(
file: ifcopenshell.file, reference: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cogo/__init__.py b/src/ifcopenshell-python/ifcopenshell/api/cogo/__init__.py
index bb1c7c5243..5fdb2bcea0 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cogo/__init__.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cogo/__init__.py
@@ -22,8 +22,8 @@ Coordinate Geometry (cogo) functions primarily for survey points and control mon
from .add_survey_point import add_survey_point
from .assign_survey_point import assign_survey_point
-from .edit_survey_point import edit_survey_point
from .bearing2dd import bearing2dd
+from .edit_survey_point import edit_survey_point
__all__ = [
"add_survey_point",
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cogo/add_survey_point.py b/src/ifcopenshell-python/ifcopenshell/api/cogo/add_survey_point.py
index c4a10661d3..20c0852a04 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cogo/add_survey_point.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cogo/add_survey_point.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.spatial
import ifcopenshell.util.representation
from ifcopenshell import entity_instance
-from typing import Union
def add_survey_point(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cogo/assign_survey_point.py b/src/ifcopenshell-python/ifcopenshell/api/cogo/assign_survey_point.py
index c9a6ba0acc..be9e650ac7 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cogo/assign_survey_point.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cogo/assign_survey_point.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import typing
+
import ifcopenshell
from ifcopenshell import entity_instance
-import typing
def assign_survey_point(annotation: entity_instance, survey_point: entity_instance):
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cogo/edit_survey_point.py b/src/ifcopenshell-python/ifcopenshell/api/cogo/edit_survey_point.py
index d2208dc649..3c7d478441 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cogo/edit_survey_point.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cogo/edit_survey_point.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import typing
+
import ifcopenshell
from ifcopenshell import entity_instance
-import typing
def edit_survey_point(annotation: entity_instance, x: float, y: float, z: float = 0.0):
diff --git a/src/ifcopenshell-python/ifcopenshell/api/constraint/assign_constraint.py b/src/ifcopenshell-python/ifcopenshell/api/constraint/assign_constraint.py
index ac021840c7..fb6364042a 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/constraint/assign_constraint.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/constraint/assign_constraint.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
-from typing import Union
def assign_constraint(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/constraint/edit_metric.py b/src/ifcopenshell-python/ifcopenshell/api/constraint/edit_metric.py
index 3967846759..f788722b75 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/constraint/edit_metric.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/constraint/edit_metric.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_metric(file: ifcopenshell.file, metric: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edit the attributes of a metric
diff --git a/src/ifcopenshell-python/ifcopenshell/api/constraint/edit_objective.py b/src/ifcopenshell-python/ifcopenshell/api/constraint/edit_objective.py
index 3cd75356a7..cd2b17e66b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/constraint/edit_objective.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/constraint/edit_objective.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_objective(
file: ifcopenshell.file, objective: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/context/add_context.py b/src/ifcopenshell-python/ifcopenshell/api/context/add_context.py
index a1a7839e09..0a6992ce8d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/context/add_context.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/context/add_context.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Optional
+
import ifcopenshell
import ifcopenshell.util.representation
-from typing import Optional, Any
def add_context(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/context/edit_context.py b/src/ifcopenshell-python/ifcopenshell/api/context/edit_context.py
index 1a7d567c58..15afc571f2 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/context/edit_context.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/context/edit_context.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_context(file: ifcopenshell.file, context: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcGeometricRepresentationContext
diff --git a/src/ifcopenshell-python/ifcopenshell/api/control/assign_control.py b/src/ifcopenshell-python/ifcopenshell/api/control/assign_control.py
index cd7c398a54..69ecb324eb 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/control/assign_control.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/control/assign_control.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
-from typing import Union
def assign_control(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/add_cost_item.py b/src/ifcopenshell-python/ifcopenshell/api/cost/add_cost_item.py
index 70c0cfc06c..1bdae9e9a1 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cost/add_cost_item.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cost/add_cost_item.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.control
-import ifcopenshell.api.root
-import ifcopenshell.api.nest
-import ifcopenshell.guid
from typing import Optional
+import ifcopenshell.api.control
+import ifcopenshell.api.nest
+import ifcopenshell.api.root
+import ifcopenshell.guid
+
def add_cost_item(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/add_cost_schedule.py b/src/ifcopenshell-python/ifcopenshell/api/cost/add_cost_schedule.py
index 19f0762b69..cc88336cb4 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cost/add_cost_schedule.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cost/add_cost_schedule.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.root
-import ifcopenshell.api.sequence
from datetime import datetime
from typing import Optional
+import ifcopenshell.api.root
+import ifcopenshell.api.sequence
+
def add_cost_schedule(
file: ifcopenshell.file, name: Optional[str] = None, predefined_type: str = "NOTDEFINED"
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/assign_cost_item_quantity.py b/src/ifcopenshell-python/ifcopenshell/api/cost/assign_cost_item_quantity.py
index 2db09c45f6..20fc24ab37 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cost/assign_cost_item_quantity.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cost/assign_cost_item_quantity.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.cost
-import ifcopenshell.api.control
from typing import Any
+import ifcopenshell.api.control
+import ifcopenshell.api.cost
+
def assign_cost_item_quantity(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/copy_cost_item.py b/src/ifcopenshell-python/ifcopenshell/api/cost/copy_cost_item.py
index fcf298ff7c..af1915d57f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cost/copy_cost_item.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cost/copy_cost_item.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.nest
import ifcopenshell.util.element
-from typing import Union
def copy_cost_item(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/copy_cost_item_values.py b/src/ifcopenshell-python/ifcopenshell/api/cost/copy_cost_item_values.py
index 01d0a02976..11e975fd53 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cost/copy_cost_item_values.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cost/copy_cost_item_values.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.element
import ifcopenshell.api.cost
+import ifcopenshell.util.element
def copy_cost_item_values(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_item.py b/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_item.py
index 813e306bc8..20770fb673 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_item.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_item.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_cost_item(
file: ifcopenshell.file, cost_item: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_item_quantity.py b/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_item_quantity.py
index 697d028a37..f5713cd33a 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_item_quantity.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_item_quantity.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_cost_item_quantity(
file: ifcopenshell.file, physical_quantity: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_schedule.py b/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_schedule.py
index d55e93330e..089c2b1336 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_schedule.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_schedule.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_cost_schedule(
file: ifcopenshell.file, cost_schedule: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_value.py b/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_value.py
index ebc09ed34c..e1be553922 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_value.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_value.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.util.unit
-import ifcopenshell.util.element
from typing import Any
+import ifcopenshell
+import ifcopenshell.util.element
+import ifcopenshell.util.unit
+
def edit_cost_value(
file: ifcopenshell.file, cost_value: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_value_formula.py b/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_value_formula.py
index 2f68a66023..213940904d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_value_formula.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/cost/edit_cost_value_formula.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any
+
import ifcopenshell
import ifcopenshell.api.cost
import ifcopenshell.util.cost
-import ifcopenshell.util.unit
import ifcopenshell.util.element
-from typing import Any
+import ifcopenshell.util.unit
def edit_cost_value_formula(file: ifcopenshell.file, cost_value: ifcopenshell.entity_instance, formula: str) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/document/add_information.py b/src/ifcopenshell-python/ifcopenshell/api/document/add_information.py
index a5018c63cb..572de820a0 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/document/add_information.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/document/add_information.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.guid
-import ifcopenshell.api.owner
from typing import Optional
+import ifcopenshell
+import ifcopenshell.api.owner
+import ifcopenshell.guid
+
def add_information(
file: ifcopenshell.file, parent: Optional[ifcopenshell.entity_instance] = None
diff --git a/src/ifcopenshell-python/ifcopenshell/api/document/assign_document.py b/src/ifcopenshell-python/ifcopenshell/api/document/assign_document.py
index a86a178e86..666d7420d1 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/document/assign_document.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/document/assign_document.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
-from typing import Union
def assign_document(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/document/edit_information.py b/src/ifcopenshell-python/ifcopenshell/api/document/edit_information.py
index 56c1d40df4..c50e74de58 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/document/edit_information.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/document/edit_information.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_information(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/document/edit_reference.py b/src/ifcopenshell-python/ifcopenshell/api/document/edit_reference.py
index 51ad195bf3..56bd3c8538 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/document/edit_reference.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/document/edit_reference.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_reference(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/drawing/edit_text_literal.py b/src/ifcopenshell-python/ifcopenshell/api/drawing/edit_text_literal.py
index c083960e59..838fbb357a 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/drawing/edit_text_literal.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/drawing/edit_text_literal.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_text_literal(
file: ifcopenshell.file, text_literal: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/feature/add_feature.py b/src/ifcopenshell-python/ifcopenshell/api/feature/add_feature.py
index 5de3f2cf42..cfdff3819c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/feature/add_feature.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/feature/add_feature.py
@@ -17,9 +17,9 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.api.owner
-import ifcopenshell.api.geometry
import ifcopenshell.api.aggregate
+import ifcopenshell.api.geometry
+import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.placement
diff --git a/src/ifcopenshell-python/ifcopenshell/api/feature/remove_feature.py b/src/ifcopenshell-python/ifcopenshell/api/feature/remove_feature.py
index 6a1d5e5610..ff847b39eb 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/feature/remove_feature.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/feature/remove_feature.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.root
import ifcopenshell.api.aggregate
+import ifcopenshell.api.root
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_axis_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_axis_representation.py
index 02bd057cc6..b206cc2ef1 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_axis_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_axis_representation.py
@@ -16,8 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Union
+
import ifcopenshell.util.unit
-from typing import Union, Any
COORD = Union[tuple[float, float], tuple[float, float, float]]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_boolean.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_boolean.py
index f5d0a31456..910df42d8c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_boolean.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_boolean.py
@@ -17,9 +17,11 @@
# along with IfcOpenShell. If not, see .
from __future__ import annotations
-import ifcopenshell.util.element
+
from typing import Literal
+import ifcopenshell.util.element
+
def add_boolean(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_door_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_door_representation.py
index d91b7b0327..a4460ce984 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_door_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_door_representation.py
@@ -17,18 +17,17 @@
# along with IfcOpenShell. If not, see .
from __future__ import annotations
-import sys
-import ifcopenshell.util.unit
-import ifcopenshell.api.geometry
+
import dataclasses
-import numpy as np
-from ifcopenshell.util.shape_builder import ShapeBuilder, V
-from ifcopenshell.api.geometry.add_window_representation import create_ifc_window
from math import cos, radians
-from typing import Any, Optional, Literal, Union, get_args, overload
+from typing import Any, Literal, Optional, Union, get_args, overload
-DATACLASS_SLOTS = {} if sys.version_info < (3, 10) else {"slots": True}
+import numpy as np
+import ifcopenshell.api.geometry
+import ifcopenshell.util.unit
+from ifcopenshell.api.geometry.add_window_representation import create_ifc_window
+from ifcopenshell.util.shape_builder import ShapeBuilder, V
DOOR_TYPE = Literal[
"SINGLE_SWING_LEFT",
@@ -99,7 +98,7 @@ def create_ifc_box(
# we use dataclass as we need default values for arguments
# it's okay to use slots since we don't need dynamic attributes
-@dataclasses.dataclass(**DATACLASS_SLOTS)
+@dataclasses.dataclass(slots=True)
class DoorLiningProperties:
LiningDepth: Optional[float] = None
"""Optional, defaults to 50mm."""
@@ -173,7 +172,7 @@ class DoorLiningProperties:
setattr(self, attr, default_value * si_conversion)
-@dataclasses.dataclass(**DATACLASS_SLOTS)
+@dataclasses.dataclass(slots=True)
class DoorPanelProperties:
PanelDepth: Optional[float] = None
"""Frame thickness by Y axis. Optional, defaults to 35 mm."""
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_mesh_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_mesh_representation.py
index 9a4b41a4df..91f816041f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_mesh_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_mesh_representation.py
@@ -16,11 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.unit
+from typing import Optional, TypeVar
+
import numpy as np
import numpy.typing as npt
-from ifcopenshell.util.shape_builder import ShapeBuilder, SequenceOfVectors, VectorType
-from typing import Optional, TypeVar
+
+import ifcopenshell.util.unit
+from ifcopenshell.util.shape_builder import SequenceOfVectors, ShapeBuilder, VectorType
T = TypeVar("T")
COORD_3D = tuple[float, float, float]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_profile_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_profile_representation.py
index 9458131046..754b7ded03 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_profile_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_profile_representation.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Literal, Optional, Union, get_args
+
import ifcopenshell.geom
import ifcopenshell.util.element
import ifcopenshell.util.shape
import ifcopenshell.util.unit
from ifcopenshell.util.data import Clipping
-from typing import Any, Union, Optional, Literal, get_args
VECTOR_3D = tuple[float, float, float]
CardinalPointNumeric = Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_railing_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_railing_representation.py
index 5f81c51fd0..a3af58dfbf 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_railing_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_railing_representation.py
@@ -16,24 +16,26 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from math import cos, pi, radians, sin, tan
+from typing import Any, Literal, Optional
+
import numpy as np
+from typing_extensions import assert_never
+
import ifcopenshell.util.unit
from ifcopenshell.util.shape_builder import (
+ SequenceOfVectors,
ShapeBuilder,
V,
- SequenceOfVectors,
is_x,
np_angle,
np_angle_signed,
- np_normalized,
- np_to_3d,
- np_normal,
np_intersect_line_line,
np_lerp,
+ np_normal,
+ np_normalized,
+ np_to_3d,
)
-from math import pi, cos, sin, tan, radians
-from typing import Literal, Optional, Any
-from typing_extensions import assert_never
def mm(x: float) -> float:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py
index 3f3a9881a7..d77655a60c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py
@@ -16,16 +16,19 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
from __future__ import annotations
-import bpy.types
+
import math
+from typing import TYPE_CHECKING, Any, Literal, Optional, Union
+
import bmesh
-import ifcopenshell.util.shape_builder
-import ifcopenshell.util.unit
+import bpy.types
import numpy as np
import numpy.typing as npt
-from mathutils import Vector, Matrix
-from typing import Union, Optional, Literal, Any, TYPE_CHECKING
-from ifcopenshell.util.shape_builder import ifc_safe_vector_type, VectorType
+from mathutils import Matrix, Vector
+
+import ifcopenshell.util.shape_builder
+import ifcopenshell.util.unit
+from ifcopenshell.util.shape_builder import VectorType, ifc_safe_vector_type
if TYPE_CHECKING:
import bonsai.tool as tool
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_shape_aspect.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_shape_aspect.py
index 2f4ee941fe..afb8489a4c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_shape_aspect.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_shape_aspect.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Optional
+import ifcopenshell
+
def add_shape_aspect(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_slab_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_slab_representation.py
index f6a6f85d1a..284f6e7c30 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_slab_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_slab_representation.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from math import cos, sin
+from typing import Any, Optional, Union
+
import ifcopenshell.util.element
import ifcopenshell.util.unit
from ifcopenshell.util.data import Clipping
-from math import sin, cos
-from typing import Any, Optional, Union
def add_slab_representation(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_wall_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_wall_representation.py
index 53e2f58660..4c108dc7df 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_wall_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_wall_representation.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from math import cos, pi, sin
+from typing import Any, Optional, Union
+
import ifcopenshell.util.element
import ifcopenshell.util.unit
-from math import sin, cos, pi
-from typing import Optional, Union, Any
from ifcopenshell.util.data import Clipping
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_window_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_window_representation.py
index 298ec18f70..36848e7883 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_window_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_window_representation.py
@@ -17,17 +17,16 @@
# along with IfcOpenShell. If not, see .
from __future__ import annotations
-import sys
-import numpy as np
+
import dataclasses
+from itertools import chain
+from typing import Any, Literal, Optional, Union, overload
+
+import numpy as np
+
import ifcopenshell.api.geometry
import ifcopenshell.util.unit
-from itertools import chain
from ifcopenshell.util.shape_builder import ShapeBuilder, V
-from typing import Any, Optional, Literal, Union, overload
-
-DATACLASS_SLOTS = {} if sys.version_info < (3, 10) else {"slots": True}
-ZIP_STRICT = {} if sys.version_info < (3, 10) else {"strict": True}
# SCHEMAS describe panels setup
# where:
@@ -169,7 +168,7 @@ def window_l_shape_check(
"""`lining_thickness` and `lining_to_panel_offset_x` expected to be defined as a list,
similarly to `create_ifc_window_frame_simple` `thickness` argument"""
l_shape_check = lining_to_panel_offset_y_full < lining_depth and any(
- x_offset < th for th, x_offset in zip(lining_thickness, lining_to_panel_offset_x, **ZIP_STRICT)
+ x_offset < th for th, x_offset in zip(lining_thickness, lining_to_panel_offset_x, strict=True)
)
return l_shape_check
@@ -211,7 +210,7 @@ def create_ifc_window(
second_lining_size = lining_size.copy()
second_lining_size[np_Y] = lining_size[np_Y] - lining_to_panel_offset_y_full
second_lining_position = V(0, lining_to_panel_offset_y_full, 0)
- second_lining_thickness = [min(th, x_offset) for th, x_offset in zip(lining_thickness, x_offsets, **ZIP_STRICT)]
+ second_lining_thickness = [min(th, x_offset) for th, x_offset in zip(lining_thickness, x_offsets, strict=True)]
second_lining_items = create_ifc_window_frame_simple(
builder, second_lining_size, second_lining_thickness, second_lining_position
@@ -241,7 +240,7 @@ def create_ifc_window(
# we use dataclass as we need default values for arguments
# it's okay to use slots since we don't need dynamic attributes
-@dataclasses.dataclass(**DATACLASS_SLOTS)
+@dataclasses.dataclass(slots=True)
class WindowLiningProperties:
LiningDepth: Optional[float] = None
"""Optional, defaults to 50mm."""
@@ -324,7 +323,7 @@ class WindowLiningProperties:
setattr(self, attr, default_value * si_conversion)
-@dataclasses.dataclass(**DATACLASS_SLOTS)
+@dataclasses.dataclass(slots=True)
class WindowPanelProperties:
FrameDepth: Optional[float] = None
"""Frame thickness by Y axis. Optional, defaults to 35 mm."""
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/assign_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/assign_representation.py
index 5b62fd4639..158f0152ac 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/assign_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/assign_representation.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.owner
-import ifcopenshell.api.geometry
-import ifcopenshell.util.element
from typing import Any
+import ifcopenshell.api.geometry
+import ifcopenshell.api.owner
+import ifcopenshell.util.element
+
def assign_representation(
file: ifcopenshell.file, product: ifcopenshell.entity_instance, representation: ifcopenshell.entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/connect_element.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/connect_element.py
index f737b54c77..1222d458a2 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/connect_element.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/connect_element.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Optional
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
-from typing import Optional
def connect_element(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/connect_path.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/connect_path.py
index 81fa276a2c..3135bef116 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/connect_path.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/connect_path.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Optional
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
-from typing import Optional
def connect_path(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/connect_wall.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/connect_wall.py
index 8666a38693..c63139b451 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/connect_wall.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/connect_wall.py
@@ -16,13 +16,15 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Optional
+
import numpy as np
+
import ifcopenshell
import ifcopenshell.api.geometry
import ifcopenshell.util.placement
import ifcopenshell.util.representation
import ifcopenshell.util.shape_builder
-from typing import Optional
def connect_wall(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/create_2pt_wall.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/create_2pt_wall.py
index 3401b29c7a..72449ada84 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/create_2pt_wall.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/create_2pt_wall.py
@@ -16,10 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any
+
import numpy as np
+
import ifcopenshell.api.geometry
import ifcopenshell.util.unit
-from typing import Any
def create_2pt_wall(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/disconnect_path.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/disconnect_path.py
index 787f7a5633..6e04a9df73 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/disconnect_path.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/disconnect_path.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Optional
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.element
-from typing import Optional
def disconnect_path(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py
index 2e37e99e26..7fbe44ce12 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py
@@ -16,14 +16,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Optional, Union
+
import numpy as np
import numpy.typing as npt
+
import ifcopenshell.api.owner
-import ifcopenshell.util.unit
import ifcopenshell.util.element
import ifcopenshell.util.placement
+import ifcopenshell.util.unit
from ifcopenshell.util.shape_builder import ShapeBuilder
-from typing import Optional, Union, Any
NPArrayOfFloats = npt.NDArray[np.float64]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/regenerate_wall_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/regenerate_wall_representation.py
index 0cce951810..9143577438 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/regenerate_wall_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/regenerate_wall_representation.py
@@ -17,7 +17,12 @@
# along with IfcOpenShell. If not, see .
import json
+from collections import namedtuple
+from math import cos, sin
+from typing import Optional
+
import numpy as np
+
import ifcopenshell
import ifcopenshell.api.context
import ifcopenshell.api.geometry
@@ -26,9 +31,6 @@ import ifcopenshell.util.placement
import ifcopenshell.util.representation
import ifcopenshell.util.shape_builder
import ifcopenshell.util.unit
-from collections import namedtuple
-from math import sin, cos
-from typing import Optional
# https://stackoverflow.com/a/9184560/9627415
# Possible optimisation to linalg.norm?
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/unassign_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/unassign_representation.py
index 5dc3bf3aeb..db4f231aff 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/unassign_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/unassign_representation.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any
+
import ifcopenshell.api.geometry
import ifcopenshell.util.element
-from typing import Any
def unassign_representation(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/validate_type.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/validate_type.py
index b5970e4d44..46bec8757b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/validate_type.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/validate_type.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell.api.geometry
import ifcopenshell.util.representation
-from typing import Union
def validate_type(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/georeference/edit_georeferencing.py b/src/ifcopenshell-python/ifcopenshell/api/georeference/edit_georeferencing.py
index 0d4da93bcb..070797356b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/georeference/edit_georeferencing.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/georeference/edit_georeferencing.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Optional
+
import ifcopenshell
import ifcopenshell.api.pset
import ifcopenshell.util.element
-from typing import Optional, Any
def edit_georeferencing(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/georeference/edit_true_north.py b/src/ifcopenshell-python/ifcopenshell/api/georeference/edit_true_north.py
index 0a7e967fbd..5a39f917f4 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/georeference/edit_true_north.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/georeference/edit_true_north.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Optional, Union
+
import ifcopenshell
import ifcopenshell.util.element
import ifcopenshell.util.geolocation
-from typing import Union, Optional
def edit_true_north(file: ifcopenshell.file, true_north: Optional[Union[tuple[float, float], float]] = 0.0) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/georeference/edit_wcs.py b/src/ifcopenshell-python/ifcopenshell/api/georeference/edit_wcs.py
index 25fb4f3b6e..126072e254 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/georeference/edit_wcs.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/georeference/edit_wcs.py
@@ -16,12 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from math import cos, radians, sin
+
+import numpy as np
+
import ifcopenshell
import ifcopenshell.util.element
import ifcopenshell.util.unit
-import numpy as np
from ifcopenshell.util.shape_builder import ShapeBuilder
-from math import sin, cos, radians
def edit_wcs(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/grid/__init__.py b/src/ifcopenshell-python/ifcopenshell/api/grid/__init__.py
index cc759ce7e0..4d821057da 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/grid/__init__.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/grid/__init__.py
@@ -22,7 +22,6 @@ A grid in IFC may contain two or more axes running in two or more directions.
"""
from .. import wrap_usecases
-
from .create_axis_curve import create_axis_curve
from .create_grid_axis import create_grid_axis
from .remove_grid_axis import remove_grid_axis
diff --git a/src/ifcopenshell-python/ifcopenshell/api/grid/create_axis_curve.py b/src/ifcopenshell-python/ifcopenshell/api/grid/create_axis_curve.py
index b87eea94d0..a71c523c3f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/grid/create_axis_curve.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/grid/create_axis_curve.py
@@ -17,12 +17,19 @@
# along with IfcOpenShell. If not, see .
from __future__ import annotations
+
+import numpy as np
+
import ifcopenshell
import ifcopenshell.util.element
-import ifcopenshell.util.unit
import ifcopenshell.util.placement
-import numpy as np
-from ifcopenshell.util.shape_builder import VectorType, V, ifc_safe_vector_type, np_apply_matrix
+import ifcopenshell.util.unit
+from ifcopenshell.util.shape_builder import (
+ V,
+ VectorType,
+ ifc_safe_vector_type,
+ np_apply_matrix,
+)
def create_axis_curve(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/grid/create_grid_axis.py b/src/ifcopenshell-python/ifcopenshell/api/grid/create_grid_axis.py
index 77228434b0..7500ab1f55 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/grid/create_grid_axis.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/grid/create_grid_axis.py
@@ -15,8 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Literal, Optional
+
import ifcopenshell
-from typing import Optional, Literal
def create_grid_axis(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/add_group.py b/src/ifcopenshell-python/ifcopenshell/api/group/add_group.py
index a2a877ef6e..4dd10adfe3 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/group/add_group.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/group/add_group.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Optional
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
-from typing import Optional
def add_group(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/assign_group.py b/src/ifcopenshell-python/ifcopenshell/api/group/assign_group.py
index cb9cd95fea..544a889cc0 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/group/assign_group.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/group/assign_group.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
-from typing import Union
def assign_group(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/edit_group.py b/src/ifcopenshell-python/ifcopenshell/api/group/edit_group.py
index 5a7a2b2018..55ee85e0f8 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/group/edit_group.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/group/edit_group.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_group(file: ifcopenshell.file, group: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcGroup
diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py
index 8a3c1dc95f..cd61465326 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Optional
+import ifcopenshell
+
def add_layer(file: ifcopenshell.file, name: str = "Unnamed") -> ifcopenshell.entity_instance:
"""Adds a new layer
diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer_with_style.py b/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer_with_style.py
index f3af61a81c..ffdf67fec0 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer_with_style.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/layer/add_layer_with_style.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-from typing import Union, Literal
from collections.abc import Sequence
+from typing import Literal, Union
+
+import ifcopenshell
IfcLogical = Union[bool, Literal["UNKNOWN"]]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/layer/edit_layer.py b/src/ifcopenshell-python/ifcopenshell/api/layer/edit_layer.py
index 7203fabb0c..5e51b1ec39 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/layer/edit_layer.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/layer/edit_layer.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_layer(file: ifcopenshell.file, layer: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcPresentationLayerAssignment
diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py b/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py
index a8ce0690d4..debdded93a 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py
@@ -17,8 +17,8 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.util.schema
import ifcopenshell.util.date
+import ifcopenshell.util.schema
def add_library(file: ifcopenshell.file, name: str) -> ifcopenshell.entity_instance:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/assign_reference.py b/src/ifcopenshell-python/ifcopenshell/api/library/assign_reference.py
index a9b6169304..2d0cb59906 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/library/assign_reference.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/library/assign_reference.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
-from typing import Union
def assign_reference(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/edit_library.py b/src/ifcopenshell-python/ifcopenshell/api/library/edit_library.py
index 4e12195bda..430ddc96a2 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/library/edit_library.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/library/edit_library.py
@@ -15,11 +15,12 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.util.date
import datetime
from typing import Any
+import ifcopenshell
+import ifcopenshell.util.date
+
def edit_library(file: ifcopenshell.file, library: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcLibraryInformation
diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/edit_reference.py b/src/ifcopenshell-python/ifcopenshell/api/library/edit_reference.py
index e6acacbd8f..7860c41943 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/library/edit_reference.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/library/edit_reference.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_reference(
file: ifcopenshell.file, reference: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/unassign_reference.py b/src/ifcopenshell-python/ifcopenshell/api/library/unassign_reference.py
index 5dd40749b9..5190b91ccb 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/library/unassign_reference.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/library/unassign_reference.py
@@ -17,8 +17,8 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.util.element
import ifcopenshell.api.owner
+import ifcopenshell.util.element
def unassign_reference(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/add_constituent.py b/src/ifcopenshell-python/ifcopenshell/api/material/add_constituent.py
index 3a2dad4ba2..057ff0849e 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/add_constituent.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/add_constituent.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Optional
+import ifcopenshell
+
def add_constituent(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/add_layer.py b/src/ifcopenshell-python/ifcopenshell/api/material/add_layer.py
index 5fae2ed275..db717528ec 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/add_layer.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/add_layer.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Optional
+
import ifcopenshell
import ifcopenshell.util.unit
-from typing import Optional
def add_layer(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/add_material.py b/src/ifcopenshell-python/ifcopenshell/api/material/add_material.py
index 6b04f78be2..87f5e4cdb4 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/add_material.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/add_material.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Optional
+import ifcopenshell
+
def add_material(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/add_material_set.py b/src/ifcopenshell-python/ifcopenshell/api/material/add_material_set.py
index bd23688ac8..f679d4c8f0 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/add_material_set.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/add_material_set.py
@@ -15,9 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Literal
+import ifcopenshell
MATERIAL_SET_TYPE = Literal[
"IfcMaterialLayerSet",
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/add_profile.py b/src/ifcopenshell-python/ifcopenshell/api/material/add_profile.py
index 160f79e453..87746cee30 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/add_profile.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/add_profile.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Optional
+import ifcopenshell
+
def add_profile(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/assign_material.py b/src/ifcopenshell-python/ifcopenshell/api/material/assign_material.py
index 0e37eef148..47c888bb1c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/assign_material.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/assign_material.py
@@ -16,14 +16,15 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from collections import defaultdict
+from typing import Any, Optional, Union
+
import ifcopenshell
-import ifcopenshell.api.owner
import ifcopenshell.api.material
+import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.representation
-from collections import defaultdict
-from typing import Optional, Union, Any
def assign_material(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/assign_profile.py b/src/ifcopenshell-python/ifcopenshell/api/material/assign_profile.py
index ce269dbc86..23a5a216b8 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/assign_profile.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/assign_profile.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.representation
from typing import Any
+import ifcopenshell.util.representation
+
def assign_profile(
file: ifcopenshell.file, material_profile: ifcopenshell.entity_instance, profile: ifcopenshell.entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/edit_assigned_material.py b/src/ifcopenshell-python/ifcopenshell/api/material/edit_assigned_material.py
index 9a01322743..09886c90fd 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/edit_assigned_material.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/edit_assigned_material.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_assigned_material(
file: ifcopenshell.file, element: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/edit_constituent.py b/src/ifcopenshell-python/ifcopenshell/api/material/edit_constituent.py
index a7398ca5f0..165a3655d5 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/edit_constituent.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/edit_constituent.py
@@ -15,8 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Optional
+
import ifcopenshell
-from typing import Optional, Any
def edit_constituent(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/edit_layer.py b/src/ifcopenshell-python/ifcopenshell/api/material/edit_layer.py
index 68f3c6d832..b21530faa3 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/edit_layer.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/edit_layer.py
@@ -15,8 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Optional
+
import ifcopenshell
-from typing import Optional, Any
def edit_layer(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/edit_layer_usage.py b/src/ifcopenshell-python/ifcopenshell/api/material/edit_layer_usage.py
index 9d1ffb14ec..35916f9c50 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/edit_layer_usage.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/edit_layer_usage.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_layer_usage(file: ifcopenshell.file, usage: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcMaterialLayerSetUsage
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/edit_material.py b/src/ifcopenshell-python/ifcopenshell/api/material/edit_material.py
index ddf541503c..749f3b0ea0 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/edit_material.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/edit_material.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_material(file: ifcopenshell.file, material: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcMaterial"""
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/edit_profile.py b/src/ifcopenshell-python/ifcopenshell/api/material/edit_profile.py
index 3bc7479388..5dec072609 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/edit_profile.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/edit_profile.py
@@ -18,6 +18,7 @@
from typing import Any, Optional
+
import ifcopenshell
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/edit_profile_usage.py b/src/ifcopenshell-python/ifcopenshell/api/material/edit_profile_usage.py
index 4c004ecfdd..2d7cdcbca8 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/edit_profile_usage.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/edit_profile_usage.py
@@ -15,11 +15,12 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any
+
import ifcopenshell.geom
import ifcopenshell.util.representation
import ifcopenshell.util.shape
from ifcopenshell.geom import ShapeType
-from typing import Any
def edit_profile_usage(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/set_shape_aspect_constituents.py b/src/ifcopenshell-python/ifcopenshell/api/material/set_shape_aspect_constituents.py
index d95f877fcf..bd0fdf9683 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/set_shape_aspect_constituents.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/set_shape_aspect_constituents.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.style
import ifcopenshell.api.material
+import ifcopenshell.api.style
import ifcopenshell.util.element
import ifcopenshell.util.representation
diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/unassign_material.py b/src/ifcopenshell-python/ifcopenshell/api/material/unassign_material.py
index 51d11b3248..00a39a4120 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/material/unassign_material.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/material/unassign_material.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.util.element
-from typing import Any
def unassign_material(file: ifcopenshell.file, products: list[ifcopenshell.entity_instance]) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/nest/assign_object.py b/src/ifcopenshell-python/ifcopenshell/api/nest/assign_object.py
index 290ac58b05..d3432b617f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/nest/assign_object.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/nest/assign_object.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
-from typing import Union
def assign_object(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/add_actor.py b/src/ifcopenshell-python/ifcopenshell/api/owner/add_actor.py
index 1456a99d5e..8b3a8306fd 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/add_actor.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/add_actor.py
@@ -17,10 +17,10 @@
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.api.root
from typing import Literal
+import ifcopenshell
+import ifcopenshell.api.root
ACTOR_TYPE = Literal["IfcActor", "IfcOccupant"]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/add_address.py b/src/ifcopenshell-python/ifcopenshell/api/owner/add_address.py
index 791f41c6a2..7d40e9a420 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/add_address.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/add_address.py
@@ -15,9 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Literal
+import ifcopenshell
ADDRESS_TYPE = Literal["IfcPostalAddress", "IfcTelecomAddress"]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/add_application.py b/src/ifcopenshell-python/ifcopenshell/api/owner/add_application.py
index 665bebc292..8387ecf871 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/add_application.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/add_application.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Optional, Union
+
import ifcopenshell.api
import ifcopenshell.api.owner
import ifcopenshell.api.pset
-from typing import Optional, Any, Union
def add_application(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/create_owner_history.py b/src/ifcopenshell-python/ifcopenshell/api/owner/create_owner_history.py
index 296834062e..39b118446c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/create_owner_history.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/create_owner_history.py
@@ -17,9 +17,10 @@
# along with IfcOpenShell. If not, see .
import time
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.owner.settings
-from typing import Union
def create_owner_history(file: ifcopenshell.file) -> Union[ifcopenshell.entity_instance, None]:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/edit_actor.py b/src/ifcopenshell-python/ifcopenshell/api/owner/edit_actor.py
index 8ad238f994..e976d9e09e 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/edit_actor.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/edit_actor.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_actor(file: ifcopenshell.file, actor: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcActor
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/edit_address.py b/src/ifcopenshell-python/ifcopenshell/api/owner/edit_address.py
index 52e80d6ef1..d274989eec 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/edit_address.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/edit_address.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_address(file: ifcopenshell.file, address: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcAddress
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/edit_application.py b/src/ifcopenshell-python/ifcopenshell/api/owner/edit_application.py
index 3224169ff2..631265f522 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/edit_application.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/edit_application.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_application(
file: ifcopenshell.file, application: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/edit_organisation.py b/src/ifcopenshell-python/ifcopenshell/api/owner/edit_organisation.py
index a2bb5e3eb6..2f0a8af568 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/edit_organisation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/edit_organisation.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_organisation(
file: ifcopenshell.file, organisation: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/edit_person.py b/src/ifcopenshell-python/ifcopenshell/api/owner/edit_person.py
index 6b697bd674..3c53fabdd4 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/edit_person.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/edit_person.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_person(file: ifcopenshell.file, person: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcPerson
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/edit_role.py b/src/ifcopenshell-python/ifcopenshell/api/owner/edit_role.py
index fca80a16b0..8fb293c151 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/edit_role.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/edit_role.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_role(file: ifcopenshell.file, role: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcActorRole
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/remove_organisation.py b/src/ifcopenshell-python/ifcopenshell/api/owner/remove_organisation.py
index acee11d9f5..fa5434d289 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/remove_organisation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/remove_organisation.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.root
import ifcopenshell.api.owner
+import ifcopenshell.api.root
def remove_organisation(file: ifcopenshell.file, organisation: ifcopenshell.entity_instance) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/remove_person.py b/src/ifcopenshell-python/ifcopenshell/api/owner/remove_person.py
index 0c618c1e74..4fc86d70c8 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/remove_person.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/remove_person.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.root
import ifcopenshell.api.owner
+import ifcopenshell.api.root
def remove_person(file: ifcopenshell.file, person: ifcopenshell.entity_instance) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/settings.py b/src/ifcopenshell-python/ifcopenshell/api/owner/settings.py
index b5dedfff49..035107da73 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/settings.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/settings.py
@@ -19,9 +19,10 @@
# Note: it is the intent for you to override these with your own functions
-import ifcopenshell
from typing import Union
+import ifcopenshell
+
def get_application(ifc: ifcopenshell.file) -> Union[ifcopenshell.entity_instance, None]:
"""Returns the application representing the authoring software
diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/update_owner_history.py b/src/ifcopenshell-python/ifcopenshell/api/owner/update_owner_history.py
index 99ec6f18d5..7df304778a 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/owner/update_owner_history.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/owner/update_owner_history.py
@@ -17,11 +17,12 @@
# along with IfcOpenShell. If not, see .
import time
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.owner.settings
import ifcopenshell.util.element
-from typing import Union
def update_owner_history(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/profile/add_arbitrary_profile.py b/src/ifcopenshell-python/ifcopenshell/api/profile/add_arbitrary_profile.py
index 80f3b8cf71..5874986031 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/profile/add_arbitrary_profile.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/profile/add_arbitrary_profile.py
@@ -16,11 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import numpy.typing as npt
-import ifcopenshell.util.unit
-from ifcopenshell.util.shape_builder import V, SequenceOfVectors, ifc_safe_vector_type
from typing import Optional, Union
+import numpy.typing as npt
+
+import ifcopenshell.util.unit
+from ifcopenshell.util.shape_builder import SequenceOfVectors, V, ifc_safe_vector_type
+
def add_arbitrary_profile(
file: ifcopenshell.file, profile: SequenceOfVectors, name: Optional[str] = None
diff --git a/src/ifcopenshell-python/ifcopenshell/api/profile/add_arbitrary_profile_with_voids.py b/src/ifcopenshell-python/ifcopenshell/api/profile/add_arbitrary_profile_with_voids.py
index b813a3c65f..5a78cd400f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/profile/add_arbitrary_profile_with_voids.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/profile/add_arbitrary_profile_with_voids.py
@@ -16,11 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.unit
-import numpy.typing as npt
-from ifcopenshell.util.shape_builder import SequenceOfVectors, ifc_safe_vector_type, V
from typing import Optional, Union
+import numpy.typing as npt
+
+import ifcopenshell.util.unit
+from ifcopenshell.util.shape_builder import SequenceOfVectors, V, ifc_safe_vector_type
+
def add_arbitrary_profile_with_voids(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/profile/add_parameterized_profile.py b/src/ifcopenshell-python/ifcopenshell/api/profile/add_parameterized_profile.py
index 12c57532b0..02f93a4a20 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/profile/add_parameterized_profile.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/profile/add_parameterized_profile.py
@@ -15,9 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Literal
+import ifcopenshell
ProfileType = Literal["AREA", "CURVE"]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/profile/edit_profile.py b/src/ifcopenshell-python/ifcopenshell/api/profile/edit_profile.py
index ba7bc3cfeb..4766f6c59b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/profile/edit_profile.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/profile/edit_profile.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_profile(file: ifcopenshell.file, profile: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcProfileDef
diff --git a/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py b/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py
index 22eb022e99..c3f55d6795 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py
@@ -16,20 +16,21 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from collections.abc import Callable
+from functools import partial
+from typing import Any, Literal, Optional, Union, get_args
+
import ifcopenshell
-import ifcopenshell.ifcopenshell_wrapper as W
-import ifcopenshell.api.geometry
-import ifcopenshell.api.type
-import ifcopenshell.api.project
import ifcopenshell.api.context
+import ifcopenshell.api.geometry
import ifcopenshell.api.owner.settings
+import ifcopenshell.api.project
+import ifcopenshell.api.type
+import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.util.element
import ifcopenshell.util.geolocation
import ifcopenshell.util.placement
import ifcopenshell.util.unit
-from typing import Optional, Any, Union, Literal, get_args, Callable
-from functools import partial
-
APPENDABLE_ASSET = Literal[
"IfcTypeProduct",
diff --git a/src/ifcopenshell-python/ifcopenshell/api/project/assign_declaration.py b/src/ifcopenshell-python/ifcopenshell/api/project/assign_declaration.py
index 2daa7dc729..35f76ac7bd 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/project/assign_declaration.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/project/assign_declaration.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
-from typing import Union
def assign_declaration(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/project/create_file.py b/src/ifcopenshell-python/ifcopenshell/api/project/create_file.py
index 41bc45fdd5..e122ba766b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/project/create_file.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/project/create_file.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import datetime
+
import ifcopenshell
import ifcopenshell.util.schema
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset/add_pset.py b/src/ifcopenshell-python/ifcopenshell/api/pset/add_pset.py
index f1a99bd847..a1075334de 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset/add_pset.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset/add_pset.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Optional
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.api.pset
import ifcopenshell.guid
-from typing import Optional, Any
def add_pset(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset/add_qto.py b/src/ifcopenshell-python/ifcopenshell/api/pset/add_qto.py
index 695ca21dd8..229a43f4ae 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset/add_qto.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset/add_qto.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
-from typing import Any
def add_qto(file: ifcopenshell.file, product: ifcopenshell.entity_instance, name: str) -> ifcopenshell.entity_instance:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset/assign_pset.py b/src/ifcopenshell-python/ifcopenshell/api/pset/assign_pset.py
index ed309944a1..eef7f6e8e9 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset/assign_pset.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset/assign_pset.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
-from typing import Union
def assign_pset(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py b/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py
index 35ef9ee6a8..97730760e7 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import datetime
+from typing import Any, Optional, Union
+
import ifcopenshell
import ifcopenshell.util.element
import ifcopenshell.util.pset
-from typing import Optional, Any, Union
def edit_pset(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset/edit_qto.py b/src/ifcopenshell-python/ifcopenshell/api/pset/edit_qto.py
index 54405efdd1..41bd4fbecf 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset/edit_qto.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset/edit_qto.py
@@ -16,11 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Optional, Union
+
+from typing_extensions import assert_never
+
import ifcopenshell
import ifcopenshell.api.pset
import ifcopenshell.util.pset
-from typing import Optional, Any, Union
-from typing_extensions import assert_never
FLOAT_TYPE_KEYWORDS = (
("Area", ("area",)),
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset_template/add_prop_template.py b/src/ifcopenshell-python/ifcopenshell/api/pset_template/add_prop_template.py
index 39d1987fa4..f9cb427d3b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset_template/add_prop_template.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset_template/add_prop_template.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Optional
+
import ifcopenshell
import ifcopenshell.guid
import ifcopenshell.util.pset
-from typing import Optional
def add_prop_template(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset_template/edit_prop_template.py b/src/ifcopenshell-python/ifcopenshell/api/pset_template/edit_prop_template.py
index 3677a8e63e..b6ea4e823c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset_template/edit_prop_template.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset_template/edit_prop_template.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_prop_template(
file: ifcopenshell.file, prop_template: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset_template/edit_pset_template.py b/src/ifcopenshell-python/ifcopenshell/api/pset_template/edit_pset_template.py
index d143b5554e..2fdd445f98 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset_template/edit_pset_template.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset_template/edit_pset_template.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_pset_template(
file: ifcopenshell.file, pset_template: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/resource/add_resource.py b/src/ifcopenshell-python/ifcopenshell/api/resource/add_resource.py
index 691ad2ec6a..642673f2dc 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/resource/add_resource.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/resource/add_resource.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.root
+from typing import Optional
+
import ifcopenshell.api.nest
import ifcopenshell.api.project
-from typing import Optional
+import ifcopenshell.api.root
def add_resource(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/resource/calculate_resource_usage.py b/src/ifcopenshell-python/ifcopenshell/api/resource/calculate_resource_usage.py
index 545016bfd2..24815d45e0 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/resource/calculate_resource_usage.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/resource/calculate_resource_usage.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import math
+
import ifcopenshell.api
import ifcopenshell.util.constraint
import ifcopenshell.util.date
diff --git a/src/ifcopenshell-python/ifcopenshell/api/resource/edit_resource.py b/src/ifcopenshell-python/ifcopenshell/api/resource/edit_resource.py
index 3476032c1a..27c27e519e 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/resource/edit_resource.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/resource/edit_resource.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_resource(file: ifcopenshell.file, resource: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcResource
diff --git a/src/ifcopenshell-python/ifcopenshell/api/resource/edit_resource_quantity.py b/src/ifcopenshell-python/ifcopenshell/api/resource/edit_resource_quantity.py
index 87a14774d8..18a2877484 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/resource/edit_resource_quantity.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/resource/edit_resource_quantity.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_resource_quantity(
file: ifcopenshell.file, physical_quantity: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/resource/edit_resource_time.py b/src/ifcopenshell-python/ifcopenshell/api/resource/edit_resource_time.py
index 7326a5fd90..45dc7cc5e1 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/resource/edit_resource_time.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/resource/edit_resource_time.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any
+
import ifcopenshell
import ifcopenshell.api.sequence
import ifcopenshell.util.constraint
import ifcopenshell.util.date
import ifcopenshell.util.resource
-from typing import Any
def edit_resource_time(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/root/copy_class.py b/src/ifcopenshell-python/ifcopenshell/api/root/copy_class.py
index 167680bd78..867f25f727 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/root/copy_class.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/root/copy_class.py
@@ -16,15 +16,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any
+
import ifcopenshell
+import ifcopenshell.api.geometry
import ifcopenshell.api.material
import ifcopenshell.api.root
import ifcopenshell.api.system
-import ifcopenshell.api.geometry
-import ifcopenshell.util.system
import ifcopenshell.util.element
import ifcopenshell.util.placement
-from typing import Any
+import ifcopenshell.util.system
def copy_class(file: ifcopenshell.file, product: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/root/create_entity.py b/src/ifcopenshell-python/ifcopenshell/api/root/create_entity.py
index 96a3b130be..6afe5ec3a6 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/root/create_entity.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/root/create_entity.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Optional
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
-from typing import Optional, Any
def create_entity(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/root/reassign_class.py b/src/ifcopenshell-python/ifcopenshell/api/root/reassign_class.py
index 18ff02b199..c7971bc4f7 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/root/reassign_class.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/root/reassign_class.py
@@ -16,6 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Literal, Optional, Union
+
import ifcopenshell
import ifcopenshell.api.aggregate
import ifcopenshell.api.geometry
@@ -23,11 +25,10 @@ import ifcopenshell.api.pset
import ifcopenshell.api.spatial
import ifcopenshell.api.type
import ifcopenshell.guid
-import ifcopenshell.util.representation
-import ifcopenshell.util.type
-import ifcopenshell.util.schema
import ifcopenshell.util.element
-from typing import Optional, Union, Literal
+import ifcopenshell.util.representation
+import ifcopenshell.util.schema
+import ifcopenshell.util.type
def reassign_class(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py b/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py
index df17e3bb69..9f1724d914 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py
@@ -16,14 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.type
-import ifcopenshell.api.grid
-import ifcopenshell.api.feature
-import ifcopenshell.api.root
-import ifcopenshell.api.pset
import ifcopenshell.api.boundary
-import ifcopenshell.api.material
+import ifcopenshell.api.feature
import ifcopenshell.api.geometry
+import ifcopenshell.api.grid
+import ifcopenshell.api.material
+import ifcopenshell.api.pset
+import ifcopenshell.api.root
+import ifcopenshell.api.type
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_date_time.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_date_time.py
index 96017a0807..3c029add56 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_date_time.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_date_time.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.date
from datetime import datetime
from typing import Union
+import ifcopenshell.util.date
+
def add_date_time(file: ifcopenshell.file, dt: datetime) -> Union[str, ifcopenshell.entity_instance]:
"""Add a new date time.
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_task.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_task.py
index 36d7d452b1..b8d0d05c15 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_task.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_task.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.control
-import ifcopenshell.api.root
-import ifcopenshell.api.nest
-import ifcopenshell
from typing import Optional
+import ifcopenshell
+import ifcopenshell.api.control
+import ifcopenshell.api.nest
+import ifcopenshell.api.root
+
def add_task(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_time_period.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_time_period.py
index 41e0785b1d..8a72d2044d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_time_period.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_time_period.py
@@ -16,12 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from datetime import datetime, time, timedelta
+from typing import Optional, Union
+
import ifcopenshell.api
import ifcopenshell.util.date
import ifcopenshell.util.sequence
-from datetime import datetime, time
-from datetime import timedelta
-from typing import Optional, Union
def add_time_period(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_calendar.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_calendar.py
index c530a766de..2be4456f0f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_calendar.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_calendar.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.root
import ifcopenshell.api.project
+import ifcopenshell.api.root
def add_work_calendar(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_plan.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_plan.py
index 75ab9944be..088199c82c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_plan.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_plan.py
@@ -16,13 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.root
-import ifcopenshell.api.project
-import ifcopenshell.api.owner.settings
-import ifcopenshell.api.sequence
from datetime import datetime, time
from typing import Optional, Union
+import ifcopenshell.api.owner.settings
+import ifcopenshell.api.project
+import ifcopenshell.api.root
+import ifcopenshell.api.sequence
+
def add_work_plan(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_schedule.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_schedule.py
index 35fa1052ce..06a3fa9e8f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_schedule.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_schedule.py
@@ -16,14 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.root
-import ifcopenshell.api.project
+from datetime import datetime, time
+from typing import Optional, Union
+
import ifcopenshell.api.aggregate
import ifcopenshell.api.owner.settings
+import ifcopenshell.api.project
+import ifcopenshell.api.root
import ifcopenshell.api.sequence
-from datetime import time
-from datetime import datetime
-from typing import Union, Optional
def add_work_schedule(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_time.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_time.py
index 05b4960e09..74317f620f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_time.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_time.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Literal
+import ifcopenshell
+
TIME_TYPE = Literal["WorkingTimes", "ExceptionTimes"]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/assign_work_plan.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/assign_work_plan.py
index 4b2fd704f4..6c4dae83f6 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/assign_work_plan.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/assign_work_plan.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
-import ifcopenshell.api.project
-import ifcopenshell.api.aggregate
from typing import Union
+import ifcopenshell
+import ifcopenshell.api.aggregate
+import ifcopenshell.api.project
+
def assign_work_plan(
file: ifcopenshell.file, work_schedule: ifcopenshell.entity_instance, work_plan: ifcopenshell.entity_instance
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/calculate_task_duration.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/calculate_task_duration.py
index d5f0e5947e..1751f57ec0 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/calculate_task_duration.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/calculate_task_duration.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import math
+from typing import Union
+
import ifcopenshell.api.sequence
import ifcopenshell.util.date
import ifcopenshell.util.element
-from typing import Union
def calculate_task_duration(file: ifcopenshell.file, task: ifcopenshell.entity_instance) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/cascade_schedule.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/cascade_schedule.py
index 65cbd5a58a..17f2fa3bd5 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/cascade_schedule.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/cascade_schedule.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import datetime
+from typing import Optional, Union
+
import ifcopenshell.util.date
import ifcopenshell.util.sequence
from ifcopenshell.util.sequence import DURATION_TYPE
-from typing import Union, Optional
def cascade_schedule(file: ifcopenshell.file, task: ifcopenshell.entity_instance) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/create_baseline.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/create_baseline.py
index 00764a4f7c..f70ead281f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/create_baseline.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/create_baseline.py
@@ -16,15 +16,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Optional, Union
+
import ifcopenshell
-import ifcopenshell.api.owner
import ifcopenshell.api.control
+import ifcopenshell.api.owner
import ifcopenshell.api.sequence
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.sequence
import ifcopenshell.util.system
-from typing import Optional, Union
def create_baseline(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/duplicate_task.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/duplicate_task.py
index fb79581f6b..db9ed0f7db 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/duplicate_task.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/duplicate_task.py
@@ -17,10 +17,10 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.guid
import ifcopenshell.api.nest
import ifcopenshell.api.owner
import ifcopenshell.api.sequence
+import ifcopenshell.guid
import ifcopenshell.util.date
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_lag_time.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_lag_time.py
index d55bf0e4b5..5bf53eecfa 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_lag_time.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_lag_time.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any
+
import ifcopenshell.api.sequence
import ifcopenshell.util.date
-from typing import Any
def edit_lag_time(file: ifcopenshell.file, lag_time: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_recurrence_pattern.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_recurrence_pattern.py
index 519c5cdf25..4cfdb0f1b6 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_recurrence_pattern.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_recurrence_pattern.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any
+
import ifcopenshell
import ifcopenshell.util.sequence
-from typing import Any
def edit_recurrence_pattern(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_sequence.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_sequence.py
index 2686ec5ace..2569d8dab6 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_sequence.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_sequence.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any
+
import ifcopenshell
import ifcopenshell.api.sequence
-from typing import Any
def edit_sequence(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_task.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_task.py
index 3fa1b88caf..d2a2243805 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_task.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_task.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_task(file: ifcopenshell.file, task: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcTask
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_task_time.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_task_time.py
index ffde70580f..06e266b6dc 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_task_time.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_task_time.py
@@ -17,12 +17,13 @@
# along with IfcOpenShell. If not, see .
import datetime
-import ifcopenshell.api.sequence
+from typing import Any
+
import ifcopenshell.api.resource
+import ifcopenshell.api.sequence
import ifcopenshell.util.constraint
import ifcopenshell.util.date
import ifcopenshell.util.sequence
-from typing import Any
def edit_task_time(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_calendar.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_calendar.py
index 83e56a4372..7dfb65de3f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_calendar.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_calendar.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_work_calendar(
file: ifcopenshell.file, work_calendar: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_plan.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_plan.py
index 145460e11c..67ed76c255 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_plan.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_plan.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.date
from typing import Any
+import ifcopenshell.util.date
+
def edit_work_plan(
file: ifcopenshell.file, work_plan: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_schedule.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_schedule.py
index 98905b9a1f..158caff06d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_schedule.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_schedule.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.date
from typing import Any
+import ifcopenshell.util.date
+
def edit_work_schedule(
file: ifcopenshell.file, work_schedule: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_time.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_time.py
index 7fae8b4c18..0c3f5c625f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_time.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/edit_work_time.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.date
from typing import Any
+import ifcopenshell.util.date
+
def edit_work_time(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/recalculate_schedule.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/recalculate_schedule.py
index 14e82822e3..bfb68051be 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/recalculate_schedule.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/recalculate_schedule.py
@@ -17,7 +17,9 @@
# along with IfcOpenShell. If not, see .
import datetime
+
import networkx as nx
+
import ifcopenshell.api.sequence
import ifcopenshell.util.date
import ifcopenshell.util.sequence
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/remove_task.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/remove_task.py
index 107dcada2b..d42ad9a7b0 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/remove_task.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/remove_task.py
@@ -17,9 +17,9 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.api.pset
import ifcopenshell.api.nest
import ifcopenshell.api.project
+import ifcopenshell.api.pset
import ifcopenshell.api.sequence
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/remove_work_plan.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/remove_work_plan.py
index 1d7fd8ce3a..a0218b2074 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/remove_work_plan.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/remove_work_plan.py
@@ -17,8 +17,8 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import ifcopenshell.api.project
import ifcopenshell.api.aggregate
+import ifcopenshell.api.project
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/remove_work_schedule.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/remove_work_schedule.py
index d0bc15b0db..e9911e09ba 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/sequence/remove_work_schedule.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/remove_work_schedule.py
@@ -17,9 +17,9 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
+import ifcopenshell.api.aggregate
import ifcopenshell.api.project
import ifcopenshell.api.sequence
-import ifcopenshell.api.aggregate
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/api/spatial/assign_container.py b/src/ifcopenshell-python/ifcopenshell/api/spatial/assign_container.py
index 15f59905f6..a98e941776 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/spatial/assign_container.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/spatial/assign_container.py
@@ -16,14 +16,15 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
-import ifcopenshell.guid
-import ifcopenshell.api.owner
-import ifcopenshell.api.geometry
import ifcopenshell.api.aggregate
+import ifcopenshell.api.geometry
+import ifcopenshell.api.owner
+import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.placement
-from typing import Union
def assign_container(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/spatial/reference_structure.py b/src/ifcopenshell-python/ifcopenshell/api/spatial/reference_structure.py
index 41452244d1..4446971f0d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/spatial/reference_structure.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/spatial/reference_structure.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
-from typing import Union
def reference_structure(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/__init__.py b/src/ifcopenshell-python/ifcopenshell/api/structural/__init__.py
index 9406c5fc12..2baa262432 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/__init__.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/__init__.py
@@ -39,7 +39,9 @@ from .edit_structural_load import edit_structural_load
from .edit_structural_load_case import edit_structural_load_case
from .remove_structural_analysis_model import remove_structural_analysis_model
from .remove_structural_boundary_condition import remove_structural_boundary_condition
-from .remove_structural_connection_condition import remove_structural_connection_condition
+from .remove_structural_connection_condition import (
+ remove_structural_connection_condition,
+)
from .remove_structural_load import remove_structural_load
from .remove_structural_load_case import remove_structural_load_case
from .remove_structural_load_group import remove_structural_load_group
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_activity.py b/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_activity.py
index 466d26526f..ef12a4cb12 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_activity.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_activity.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.root
from typing import Literal
+import ifcopenshell.api.root
+
def add_structural_activity(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_boundary_condition.py b/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_boundary_condition.py
index 4e3ac0c1b9..c78bba2b68 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_boundary_condition.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_boundary_condition.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Optional
+import ifcopenshell
+
def add_structural_boundary_condition(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_load.py b/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_load.py
index ad79a58ce5..6a7d9eb03f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_load.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_load.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api
from typing import Optional
+import ifcopenshell.api
+
def add_structural_load(
file: ifcopenshell.file, name: Optional[str] = None, ifc_class: str = "IfcStructuralLoadLinearForce"
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/assign_structural_analysis_model.py b/src/ifcopenshell-python/ifcopenshell/api/structural/assign_structural_analysis_model.py
index dfae40d862..e378b3d984 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/assign_structural_analysis_model.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/assign_structural_analysis_model.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.group
import ifcopenshell.api.owner
import ifcopenshell.guid
-from typing import Union
def assign_structural_analysis_model(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_analysis_model.py b/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_analysis_model.py
index 65c03eb238..6d9b87b596 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_analysis_model.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_analysis_model.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_structural_analysis_model(
file: ifcopenshell.file, structural_analysis_model: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_boundary_condition.py b/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_boundary_condition.py
index f88eb7fc71..67eaadf46d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_boundary_condition.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_boundary_condition.py
@@ -15,8 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Literal, TypedDict, Union
+
import ifcopenshell
-from typing import Any, TypedDict, Literal, Union
class AttributeDict(TypedDict):
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_load.py b/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_load.py
index faa218a7a3..874db34655 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_load.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_load.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_structural_load(
file: ifcopenshell.file, structural_load: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_load_case.py b/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_load_case.py
index 02948c637d..511ef3fe87 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_load_case.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/edit_structural_load_case.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_structural_load_case(
file: ifcopenshell.file, load_case: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/remove_structural_boundary_condition.py b/src/ifcopenshell-python/ifcopenshell/api/structural/remove_structural_boundary_condition.py
index d31811a739..6f17b4ffba 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/structural/remove_structural_boundary_condition.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/structural/remove_structural_boundary_condition.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Optional
+import ifcopenshell
+
def remove_structural_boundary_condition(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/add_style.py b/src/ifcopenshell-python/ifcopenshell/api/style/add_style.py
index 54e5ffd2a8..3b5c3acef8 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/style/add_style.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/style/add_style.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Optional
+import ifcopenshell
+
def add_style(
file: ifcopenshell.file, name: Optional[str] = None, ifc_class="IfcSurfaceStyle"
diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_style.py b/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_style.py
index 55af1b35b2..e4c3f82c9c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_style.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_style.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Literal, Optional
+
import ifcopenshell
import ifcopenshell.api.style
-from typing import Any, Optional, Literal
-
SURFACE_STYLE_TYPES = Literal[
"IfcSurfaceStyleShading",
diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_textures.py b/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_textures.py
index 89505d1a98..a0765bbf8d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_textures.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_textures.py
@@ -16,9 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any, Optional
+
import ifcopenshell
import ifcopenshell.api
-from typing import TYPE_CHECKING, Optional, Any
if TYPE_CHECKING:
import bpy
diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/assign_item_style.py b/src/ifcopenshell-python/ifcopenshell/api/style/assign_item_style.py
index 0712bc2f83..cf8b5dc1a6 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/style/assign_item_style.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/style/assign_item_style.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Optional, Union
+import ifcopenshell
+
def assign_item_style(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/assign_material_style.py b/src/ifcopenshell-python/ifcopenshell/api/style/assign_material_style.py
index a9050a3379..bccd0568f1 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/style/assign_material_style.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/style/assign_material_style.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any
+
import ifcopenshell
import ifcopenshell.api.style
import ifcopenshell.util.element
-from typing import Any
def assign_material_style(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/assign_representation_styles.py b/src/ifcopenshell-python/ifcopenshell/api/style/assign_representation_styles.py
index b4d0fbe0e5..2182d354c1 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/style/assign_representation_styles.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/style/assign_representation_styles.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def assign_representation_styles(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/edit_presentation_style.py b/src/ifcopenshell-python/ifcopenshell/api/style/edit_presentation_style.py
index 7a39629528..a259b7ac83 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/style/edit_presentation_style.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/style/edit_presentation_style.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_presentation_style(
file: ifcopenshell.file, style: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/edit_surface_style.py b/src/ifcopenshell-python/ifcopenshell/api/style/edit_surface_style.py
index 7f7f05948d..681ba6ccf6 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/style/edit_surface_style.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/style/edit_surface_style.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any, Union
+import ifcopenshell
+
def edit_surface_style(
file: ifcopenshell.file, style: ifcopenshell.entity_instance, attributes: dict[str, Any]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/remove_style.py b/src/ifcopenshell-python/ifcopenshell/api/style/remove_style.py
index 3637dcaca7..cc8045b189 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/style/remove_style.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/style/remove_style.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from collections.abc import Iterable
+
import ifcopenshell.api.style
import ifcopenshell.util.element
-from collections.abc import Iterable
def remove_style(file: ifcopenshell.file, style: ifcopenshell.entity_instance) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/unassign_representation_styles.py b/src/ifcopenshell-python/ifcopenshell/api/style/unassign_representation_styles.py
index 47a542c1b7..ef2d516fb8 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/style/unassign_representation_styles.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/style/unassign_representation_styles.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def unassign_representation_styles(
file: ifcopenshell.file,
diff --git a/src/ifcopenshell-python/ifcopenshell/api/system/add_port.py b/src/ifcopenshell-python/ifcopenshell/api/system/add_port.py
index 5c1ba67bda..3b8348f77b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/system/add_port.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/system/add_port.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Optional
+
import ifcopenshell
import ifcopenshell.api.root
import ifcopenshell.api.system
-from typing import Optional
def add_port(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/system/assign_flow_control.py b/src/ifcopenshell-python/ifcopenshell/api/system/assign_flow_control.py
index 3b9273acf1..1be4d2c3bd 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/system/assign_flow_control.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/system/assign_flow_control.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
-from typing import Union
def assign_flow_control(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/system/assign_port.py b/src/ifcopenshell-python/ifcopenshell/api/system/assign_port.py
index eee8780778..20e2ec26b8 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/system/assign_port.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/system/assign_port.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any
+
import ifcopenshell
-import ifcopenshell.api.owner
import ifcopenshell.api.geometry
+import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.placement
-from typing import Any
def assign_port(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/system/assign_system.py b/src/ifcopenshell-python/ifcopenshell/api/system/assign_system.py
index 8677f748b4..ee1acff2c4 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/system/assign_system.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/system/assign_system.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.group
import ifcopenshell.util.system
-from typing import Union
def assign_system(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/system/connect_port.py b/src/ifcopenshell-python/ifcopenshell/api/system/connect_port.py
index d64f5c2064..6c43df1b8b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/system/connect_port.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/system/connect_port.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Optional
+
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.guid
import ifcopenshell.util.element
-from typing import Optional, Any
def connect_port(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/system/edit_system.py b/src/ifcopenshell-python/ifcopenshell/api/system/edit_system.py
index c90894ec7f..0615025f4c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/system/edit_system.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/system/edit_system.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_system(file: ifcopenshell.file, system: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcSystem
diff --git a/src/ifcopenshell-python/ifcopenshell/api/type/assign_type.py b/src/ifcopenshell-python/ifcopenshell/api/type/assign_type.py
index f412d4dd2e..2c7abcd169 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/type/assign_type.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/type/assign_type.py
@@ -16,13 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Union
+
import ifcopenshell
-import ifcopenshell.api.type
-import ifcopenshell.api.owner
import ifcopenshell.api.material
+import ifcopenshell.api.owner
+import ifcopenshell.api.type
import ifcopenshell.guid
import ifcopenshell.util.element
-from typing import Union
def assign_type(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/__init__.py b/src/ifcopenshell-python/ifcopenshell/api/unit/__init__.py
index 4245b49c37..31ed3d0ddc 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/unit/__init__.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/unit/__init__.py
@@ -26,9 +26,9 @@ equipment.
from .. import wrap_usecases
from .add_context_dependent_unit import add_context_dependent_unit
from .add_conversion_based_unit import add_conversion_based_unit
+from .add_derived_unit import add_derived_unit
from .add_monetary_unit import add_monetary_unit
from .add_si_unit import add_si_unit
-from .add_derived_unit import add_derived_unit
from .assign_unit import assign_unit
from .edit_derived_unit import edit_derived_unit
from .edit_monetary_unit import edit_monetary_unit
diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/add_conversion_based_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/add_conversion_based_unit.py
index 6a4f17f8fd..b223f7cc46 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/unit/add_conversion_based_unit.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/unit/add_conversion_based_unit.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Optional
+
import ifcopenshell
import ifcopenshell.util.unit
-from typing import Optional
def add_conversion_based_unit(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/add_derived_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/add_derived_unit.py
index aba4388010..5cd167e66d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/unit/add_derived_unit.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/unit/add_derived_unit.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.unit
from typing import Any, Optional
+import ifcopenshell.util.unit
+
def add_derived_unit(
file: ifcopenshell.file, unit_type: str, userdefinedtype: str, attributes: dict[ifcopenshell.entity_instance, int]
diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/add_si_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/add_si_unit.py
index 50da1c10f2..52f79f413b 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/unit/add_si_unit.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/unit/add_si_unit.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.unit
from typing import Optional
+import ifcopenshell.util.unit
+
def add_si_unit(
file: ifcopenshell.file, unit_type: str = "LENGTHUNIT", prefix: Optional[str] = None
diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/assign_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/assign_unit.py
index 5861e4248a..7b5c2b6ae4 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/unit/assign_unit.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/unit/assign_unit.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Any, Optional
+
import ifcopenshell
import ifcopenshell.util.unit
-from typing import Optional, Any
def assign_unit(
diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/edit_derived_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/edit_derived_unit.py
index 5bc9bbd316..6c82e5edad 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/unit/edit_derived_unit.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/unit/edit_derived_unit.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_derived_unit(file: ifcopenshell.file, unit: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcDerivedUnit
diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/edit_monetary_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/edit_monetary_unit.py
index bccc61afc0..62d3d1186f 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/unit/edit_monetary_unit.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/unit/edit_monetary_unit.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_monetary_unit(file: ifcopenshell.file, unit: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcMonetaryUnit
diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/edit_named_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/edit_named_unit.py
index 683feb7216..87e3608138 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/unit/edit_named_unit.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/unit/edit_named_unit.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Any
+import ifcopenshell
+
def edit_named_unit(file: ifcopenshell.file, unit: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
"""Edits the attributes of an IfcNamedUnit
diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/remove_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/remove_unit.py
index a9920e0e5c..36ab2f73a2 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/unit/remove_unit.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/unit/remove_unit.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.unit
import ifcopenshell.util.element
+import ifcopenshell.util.unit
def remove_unit(file: ifcopenshell.file, unit: ifcopenshell.entity_instance) -> None:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/unassign_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/unassign_unit.py
index 443d9d0b1c..db968a960d 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/unit/unassign_unit.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/unit/unassign_unit.py
@@ -15,9 +15,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
from typing import Optional
+import ifcopenshell
+
def unassign_unit(file: ifcopenshell.file, units: Optional[list[ifcopenshell.entity_instance]] = None) -> None:
"""Unassigns units as default units for the project
diff --git a/src/ifcopenshell-python/ifcopenshell/draw.py b/src/ifcopenshell-python/ifcopenshell/draw.py
index e2e38d700b..15ad2ef11f 100644
--- a/src/ifcopenshell-python/ifcopenshell/draw.py
+++ b/src/ifcopenshell-python/ifcopenshell/draw.py
@@ -18,12 +18,17 @@
"""2D drawing generation and serialisation"""
-from functools import reduce
import itertools
-import math
import json
+import math
import operator
import warnings
+from collections.abc import Callable, Sequence
+from dataclasses import dataclass, field, fields
+from functools import reduce
+from xml.dom.minidom import parseString
+
+import numpy
import shapely
import ifcopenshell
@@ -31,12 +36,6 @@ import ifcopenshell.geom
import ifcopenshell.util.element
import ifcopenshell.util.selector
-from xml.dom.minidom import parseString
-from dataclasses import dataclass, fields, field
-from collections.abc import Callable, Sequence
-
-import numpy
-
W = ifcopenshell.ifcopenshell_wrapper
WHITE = numpy.array((1.0, 1.0, 1.0))
@@ -670,9 +669,9 @@ def main(
if __name__ == "__main__":
+ import argparse
import sys
import time
- import argparse
times = []
diff --git a/src/ifcopenshell-python/ifcopenshell/entity_instance.py b/src/ifcopenshell-python/ifcopenshell/entity_instance.py
index 0cae2608f3..1dea67b793 100644
--- a/src/ifcopenshell-python/ifcopenshell/entity_instance.py
+++ b/src/ifcopenshell-python/ifcopenshell/entity_instance.py
@@ -18,19 +18,19 @@
from __future__ import annotations
+
import functools
import importlib
-import numbers
import itertools
+import numbers
import operator
import subprocess
import sys
import time
-from typing import Union, Any, TypeVar, overload, TYPE_CHECKING, cast, NoReturn
from collections.abc import Callable, Sequence
+from typing import TYPE_CHECKING, Any, NoReturn, TypeVar, Union, cast, overload
-from . import ifcopenshell_wrapper
-from . import settings
+from . import ifcopenshell_wrapper, settings
if TYPE_CHECKING:
import ifcopenshell
diff --git a/src/ifcopenshell-python/ifcopenshell/file.py b/src/ifcopenshell-python/ifcopenshell/file.py
index 0aadacfbfc..a12d12eb57 100644
--- a/src/ifcopenshell-python/ifcopenshell/file.py
+++ b/src/ifcopenshell-python/ifcopenshell/file.py
@@ -17,25 +17,27 @@
# along with IfcOpenShell. If not, see .
from __future__ import annotations
+
+import functools
+import numbers
import os
import re
-import numbers
import time
-import zipfile
-import functools
-import ifcopenshell
-import weakref
import types
-from pathlib import Path
-from typing import Any, Optional, TYPE_CHECKING, Union, overload, Literal, TypedDict
+import weakref
+import zipfile
from collections.abc import Callable, Generator
+from pathlib import Path
+from typing import TYPE_CHECKING, Any, Literal, Optional, TypedDict, Union, overload
+
from typing_extensions import assert_never
+import ifcopenshell
+from ifcopenshell.util.mvd_info import LARK_AVAILABLE, MvdInfo
+
from . import ifcopenshell_wrapper
from .entity_instance import entity_instance
-from ifcopenshell.util.mvd_info import MvdInfo, LARK_AVAILABLE
-
if TYPE_CHECKING:
import ifcopenshell.util.schema
diff --git a/src/ifcopenshell-python/ifcopenshell/geom/app.py b/src/ifcopenshell-python/ifcopenshell/geom/app.py
index aa11f18c1f..4ee0a5d482 100644
--- a/src/ifcopenshell-python/ifcopenshell/geom/app.py
+++ b/src/ifcopenshell-python/ifcopenshell/geom/app.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import functools
+import multiprocessing
+import operator
import os
import sys
import time
-import operator
-import functools
-import multiprocessing
+
import ifcopenshell.ifcopenshell_wrapper as W
try:
@@ -33,7 +34,7 @@ except ImportError:
USE_OCCT_HANDLE = True
-from collections import defaultdict, OrderedDict
+from collections import OrderedDict, defaultdict
from collections.abc import Iterable
try:
@@ -69,11 +70,10 @@ except BaseException:
from OCC.Display.qtDisplay import qtViewer3d
-from .main import settings, iterator
-from .occ_utils import display_shape
-
from .. import open as open_ifc_file
from .. import version as ifcopenshell_version
+from .main import iterator, settings
+from .occ_utils import display_shape
if ifcopenshell_version < "0.6":
# not yet ported
diff --git a/src/ifcopenshell-python/ifcopenshell/geom/code_editor_pane.py b/src/ifcopenshell-python/ifcopenshell/geom/code_editor_pane.py
index f84f45a234..ff46b67d8d 100644
--- a/src/ifcopenshell-python/ifcopenshell/geom/code_editor_pane.py
+++ b/src/ifcopenshell-python/ifcopenshell/geom/code_editor_pane.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import logging
import os
import sys
-import logging
-
from code import InteractiveConsole
+
from PyQt5 import QtCore, QtGui, QtWidgets
try:
@@ -29,14 +29,14 @@ except BaseException:
QtWidgets = QtGui
try:
- from pyqode.core.panels import CheckerPanel
- from pyqode.core import api
- from pyqode.core import modes
- from pyqode.core import panels
+ from pyqode.core import api, modes, panels
from pyqode.core.api import CodeEdit, ColorScheme
- from pyqode.python.modes import PyAutoIndentMode, PythonSH
+ from pyqode.core.panels import CheckerPanel
+ from pyqode.python import modes as pymodes
+ from pyqode.python import panels as pypanels
+ from pyqode.python import widgets
from pyqode.python.backend import server
- from pyqode.python import modes as pymodes, panels as pypanels, widgets
+ from pyqode.python.modes import PyAutoIndentMode, PythonSH
from pyqode.python.widgets import PyInteractiveConsole
has_pyqode = True
diff --git a/src/ifcopenshell-python/ifcopenshell/geom/main.py b/src/ifcopenshell-python/ifcopenshell/geom/main.py
index 0800ac7763..fe31a15d84 100644
--- a/src/ifcopenshell-python/ifcopenshell/geom/main.py
+++ b/src/ifcopenshell-python/ifcopenshell/geom/main.py
@@ -18,18 +18,17 @@
from __future__ import annotations
+
+import operator
import os
import sys
-import operator
-
-from .. import open, ifcopenshell_wrapper
-from ..file import file
-from ..entity_instance import entity_instance
-
-from . import has_occ
-
-from typing import TypeVar, Union, Optional, Any, Literal, overload, TYPE_CHECKING, cast
from collections.abc import Generator, Iterable
+from typing import TYPE_CHECKING, Any, Literal, Optional, TypeVar, Union, cast, overload
+
+from .. import ifcopenshell_wrapper, open
+from ..entity_instance import entity_instance
+from ..file import file
+from . import has_occ
if TYPE_CHECKING:
from OCC.Core import TopoDS
diff --git a/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py b/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py
index 9835b48696..9abddff470 100644
--- a/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py
+++ b/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py
@@ -18,24 +18,25 @@
from __future__ import annotations
-import inspect
-import random
-import operator
-import warnings
-import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
-from typing import NamedTuple, Any, Union
-from typing_extensions import assert_never
+import inspect
+import operator
+import random
+import warnings
from collections.abc import Iterable
+from typing import Any, NamedTuple, Union
import OCC
+from typing_extensions import assert_never
+
+import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
try:
- from OCC.Core import V3d, TopoDS, gp, AIS, Quantity, BRepTools, Graphic3d
+ from OCC.Core import AIS, BRepTools, Graphic3d, Quantity, TopoDS, V3d, gp
USE_OCCT_HANDLE = False
except ImportError:
- from OCC import V3d, TopoDS, gp, AIS, Quantity, BRepTools, Graphic3d
+ from OCC import AIS, BRepTools, Graphic3d, Quantity, TopoDS, V3d, gp
USE_OCCT_HANDLE = True
diff --git a/src/ifcopenshell-python/ifcopenshell/geom/stats.py b/src/ifcopenshell-python/ifcopenshell/geom/stats.py
index 364083acd7..9266d532d4 100644
--- a/src/ifcopenshell-python/ifcopenshell/geom/stats.py
+++ b/src/ifcopenshell-python/ifcopenshell/geom/stats.py
@@ -1,6 +1,6 @@
import sys
-from typing import Optional, IO
from itertools import accumulate
+from typing import IO, Optional
from . import ifcopenshell_wrapper
diff --git a/src/ifcopenshell-python/ifcopenshell/guid.py b/src/ifcopenshell-python/ifcopenshell/guid.py
index 6e3c6f5b0a..4f6d30332d 100644
--- a/src/ifcopenshell-python/ifcopenshell/guid.py
+++ b/src/ifcopenshell-python/ifcopenshell/guid.py
@@ -47,11 +47,10 @@ cf. .
-import ifcopenshell
-from typing import Any, Union, Literal
+from typing import Any, Literal, Union
+
from typing_extensions import Self
+import ifcopenshell
+
# `std::vector` usually translated to `tuple[xxx, ...]`.
ON_SLABS_AND_WALLS: Any
diff --git a/src/ifcopenshell-python/ifcopenshell/simple_spf b/src/ifcopenshell-python/ifcopenshell/simple_spf
index 2849a31788..30317826f8 160000
--- a/src/ifcopenshell-python/ifcopenshell/simple_spf
+++ b/src/ifcopenshell-python/ifcopenshell/simple_spf
@@ -1 +1 @@
-Subproject commit 2849a31788c4f82edca7d1b1046d0606fdf8b9be
+Subproject commit 30317826f8f743860ecff9e183699296593e42cb
diff --git a/src/ifcopenshell-python/ifcopenshell/sql.py b/src/ifcopenshell-python/ifcopenshell/sql.py
index e0701cf8ed..dcc170e006 100644
--- a/src/ifcopenshell-python/ifcopenshell/sql.py
+++ b/src/ifcopenshell-python/ifcopenshell/sql.py
@@ -16,19 +16,23 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
from __future__ import annotations
-import re
+
import json
+import re
import types
+from pathlib import Path
+from typing import TYPE_CHECKING, Any, NoReturn, Optional, TypedDict, Union
+
import numpy as np
import numpy.typing as npt
+
import ifcopenshell
import ifcopenshell.util.attribute
import ifcopenshell.util.schema
-from pathlib import Path
-from typing import Any, NoReturn, Union, Optional, TYPE_CHECKING, TypedDict
+
from . import ifcopenshell_wrapper
-from .file import file
from .entity_instance import entity_instance
+from .file import file
if TYPE_CHECKING:
import sqlite3
diff --git a/src/ifcopenshell-python/ifcopenshell/stream.py b/src/ifcopenshell-python/ifcopenshell/stream.py
index 655dc2d9cd..627ebac82c 100644
--- a/src/ifcopenshell-python/ifcopenshell/stream.py
+++ b/src/ifcopenshell-python/ifcopenshell/stream.py
@@ -21,15 +21,16 @@ from __future__ import annotations
try:
import os
import re
+ from typing import Any, NoReturn, Optional, Union
+
+ from lark import Lark, Transformer
import ifcopenshell.util.attribute
import ifcopenshell.util.schema
- from .file import file
+
from . import ifcopenshell_wrapper
from .entity_instance import entity_instance
-
- from lark import Lark, Transformer
- from typing import Any, NoReturn, Union, Optional
+ from .file import file
class StreamTransformer(Transformer):
file: file
diff --git a/src/ifcopenshell-python/ifcopenshell/template.py b/src/ifcopenshell-python/ifcopenshell/template.py
index d31b125279..bd58d0fdef 100644
--- a/src/ifcopenshell-python/ifcopenshell/template.py
+++ b/src/ifcopenshell-python/ifcopenshell/template.py
@@ -19,12 +19,11 @@
import time
import uuid
+from typing import Optional
from .file import file
from .guid import compress
from .ifcopenshell_wrapper import version
-from typing import Optional
-
# A quick way to setup an 'empty' IFC file, taken from:
# http://academy.ifcopenshell.org/creating-a-simple-wall-with-property-set-and-quantity-information/
diff --git a/src/ifcopenshell-python/ifcopenshell/util/alignment.py b/src/ifcopenshell-python/ifcopenshell/util/alignment.py
index ad6c6dd65d..1b90ac7c5f 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/alignment.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/alignment.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import math
+
import ifcopenshell
import ifcopenshell.util.unit
diff --git a/src/ifcopenshell-python/ifcopenshell/util/attribute.py b/src/ifcopenshell-python/ifcopenshell/util/attribute.py
index a3212aca67..0e34b5c022 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/attribute.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/attribute.py
@@ -16,8 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Literal, Union
+
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
-from typing import Union, Literal
PrimitiveType = Literal["entity", "string", "float", "integer", "boolean", "enum", "binary"]
ComplexPrimitiveType = Literal["list", "array", "set"]
diff --git a/src/ifcopenshell-python/ifcopenshell/util/brick.py b/src/ifcopenshell-python/ifcopenshell/util/brick.py
index 04e0be5452..ec358c2b98 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/brick.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/brick.py
@@ -16,14 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import os
import json
+import os
+from typing import Union
+
import ifcopenshell
import ifcopenshell.util.classification
import ifcopenshell.util.element
import ifcopenshell.util.system
-from typing import Union
-
cwd = os.path.dirname(os.path.realpath(__file__))
diff --git a/src/ifcopenshell-python/ifcopenshell/util/classification.py b/src/ifcopenshell-python/ifcopenshell/util/classification.py
index 06f9b0e31a..df36eb97a4 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/classification.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/classification.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.element
from typing import Optional
+import ifcopenshell.util.element
+
def get_references(element: ifcopenshell.entity_instance, should_inherit=True) -> set[ifcopenshell.entity_instance]:
"""Gets classification references associated with the element
diff --git a/src/ifcopenshell-python/ifcopenshell/util/constraint.py b/src/ifcopenshell-python/ifcopenshell/util/constraint.py
index 2c370aa997..6d52d74676 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/constraint.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/constraint.py
@@ -18,9 +18,10 @@
#
#
-import ifcopenshell
from typing import Union
+import ifcopenshell
+
def get_constraints(product: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
"""
diff --git a/src/ifcopenshell-python/ifcopenshell/util/cost.py b/src/ifcopenshell-python/ifcopenshell/util/cost.py
index a7e96221d9..19172c4710 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/cost.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/cost.py
@@ -16,10 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import lark
-import ifcopenshell
-from typing import Optional, Union, Literal, Any
from collections.abc import Generator
+from typing import Any, Literal, Optional, Union
+
+import lark
+
+import ifcopenshell
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
import ifcopenshell.util.attribute
import ifcopenshell.util.element
diff --git a/src/ifcopenshell-python/ifcopenshell/util/data.py b/src/ifcopenshell-python/ifcopenshell/util/data.py
index c65a87ddb0..4169b1ea4d 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/data.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/data.py
@@ -17,10 +17,13 @@
# along with IfcOpenShell. If not, see .
from __future__ import annotations
-import numpy as np
-import ifcopenshell
-from typing import Any, Union
+
from dataclasses import dataclass
+from typing import Any, Union
+
+import numpy as np
+
+import ifcopenshell
from ifcopenshell.util.shape_builder import ShapeBuilder
diff --git a/src/ifcopenshell-python/ifcopenshell/util/date.py b/src/ifcopenshell-python/ifcopenshell/util/date.py
index 3b0761f75c..dcd1c36ca5 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/date.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/date.py
@@ -16,12 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
import datetime
-import isodate
from re import findall
+from typing import Any, Literal, Union, overload
+
+import isodate
from dateutil import parser
-from typing import Literal, Union, Any, overload
+
+import ifcopenshell
def timedelta2duration(timedelta):
diff --git a/src/ifcopenshell-python/ifcopenshell/util/doc.py b/src/ifcopenshell-python/ifcopenshell/util/doc.py
index 41d6189fe4..9c7acf16b7 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/doc.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/doc.py
@@ -16,27 +16,30 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import copy
import json
from pathlib import Path
-import copy
+from typing import Any, Literal, Optional, TypedDict, Union
+
+from typing_extensions import NotRequired
+
import ifcopenshell
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
import ifcopenshell.util.attribute
import ifcopenshell.util.schema
-from typing import Optional, Literal, Any, Union, TypedDict
-from typing_extensions import NotRequired
try:
import glob
- import warnings
- import requests
- import urllib.parse
- from markdown import markdown
- from bs4 import BeautifulSoup, MarkupResemblesLocatorWarning
- import zipfile
- from lxml import etree
import re
import shutil
+ import urllib.parse
+ import warnings
+ import zipfile
+
+ import requests
+ from bs4 import BeautifulSoup, MarkupResemblesLocatorWarning
+ from lxml import etree
+ from markdown import markdown
except:
pass # Only necessary if you're using it to generate the docs database
diff --git a/src/ifcopenshell-python/ifcopenshell/util/element.py b/src/ifcopenshell-python/ifcopenshell/util/element.py
index 067febd115..149606cb14 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/element.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/element.py
@@ -16,14 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from collections import namedtuple
+from collections.abc import Callable, Generator, Sequence
+from typing import Any, Literal, Optional, Union, overload
+
import ifcopenshell
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.representation
-from typing import Any, Callable, Optional, Union, Literal, overload
-from collections.abc import Generator, Sequence
-from collections import namedtuple
-
MATERIAL_TYPE = Literal[
"IfcMaterial",
diff --git a/src/ifcopenshell-python/ifcopenshell/util/file.py b/src/ifcopenshell-python/ifcopenshell/util/file.py
index 4875ddf3b7..a874e1ba4d 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/file.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/file.py
@@ -17,7 +17,8 @@
# along with IfcOpenShell. If not, see .
import zipfile
-from typing import IO, Union, TypedDict
+from typing import IO, TypedDict, Union
+
from typing_extensions import NotRequired
diff --git a/src/ifcopenshell-python/ifcopenshell/util/fm.py b/src/ifcopenshell-python/ifcopenshell/util/fm.py
index c9b1977e4e..bfb7391dc3 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/fm.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/fm.py
@@ -16,11 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import Literal
+
+from typing_extensions import assert_never
+
import ifcopenshell
import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.util.attribute
-from typing import Literal
-from typing_extensions import assert_never
# COBie actually uses an exclusion list, but this inclusion list is equivalent.
cobie_type_classes = [
diff --git a/src/ifcopenshell-python/ifcopenshell/util/generate_pset_templates.py b/src/ifcopenshell-python/ifcopenshell/util/generate_pset_templates.py
index 44d5bc28cf..87c65e2f28 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/generate_pset_templates.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/generate_pset_templates.py
@@ -18,22 +18,23 @@
RUN_FROM_DEV_REPO = False
-import ifcopenshell.ifcopenshell_wrapper as W
-import ifcopenshell.api.unit
-import ifcopenshell.api.project
-import ifcopenshell.guid
-import ifcopenshell.util.attribute
import glob
import sys
-from pathlib import Path
-from lxml import etree
from itertools import chain
+from pathlib import Path
from typing import cast
+from lxml import etree
+
+import ifcopenshell.api.project
+import ifcopenshell.api.unit
+import ifcopenshell.guid
+import ifcopenshell.ifcopenshell_wrapper as W
+import ifcopenshell.util.attribute
if not RUN_FROM_DEV_REPO:
- import zipfile
import shutil
+ import zipfile
BASE_MODULE_PATH = Path(__file__).parent
diff --git a/src/ifcopenshell-python/ifcopenshell/util/geolocation.py b/src/ifcopenshell-python/ifcopenshell/util/geolocation.py
index 748ba8f3c3..fba8dfffaf 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/geolocation.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/geolocation.py
@@ -17,12 +17,14 @@
# along with IfcOpenShell. If not, see .
import math
+from decimal import ROUND_HALF_UP, Decimal
+from typing import NamedTuple, Optional, Union
+
import numpy as np
+
import ifcopenshell
import ifcopenshell.util.element
import ifcopenshell.util.placement
-from typing import NamedTuple, Optional, Union
-from decimal import Decimal, ROUND_HALF_UP
MatrixType = ifcopenshell.util.placement.MatrixType
diff --git a/src/ifcopenshell-python/ifcopenshell/util/ifc4x3dev_scrape_data_for_docs.py b/src/ifcopenshell-python/ifcopenshell/util/ifc4x3dev_scrape_data_for_docs.py
index 02e4f1f491..86ab81ef4c 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/ifc4x3dev_scrape_data_for_docs.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/ifc4x3dev_scrape_data_for_docs.py
@@ -17,7 +17,12 @@
# along with IfcOpenShell. If not, see .
try:
- from server import get_resource_path, resource_documentation_builder, process_markdown, R
+ from server import (
+ R,
+ get_resource_path,
+ process_markdown,
+ resource_documentation_builder,
+ )
except ModuleNotFoundError as e:
print(
"ERROR. Failed to import `server.py`.\n"
@@ -26,13 +31,15 @@ except ModuleNotFoundError as e:
raise e
import itertools
-import operator
import json
-import ifcopenshell
+import operator
from collections import Counter
-from bs4 import BeautifulSoup
from typing import Any, Union
+from bs4 import BeautifulSoup
+
+import ifcopenshell
+
# Hacky modified functions from server.py to make parser work
def get_definition_from_md(resource: str, mdc: str) -> str:
diff --git a/src/ifcopenshell-python/ifcopenshell/util/mvd_info.py b/src/ifcopenshell-python/ifcopenshell/util/mvd_info.py
index a4ca36039d..a3bdb07337 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/mvd_info.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/mvd_info.py
@@ -26,8 +26,8 @@ try:
except ImportError:
LARK_AVAILABLE = False
-from typing import Callable, Union
import re
+from typing import Union
if LARK_AVAILABLE:
mvd_grammar = r"""
@@ -51,9 +51,9 @@ if LARK_AVAILABLE:
value: /[A-Za-z0-9 _\.-]+/
- other_keyword: /[^\[\]]+/
-
- dynamic_option_word: /[^\[\]]+/
+ other_keyword: /[^\[\]]+/
+
+ dynamic_option_word: /[^\[\]]+/
%import common.WS
%ignore WS
diff --git a/src/ifcopenshell-python/ifcopenshell/util/placement.py b/src/ifcopenshell-python/ifcopenshell/util/placement.py
index e7e7b99a68..cc37ab9906 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/placement.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/placement.py
@@ -16,11 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from collections.abc import Iterable
+from typing import Literal, Optional
+
import numpy as np
import numpy.typing as npt
+
import ifcopenshell
-from typing import Literal, Optional
-from collections.abc import Iterable
MatrixType = npt.NDArray[np.float64]
"""`npt.NDArray[np.float64]`"""
diff --git a/src/ifcopenshell-python/ifcopenshell/util/pset.py b/src/ifcopenshell-python/ifcopenshell/util/pset.py
index df906a2e57..68fc84a5b1 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/pset.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/pset.py
@@ -16,15 +16,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import re
import pathlib
+import re
+from functools import lru_cache
+from typing import Literal, NamedTuple, Optional, Union
+
import ifcopenshell
import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.util.schema
import ifcopenshell.util.type
from ifcopenshell.entity_instance import entity_instance
-from functools import lru_cache
-from typing import Optional, Literal, NamedTuple, Union
templates: dict[ifcopenshell.util.schema.IFC_SCHEMA, "PsetQto"] = {}
diff --git a/src/ifcopenshell-python/ifcopenshell/util/representation.py b/src/ifcopenshell-python/ifcopenshell/util/representation.py
index 10743294b0..f0c2b54fca 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/representation.py
@@ -16,15 +16,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from collections.abc import Generator, Sequence
+from typing import Literal, Optional, TypedDict, Union
+
import numpy as np
import numpy.typing as npt
-import ifcopenshell
-import ifcopenshell.util.representation
-import ifcopenshell.util.placement
-import ifcopenshell.util.shape
-from typing import Optional, Union, TypedDict, Literal
-from collections.abc import Generator, Sequence
+import ifcopenshell
+import ifcopenshell.util.placement
+import ifcopenshell.util.representation
+import ifcopenshell.util.shape
CONTEXT_TYPE = Literal["Model", "Plan", "NotDefined"]
REPRESENTATION_IDENTIFIER = Literal[
diff --git a/src/ifcopenshell-python/ifcopenshell/util/resource.py b/src/ifcopenshell-python/ifcopenshell/util/resource.py
index f518a09125..262ddda125 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/resource.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/resource.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.cost
-import ifcopenshell.util.element
-import ifcopenshell.util.date
-from typing import Union, Any
+from typing import Any, Union
+import ifcopenshell.util.cost
+import ifcopenshell.util.date
+import ifcopenshell.util.element
PRODUCTIVITY_PSET_DATA = Union[dict[str, Any], None]
# https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcConstructionResource.htm#Table-7.3.3.7.1.3.H
diff --git a/src/ifcopenshell-python/ifcopenshell/util/schema.py b/src/ifcopenshell-python/ifcopenshell/util/schema.py
index d3d7b65c6a..bdd6d489d0 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/schema.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/schema.py
@@ -16,13 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import os
import json
+import os
import time
+from typing import Any, Literal, Union
+
import ifcopenshell
-import ifcopenshell.util.attribute
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
-from typing import Union, Any, Literal
+import ifcopenshell.util.attribute
# This is highly experimental and incomplete, however, it may work for simple datasets.
diff --git a/src/ifcopenshell-python/ifcopenshell/util/schema/ifc_classes_suggestions.json b/src/ifcopenshell-python/ifcopenshell/util/schema/ifc_classes_suggestions.json
index f9f76947bb..c3cf248ada 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/schema/ifc_classes_suggestions.json
+++ b/src/ifcopenshell-python/ifcopenshell/util/schema/ifc_classes_suggestions.json
@@ -5,6 +5,16 @@
"predefined_type": "NOTDEFINED"
}
],
+ "IfcAirTerminal": [
+ {
+ "name": "Commercial Kitchen Hood"
+ }
+ ],
+ "IfcAirTerminalType": [
+ {
+ "name": "Commercial Kitchen Hood"
+ }
+ ],
"IfcAirTerminalBox": [
{
"name": "VAV Box"
diff --git a/src/ifcopenshell-python/ifcopenshell/util/scripts/validate_stub.py b/src/ifcopenshell-python/ifcopenshell/util/scripts/validate_stub.py
index 14b05ed258..2ddf444704 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/scripts/validate_stub.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/scripts/validate_stub.py
@@ -30,6 +30,7 @@ import ast
import difflib
from pathlib import Path
from typing import Union
+
from typing_extensions import assert_never
diff --git a/src/ifcopenshell-python/ifcopenshell/util/selector.py b/src/ifcopenshell-python/ifcopenshell/util/selector.py
index a2ce6fb467..1508e36e8f 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/selector.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/selector.py
@@ -18,10 +18,16 @@
import re
import sys
+from collections.abc import Iterable
+from decimal import Decimal
+from types import EllipsisType
+from typing import Any, Optional, Union
+
import lark
import numpy as np
-import ifcopenshell.api.pset
+
import ifcopenshell.api.geometry
+import ifcopenshell.api.pset
import ifcopenshell.util
import ifcopenshell.util.attribute
import ifcopenshell.util.classification
@@ -34,15 +40,6 @@ import ifcopenshell.util.schema
import ifcopenshell.util.shape
import ifcopenshell.util.system
import ifcopenshell.util.unit
-from decimal import Decimal
-from typing import Optional, Any, Union
-from collections.abc import Iterable
-
-if sys.version_info >= (3, 10):
- from types import EllipsisType
-else:
- EllipsisType = type(...)
-
filter_elements_grammar = lark.Lark(
"""start: filter_group
diff --git a/src/ifcopenshell-python/ifcopenshell/util/sequence.py b/src/ifcopenshell-python/ifcopenshell/util/sequence.py
index 51f34b7226..518d581657 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/sequence.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/sequence.py
@@ -17,13 +17,13 @@
# along with IfcOpenShell. If not, see .
import datetime
+from collections.abc import Generator
+from functools import cache
+from math import floor
+from typing import Literal, Optional, Union
+
import ifcopenshell.util.date
import ifcopenshell.util.element
-from math import floor
-from functools import cache
-from typing import Union, Literal, Optional
-from collections.abc import Generator
-
DURATION_TYPE = Literal["ELAPSEDTIME", "WORKTIME", "NOTDEFINED"]
RECURRENCE_TYPE = Literal[
diff --git a/src/ifcopenshell-python/ifcopenshell/util/shape.py b/src/ifcopenshell-python/ifcopenshell/util/shape.py
index 75c15b6935..4c41eff9f9 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/shape.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/shape.py
@@ -16,18 +16,20 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import shapely
-import shapely.ops
+from math import cos, radians
+from typing import Literal, Optional, Union
+
import numpy as np
import numpy.typing as npt
+import shapely
+import shapely.ops
+
import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.util.element
import ifcopenshell.util.placement
import ifcopenshell.util.representation
-from ifcopenshell.util.shape_builder import VectorType
-from math import radians, cos
from ifcopenshell.geom import ShapeElementType
-from typing import Optional, Literal, Union
+from ifcopenshell.util.shape_builder import VectorType
tol = 1e-6
AXIS_LITERAL = Literal["X", "Y", "Z"]
diff --git a/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py b/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py
index 0811b8798c..8c0f3d6ce9 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py
@@ -17,20 +17,23 @@
# along with IfcOpenShell. If not, see .
from __future__ import annotations
-import numpy as np
-import numpy.typing as npt
+
import collections
import collections.abc
+from collections.abc import Sequence
+from itertools import chain
+from math import atan, cos, degrees, pi, radians, sin, sqrt, tan
+from typing import TYPE_CHECKING, Any, Literal, Optional, Union
+
+import numpy as np
+import numpy.typing as npt
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.element
import ifcopenshell.util.placement
import ifcopenshell.util.representation
import ifcopenshell.util.unit
-from math import cos, sin, pi, tan, radians, degrees, atan, sqrt
-from typing import Union, Optional, Literal, Any, TYPE_CHECKING
-from collections.abc import Sequence
-from itertools import chain
PRECISION = 1.0e-5
diff --git a/src/ifcopenshell-python/ifcopenshell/util/system.py b/src/ifcopenshell-python/ifcopenshell/util/system.py
index 832daefc0d..39d9207018 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/system.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/system.py
@@ -17,8 +17,9 @@
# along with IfcOpenShell. If not, see .
+from typing import Literal, Optional, Union
+
import ifcopenshell.util.system
-from typing import Optional, Union, Literal
group_types: dict[str, tuple[str, ...]] = {
"IfcZone": ("IfcZone", "IfcSpace", "IfcSpatialZone"),
diff --git a/src/ifcopenshell-python/ifcopenshell/util/type.py b/src/ifcopenshell-python/ifcopenshell/util/type.py
index ab58814267..86a1ccc7c9 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/type.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/type.py
@@ -16,8 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import os
import json
+import os
+
import ifcopenshell.util.schema
cwd = os.path.dirname(os.path.realpath(__file__))
diff --git a/src/ifcopenshell-python/ifcopenshell/util/unit.py b/src/ifcopenshell-python/ifcopenshell/util/unit.py
index 86254cb826..93d4776df0 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/unit.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/unit.py
@@ -16,14 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from collections.abc import Generator
from fractions import Fraction
from math import pi
from typing import Literal, Optional, Union
-from collections.abc import Generator
import ifcopenshell
-import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
import ifcopenshell.api.unit
+import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
prefixes = {
"EXA": 1e18,
@@ -869,10 +869,10 @@ def iter_element_and_attributes_per_type(ifc_file: ifcopenshell.file, attr_type_
def convert_file_length_units(ifc_file: ifcopenshell.file, target_units: str = "METER") -> ifcopenshell.file:
"""Converts all units in an IFC file to the specified target units. Returns a new file."""
- import ifcopenshell.util.element
- import ifcopenshell.util.geolocation
import ifcopenshell.api.georeference
import ifcopenshell.api.unit
+ import ifcopenshell.util.element
+ import ifcopenshell.util.geolocation
prefix = get_prefix(target_units)
si_unit = get_unit_name(target_units)
diff --git a/src/ifcopenshell-python/ifcopenshell/validate.py b/src/ifcopenshell-python/ifcopenshell/validate.py
index 25f9b3a685..13f148d520 100644
--- a/src/ifcopenshell-python/ifcopenshell/validate.py
+++ b/src/ifcopenshell-python/ifcopenshell/validate.py
@@ -44,27 +44,23 @@ Can be used to run validation on IFC file from the command line:
"""
from __future__ import annotations
+
+import argparse
+import functools
+import json
import os
import sys
-import json
-import functools
import types
-import argparse
-
from collections import namedtuple
-from typing import Union, Any, Optional, TYPE_CHECKING
from collections.abc import Iterator
-from logging import Logger, Handler
-
-if sys.version_info >= (3, 10):
- from types import EllipsisType
-else:
- EllipsisType = type(...)
+from logging import Handler, Logger
+from types import EllipsisType
+from typing import TYPE_CHECKING, Any, Optional, Union
import ifcopenshell
+import ifcopenshell.express.rule_executor
import ifcopenshell.ifcopenshell_wrapper
import ifcopenshell.ifcopenshell_wrapper as W
-import ifcopenshell.express.rule_executor
if TYPE_CHECKING:
import ifcopenshell.simple_spf
@@ -315,8 +311,8 @@ def assert_valid(
def log_internal_cpp_errors(
f: Optional[ifcopenshell.file], filename: str, logger: Union[Logger, json_logger], log_content: Optional[str] = None
) -> None:
- import re
import bisect
+ import re
chr_offset_re = re.compile(r"at offset (\d+)\s*")
for_instance_re = re.compile(r"\s*for instance #(\d+)\s*")
@@ -779,8 +775,8 @@ class LogDetectionHandler(Handler):
if __name__ == "__main__":
- import sys
import logging
+ import sys
def handle_exception(exc_type, exc_value, exc_traceback):
import traceback
diff --git a/src/ifcopenshell-python/pyproject.toml b/src/ifcopenshell-python/pyproject.toml
index 08f8c433fc..790891e350 100644
--- a/src/ifcopenshell-python/pyproject.toml
+++ b/src/ifcopenshell-python/pyproject.toml
@@ -10,7 +10,7 @@ authors = [
]
description = "Python bindings, utility functions, and high-level API for IfcOpenShell"
readme = "README.md"
-requires-python = ">=3.9,<3.15"
+requires-python = ">=3.10,<3.15"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)",
diff --git a/src/ifcopenshell-python/test/api/aggregate/test_assign_object.py b/src/ifcopenshell-python/test/api/aggregate/test_assign_object.py
index f00ff6c1d0..e8b41e8dbb 100644
--- a/src/ifcopenshell-python/test/api/aggregate/test_assign_object.py
+++ b/src/ifcopenshell-python/test/api/aggregate/test_assign_object.py
@@ -18,14 +18,15 @@
import numpy
import pytest
-import test.bootstrap
-import ifcopenshell.api.root
-import ifcopenshell.api.unit
-import ifcopenshell.api.spatial
-import ifcopenshell.api.geometry
+
import ifcopenshell.api.aggregate
+import ifcopenshell.api.geometry
+import ifcopenshell.api.root
+import ifcopenshell.api.spatial
+import ifcopenshell.api.unit
import ifcopenshell.util.element
import ifcopenshell.util.placement
+import test.bootstrap
class TestAssignObject(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/aggregate/test_unassign_object.py b/src/ifcopenshell-python/test/api/aggregate/test_unassign_object.py
index 722cccdb93..3d8e25134d 100644
--- a/src/ifcopenshell-python/test/api/aggregate/test_unassign_object.py
+++ b/src/ifcopenshell-python/test/api/aggregate/test_unassign_object.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.aggregate
+import ifcopenshell.api.root
import ifcopenshell.util.element
+import test.bootstrap
class TestUnassignObject(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/alignment/test_add_segment_to_layout.py b/src/ifcopenshell-python/test/api/alignment/test_add_segment_to_layout.py
index bea6f8989a..9c6503516a 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_add_segment_to_layout.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_add_segment_to_layout.py
@@ -17,10 +17,10 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
-
from ifcopenshell.api.alignment._add_segment_to_layout import _add_segment_to_layout
diff --git a/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py b/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py
index 49cbd70367..52786cb28c 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_add_stationing_to_alignment.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_add_vertical_alignment.py b/src/ifcopenshell-python/test/api/alignment/test_add_vertical_alignment.py
index 243188866c..50298717b3 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_add_vertical_alignment.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_add_vertical_alignment.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_create.py b/src/ifcopenshell-python/test/api/alignment/test_create.py
index 355c2d1ae5..e9fb2d00f3 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_create.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_create.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_as_offset_curve.py b/src/ifcopenshell-python/test/api/alignment/test_create_as_offset_curve.py
index 25b2656611..90321574bd 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_create_as_offset_curve.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_create_as_offset_curve.py
@@ -16,12 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util
-import ifcopenshell.util.unit
-import pytest
import math
+
+import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.unit
+import ifcopenshell.util
+import ifcopenshell.util.unit
def test_create_as_offset_curve():
diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_as_polyline.py b/src/ifcopenshell-python/test/api/alignment/test_create_as_polyline.py
index dac7d3156b..8724de5e95 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_create_as_polyline.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_create_as_polyline.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_by_pi_method.py b/src/ifcopenshell-python/test/api/alignment/test_create_by_pi_method.py
index bd3a25faed..17a7d9b558 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_create_by_pi_method.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_create_by_pi_method.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_layout_segment.py b/src/ifcopenshell-python/test/api/alignment/test_create_layout_segment.py
index 6713f0f78a..87d1ca563f 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_create_layout_segment.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_create_layout_segment.py
@@ -16,11 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import math
+
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
-import math
def _test_horizontal() -> ifcopenshell.file:
diff --git a/src/ifcopenshell-python/test/api/alignment/test_create_no_geometry.py b/src/ifcopenshell-python/test/api/alignment/test_create_no_geometry.py
index 15b64af2f9..a8f7c3ac06 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_create_no_geometry.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_create_no_geometry.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_distance_along_from_station.py b/src/ifcopenshell-python/test/api/alignment/test_distance_along_from_station.py
index d5c8518259..a5af19ebe3 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_distance_along_from_station.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_distance_along_from_station.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_get_alignment.py b/src/ifcopenshell-python/test/api/alignment/test_get_alignment.py
index b1d5ac720e..a7821ce213 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_get_alignment.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_get_alignment.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_horizontal_layout_by_pi_method.py b/src/ifcopenshell-python/test/api/alignment/test_horizontal_layout_by_pi_method.py
index a4678f7e0e..75d46ba173 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_horizontal_layout_by_pi_method.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_horizontal_layout_by_pi_method.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_cant_segment.py b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_cant_segment.py
index 021314547c..2f529fb08a 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_cant_segment.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_cant_segment.py
@@ -17,9 +17,12 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
-from ifcopenshell.api.alignment._map_alignment_cant_segment import _map_alignment_cant_segment
+from ifcopenshell.api.alignment._map_alignment_cant_segment import (
+ _map_alignment_cant_segment,
+)
def _BlossCurve_100_0_300_1000_1_Meter(file):
diff --git a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_horizontal_segment.py b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_horizontal_segment.py
index c9bdfc0432..191f56a279 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_horizontal_segment.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_horizontal_segment.py
@@ -20,9 +20,12 @@
# for horizontal alignment.
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.unit
-from ifcopenshell.api.alignment._map_alignment_horizontal_segment import _map_alignment_horizontal_segment
+from ifcopenshell.api.alignment._map_alignment_horizontal_segment import (
+ _map_alignment_horizontal_segment,
+)
def _BlossCurve_100_0_300_1000_1_Meter(file):
diff --git a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_vertical_segment.py b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_vertical_segment.py
index 2d5f6a6133..fc88aed036 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_map_alignment_vertical_segment.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_map_alignment_vertical_segment.py
@@ -20,8 +20,11 @@
# for vertical alignment.
import pytest
+
import ifcopenshell.api.alignment
-from ifcopenshell.api.alignment._map_alignment_vertical_segment import _map_alignment_vertical_segment
+from ifcopenshell.api.alignment._map_alignment_vertical_segment import (
+ _map_alignment_vertical_segment,
+)
def _CircularArc_100_0_10_0_0_0_0_5_1_Meter(file):
diff --git a/src/ifcopenshell-python/test/api/alignment/test_name_segments.py b/src/ifcopenshell-python/test/api/alignment/test_name_segments.py
index 5a1174573b..20ed746ab0 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_name_segments.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_name_segments.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_referent_names.py b/src/ifcopenshell-python/test/api/alignment/test_referent_names.py
index 2e0e50a683..d18ecf16c3 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_referent_names.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_referent_names.py
@@ -18,6 +18,7 @@
import pytest
from pytest import fixture
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_update_curve_segment_transition_code.py b/src/ifcopenshell-python/test/api/alignment/test_update_curve_segment_transition_code.py
index 2b6accf037..30803b5a59 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_update_curve_segment_transition_code.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_update_curve_segment_transition_code.py
@@ -17,9 +17,12 @@
# along with IfcOpenShell. If not, see .
import pytest
-from ifcopenshell.api.alignment._update_curve_segment_transition_code import _update_curve_segment_transition_code
+
import ifcopenshell.api.context
import ifcopenshell.api.unit
+from ifcopenshell.api.alignment._update_curve_segment_transition_code import (
+ _update_curve_segment_transition_code,
+)
def _test1():
diff --git a/src/ifcopenshell-python/test/api/alignment/test_update_fallback_position.py b/src/ifcopenshell-python/test/api/alignment/test_update_fallback_position.py
index 2982cb466b..a53c162ea9 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_update_fallback_position.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_update_fallback_position.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/alignment/test_vertical_layout_by_pi_method.py b/src/ifcopenshell-python/test/api/alignment/test_vertical_layout_by_pi_method.py
index 8dab67c181..b34e22c741 100644
--- a/src/ifcopenshell-python/test/api/alignment/test_vertical_layout_by_pi_method.py
+++ b/src/ifcopenshell-python/test/api/alignment/test_vertical_layout_by_pi_method.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.alignment
import ifcopenshell.api.context
import ifcopenshell.api.unit
diff --git a/src/ifcopenshell-python/test/api/boundary/test_copy_boundary.py b/src/ifcopenshell-python/test/api/boundary/test_copy_boundary.py
index 30adbf74c4..675f187c09 100644
--- a/src/ifcopenshell-python/test/api/boundary/test_copy_boundary.py
+++ b/src/ifcopenshell-python/test/api/boundary/test_copy_boundary.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.boundary
+import ifcopenshell.api.root
+import test.bootstrap
class TestCopyBoundary(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/boundary/test_remove_boundary.py b/src/ifcopenshell-python/test/api/boundary/test_remove_boundary.py
index 7dea36b2bc..91227b66a4 100644
--- a/src/ifcopenshell-python/test/api/boundary/test_remove_boundary.py
+++ b/src/ifcopenshell-python/test/api/boundary/test_remove_boundary.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.boundary
+import ifcopenshell.api.root
+import test.bootstrap
class TestRemoveBoundary(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/classification/test_add_classification.py b/src/ifcopenshell-python/test/api/classification/test_add_classification.py
index 12442255fe..f97d32d881 100644
--- a/src/ifcopenshell-python/test/api/classification/test_add_classification.py
+++ b/src/ifcopenshell-python/test/api/classification/test_add_classification.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.classification
+import ifcopenshell.api.root
+import test.bootstrap
class TestAddClassification(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/classification/test_add_reference.py b/src/ifcopenshell-python/test/api/classification/test_add_reference.py
index caf6f5d8af..7aad6996f1 100644
--- a/src/ifcopenshell-python/test/api/classification/test_add_reference.py
+++ b/src/ifcopenshell-python/test/api/classification/test_add_reference.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
-import ifcopenshell.api.root
+
import ifcopenshell.api.classification
+import ifcopenshell.api.root
import ifcopenshell.util.classification
+import test.bootstrap
class TestAddReference(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/classification/test_remove_classification.py b/src/ifcopenshell-python/test/api/classification/test_remove_classification.py
index 15a8b414cb..54d3b8418b 100644
--- a/src/ifcopenshell-python/test/api/classification/test_remove_classification.py
+++ b/src/ifcopenshell-python/test/api/classification/test_remove_classification.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.classification
+import ifcopenshell.api.root
+import test.bootstrap
class TestRemoveClassification(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/classification/test_remove_reference.py b/src/ifcopenshell-python/test/api/classification/test_remove_reference.py
index 6812805594..9bcede5db3 100644
--- a/src/ifcopenshell-python/test/api/classification/test_remove_reference.py
+++ b/src/ifcopenshell-python/test/api/classification/test_remove_reference.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
-import ifcopenshell.api.root
+
import ifcopenshell.api.classification
+import ifcopenshell.api.root
import ifcopenshell.util.classification
+import test.bootstrap
class TestRemoveReference(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/cogo/test_add_survey_point.py b/src/ifcopenshell-python/test/api/cogo/test_add_survey_point.py
index 068fef52a8..73d3c69105 100644
--- a/src/ifcopenshell-python/test/api/cogo/test_add_survey_point.py
+++ b/src/ifcopenshell-python/test/api/cogo/test_add_survey_point.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.aggregate
import ifcopenshell.api.alignment
-import ifcopenshell.api.context
import ifcopenshell.api.cogo
+import ifcopenshell.api.context
def test_add_survey_point():
diff --git a/src/ifcopenshell-python/test/api/cogo/test_assign_survey_point.py b/src/ifcopenshell-python/test/api/cogo/test_assign_survey_point.py
index 39e7823af9..e19639166f 100644
--- a/src/ifcopenshell-python/test/api/cogo/test_assign_survey_point.py
+++ b/src/ifcopenshell-python/test/api/cogo/test_assign_survey_point.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.aggregate
import ifcopenshell.api.alignment
-import ifcopenshell.api.context
import ifcopenshell.api.cogo
+import ifcopenshell.api.context
def test_assign_survey_point():
diff --git a/src/ifcopenshell-python/test/api/cogo/test_bearing2dd.py b/src/ifcopenshell-python/test/api/cogo/test_bearing2dd.py
index 657c0a65a8..433a981ac7 100644
--- a/src/ifcopenshell-python/test/api/cogo/test_bearing2dd.py
+++ b/src/ifcopenshell-python/test/api/cogo/test_bearing2dd.py
@@ -16,10 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
-import ifcopenshell.api.cogo
import math
+import pytest
+
+import ifcopenshell.api.cogo
+
def test_bearing2dd():
assert 44.743888875 == pytest.approx(ifcopenshell.api.cogo.bearing2dd("N 45 15 22.5 E"))
diff --git a/src/ifcopenshell-python/test/api/cogo/test_edit_survey_point.py b/src/ifcopenshell-python/test/api/cogo/test_edit_survey_point.py
index 17038f533b..6b714b7342 100644
--- a/src/ifcopenshell-python/test/api/cogo/test_edit_survey_point.py
+++ b/src/ifcopenshell-python/test/api/cogo/test_edit_survey_point.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.api.aggregate
import ifcopenshell.api.alignment
-import ifcopenshell.api.context
import ifcopenshell.api.cogo
+import ifcopenshell.api.context
def test_edit_survey_point():
diff --git a/src/ifcopenshell-python/test/api/constraint/test_assign_constraint.py b/src/ifcopenshell-python/test/api/constraint/test_assign_constraint.py
index 41d594098e..f83c00be19 100644
--- a/src/ifcopenshell-python/test/api/constraint/test_assign_constraint.py
+++ b/src/ifcopenshell-python/test/api/constraint/test_assign_constraint.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.constraint
+import ifcopenshell.api.root
import ifcopenshell.util.constraint
+import test.bootstrap
class TestAssignConstraint(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/constraint/test_unassign_constraint.py b/src/ifcopenshell-python/test/api/constraint/test_unassign_constraint.py
index bf311f2870..245ae07e91 100644
--- a/src/ifcopenshell-python/test/api/constraint/test_unassign_constraint.py
+++ b/src/ifcopenshell-python/test/api/constraint/test_unassign_constraint.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.constraint
+import ifcopenshell.api.root
import ifcopenshell.util.constraint
+import test.bootstrap
class TestUnassignConstraint(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/context/test_add_context.py b/src/ifcopenshell-python/test/api/context/test_add_context.py
index 1ae3183697..4e24fe623a 100644
--- a/src/ifcopenshell-python/test/api/context/test_add_context.py
+++ b/src/ifcopenshell-python/test/api/context/test_add_context.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.context
+import test.bootstrap
class TestAddContext(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/context/test_edit_context.py b/src/ifcopenshell-python/test/api/context/test_edit_context.py
index f138b649e1..eead4d1971 100644
--- a/src/ifcopenshell-python/test/api/context/test_edit_context.py
+++ b/src/ifcopenshell-python/test/api/context/test_edit_context.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.context
+import test.bootstrap
class TestEditContext(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/context/test_remove_context.py b/src/ifcopenshell-python/test/api/context/test_remove_context.py
index dbc4185b6c..1dd3e255b4 100644
--- a/src/ifcopenshell-python/test/api/context/test_remove_context.py
+++ b/src/ifcopenshell-python/test/api/context/test_remove_context.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.context
import ifcopenshell.api.geometry
import ifcopenshell.api.root
+import test.bootstrap
class TestRemoveContext(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/control/test_assign_control.py b/src/ifcopenshell-python/test/api/control/test_assign_control.py
index 75c6c0e8d3..a84b8d3ed7 100644
--- a/src/ifcopenshell-python/test/api/control/test_assign_control.py
+++ b/src/ifcopenshell-python/test/api/control/test_assign_control.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.cost
import ifcopenshell.api.control
+import ifcopenshell.api.cost
+import test.bootstrap
class TestAssignControl(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/control/test_unassign_control.py b/src/ifcopenshell-python/test/api/control/test_unassign_control.py
index ecaebdae32..e413847f76 100644
--- a/src/ifcopenshell-python/test/api/control/test_unassign_control.py
+++ b/src/ifcopenshell-python/test/api/control/test_unassign_control.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.cost
import ifcopenshell.api.control
+import ifcopenshell.api.cost
+import test.bootstrap
class TestUnassignControl(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/cost/test_add_cost_item.py b/src/ifcopenshell-python/test/api/cost/test_add_cost_item.py
index c2a3762e78..b473bdc86c 100644
--- a/src/ifcopenshell-python/test/api/cost/test_add_cost_item.py
+++ b/src/ifcopenshell-python/test/api/cost/test_add_cost_item.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.cost
import ifcopenshell.util.element
+import test.bootstrap
class TestAddCostItem(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/cost/test_add_cost_item_quantity.py b/src/ifcopenshell-python/test/api/cost/test_add_cost_item_quantity.py
index e5ffe38ce0..7680e9e376 100644
--- a/src/ifcopenshell-python/test/api/cost/test_add_cost_item_quantity.py
+++ b/src/ifcopenshell-python/test/api/cost/test_add_cost_item_quantity.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
+import ifcopenshell.api.control
import ifcopenshell.api.cost
import ifcopenshell.api.root
-import ifcopenshell.api.control
+import test.bootstrap
class TestAddCostItemQuantity(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/cost/test_add_cost_schedule.py b/src/ifcopenshell-python/test/api/cost/test_add_cost_schedule.py
index 019bc2b6b4..af138af60a 100644
--- a/src/ifcopenshell-python/test/api/cost/test_add_cost_schedule.py
+++ b/src/ifcopenshell-python/test/api/cost/test_add_cost_schedule.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.cost
+import test.bootstrap
class TestAddCostSchedule(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/cost/test_remove_cost_item.py b/src/ifcopenshell-python/test/api/cost/test_remove_cost_item.py
index a987063769..1bcd60eae9 100644
--- a/src/ifcopenshell-python/test/api/cost/test_remove_cost_item.py
+++ b/src/ifcopenshell-python/test/api/cost/test_remove_cost_item.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.cost
+import test.bootstrap
class TestRemoveCostItem(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/cost/test_remove_cost_schedule.py b/src/ifcopenshell-python/test/api/cost/test_remove_cost_schedule.py
index 309f4b0906..5acadb9673 100644
--- a/src/ifcopenshell-python/test/api/cost/test_remove_cost_schedule.py
+++ b/src/ifcopenshell-python/test/api/cost/test_remove_cost_schedule.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api
import ifcopenshell.api.cost
+import test.bootstrap
class TestRemoveCostSchedule(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/document/test_add_information.py b/src/ifcopenshell-python/test/api/document/test_add_information.py
index 8dc687652b..ea4846c9a5 100644
--- a/src/ifcopenshell-python/test/api/document/test_add_information.py
+++ b/src/ifcopenshell-python/test/api/document/test_add_information.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.document
+import test.bootstrap
class TestAddInformation(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/document/test_add_reference.py b/src/ifcopenshell-python/test/api/document/test_add_reference.py
index a0420a6d15..dbfbfb474b 100644
--- a/src/ifcopenshell-python/test/api/document/test_add_reference.py
+++ b/src/ifcopenshell-python/test/api/document/test_add_reference.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.document
+import test.bootstrap
class TestAddReference(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/document/test_assign_document.py b/src/ifcopenshell-python/test/api/document/test_assign_document.py
index 2a3051fe4b..336e640a67 100644
--- a/src/ifcopenshell-python/test/api/document/test_assign_document.py
+++ b/src/ifcopenshell-python/test/api/document/test_assign_document.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.document
+import ifcopenshell.api.root
import ifcopenshell.util.element
+import test.bootstrap
class TestAssignDocument(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/document/test_remove_information.py b/src/ifcopenshell-python/test/api/document/test_remove_information.py
index 69e87faece..cee5357fd7 100644
--- a/src/ifcopenshell-python/test/api/document/test_remove_information.py
+++ b/src/ifcopenshell-python/test/api/document/test_remove_information.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.document
+import test.bootstrap
class TestRemoveInformation(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/document/test_remove_reference.py b/src/ifcopenshell-python/test/api/document/test_remove_reference.py
index dd5fde6602..56a6971a76 100644
--- a/src/ifcopenshell-python/test/api/document/test_remove_reference.py
+++ b/src/ifcopenshell-python/test/api/document/test_remove_reference.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.document
+import test.bootstrap
class TestRemoveReference(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/document/test_unassign_document.py b/src/ifcopenshell-python/test/api/document/test_unassign_document.py
index a5671a2b89..167143a949 100644
--- a/src/ifcopenshell-python/test/api/document/test_unassign_document.py
+++ b/src/ifcopenshell-python/test/api/document/test_unassign_document.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.document
+import ifcopenshell.api.root
import ifcopenshell.util.element
+import test.bootstrap
class TestUnassignDocument(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/drawing/test_assign_product.py b/src/ifcopenshell-python/test/api/drawing/test_assign_product.py
index c2464203c0..925afc7073 100644
--- a/src/ifcopenshell-python/test/api/drawing/test_assign_product.py
+++ b/src/ifcopenshell-python/test/api/drawing/test_assign_product.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.drawing
+import test.bootstrap
class TestAssignProduct(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/drawing/test_edit_text_literal.py b/src/ifcopenshell-python/test/api/drawing/test_edit_text_literal.py
index 410c11ce7a..dcc7ba3dd5 100644
--- a/src/ifcopenshell-python/test/api/drawing/test_edit_text_literal.py
+++ b/src/ifcopenshell-python/test/api/drawing/test_edit_text_literal.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.drawing
+import test.bootstrap
class TestEditTextLiteral(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/drawing/test_unassign_product.py b/src/ifcopenshell-python/test/api/drawing/test_unassign_product.py
index f80a9b2ecc..381b9c01e7 100644
--- a/src/ifcopenshell-python/test/api/drawing/test_unassign_product.py
+++ b/src/ifcopenshell-python/test/api/drawing/test_unassign_product.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.drawing
+import test.bootstrap
class TestUnassignProduct(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/feature/test_add_feature.py b/src/ifcopenshell-python/test/api/feature/test_add_feature.py
index 7ac05f6ecf..eb4f0e3565 100644
--- a/src/ifcopenshell-python/test/api/feature/test_add_feature.py
+++ b/src/ifcopenshell-python/test/api/feature/test_add_feature.py
@@ -17,12 +17,13 @@
# along with IfcOpenShell. If not, see .
import numpy
-import test.bootstrap
+
import ifcopenshell.api.feature
+import ifcopenshell.api.geometry
import ifcopenshell.api.root
import ifcopenshell.api.unit
-import ifcopenshell.api.geometry
import ifcopenshell.util.placement
+import test.bootstrap
class TestAddFeature(test.bootstrap.IFC4X3):
diff --git a/src/ifcopenshell-python/test/api/feature/test_add_filling.py b/src/ifcopenshell-python/test/api/feature/test_add_filling.py
index 49259d75ab..c968215187 100644
--- a/src/ifcopenshell-python/test/api/feature/test_add_filling.py
+++ b/src/ifcopenshell-python/test/api/feature/test_add_filling.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.feature
import ifcopenshell.api.root
+import test.bootstrap
class TestAddFilling(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/feature/test_remove_feature.py b/src/ifcopenshell-python/test/api/feature/test_remove_feature.py
index 5275639525..74065267da 100644
--- a/src/ifcopenshell-python/test/api/feature/test_remove_feature.py
+++ b/src/ifcopenshell-python/test/api/feature/test_remove_feature.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.feature
import ifcopenshell.api.root
+import test.bootstrap
class TestRemoveFeature(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/geometry/test_add_boolean.py b/src/ifcopenshell-python/test/api/geometry/test_add_boolean.py
index 80673275f8..d507f89308 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_add_boolean.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_add_boolean.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.context
import ifcopenshell.api.geometry
+import ifcopenshell.api.root
import ifcopenshell.util.shape_builder
+import test.bootstrap
class TestAddBoolean(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/geometry/test_add_profile_representation.py b/src/ifcopenshell-python/test/api/geometry/test_add_profile_representation.py
index 39ac9aa928..e0c500a8cf 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_add_profile_representation.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_add_profile_representation.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.unit
-import ifcopenshell.api.root
import ifcopenshell.api.context
import ifcopenshell.api.geometry
+import ifcopenshell.api.root
+import ifcopenshell.api.unit
+import test.bootstrap
from ifcopenshell.util.shape_builder import ShapeBuilder
diff --git a/src/ifcopenshell-python/test/api/geometry/test_add_shape_aspect.py b/src/ifcopenshell-python/test/api/geometry/test_add_shape_aspect.py
index c827f1e33a..b0e9b63f48 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_add_shape_aspect.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_add_shape_aspect.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.context
import ifcopenshell.api.geometry
+import ifcopenshell.api.root
import ifcopenshell.util.shape_builder
+import test.bootstrap
class TestAddShapeAspect(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/geometry/test_assign_representation.py b/src/ifcopenshell-python/test/api/geometry/test_assign_representation.py
index c971219157..ec02c7bc27 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_assign_representation.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_assign_representation.py
@@ -16,12 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api
-import ifcopenshell.api.material
-import ifcopenshell.api.type
-import ifcopenshell.api.root
import ifcopenshell.api.geometry
+import ifcopenshell.api.material
+import ifcopenshell.api.root
+import ifcopenshell.api.type
+import test.bootstrap
class TestAssignRepresentation(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/geometry/test_connect_element.py b/src/ifcopenshell-python/test/api/geometry/test_connect_element.py
index 240976463b..9902b7b4df 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_connect_element.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_connect_element.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.geometry
+import ifcopenshell.api.root
+import test.bootstrap
class TestConnectElement(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/geometry/test_connect_path.py b/src/ifcopenshell-python/test/api/geometry/test_connect_path.py
index 634eb1b45e..bda341d2c6 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_connect_path.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_connect_path.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.geometry
+import ifcopenshell.api.root
+import test.bootstrap
class TestConnectPath(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/geometry/test_disconnect_element.py b/src/ifcopenshell-python/test/api/geometry/test_disconnect_element.py
index 4bf8dfbbc8..9fab39cc01 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_disconnect_element.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_disconnect_element.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.geometry
+import ifcopenshell.api.root
+import test.bootstrap
class TestDisconnectElement(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/geometry/test_disconnect_path.py b/src/ifcopenshell-python/test/api/geometry/test_disconnect_path.py
index fdb0c013d8..5a58a8693b 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_disconnect_path.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_disconnect_path.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.geometry
+import ifcopenshell.api.root
+import test.bootstrap
class TestDisconnectPath(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py b/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py
index 70dcbf7285..d243d4b738 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py
@@ -18,16 +18,17 @@
import numpy
import pytest
-import test.bootstrap
-import ifcopenshell.api.feature
-import ifcopenshell.api.root
-import ifcopenshell.api.unit
-import ifcopenshell.api.system
-import ifcopenshell.api.spatial
-import ifcopenshell.api.geometry
+
import ifcopenshell.api.aggregate
+import ifcopenshell.api.feature
+import ifcopenshell.api.geometry
+import ifcopenshell.api.root
+import ifcopenshell.api.spatial
+import ifcopenshell.api.system
+import ifcopenshell.api.unit
import ifcopenshell.guid
import ifcopenshell.util.placement
+import test.bootstrap
class TestEditObjectPlacement(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/geometry/test_remove_boolean.py b/src/ifcopenshell-python/test/api/geometry/test_remove_boolean.py
index 5330d097cc..aeb7728ea6 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_remove_boolean.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_remove_boolean.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.context
import ifcopenshell.api.geometry
+import ifcopenshell.api.root
import ifcopenshell.util.shape_builder
+import test.bootstrap
class TestRemoveBoolean(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/geometry/test_remove_representation.py b/src/ifcopenshell-python/test/api/geometry/test_remove_representation.py
index 4363cc8ac8..1c37f8960a 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_remove_representation.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_remove_representation.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.geometry
+import test.bootstrap
class TestRemoveRepresentation(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/geometry/test_unassign_representation.py b/src/ifcopenshell-python/test/api/geometry/test_unassign_representation.py
index 1e45054369..55fbcaefe9 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_unassign_representation.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_unassign_representation.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.geometry
import ifcopenshell.util.placement
+import test.bootstrap
class TestUnassignRepresentation(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/geometry/test_validate_type.py b/src/ifcopenshell-python/test/api/geometry/test_validate_type.py
index 189f9619a9..7f4a57e995 100644
--- a/src/ifcopenshell-python/test/api/geometry/test_validate_type.py
+++ b/src/ifcopenshell-python/test/api/geometry/test_validate_type.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.context
import ifcopenshell.api.geometry
+import ifcopenshell.api.root
import ifcopenshell.util.shape_builder
+import test.bootstrap
class TestValidateType(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/georeference/test_add_georeferencing.py b/src/ifcopenshell-python/test/api/georeference/test_add_georeferencing.py
index 121af8f5a1..68f1ac2597 100644
--- a/src/ifcopenshell-python/test/api/georeference/test_add_georeferencing.py
+++ b/src/ifcopenshell-python/test/api/georeference/test_add_georeferencing.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.context
import ifcopenshell.api.georeference
+import ifcopenshell.api.root
import ifcopenshell.util.element
+import test.bootstrap
class TestAddGeoreferencing(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/georeference/test_edit_georeferencing.py b/src/ifcopenshell-python/test/api/georeference/test_edit_georeferencing.py
index 862983fdc5..729eb0559b 100644
--- a/src/ifcopenshell-python/test/api/georeference/test_edit_georeferencing.py
+++ b/src/ifcopenshell-python/test/api/georeference/test_edit_georeferencing.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.context
import ifcopenshell.api.georeference
+import ifcopenshell.api.root
import ifcopenshell.util.element
+import test.bootstrap
class TestEditGeoreferencing(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/georeference/test_edit_true_north.py b/src/ifcopenshell-python/test/api/georeference/test_edit_true_north.py
index 9f8f2dd07a..dc8ea2bc3e 100644
--- a/src/ifcopenshell-python/test/api/georeference/test_edit_true_north.py
+++ b/src/ifcopenshell-python/test/api/georeference/test_edit_true_north.py
@@ -17,11 +17,12 @@
# along with IfcOpenShell. If not, see .
import numpy as np
-import test.bootstrap
-import ifcopenshell.api.root
+
import ifcopenshell.api.context
import ifcopenshell.api.georeference
+import ifcopenshell.api.root
import ifcopenshell.util.geolocation
+import test.bootstrap
class TestEditTrueNorth(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/georeference/test_edit_wcs.py b/src/ifcopenshell-python/test/api/georeference/test_edit_wcs.py
index f23ce928ce..9e761e81bb 100644
--- a/src/ifcopenshell-python/test/api/georeference/test_edit_wcs.py
+++ b/src/ifcopenshell-python/test/api/georeference/test_edit_wcs.py
@@ -17,11 +17,12 @@
# along with IfcOpenShell. If not, see .
import numpy as np
-import test.bootstrap
-import ifcopenshell.api.root
+
import ifcopenshell.api.context
import ifcopenshell.api.georeference
+import ifcopenshell.api.root
import ifcopenshell.util.geolocation
+import test.bootstrap
class TestEditWCS(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/georeference/test_remove_georeferencing.py b/src/ifcopenshell-python/test/api/georeference/test_remove_georeferencing.py
index 5befb17b99..13bca27c5d 100644
--- a/src/ifcopenshell-python/test/api/georeference/test_remove_georeferencing.py
+++ b/src/ifcopenshell-python/test/api/georeference/test_remove_georeferencing.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.context
import ifcopenshell.api.georeference
+import ifcopenshell.api.root
import ifcopenshell.util.element
+import test.bootstrap
class TestRemoveGeoreferencing(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/grid/test_create_grid_axis.py b/src/ifcopenshell-python/test/api/grid/test_create_grid_axis.py
index 518f6308d2..24ca32f9ef 100644
--- a/src/ifcopenshell-python/test/api/grid/test_create_grid_axis.py
+++ b/src/ifcopenshell-python/test/api/grid/test_create_grid_axis.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.grid
+import test.bootstrap
class TestCreateGridAxis(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/group/test_add_group.py b/src/ifcopenshell-python/test/api/group/test_add_group.py
index 0c8af993ab..0c3547ce49 100644
--- a/src/ifcopenshell-python/test/api/group/test_add_group.py
+++ b/src/ifcopenshell-python/test/api/group/test_add_group.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.group
import ifcopenshell.util.element
+import test.bootstrap
class TestAddGroup(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/group/test_assign_group.py b/src/ifcopenshell-python/test/api/group/test_assign_group.py
index 85b2711e27..959883db3b 100644
--- a/src/ifcopenshell-python/test/api/group/test_assign_group.py
+++ b/src/ifcopenshell-python/test/api/group/test_assign_group.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.group
+import ifcopenshell.api.root
import ifcopenshell.util.element
+import test.bootstrap
class TestAssignGroup(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/group/test_remove_group.py b/src/ifcopenshell-python/test/api/group/test_remove_group.py
index 28e59493c5..efe7cd25d3 100644
--- a/src/ifcopenshell-python/test/api/group/test_remove_group.py
+++ b/src/ifcopenshell-python/test/api/group/test_remove_group.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
+import ifcopenshell.api.group
import ifcopenshell.api.pset
import ifcopenshell.api.root
-import ifcopenshell.api.group
+import test.bootstrap
class TestRemoveGroup(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/group/test_unassign_group.py b/src/ifcopenshell-python/test/api/group/test_unassign_group.py
index c40b4affcb..f909e428f7 100644
--- a/src/ifcopenshell-python/test/api/group/test_unassign_group.py
+++ b/src/ifcopenshell-python/test/api/group/test_unassign_group.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.group
+import ifcopenshell.api.root
+import test.bootstrap
class TestAssignGroup(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/group/test_update_group_products.py b/src/ifcopenshell-python/test/api/group/test_update_group_products.py
index 56d685de9a..c8e50f7d0e 100644
--- a/src/ifcopenshell-python/test/api/group/test_update_group_products.py
+++ b/src/ifcopenshell-python/test/api/group/test_update_group_products.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.group
+import ifcopenshell.api.root
import ifcopenshell.util.element
+import test.bootstrap
class TestUpdateGroupProductsIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/layer/test_add_layer.py b/src/ifcopenshell-python/test/api/layer/test_add_layer.py
index 97635ccb63..aa54065048 100644
--- a/src/ifcopenshell-python/test/api/layer/test_add_layer.py
+++ b/src/ifcopenshell-python/test/api/layer/test_add_layer.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.layer
+import test.bootstrap
class TestAddLayer(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/layer/test_add_layer_with_style.py b/src/ifcopenshell-python/test/api/layer/test_add_layer_with_style.py
index 0395e40178..8d52258727 100644
--- a/src/ifcopenshell-python/test/api/layer/test_add_layer_with_style.py
+++ b/src/ifcopenshell-python/test/api/layer/test_add_layer_with_style.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.layer
+import test.bootstrap
class TestAddLayerWithStyle(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/layer/test_assign_layer.py b/src/ifcopenshell-python/test/api/layer/test_assign_layer.py
index f2b0e831d9..9c174975ca 100644
--- a/src/ifcopenshell-python/test/api/layer/test_assign_layer.py
+++ b/src/ifcopenshell-python/test/api/layer/test_assign_layer.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.layer
+import test.bootstrap
class TestAssignLayer(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/layer/test_unassign_layer.py b/src/ifcopenshell-python/test/api/layer/test_unassign_layer.py
index 018c9125f5..8d14f6ad94 100644
--- a/src/ifcopenshell-python/test/api/layer/test_unassign_layer.py
+++ b/src/ifcopenshell-python/test/api/layer/test_unassign_layer.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.layer
+import test.bootstrap
class TestUnassignLayer(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/library/test_add_library.py b/src/ifcopenshell-python/test/api/library/test_add_library.py
index e2cd440028..36b63b70f6 100644
--- a/src/ifcopenshell-python/test/api/library/test_add_library.py
+++ b/src/ifcopenshell-python/test/api/library/test_add_library.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.library
+import test.bootstrap
class TestAddLibrary(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/library/test_add_reference.py b/src/ifcopenshell-python/test/api/library/test_add_reference.py
index 95f23d495f..596d878b67 100644
--- a/src/ifcopenshell-python/test/api/library/test_add_reference.py
+++ b/src/ifcopenshell-python/test/api/library/test_add_reference.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.library
+import test.bootstrap
class TestAddReference(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/library/test_assign_reference.py b/src/ifcopenshell-python/test/api/library/test_assign_reference.py
index 988d4c2265..822687f2db 100644
--- a/src/ifcopenshell-python/test/api/library/test_assign_reference.py
+++ b/src/ifcopenshell-python/test/api/library/test_assign_reference.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.library
+import test.bootstrap
class TestAssignReference(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/library/test_edit_library.py b/src/ifcopenshell-python/test/api/library/test_edit_library.py
index 26f46d3016..42f4119f99 100644
--- a/src/ifcopenshell-python/test/api/library/test_edit_library.py
+++ b/src/ifcopenshell-python/test/api/library/test_edit_library.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import datetime
+
import ifcopenshell.api.library
import ifcopenshell.util.date
+import test.bootstrap
class TestEditLibrary(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/library/test_edit_reference.py b/src/ifcopenshell-python/test/api/library/test_edit_reference.py
index b979a56357..6bb638ff5b 100644
--- a/src/ifcopenshell-python/test/api/library/test_edit_reference.py
+++ b/src/ifcopenshell-python/test/api/library/test_edit_reference.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.library
+import test.bootstrap
class TestEditReference(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/library/test_remove_library.py b/src/ifcopenshell-python/test/api/library/test_remove_library.py
index 7376d4a288..038249f49b 100644
--- a/src/ifcopenshell-python/test/api/library/test_remove_library.py
+++ b/src/ifcopenshell-python/test/api/library/test_remove_library.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.library
+import test.bootstrap
class TestRemoveLibrary(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/library/test_remove_reference.py b/src/ifcopenshell-python/test/api/library/test_remove_reference.py
index f6f6d90588..32b0920188 100644
--- a/src/ifcopenshell-python/test/api/library/test_remove_reference.py
+++ b/src/ifcopenshell-python/test/api/library/test_remove_reference.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.library
+import test.bootstrap
class TestRemoveReference(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/library/test_unassign_reference.py b/src/ifcopenshell-python/test/api/library/test_unassign_reference.py
index e7e1b9cf63..e1223b91fe 100644
--- a/src/ifcopenshell-python/test/api/library/test_unassign_reference.py
+++ b/src/ifcopenshell-python/test/api/library/test_unassign_reference.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.library
import ifcopenshell.util.element
+import test.bootstrap
class TestUnassignReference(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/material/test_add_material_set.py b/src/ifcopenshell-python/test/api/material/test_add_material_set.py
index 758c40b824..10e65cb6d3 100644
--- a/src/ifcopenshell-python/test/api/material/test_add_material_set.py
+++ b/src/ifcopenshell-python/test/api/material/test_add_material_set.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.material
+import test.bootstrap
class TestAddMaterialSetIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/material/test_assign_material.py b/src/ifcopenshell-python/test/api/material/test_assign_material.py
index 2baeedcb50..554bc95b9f 100644
--- a/src/ifcopenshell-python/test/api/material/test_assign_material.py
+++ b/src/ifcopenshell-python/test/api/material/test_assign_material.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
+import ifcopenshell.api.material
import ifcopenshell.api.root
import ifcopenshell.api.type
-import ifcopenshell.api.material
import ifcopenshell.util.element
+import test.bootstrap
class TestAssignMaterialIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/material/test_copy_material.py b/src/ifcopenshell-python/test/api/material/test_copy_material.py
index 2faa210e6c..51e36f0eac 100644
--- a/src/ifcopenshell-python/test/api/material/test_copy_material.py
+++ b/src/ifcopenshell-python/test/api/material/test_copy_material.py
@@ -16,13 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
+import ifcopenshell.api.context
+import ifcopenshell.api.material
import ifcopenshell.api.pset
import ifcopenshell.api.root
import ifcopenshell.api.style
-import ifcopenshell.api.context
-import ifcopenshell.api.material
import ifcopenshell.util.element
+import test.bootstrap
class TestCopyMaterial(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/material/test_edit_profile_usage.py b/src/ifcopenshell-python/test/api/material/test_edit_profile_usage.py
index 3a029482c1..478c41eb55 100644
--- a/src/ifcopenshell-python/test/api/material/test_edit_profile_usage.py
+++ b/src/ifcopenshell-python/test/api/material/test_edit_profile_usage.py
@@ -16,12 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.context
import ifcopenshell.api.geometry
import ifcopenshell.api.material
import ifcopenshell.api.root
import ifcopenshell.util.placement
+import test.bootstrap
from ifcopenshell.util.shape_builder import ShapeBuilder
diff --git a/src/ifcopenshell-python/test/api/material/test_remove_material.py b/src/ifcopenshell-python/test/api/material/test_remove_material.py
index 01f3621a81..d33f9114dc 100644
--- a/src/ifcopenshell-python/test/api/material/test_remove_material.py
+++ b/src/ifcopenshell-python/test/api/material/test_remove_material.py
@@ -16,12 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
+import ifcopenshell.api.context
+import ifcopenshell.api.material
import ifcopenshell.api.pset
import ifcopenshell.api.root
import ifcopenshell.api.style
-import ifcopenshell.api.context
-import ifcopenshell.api.material
+import test.bootstrap
class TestRemoveMaterialIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/material/test_remove_material_set.py b/src/ifcopenshell-python/test/api/material/test_remove_material_set.py
index 3c6c70b44a..24330c3720 100644
--- a/src/ifcopenshell-python/test/api/material/test_remove_material_set.py
+++ b/src/ifcopenshell-python/test/api/material/test_remove_material_set.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.material
import ifcopenshell.api.pset
import ifcopenshell.api.root
import ifcopenshell.api.type
+import test.bootstrap
class TestRemoveMaterialSetIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/material/test_unassign_material.py b/src/ifcopenshell-python/test/api/material/test_unassign_material.py
index 398661c7b0..ba5f29c04a 100644
--- a/src/ifcopenshell-python/test/api/material/test_unassign_material.py
+++ b/src/ifcopenshell-python/test/api/material/test_unassign_material.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
+import ifcopenshell.api.material
import ifcopenshell.api.root
import ifcopenshell.api.type
-import ifcopenshell.api.material
import ifcopenshell.util.element
+import test.bootstrap
class TestUnassignMaterialIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/nest/test_assign_object.py b/src/ifcopenshell-python/test/api/nest/test_assign_object.py
index a6abfde611..45c4d828e3 100644
--- a/src/ifcopenshell-python/test/api/nest/test_assign_object.py
+++ b/src/ifcopenshell-python/test/api/nest/test_assign_object.py
@@ -17,11 +17,12 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api.nest
import ifcopenshell.api.root
import ifcopenshell.util.element
import ifcopenshell.util.placement
+import test.bootstrap
class TestAssignObject(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/nest/test_unassign_object.py b/src/ifcopenshell-python/test/api/nest/test_unassign_object.py
index 9f3979b85d..925d15b2db 100644
--- a/src/ifcopenshell-python/test/api/nest/test_unassign_object.py
+++ b/src/ifcopenshell-python/test/api/nest/test_unassign_object.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.nest
import ifcopenshell.api.root
import ifcopenshell.util.element
+import test.bootstrap
class TestUnassignObject(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_add_actor.py b/src/ifcopenshell-python/test/api/owner/test_add_actor.py
index 2a4bf52cf7..c3a8410ae6 100644
--- a/src/ifcopenshell-python/test/api/owner/test_add_actor.py
+++ b/src/ifcopenshell-python/test/api/owner/test_add_actor.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestAddActor(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_add_address.py b/src/ifcopenshell-python/test/api/owner/test_add_address.py
index 16dc75f492..ffb3daebf2 100644
--- a/src/ifcopenshell-python/test/api/owner/test_add_address.py
+++ b/src/ifcopenshell-python/test/api/owner/test_add_address.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestAddAddress(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_add_application.py b/src/ifcopenshell-python/test/api/owner/test_add_application.py
index 77890c19cf..bc70fae55a 100644
--- a/src/ifcopenshell-python/test/api/owner/test_add_application.py
+++ b/src/ifcopenshell-python/test/api/owner/test_add_application.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
import ifcopenshell.util.element
+import test.bootstrap
class TestAddApplication(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_add_organisation.py b/src/ifcopenshell-python/test/api/owner/test_add_organisation.py
index 5f20a35129..5080951e57 100644
--- a/src/ifcopenshell-python/test/api/owner/test_add_organisation.py
+++ b/src/ifcopenshell-python/test/api/owner/test_add_organisation.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestAddOrganisation(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_add_person.py b/src/ifcopenshell-python/test/api/owner/test_add_person.py
index 9f1dc8e776..8d02a45d0a 100644
--- a/src/ifcopenshell-python/test/api/owner/test_add_person.py
+++ b/src/ifcopenshell-python/test/api/owner/test_add_person.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestAddPerson(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_add_person_and_organisation.py b/src/ifcopenshell-python/test/api/owner/test_add_person_and_organisation.py
index ac97b7a317..7ed6cf8934 100644
--- a/src/ifcopenshell-python/test/api/owner/test_add_person_and_organisation.py
+++ b/src/ifcopenshell-python/test/api/owner/test_add_person_and_organisation.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestAddPersonAndOrganisation(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_add_role.py b/src/ifcopenshell-python/test/api/owner/test_add_role.py
index c98cba08e9..05c450aa2f 100644
--- a/src/ifcopenshell-python/test/api/owner/test_add_role.py
+++ b/src/ifcopenshell-python/test/api/owner/test_add_role.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestAddRole(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_assign_actor.py b/src/ifcopenshell-python/test/api/owner/test_assign_actor.py
index c4c6f84c24..0098037f39 100644
--- a/src/ifcopenshell-python/test/api/owner/test_assign_actor.py
+++ b/src/ifcopenshell-python/test/api/owner/test_assign_actor.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestAssignActor(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_create_owner_history.py b/src/ifcopenshell-python/test/api/owner/test_create_owner_history.py
index 839f46ea73..5d717fed80 100644
--- a/src/ifcopenshell-python/test/api/owner/test_create_owner_history.py
+++ b/src/ifcopenshell-python/test/api/owner/test_create_owner_history.py
@@ -17,10 +17,12 @@
# along with IfcOpenShell. If not, see .
import time
+
import pytest
-import test.bootstrap
+
import ifcopenshell.api
import ifcopenshell.api.owner.settings
+import test.bootstrap
class TestCreateOwnerHistory(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_edit_actor.py b/src/ifcopenshell-python/test/api/owner/test_edit_actor.py
index 02335cca41..f050514819 100644
--- a/src/ifcopenshell-python/test/api/owner/test_edit_actor.py
+++ b/src/ifcopenshell-python/test/api/owner/test_edit_actor.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestEditActor(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_edit_address.py b/src/ifcopenshell-python/test/api/owner/test_edit_address.py
index c01b072939..1529f1b863 100644
--- a/src/ifcopenshell-python/test/api/owner/test_edit_address.py
+++ b/src/ifcopenshell-python/test/api/owner/test_edit_address.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestEditAddress(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_edit_application.py b/src/ifcopenshell-python/test/api/owner/test_edit_application.py
index 4a88e8631b..ac3612bca9 100644
--- a/src/ifcopenshell-python/test/api/owner/test_edit_application.py
+++ b/src/ifcopenshell-python/test/api/owner/test_edit_application.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestEditApplication(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_edit_organisation.py b/src/ifcopenshell-python/test/api/owner/test_edit_organisation.py
index c1a6742239..6580762406 100644
--- a/src/ifcopenshell-python/test/api/owner/test_edit_organisation.py
+++ b/src/ifcopenshell-python/test/api/owner/test_edit_organisation.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestEditOrganisation(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_edit_person.py b/src/ifcopenshell-python/test/api/owner/test_edit_person.py
index e1b79ddc6e..ae07f78e91 100644
--- a/src/ifcopenshell-python/test/api/owner/test_edit_person.py
+++ b/src/ifcopenshell-python/test/api/owner/test_edit_person.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestEditPerson(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_edit_role.py b/src/ifcopenshell-python/test/api/owner/test_edit_role.py
index c92f38d15c..8fb203cbf1 100644
--- a/src/ifcopenshell-python/test/api/owner/test_edit_role.py
+++ b/src/ifcopenshell-python/test/api/owner/test_edit_role.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestEditRole(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_remove_actor.py b/src/ifcopenshell-python/test/api/owner/test_remove_actor.py
index f46b70ca6e..db044c3efe 100644
--- a/src/ifcopenshell-python/test/api/owner/test_remove_actor.py
+++ b/src/ifcopenshell-python/test/api/owner/test_remove_actor.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestRemoveActor(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_remove_address.py b/src/ifcopenshell-python/test/api/owner/test_remove_address.py
index f8d6c6094f..e8dfb72dc0 100644
--- a/src/ifcopenshell-python/test/api/owner/test_remove_address.py
+++ b/src/ifcopenshell-python/test/api/owner/test_remove_address.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestRemoveAddress(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_remove_organisation.py b/src/ifcopenshell-python/test/api/owner/test_remove_organisation.py
index 7da306ecf3..0a0f25dd73 100644
--- a/src/ifcopenshell-python/test/api/owner/test_remove_organisation.py
+++ b/src/ifcopenshell-python/test/api/owner/test_remove_organisation.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
import ifcopenshell.guid
+import test.bootstrap
class TestRemoveOrganisationIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/owner/test_remove_person.py b/src/ifcopenshell-python/test/api/owner/test_remove_person.py
index 8304d4b985..d8effdd4ec 100644
--- a/src/ifcopenshell-python/test/api/owner/test_remove_person.py
+++ b/src/ifcopenshell-python/test/api/owner/test_remove_person.py
@@ -17,9 +17,10 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api.owner
import ifcopenshell.guid
+import test.bootstrap
class TestRemovePersonIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/owner/test_remove_person_and_organisation.py b/src/ifcopenshell-python/test/api/owner/test_remove_person_and_organisation.py
index a07d8dbe6a..a8bfa3a891 100644
--- a/src/ifcopenshell-python/test/api/owner/test_remove_person_and_organisation.py
+++ b/src/ifcopenshell-python/test/api/owner/test_remove_person_and_organisation.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
import ifcopenshell.guid
+import test.bootstrap
class TestRemovePersonAndOrganisationIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/owner/test_remove_role.py b/src/ifcopenshell-python/test/api/owner/test_remove_role.py
index 0c2afcdd99..3ef261be00 100644
--- a/src/ifcopenshell-python/test/api/owner/test_remove_role.py
+++ b/src/ifcopenshell-python/test/api/owner/test_remove_role.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestRemoveRoleIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/owner/test_unassign_actor.py b/src/ifcopenshell-python/test/api/owner/test_unassign_actor.py
index 96a21c1a79..465ca01bae 100644
--- a/src/ifcopenshell-python/test/api/owner/test_unassign_actor.py
+++ b/src/ifcopenshell-python/test/api/owner/test_unassign_actor.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.owner
+import test.bootstrap
class TestUnassignActor(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/owner/test_update_owner_history.py b/src/ifcopenshell-python/test/api/owner/test_update_owner_history.py
index fb500658e1..1aeb5ad7c3 100644
--- a/src/ifcopenshell-python/test/api/owner/test_update_owner_history.py
+++ b/src/ifcopenshell-python/test/api/owner/test_update_owner_history.py
@@ -17,9 +17,10 @@
# along with IfcOpenShell. If not, see .
import time
-import test.bootstrap
+
import ifcopenshell.api.owner
import ifcopenshell.api.owner.settings
+import test.bootstrap
class TestUpdateOwnerHistory(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/profile/test_add_parameterized_profile.py b/src/ifcopenshell-python/test/api/profile/test_add_parameterized_profile.py
index 8481592643..b485cc97e7 100644
--- a/src/ifcopenshell-python/test/api/profile/test_add_parameterized_profile.py
+++ b/src/ifcopenshell-python/test/api/profile/test_add_parameterized_profile.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.profile
import ifcopenshell.util.schema
+import test.bootstrap
class TestAddParametrizedProfileIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/profile/test_copy_profile.py b/src/ifcopenshell-python/test/api/profile/test_copy_profile.py
index 8cc19b1489..b82c47c12b 100644
--- a/src/ifcopenshell-python/test/api/profile/test_copy_profile.py
+++ b/src/ifcopenshell-python/test/api/profile/test_copy_profile.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.profile
import ifcopenshell.api.pset
import ifcopenshell.util.element
+import test.bootstrap
class TestCopyProfileIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/profile/test_remove_profile.py b/src/ifcopenshell-python/test/api/profile/test_remove_profile.py
index 86b3e136e7..3657ebc2d2 100644
--- a/src/ifcopenshell-python/test/api/profile/test_remove_profile.py
+++ b/src/ifcopenshell-python/test/api/profile/test_remove_profile.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.profile
import ifcopenshell.api.pset
+import test.bootstrap
class TestRemoveProfileIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/project/test_append_asset.py b/src/ifcopenshell-python/test/api/project/test_append_asset.py
index 399ee1fd04..f89e4d5c89 100644
--- a/src/ifcopenshell-python/test/api/project/test_append_asset.py
+++ b/src/ifcopenshell-python/test/api/project/test_append_asset.py
@@ -16,28 +16,29 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.layer
-import ifcopenshell.api.geometry
-import ifcopenshell.api.georeference
-import ifcopenshell.api.pset
-import ifcopenshell.api.root
-import ifcopenshell.api.type
+import numpy as np
+
+import ifcopenshell.api.classification
+import ifcopenshell.api.context
import ifcopenshell.api.cost
import ifcopenshell.api.feature
-import ifcopenshell.api.style
-import ifcopenshell.api.context
-import ifcopenshell.api.project
+import ifcopenshell.api.geometry
+import ifcopenshell.api.georeference
+import ifcopenshell.api.layer
import ifcopenshell.api.material
-import ifcopenshell.api.profile
-import ifcopenshell.api.unit
-import ifcopenshell.api.classification
import ifcopenshell.api.owner.settings
-import ifcopenshell.util.element
+import ifcopenshell.api.profile
+import ifcopenshell.api.project
+import ifcopenshell.api.pset
+import ifcopenshell.api.root
+import ifcopenshell.api.style
+import ifcopenshell.api.type
+import ifcopenshell.api.unit
import ifcopenshell.util.classification
+import ifcopenshell.util.element
import ifcopenshell.util.placement
import ifcopenshell.util.unit
-import numpy as np
+import test.bootstrap
from ifcopenshell.util.shape_builder import ShapeBuilder
diff --git a/src/ifcopenshell-python/test/api/project/test_assign_declaration.py b/src/ifcopenshell-python/test/api/project/test_assign_declaration.py
index 8bbaf521cc..af24565b59 100644
--- a/src/ifcopenshell-python/test/api/project/test_assign_declaration.py
+++ b/src/ifcopenshell-python/test/api/project/test_assign_declaration.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.project
+import ifcopenshell.api.root
+import test.bootstrap
# NOTE: supported only in IFC4+
diff --git a/src/ifcopenshell-python/test/api/project/test_create_file.py b/src/ifcopenshell-python/test/api/project/test_create_file.py
index 8456e2fe27..6373968cb2 100644
--- a/src/ifcopenshell-python/test/api/project/test_create_file.py
+++ b/src/ifcopenshell-python/test/api/project/test_create_file.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.project
+import test.bootstrap
class TestCreateFile(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/project/test_unassign_declaration.py b/src/ifcopenshell-python/test/api/project/test_unassign_declaration.py
index 6a1683840b..4d77f2b721 100644
--- a/src/ifcopenshell-python/test/api/project/test_unassign_declaration.py
+++ b/src/ifcopenshell-python/test/api/project/test_unassign_declaration.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
-import ifcopenshell.api.project
from typing import Union
+import ifcopenshell.api.project
+import ifcopenshell.api.root
+import test.bootstrap
+
# NOTE: supported only in IFC4+
class TestUnassignDeclaration(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/pset/test_add_pset.py b/src/ifcopenshell-python/test/api/pset/test_add_pset.py
index fadb1a369c..1629c639bf 100644
--- a/src/ifcopenshell-python/test/api/pset/test_add_pset.py
+++ b/src/ifcopenshell-python/test/api/pset/test_add_pset.py
@@ -16,12 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
+import ifcopenshell.api.material
+import ifcopenshell.api.profile
import ifcopenshell.api.pset
import ifcopenshell.api.root
-import ifcopenshell.api.profile
-import ifcopenshell.api.material
import ifcopenshell.util.element
+import test.bootstrap
class TestAddPset(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/pset/test_add_qto.py b/src/ifcopenshell-python/test/api/pset/test_add_qto.py
index 4c7493ca14..3f4a4e3ce6 100644
--- a/src/ifcopenshell-python/test/api/pset/test_add_qto.py
+++ b/src/ifcopenshell-python/test/api/pset/test_add_qto.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.pset
import ifcopenshell.api.root
import ifcopenshell.util.element
+import test.bootstrap
class TestAddQto(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/pset/test_assign_pset.py b/src/ifcopenshell-python/test/api/pset/test_assign_pset.py
index 950d2743cb..e1234e8fe1 100644
--- a/src/ifcopenshell-python/test/api/pset/test_assign_pset.py
+++ b/src/ifcopenshell-python/test/api/pset/test_assign_pset.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.pset
import ifcopenshell.util.element
+import test.bootstrap
class TestAssignPset(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/pset/test_edit_pset.py b/src/ifcopenshell-python/test/api/pset/test_edit_pset.py
index 257297f6b9..84347c626f 100644
--- a/src/ifcopenshell-python/test/api/pset/test_edit_pset.py
+++ b/src/ifcopenshell-python/test/api/pset/test_edit_pset.py
@@ -17,12 +17,13 @@
# along with IfcOpenShell. If not, see .
import operator
-import test.bootstrap
+from typing import Union
+
import ifcopenshell.api.pset
import ifcopenshell.api.root
import ifcopenshell.guid
import ifcopenshell.util.element
-from typing import Union
+import test.bootstrap
def get_properties(material: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
diff --git a/src/ifcopenshell-python/test/api/pset/test_edit_qto.py b/src/ifcopenshell-python/test/api/pset/test_edit_qto.py
index 0dc2bb5ef7..5bf31f8262 100644
--- a/src/ifcopenshell-python/test/api/pset/test_edit_qto.py
+++ b/src/ifcopenshell-python/test/api/pset/test_edit_qto.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.pset
import ifcopenshell.api.root
+import test.bootstrap
class TestEditQto(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/pset/test_remove_pset.py b/src/ifcopenshell-python/test/api/pset/test_remove_pset.py
index bb154cfc4f..b0f5dfd004 100644
--- a/src/ifcopenshell-python/test/api/pset/test_remove_pset.py
+++ b/src/ifcopenshell-python/test/api/pset/test_remove_pset.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.pset
import ifcopenshell.api.root
import ifcopenshell.util.element
+import test.bootstrap
class TestRemovePset(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/pset/test_unassign_pset.py b/src/ifcopenshell-python/test/api/pset/test_unassign_pset.py
index 585a281713..58c476d74a 100644
--- a/src/ifcopenshell-python/test/api/pset/test_unassign_pset.py
+++ b/src/ifcopenshell-python/test/api/pset/test_unassign_pset.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.pset
import ifcopenshell.util.element
+import test.bootstrap
class TestUnassignPset(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/pset/test_unshare_pset.py b/src/ifcopenshell-python/test/api/pset/test_unshare_pset.py
index 846d2d5a54..769294e1b5 100644
--- a/src/ifcopenshell-python/test/api/pset/test_unshare_pset.py
+++ b/src/ifcopenshell-python/test/api/pset/test_unshare_pset.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.pset
import ifcopenshell.api.root
-import ifcopenshell.util.element
import ifcopenshell.guid
+import ifcopenshell.util.element
+import test.bootstrap
class TestUnsharePset(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/pset_template/test_edit_prop_template.py b/src/ifcopenshell-python/test/api/pset_template/test_edit_prop_template.py
index ac076964c7..5f26b02983 100644
--- a/src/ifcopenshell-python/test/api/pset_template/test_edit_prop_template.py
+++ b/src/ifcopenshell-python/test/api/pset_template/test_edit_prop_template.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.pset_template
+import test.bootstrap
class TestEditPropTemplate(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/resource/test_add_resource_quantity.py b/src/ifcopenshell-python/test/api/resource/test_add_resource_quantity.py
index c9e20e7a49..890f290bc6 100644
--- a/src/ifcopenshell-python/test/api/resource/test_add_resource_quantity.py
+++ b/src/ifcopenshell-python/test/api/resource/test_add_resource_quantity.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api
import ifcopenshell.api.resource
import ifcopenshell.util.resource
+import test.bootstrap
class TestAddResourceQuantity(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/resource/test_calculate_resource_work.py b/src/ifcopenshell-python/test/api/resource/test_calculate_resource_work.py
index c80e3dae28..6affa8a60f 100644
--- a/src/ifcopenshell-python/test/api/resource/test_calculate_resource_work.py
+++ b/src/ifcopenshell-python/test/api/resource/test_calculate_resource_work.py
@@ -16,12 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.pset
-import ifcopenshell.api.root
import ifcopenshell.api.resource
+import ifcopenshell.api.root
import ifcopenshell.api.sequence
import ifcopenshell.util.constraint
+import test.bootstrap
# NOTE: resource module features relies on entities introduced in IFC4
diff --git a/src/ifcopenshell-python/test/api/root/test_copy_class.py b/src/ifcopenshell-python/test/api/root/test_copy_class.py
index 66ba27ec06..77de023379 100644
--- a/src/ifcopenshell-python/test/api/root/test_copy_class.py
+++ b/src/ifcopenshell-python/test/api/root/test_copy_class.py
@@ -17,19 +17,20 @@
# along with IfcOpenShell. If not, see .
import numpy
-import test.bootstrap
-import ifcopenshell.api.unit
-import ifcopenshell.api.type
-import ifcopenshell.api.root
-import ifcopenshell.api.feature
-import ifcopenshell.api.pset
-import ifcopenshell.api.group
-import ifcopenshell.api.system
-import ifcopenshell.api.spatial
-import ifcopenshell.api.geometry
+
import ifcopenshell.api.aggregate
+import ifcopenshell.api.feature
+import ifcopenshell.api.geometry
+import ifcopenshell.api.group
+import ifcopenshell.api.pset
+import ifcopenshell.api.root
+import ifcopenshell.api.spatial
+import ifcopenshell.api.system
+import ifcopenshell.api.type
+import ifcopenshell.api.unit
import ifcopenshell.util
import ifcopenshell.util.system
+import test.bootstrap
class TestCopyClass(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/root/test_create_entity.py b/src/ifcopenshell-python/test/api/root/test_create_entity.py
index dbe27a3a51..9616b2fec1 100644
--- a/src/ifcopenshell-python/test/api/root/test_create_entity.py
+++ b/src/ifcopenshell-python/test/api/root/test_create_entity.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.root
+import test.bootstrap
class TestCreateEntity(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/root/test_reassign_class.py b/src/ifcopenshell-python/test/api/root/test_reassign_class.py
index f8be13225e..bd6d0f05e8 100644
--- a/src/ifcopenshell-python/test/api/root/test_reassign_class.py
+++ b/src/ifcopenshell-python/test/api/root/test_reassign_class.py
@@ -18,13 +18,13 @@
import ifcopenshell.api.aggregate
import ifcopenshell.api.geometry
-import ifcopenshell.api.spatial
-import ifcopenshell.util.representation
-import test.bootstrap
import ifcopenshell.api.pset
import ifcopenshell.api.root
+import ifcopenshell.api.spatial
import ifcopenshell.api.type
import ifcopenshell.util.element
+import ifcopenshell.util.representation
+import test.bootstrap
class TestReassignClass(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/root/test_remove_product.py b/src/ifcopenshell-python/test/api/root/test_remove_product.py
index da9b46dbe5..ae2308b360 100644
--- a/src/ifcopenshell-python/test/api/root/test_remove_product.py
+++ b/src/ifcopenshell-python/test/api/root/test_remove_product.py
@@ -16,24 +16,24 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.unit
-import ifcopenshell.api.nest
-import ifcopenshell.api.root
-import ifcopenshell.api.feature
-import ifcopenshell.api.grid
-import ifcopenshell.api.type
-import ifcopenshell.api.pset
-import ifcopenshell.api.group
-import ifcopenshell.api.owner
-import ifcopenshell.api.system
-import ifcopenshell.api.spatial
-import ifcopenshell.api.drawing
-import ifcopenshell.api.context
-import ifcopenshell.api.geometry
-import ifcopenshell.api.material
import ifcopenshell.api.aggregate
+import ifcopenshell.api.context
+import ifcopenshell.api.drawing
+import ifcopenshell.api.feature
+import ifcopenshell.api.geometry
+import ifcopenshell.api.grid
+import ifcopenshell.api.group
+import ifcopenshell.api.material
+import ifcopenshell.api.nest
+import ifcopenshell.api.owner
+import ifcopenshell.api.pset
+import ifcopenshell.api.root
+import ifcopenshell.api.spatial
+import ifcopenshell.api.system
+import ifcopenshell.api.type
+import ifcopenshell.api.unit
import ifcopenshell.guid
+import test.bootstrap
class TestRemoveProduct(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/sequence/test_add_date_time.py b/src/ifcopenshell-python/test/api/sequence/test_add_date_time.py
index 3b5d5ac15c..742a7d54ec 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_add_date_time.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_add_date_time.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from datetime import datetime
+
+import ifcopenshell.api.sequence
import ifcopenshell.util
import ifcopenshell.util.date
import test.bootstrap
-import ifcopenshell.api.sequence
-from datetime import datetime
class TestAddDateTime(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/sequence/test_assign_product.py b/src/ifcopenshell-python/test/api/sequence/test_assign_product.py
index 19812e820c..b78b4d65a8 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_assign_product.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_assign_product.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.sequence
+import test.bootstrap
class TestAssignProduct(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/sequence/test_calculate_task_duration.py b/src/ifcopenshell-python/test/api/sequence/test_calculate_task_duration.py
index daed2ecb64..462526966a 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_calculate_task_duration.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_calculate_task_duration.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.pset
-import ifcopenshell.api.sequence
import ifcopenshell.api.resource
+import ifcopenshell.api.root
+import ifcopenshell.api.sequence
+import test.bootstrap
# NOTE: sequence module features relies on entities introduced in IFC4
diff --git a/src/ifcopenshell-python/test/api/sequence/test_cascade_schedule.py b/src/ifcopenshell-python/test/api/sequence/test_cascade_schedule.py
index 87d5647343..32c9908736 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_cascade_schedule.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_cascade_schedule.py
@@ -16,10 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import datetime
-import test.bootstrap
+
+import pytest
+
import ifcopenshell.api.sequence
+import test.bootstrap
# NOTE: sequence module features relies on entities introduced in IFC4
diff --git a/src/ifcopenshell-python/test/api/sequence/test_edit_task_time.py b/src/ifcopenshell-python/test/api/sequence/test_edit_task_time.py
index dcaf082bf8..a28a6cd604 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_edit_task_time.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_edit_task_time.py
@@ -17,11 +17,11 @@
# along with IfcOpenShell. If not, see .
import datetime
-import test.bootstrap
-import ifcopenshell.api.root
-import ifcopenshell.api.control
-import ifcopenshell.api.sequence
+import ifcopenshell.api.control
+import ifcopenshell.api.root
+import ifcopenshell.api.sequence
+import test.bootstrap
# NOTE: IfcTaskTime was introduced in IFC4
diff --git a/src/ifcopenshell-python/test/api/sequence/test_edit_work_time.py b/src/ifcopenshell-python/test/api/sequence/test_edit_work_time.py
index dc58088d38..8ca467b681 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_edit_work_time.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_edit_work_time.py
@@ -17,8 +17,9 @@
# along with IfcOpenShell. If not, see .
import datetime
-import test.bootstrap
+
import ifcopenshell.api.sequence
+import test.bootstrap
# NOTE: IfcWorkTime was introduced in IFC4
diff --git a/src/ifcopenshell-python/test/api/sequence/test_recalculate_schedule.py b/src/ifcopenshell-python/test/api/sequence/test_recalculate_schedule.py
index d5aacde632..0445f16474 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_recalculate_schedule.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_recalculate_schedule.py
@@ -16,11 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import datetime
-import test.bootstrap
+
+import pytest
+
import ifcopenshell.api.root
import ifcopenshell.api.sequence
+import test.bootstrap
# NOTE: sequence module features relies on entities introduced in IFC4
diff --git a/src/ifcopenshell-python/test/api/sequence/test_remove_task.py b/src/ifcopenshell-python/test/api/sequence/test_remove_task.py
index a23cf9cb54..1d1d3c1467 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_remove_task.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_remove_task.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api
import ifcopenshell.api.nest
import ifcopenshell.api.sequence
+import test.bootstrap
# NOTE: sequence module features relies on entities introduced in IFC4
diff --git a/src/ifcopenshell-python/test/api/sequence/test_remove_work_calendar.py b/src/ifcopenshell-python/test/api/sequence/test_remove_work_calendar.py
index 99b0a035dc..42264d1182 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_remove_work_calendar.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_remove_work_calendar.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api
import ifcopenshell.api.control
import ifcopenshell.api.sequence
+import test.bootstrap
# NOTE: sequence module features relies on entities introduced in IFC4
diff --git a/src/ifcopenshell-python/test/api/sequence/test_remove_work_plan.py b/src/ifcopenshell-python/test/api/sequence/test_remove_work_plan.py
index 273577f63e..6f9a0ee9cf 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_remove_work_plan.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_remove_work_plan.py
@@ -17,9 +17,10 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api
import ifcopenshell.api.sequence
+import test.bootstrap
def declared_objects(ifc_file: ifcopenshell.file) -> set[ifcopenshell.entity_instance]:
diff --git a/src/ifcopenshell-python/test/api/sequence/test_remove_work_schedule.py b/src/ifcopenshell-python/test/api/sequence/test_remove_work_schedule.py
index b661b8df48..ea2b094364 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_remove_work_schedule.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_remove_work_schedule.py
@@ -17,9 +17,10 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api
import ifcopenshell.api.sequence
+import test.bootstrap
def declared_objects(ifc_file: ifcopenshell.file) -> set[ifcopenshell.entity_instance]:
diff --git a/src/ifcopenshell-python/test/api/sequence/test_remove_work_time.py b/src/ifcopenshell-python/test/api/sequence/test_remove_work_time.py
index d0318c5c7a..30393c540b 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_remove_work_time.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_remove_work_time.py
@@ -17,9 +17,10 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api
import ifcopenshell.api.sequence
+import test.bootstrap
# NOTE: sequence module features relies on entities introduced in IFC4
diff --git a/src/ifcopenshell-python/test/api/sequence/test_unassign_product.py b/src/ifcopenshell-python/test/api/sequence/test_unassign_product.py
index fdeae7e25d..537b2c6043 100644
--- a/src/ifcopenshell-python/test/api/sequence/test_unassign_product.py
+++ b/src/ifcopenshell-python/test/api/sequence/test_unassign_product.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.sequence
+import test.bootstrap
class TestUnassignProduct(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/spatial/test_assign_container.py b/src/ifcopenshell-python/test/api/spatial/test_assign_container.py
index 4e0ba57666..fcee090724 100644
--- a/src/ifcopenshell-python/test/api/spatial/test_assign_container.py
+++ b/src/ifcopenshell-python/test/api/spatial/test_assign_container.py
@@ -18,14 +18,15 @@
import numpy
import pytest
-import test.bootstrap
-import ifcopenshell.api.root
-import ifcopenshell.api.unit
-import ifcopenshell.api.spatial
-import ifcopenshell.api.geometry
+
import ifcopenshell.api.aggregate
+import ifcopenshell.api.geometry
+import ifcopenshell.api.root
+import ifcopenshell.api.spatial
+import ifcopenshell.api.unit
import ifcopenshell.util.element
import ifcopenshell.util.placement
+import test.bootstrap
class TestAssignContainer(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/spatial/test_dereference_structure.py b/src/ifcopenshell-python/test/api/spatial/test_dereference_structure.py
index 9e618033e1..5f9d2b5099 100644
--- a/src/ifcopenshell-python/test/api/spatial/test_dereference_structure.py
+++ b/src/ifcopenshell-python/test/api/spatial/test_dereference_structure.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.root
import ifcopenshell.api.spatial
import ifcopenshell.util.element
+import test.bootstrap
class TestDereferenceStructure(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/spatial/test_reference_structure.py b/src/ifcopenshell-python/test/api/spatial/test_reference_structure.py
index 013b0e4a18..6b5a3daeaa 100644
--- a/src/ifcopenshell-python/test/api/spatial/test_reference_structure.py
+++ b/src/ifcopenshell-python/test/api/spatial/test_reference_structure.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.root
import ifcopenshell.api.spatial
import ifcopenshell.util.element
+import test.bootstrap
class TestReferenceStructure(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/spatial/test_unassign_container.py b/src/ifcopenshell-python/test/api/spatial/test_unassign_container.py
index 795614e35d..efd89c990f 100644
--- a/src/ifcopenshell-python/test/api/spatial/test_unassign_container.py
+++ b/src/ifcopenshell-python/test/api/spatial/test_unassign_container.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.root
import ifcopenshell.api.spatial
import ifcopenshell.util.element
import ifcopenshell.util.placement
+import test.bootstrap
class TestUnassignContainer(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/structural/test_add_structural_analysis_model.py b/src/ifcopenshell-python/test/api/structural/test_add_structural_analysis_model.py
index c7c715d1c0..3d19dd50eb 100644
--- a/src/ifcopenshell-python/test/api/structural/test_add_structural_analysis_model.py
+++ b/src/ifcopenshell-python/test/api/structural/test_add_structural_analysis_model.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.structural
+import test.bootstrap
class TestAddStructuralAnalysisModel(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/structural/test_assign_structural_analysis_model.py b/src/ifcopenshell-python/test/api/structural/test_assign_structural_analysis_model.py
index da09c38674..867630696b 100644
--- a/src/ifcopenshell-python/test/api/structural/test_assign_structural_analysis_model.py
+++ b/src/ifcopenshell-python/test/api/structural/test_assign_structural_analysis_model.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.root
import ifcopenshell.api.structural
+import test.bootstrap
class TestAssignStructuralAnalysisModel(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/structural/test_edit_structural_analysis_model.py b/src/ifcopenshell-python/test/api/structural/test_edit_structural_analysis_model.py
index fddb8a9993..6deda5a833 100644
--- a/src/ifcopenshell-python/test/api/structural/test_edit_structural_analysis_model.py
+++ b/src/ifcopenshell-python/test/api/structural/test_edit_structural_analysis_model.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.structural
+import test.bootstrap
class TestEditStructuralAnalysisModel(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/structural/test_remove_structural_analysis_model.py b/src/ifcopenshell-python/test/api/structural/test_remove_structural_analysis_model.py
index b496dcc9a1..c330be81cb 100644
--- a/src/ifcopenshell-python/test/api/structural/test_remove_structural_analysis_model.py
+++ b/src/ifcopenshell-python/test/api/structural/test_remove_structural_analysis_model.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.structural
+import test.bootstrap
class TestRemoveStructuralAnalysisModel(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/structural/test_unassign_structural_analysis_model.py b/src/ifcopenshell-python/test/api/structural/test_unassign_structural_analysis_model.py
index c80842b7ad..43992acd3c 100644
--- a/src/ifcopenshell-python/test/api/structural/test_unassign_structural_analysis_model.py
+++ b/src/ifcopenshell-python/test/api/structural/test_unassign_structural_analysis_model.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.root
import ifcopenshell.api.structural
+import test.bootstrap
class TestUnassignStructuralAnalysisModel(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/style/test_add_surface_style.py b/src/ifcopenshell-python/test/api/style/test_add_surface_style.py
index 83f176a690..dcfd42fd2c 100644
--- a/src/ifcopenshell-python/test/api/style/test_add_surface_style.py
+++ b/src/ifcopenshell-python/test/api/style/test_add_surface_style.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.style
+import test.bootstrap
class TestAddSurfaceStyle(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/style/test_add_surface_textures.py b/src/ifcopenshell-python/test/api/style/test_add_surface_textures.py
index 78971148d7..12c1711baa 100644
--- a/src/ifcopenshell-python/test/api/style/test_add_surface_textures.py
+++ b/src/ifcopenshell-python/test/api/style/test_add_surface_textures.py
@@ -17,8 +17,9 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api.style
+import test.bootstrap
# TODO: add ifc2x3 tests after add_surface_textures will support ifc2x3
diff --git a/src/ifcopenshell-python/test/api/style/test_assign_material_style.py b/src/ifcopenshell-python/test/api/style/test_assign_material_style.py
index 47f26ee6ac..7b7ea3df56 100644
--- a/src/ifcopenshell-python/test/api/style/test_assign_material_style.py
+++ b/src/ifcopenshell-python/test/api/style/test_assign_material_style.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell
+import ifcopenshell.api.material
import ifcopenshell.api.root
import ifcopenshell.api.style
-import ifcopenshell.api.material
+import test.bootstrap
class TestAssignMaterialStyleIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/style/test_assign_representation_styles.py b/src/ifcopenshell-python/test/api/style/test_assign_representation_styles.py
index 9527813291..157acf49da 100644
--- a/src/ifcopenshell-python/test/api/style/test_assign_representation_styles.py
+++ b/src/ifcopenshell-python/test/api/style/test_assign_representation_styles.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell
import ifcopenshell.api.root
import ifcopenshell.api.style
+import test.bootstrap
class TestAssignRepresentationStyles(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/style/test_edit_surface_style.py b/src/ifcopenshell-python/test/api/style/test_edit_surface_style.py
index 5875396a7a..b8fc7e241b 100644
--- a/src/ifcopenshell-python/test/api/style/test_edit_surface_style.py
+++ b/src/ifcopenshell-python/test/api/style/test_edit_surface_style.py
@@ -17,8 +17,9 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api.style
+import test.bootstrap
class TestEditSurfaceStyle(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/style/test_remove_style.py b/src/ifcopenshell-python/test/api/style/test_remove_style.py
index 1993ef3cf3..5b39ec655c 100644
--- a/src/ifcopenshell-python/test/api/style/test_remove_style.py
+++ b/src/ifcopenshell-python/test/api/style/test_remove_style.py
@@ -17,9 +17,10 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api.material
import ifcopenshell.api.style
+import test.bootstrap
class TestRemoveStyle(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/style/test_remove_surface_style.py b/src/ifcopenshell-python/test/api/style/test_remove_surface_style.py
index 14f8173a3a..12ebf766f2 100644
--- a/src/ifcopenshell-python/test/api/style/test_remove_surface_style.py
+++ b/src/ifcopenshell-python/test/api/style/test_remove_surface_style.py
@@ -17,8 +17,9 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api.style
+import test.bootstrap
class TestRemoveSurfaceStyleIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/style/test_unassign_material_style.py b/src/ifcopenshell-python/test/api/style/test_unassign_material_style.py
index b009de1616..919f26e3c9 100644
--- a/src/ifcopenshell-python/test/api/style/test_unassign_material_style.py
+++ b/src/ifcopenshell-python/test/api/style/test_unassign_material_style.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell
+import ifcopenshell.api.material
import ifcopenshell.api.root
import ifcopenshell.api.style
-import ifcopenshell.api.material
+import test.bootstrap
class TestUnassignMaterialStyleIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/style/test_unassign_representation_styles.py b/src/ifcopenshell-python/test/api/style/test_unassign_representation_styles.py
index 2138f6cb9b..ed7285b1de 100644
--- a/src/ifcopenshell-python/test/api/style/test_unassign_representation_styles.py
+++ b/src/ifcopenshell-python/test/api/style/test_unassign_representation_styles.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell
import ifcopenshell.api.root
import ifcopenshell.api.style
+import test.bootstrap
class TestUnassignRepresentationStyles(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/system/test_add_port.py b/src/ifcopenshell-python/test/api/system/test_add_port.py
index c2c420427c..ff8163fa15 100644
--- a/src/ifcopenshell-python/test/api/system/test_add_port.py
+++ b/src/ifcopenshell-python/test/api/system/test_add_port.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.root
import ifcopenshell.api.system
import ifcopenshell.util.system
+import test.bootstrap
class TestAddPort(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/system/test_add_system.py b/src/ifcopenshell-python/test/api/system/test_add_system.py
index 8d98d5c3dd..1801a2332a 100644
--- a/src/ifcopenshell-python/test/api/system/test_add_system.py
+++ b/src/ifcopenshell-python/test/api/system/test_add_system.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.system
+import test.bootstrap
class TestAddSystem(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/system/test_assign_flow_control.py b/src/ifcopenshell-python/test/api/system/test_assign_flow_control.py
index e3d1df3bec..4ce38defa7 100644
--- a/src/ifcopenshell-python/test/api/system/test_assign_flow_control.py
+++ b/src/ifcopenshell-python/test/api/system/test_assign_flow_control.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.system
+import test.bootstrap
class TestAssignFlowControl(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/system/test_assign_port.py b/src/ifcopenshell-python/test/api/system/test_assign_port.py
index d17f2775d8..650496f875 100644
--- a/src/ifcopenshell-python/test/api/system/test_assign_port.py
+++ b/src/ifcopenshell-python/test/api/system/test_assign_port.py
@@ -17,13 +17,14 @@
# along with IfcOpenShell. If not, see .
import numpy
-import test.bootstrap
-import ifcopenshell.api.unit
+
+import ifcopenshell.api.geometry
import ifcopenshell.api.root
import ifcopenshell.api.system
-import ifcopenshell.api.geometry
+import ifcopenshell.api.unit
import ifcopenshell.util.placement
import ifcopenshell.util.system
+import test.bootstrap
class TestAssignPort(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/system/test_assign_system.py b/src/ifcopenshell-python/test/api/system/test_assign_system.py
index 22c26d9214..e262419d13 100644
--- a/src/ifcopenshell-python/test/api/system/test_assign_system.py
+++ b/src/ifcopenshell-python/test/api/system/test_assign_system.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api.root
import ifcopenshell.api.system
import ifcopenshell.util.system
+import test.bootstrap
class TestAssignSystem(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/system/test_connect_port.py b/src/ifcopenshell-python/test/api/system/test_connect_port.py
index 8dd19d47fa..06d1fb7f26 100644
--- a/src/ifcopenshell-python/test/api/system/test_connect_port.py
+++ b/src/ifcopenshell-python/test/api/system/test_connect_port.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.root
import ifcopenshell.api.system
import ifcopenshell.util.system
+import test.bootstrap
class TestConnectPort(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/system/test_disconnect_port.py b/src/ifcopenshell-python/test/api/system/test_disconnect_port.py
index a34fdfc615..4d782414a6 100644
--- a/src/ifcopenshell-python/test/api/system/test_disconnect_port.py
+++ b/src/ifcopenshell-python/test/api/system/test_disconnect_port.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.system
import ifcopenshell.util.system
+import test.bootstrap
class TestDisconnectPort(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/system/test_remove_system.py b/src/ifcopenshell-python/test/api/system/test_remove_system.py
index 44e00987d6..c347ae09a0 100644
--- a/src/ifcopenshell-python/test/api/system/test_remove_system.py
+++ b/src/ifcopenshell-python/test/api/system/test_remove_system.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
-import ifcopenshell.api.root
import ifcopenshell.api.pset
+import ifcopenshell.api.root
import ifcopenshell.api.system
+import test.bootstrap
class TestRemoveSystem(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/system/test_unassign_flow_control.py b/src/ifcopenshell-python/test/api/system/test_unassign_flow_control.py
index 22d2559561..afc20789fd 100644
--- a/src/ifcopenshell-python/test/api/system/test_unassign_flow_control.py
+++ b/src/ifcopenshell-python/test/api/system/test_unassign_flow_control.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.system
+import test.bootstrap
class TestUnassignFlowControl(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/system/test_unassign_port.py b/src/ifcopenshell-python/test/api/system/test_unassign_port.py
index b49de25f9a..711b17eeeb 100644
--- a/src/ifcopenshell-python/test/api/system/test_unassign_port.py
+++ b/src/ifcopenshell-python/test/api/system/test_unassign_port.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.root
import ifcopenshell.api.system
import ifcopenshell.util.system
+import test.bootstrap
class TestAssignPort(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/system/test_unassign_system.py b/src/ifcopenshell-python/test/api/system/test_unassign_system.py
index 8503dd82c3..7e60cbb07c 100644
--- a/src/ifcopenshell-python/test/api/system/test_unassign_system.py
+++ b/src/ifcopenshell-python/test/api/system/test_unassign_system.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api.root
import ifcopenshell.api.system
import ifcopenshell.util.system
+import test.bootstrap
class TestUnassignSystem(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/test_api.py b/src/ifcopenshell-python/test/api/test_api.py
index 8dca81d32f..55889cc627 100644
--- a/src/ifcopenshell-python/test/api/test_api.py
+++ b/src/ifcopenshell-python/test/api/test_api.py
@@ -16,16 +16,17 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.api.cost
-import ifcopenshell.api.root
-import test.bootstrap
-import ifcopenshell.api
-import ifcopenshell.api.control
-import ifcopenshell.api.sequence
-import ifcopenshell.util.element
from datetime import datetime
from typing import Union
+import ifcopenshell.api
+import ifcopenshell.api.control
+import ifcopenshell.api.cost
+import ifcopenshell.api.root
+import ifcopenshell.api.sequence
+import ifcopenshell.util.element
+import test.bootstrap
+
def deprecation_check(test):
def new_test(self):
diff --git a/src/ifcopenshell-python/test/api/type/test_assign_type.py b/src/ifcopenshell-python/test/api/type/test_assign_type.py
index 21df8c8bba..009d4efedf 100644
--- a/src/ifcopenshell-python/test/api/type/test_assign_type.py
+++ b/src/ifcopenshell-python/test/api/type/test_assign_type.py
@@ -16,14 +16,15 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
+import pytest
+
+import ifcopenshell.api.geometry
+import ifcopenshell.api.material
import ifcopenshell.api.root
import ifcopenshell.api.type
-import ifcopenshell.api.material
-import ifcopenshell.api.geometry
import ifcopenshell.util.element
import ifcopenshell.util.representation
-import pytest
+import test.bootstrap
class TestAssignType(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/type/test_map_type_representation.py b/src/ifcopenshell-python/test/api/type/test_map_type_representation.py
index cd52591fd7..520c22e5f3 100644
--- a/src/ifcopenshell-python/test/api/type/test_map_type_representation.py
+++ b/src/ifcopenshell-python/test/api/type/test_map_type_representation.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.type
+import test.bootstrap
class TestMapTypeRepresentations(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/type/test_unassign_type.py b/src/ifcopenshell-python/test/api/type/test_unassign_type.py
index c37ae7214d..3f5adf1148 100644
--- a/src/ifcopenshell-python/test/api/type/test_unassign_type.py
+++ b/src/ifcopenshell-python/test/api/type/test_unassign_type.py
@@ -16,12 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
+import ifcopenshell.api.geometry
+import ifcopenshell.api.material
import ifcopenshell.api.root
import ifcopenshell.api.type
-import ifcopenshell.api.material
-import ifcopenshell.api.geometry
import ifcopenshell.util.element
+import test.bootstrap
class TestUnassignType(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/unit/test_add_context_dependent_unit.py b/src/ifcopenshell-python/test/api/unit/test_add_context_dependent_unit.py
index 705a2f0815..567d2cfd7a 100644
--- a/src/ifcopenshell-python/test/api/unit/test_add_context_dependent_unit.py
+++ b/src/ifcopenshell-python/test/api/unit/test_add_context_dependent_unit.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.unit
+import test.bootstrap
class TestAddContextDependentUnit(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/unit/test_add_conversion_based_unit.py b/src/ifcopenshell-python/test/api/unit/test_add_conversion_based_unit.py
index a29b9b2ad8..2286be6df1 100644
--- a/src/ifcopenshell-python/test/api/unit/test_add_conversion_based_unit.py
+++ b/src/ifcopenshell-python/test/api/unit/test_add_conversion_based_unit.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.unit
+import test.bootstrap
class TestAddConversionBasedUnitIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/unit/test_add_monetary_unit.py b/src/ifcopenshell-python/test/api/unit/test_add_monetary_unit.py
index 3d3e44bfe4..0e11f29882 100644
--- a/src/ifcopenshell-python/test/api/unit/test_add_monetary_unit.py
+++ b/src/ifcopenshell-python/test/api/unit/test_add_monetary_unit.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.unit
+import test.bootstrap
class TestAddMonetaryUnit(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/unit/test_add_si_unit.py b/src/ifcopenshell-python/test/api/unit/test_add_si_unit.py
index f618f9871e..b12cbd16ca 100644
--- a/src/ifcopenshell-python/test/api/unit/test_add_si_unit.py
+++ b/src/ifcopenshell-python/test/api/unit/test_add_si_unit.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.unit
+import test.bootstrap
class TestAddSIUnit(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/unit/test_assign_unit.py b/src/ifcopenshell-python/test/api/unit/test_assign_unit.py
index 21a136b257..66cee04442 100644
--- a/src/ifcopenshell-python/test/api/unit/test_assign_unit.py
+++ b/src/ifcopenshell-python/test/api/unit/test_assign_unit.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.unit
+import test.bootstrap
class TestAssignUnit(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/unit/test_edit_derived_unit.py b/src/ifcopenshell-python/test/api/unit/test_edit_derived_unit.py
index 679f5602b7..c97d55b407 100644
--- a/src/ifcopenshell-python/test/api/unit/test_edit_derived_unit.py
+++ b/src/ifcopenshell-python/test/api/unit/test_edit_derived_unit.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.unit
+import test.bootstrap
class TestEditDerivedUnit(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/unit/test_edit_monetary_unit.py b/src/ifcopenshell-python/test/api/unit/test_edit_monetary_unit.py
index d956b2fb04..a8bba121c0 100644
--- a/src/ifcopenshell-python/test/api/unit/test_edit_monetary_unit.py
+++ b/src/ifcopenshell-python/test/api/unit/test_edit_monetary_unit.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.unit
+import test.bootstrap
class TestEditMonetaryUnit(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/unit/test_edit_named_unit.py b/src/ifcopenshell-python/test/api/unit/test_edit_named_unit.py
index cc99e69eae..6f861f9cd8 100644
--- a/src/ifcopenshell-python/test/api/unit/test_edit_named_unit.py
+++ b/src/ifcopenshell-python/test/api/unit/test_edit_named_unit.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.unit
+import test.bootstrap
class TestEditNamedUnitIFC2X3(test.bootstrap.IFC2X3):
diff --git a/src/ifcopenshell-python/test/api/unit/test_remove_unit.py b/src/ifcopenshell-python/test/api/unit/test_remove_unit.py
index 5b3ab7bcc4..02df1ec562 100644
--- a/src/ifcopenshell-python/test/api/unit/test_remove_unit.py
+++ b/src/ifcopenshell-python/test/api/unit/test_remove_unit.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.unit
+import test.bootstrap
class TestRemoveUnit(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/api/unit/test_unassign_unit.py b/src/ifcopenshell-python/test/api/unit/test_unassign_unit.py
index 5a101e2018..a30a9570a9 100644
--- a/src/ifcopenshell-python/test/api/unit/test_unassign_unit.py
+++ b/src/ifcopenshell-python/test/api/unit/test_unassign_unit.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.unit
+import test.bootstrap
class TestUnassignUnit(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/bootstrap.py b/src/ifcopenshell-python/test/bootstrap.py
index 055ea8774a..1342be206c 100644
--- a/src/ifcopenshell-python/test/bootstrap.py
+++ b/src/ifcopenshell-python/test/bootstrap.py
@@ -26,9 +26,10 @@ if os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) == sys.path[0]
import pytest
+
import ifcopenshell
-import ifcopenshell.api.project
import ifcopenshell.api.owner.settings
+import ifcopenshell.api.project
class IFC4X3:
diff --git a/src/ifcopenshell-python/test/file_gc.py b/src/ifcopenshell-python/test/file_gc.py
index f28256a3d0..483c268e17 100644
--- a/src/ifcopenshell-python/test/file_gc.py
+++ b/src/ifcopenshell-python/test/file_gc.py
@@ -1,14 +1,16 @@
-import os
-import pytest
-import weakref
import itertools
+import os
+import weakref
+
+import pytest
+
import ifcopenshell
-import ifcopenshell.guid
-import ifcopenshell.api.pset
+import ifcopenshell.api.attribute
+import ifcopenshell.api.material
import ifcopenshell.api.owner
import ifcopenshell.api.project
-import ifcopenshell.api.material
-import ifcopenshell.api.attribute
+import ifcopenshell.api.pset
+import ifcopenshell.guid
import ifcopenshell.template
diff --git a/src/ifcopenshell-python/test/fixtures/rules/generate_00.py b/src/ifcopenshell-python/test/fixtures/rules/generate_00.py
index 251f501bec..e50e20a81e 100644
--- a/src/ifcopenshell-python/test/fixtures/rules/generate_00.py
+++ b/src/ifcopenshell-python/test/fixtures/rules/generate_00.py
@@ -1,4 +1,5 @@
import time
+
import ifcopenshell
for i in range(3):
diff --git a/src/ifcopenshell-python/test/fixtures/rules/generate_02.py b/src/ifcopenshell-python/test/fixtures/rules/generate_02.py
index 298fee7eba..5747fa589f 100644
--- a/src/ifcopenshell-python/test/fixtures/rules/generate_02.py
+++ b/src/ifcopenshell-python/test/fixtures/rules/generate_02.py
@@ -1,4 +1,5 @@
import time
+
import ifcopenshell
latitudes = [
diff --git a/src/ifcopenshell-python/test/fixtures/rules/generate_06.py b/src/ifcopenshell-python/test/fixtures/rules/generate_06.py
index b36c5108cb..fd9cca7153 100644
--- a/src/ifcopenshell-python/test/fixtures/rules/generate_06.py
+++ b/src/ifcopenshell-python/test/fixtures/rules/generate_06.py
@@ -1,5 +1,6 @@
import itertools
import time
+
import ifcopenshell
for pty, ety in itertools.product(("GRILLE", "USERDEFINED"), (None, "Something")):
diff --git a/src/ifcopenshell-python/test/fixtures/rules/generate_10.py b/src/ifcopenshell-python/test/fixtures/rules/generate_10.py
index b717411dfd..f4ac7209e8 100644
--- a/src/ifcopenshell-python/test/fixtures/rules/generate_10.py
+++ b/src/ifcopenshell-python/test/fixtures/rules/generate_10.py
@@ -1,4 +1,5 @@
import itertools
+
import ifcopenshell
defaults = {"Girth": 1.0, "WallThickness": 0.11}
diff --git a/src/ifcopenshell-python/test/fixtures/rules/generate_16.py b/src/ifcopenshell-python/test/fixtures/rules/generate_16.py
index 7b6a32dfb1..88964b17ff 100644
--- a/src/ifcopenshell-python/test/fixtures/rules/generate_16.py
+++ b/src/ifcopenshell-python/test/fixtures/rules/generate_16.py
@@ -1,4 +1,5 @@
import time
+
import ifcopenshell
names = [("Same", "Same"), ("Different", "SomethingElse")]
diff --git a/src/ifcopenshell-python/test/fixtures/rules/generate_17.py b/src/ifcopenshell-python/test/fixtures/rules/generate_17.py
index 2daa8b3b38..c313ac93a1 100644
--- a/src/ifcopenshell-python/test/fixtures/rules/generate_17.py
+++ b/src/ifcopenshell-python/test/fixtures/rules/generate_17.py
@@ -1,4 +1,5 @@
import time
+
import ifcopenshell
for i, nm in enumerate(("no-mls", "mls", "mlsu")):
diff --git a/src/ifcopenshell-python/test/fixtures/rules/generate_21.py b/src/ifcopenshell-python/test/fixtures/rules/generate_21.py
index f5fcc68b71..0d99acc560 100644
--- a/src/ifcopenshell-python/test/fixtures/rules/generate_21.py
+++ b/src/ifcopenshell-python/test/fixtures/rules/generate_21.py
@@ -1,4 +1,5 @@
import itertools
+
import ifcopenshell
diff --git a/src/ifcopenshell-python/test/fixtures/rules/generate_24.py b/src/ifcopenshell-python/test/fixtures/rules/generate_24.py
index c790a6103d..f792a169f6 100644
--- a/src/ifcopenshell-python/test/fixtures/rules/generate_24.py
+++ b/src/ifcopenshell-python/test/fixtures/rules/generate_24.py
@@ -1,4 +1,5 @@
import time
+
import ifcopenshell
for ents in [
diff --git a/src/ifcopenshell-python/test/fixtures/validate/generate_00.py b/src/ifcopenshell-python/test/fixtures/validate/generate_00.py
index 082804fa26..3d6db0620e 100644
--- a/src/ifcopenshell-python/test/fixtures/validate/generate_00.py
+++ b/src/ifcopenshell-python/test/fixtures/validate/generate_00.py
@@ -1,8 +1,8 @@
-import ifcopenshell
-import ifcopenshell.api.root
-import ifcopenshell.api.owner
from pathlib import Path
+import ifcopenshell
+import ifcopenshell.api.owner
+import ifcopenshell.api.root
guid1 = "3pdqyORIn8KBHZAhhtJ72T"
guid2 = "1sEzC8v31DshmvW5t5P631"
diff --git a/src/ifcopenshell-python/test/geom/geometry_tests.py b/src/ifcopenshell-python/test/geom/geometry_tests.py
index d84ef3e9ea..f18cb3206a 100644
--- a/src/ifcopenshell-python/test/geom/geometry_tests.py
+++ b/src/ifcopenshell-python/test/geom/geometry_tests.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import numpy as np
+
import ifcopenshell
import ifcopenshell.geom
import ifcopenshell.util.shape
import test.bootstrap
-import numpy as np
from ifcopenshell.util.shape_builder import ShapeBuilder, V
diff --git a/src/ifcopenshell-python/test/geom/polyhedral_shapes.py b/src/ifcopenshell-python/test/geom/polyhedral_shapes.py
index 2e58809f71..07ed5bf6e6 100644
--- a/src/ifcopenshell-python/test/geom/polyhedral_shapes.py
+++ b/src/ifcopenshell-python/test/geom/polyhedral_shapes.py
@@ -1,11 +1,10 @@
import collections
import numpy as np
-import ifcopenshell
-import ifcopenshell.geom
-
import pytest
+import ifcopenshell
+import ifcopenshell.geom
from test.bootstrap import file
diff --git a/src/ifcopenshell-python/test/geom/settings.py b/src/ifcopenshell-python/test/geom/settings.py
index c4e24b2027..3ede93b941 100644
--- a/src/ifcopenshell-python/test/geom/settings.py
+++ b/src/ifcopenshell-python/test/geom/settings.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import numpy as np
+
import ifcopenshell
import ifcopenshell.api.context
import ifcopenshell.api.geometry
@@ -24,7 +25,6 @@ import ifcopenshell.api.profile
import ifcopenshell.api.root
import ifcopenshell.api.unit
import ifcopenshell.geom
-import ifcopenshell.geom
import ifcopenshell.util.unit
import test.bootstrap
from ifcopenshell.util.shape_builder import ShapeBuilder
diff --git a/src/ifcopenshell-python/test/geom/stats.py b/src/ifcopenshell-python/test/geom/stats.py
index fd0cd8e337..9e2a9b2985 100644
--- a/src/ifcopenshell-python/test/geom/stats.py
+++ b/src/ifcopenshell-python/test/geom/stats.py
@@ -1,7 +1,9 @@
import os
+
+import pytest
+
import ifcopenshell
from ifcopenshell.geom.stats import StatsCollector
-import pytest
@pytest.mark.parametrize(
diff --git a/src/ifcopenshell-python/test/geom/test_sweeps.py b/src/ifcopenshell-python/test/geom/test_sweeps.py
index d77faec540..ac2b2faf6f 100644
--- a/src/ifcopenshell-python/test/geom/test_sweeps.py
+++ b/src/ifcopenshell-python/test/geom/test_sweeps.py
@@ -1,9 +1,10 @@
import pathlib
from collections.abc import Sequence
-import ifcopenshell
import pytest
+import ifcopenshell
+
def _bbox_from_vertices(verts: list[tuple[float, float, float]]):
if not verts:
diff --git a/src/ifcopenshell-python/test/global_id_updates.py b/src/ifcopenshell-python/test/global_id_updates.py
index 40b548f8c6..c128eef4a5 100644
--- a/src/ifcopenshell-python/test/global_id_updates.py
+++ b/src/ifcopenshell-python/test/global_id_updates.py
@@ -1,4 +1,5 @@
import pytest
+
import ifcopenshell
import ifcopenshell.guid
diff --git a/src/ifcopenshell-python/test/instance_string_formatting.py b/src/ifcopenshell-python/test/instance_string_formatting.py
index 2d85e99d26..6f5a096a57 100644
--- a/src/ifcopenshell-python/test/instance_string_formatting.py
+++ b/src/ifcopenshell-python/test/instance_string_formatting.py
@@ -1,4 +1,5 @@
import pytest
+
import ifcopenshell
import ifcopenshell.guid
diff --git a/src/ifcopenshell-python/test/test_create_shape.py b/src/ifcopenshell-python/test/test_create_shape.py
index bc743217bf..dfcb68c7be 100644
--- a/src/ifcopenshell-python/test/test_create_shape.py
+++ b/src/ifcopenshell-python/test/test_create_shape.py
@@ -3,8 +3,10 @@ import itertools
import multiprocessing
import operator
import os
+from typing import get_args
+
import pytest
-import test.bootstrap
+
import ifcopenshell
import ifcopenshell.api.context
import ifcopenshell.api.owner.settings
@@ -14,8 +16,8 @@ import ifcopenshell.api.unit
import ifcopenshell.geom
import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.util.shape
+import test.bootstrap
from ifcopenshell.util.shape_builder import ShapeBuilder
-from typing import get_args
fn = os.path.join(os.path.dirname(__file__), "fixtures/ColumnPSetsOfSets.ifc")
diff --git a/src/ifcopenshell-python/test/test_entity_instance.py b/src/ifcopenshell-python/test/test_entity_instance.py
index 6af57585d0..c031796b9f 100644
--- a/src/ifcopenshell-python/test/test_entity_instance.py
+++ b/src/ifcopenshell-python/test/test_entity_instance.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.element
+import test.bootstrap
class TestGetInfo2(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/test_file.py b/src/ifcopenshell-python/test/test_file.py
index 31c77cd6e6..062ef88b9f 100644
--- a/src/ifcopenshell-python/test/test_file.py
+++ b/src/ifcopenshell-python/test/test_file.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.element
+import test.bootstrap
class TestTransaction(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/test_file_inverse.py b/src/ifcopenshell-python/test/test_file_inverse.py
index 9d385ff0f0..d1708bc2bb 100644
--- a/src/ifcopenshell-python/test/test_file_inverse.py
+++ b/src/ifcopenshell-python/test/test_file_inverse.py
@@ -1,9 +1,11 @@
import gc
-import sys
-import pytest
-import pprint
-import weakref
import itertools
+import pprint
+import sys
+import weakref
+
+import pytest
+
import ifcopenshell
import ifcopenshell.api
diff --git a/src/ifcopenshell-python/test/test_guid.py b/src/ifcopenshell-python/test/test_guid.py
index 53af52bbed..ff361a2d77 100644
--- a/src/ifcopenshell-python/test/test_guid.py
+++ b/src/ifcopenshell-python/test/test_guid.py
@@ -20,15 +20,14 @@
# IMPORTS
# ----------------------------------------------------------------
+import string
from functools import reduce
from unittest import TestCase
-from pytest import mark
-from pytest import fixture
from uuid import uuid4
-import string
-from ifcopenshell.guid import compress
-from ifcopenshell.guid import expand
+from pytest import fixture, mark
+
+from ifcopenshell.guid import compress, expand
# ----------------------------------------------------------------
# FIXTURES
diff --git a/src/ifcopenshell-python/test/test_mvd_info.py b/src/ifcopenshell-python/test/test_mvd_info.py
index 80fe2f2154..7ba33481e6 100644
--- a/src/ifcopenshell-python/test/test_mvd_info.py
+++ b/src/ifcopenshell-python/test/test_mvd_info.py
@@ -1,5 +1,7 @@
import os
+
import pytest
+
import ifcopenshell
from ifcopenshell.util import mvd_info
from ifcopenshell.util.mvd_info import parse_mvd
diff --git a/src/ifcopenshell-python/test/test_open.py b/src/ifcopenshell-python/test/test_open.py
index 99f312c76e..7525adaa72 100644
--- a/src/ifcopenshell-python/test/test_open.py
+++ b/src/ifcopenshell-python/test/test_open.py
@@ -17,9 +17,10 @@
# along with IfcOpenShell. If not, see .
from pathlib import Path
-import pytest
-import ifcopenshell
+import pytest
+
+import ifcopenshell
TEST_FILE_DIR = Path(__file__).parent / "../../../test/input/"
diff --git a/src/ifcopenshell-python/test/test_package.py b/src/ifcopenshell-python/test/test_package.py
index 137c1079bf..b251e081c7 100644
--- a/src/ifcopenshell-python/test/test_package.py
+++ b/src/ifcopenshell-python/test/test_package.py
@@ -17,11 +17,12 @@
# along with IfcOpenShell. If not, see .
import http.client
-from pathlib import Path
from collections.abc import Sequence
-from typing_extensions import assert_never
+from pathlib import Path
from urllib.parse import urlparse
+from typing_extensions import assert_never
+
try:
from bs4 import BeautifulSoup
except:
diff --git a/src/ifcopenshell-python/test/test_rules.py b/src/ifcopenshell-python/test/test_rules.py
index a54e98ed68..9754405626 100644
--- a/src/ifcopenshell-python/test/test_rules.py
+++ b/src/ifcopenshell-python/test/test_rules.py
@@ -1,12 +1,12 @@
+import glob
import os
import sys
-import glob
import pytest
import tabulate
-import ifcopenshell.validate
import ifcopenshell.express.rule_executor
+import ifcopenshell.validate
@pytest.mark.parametrize(
diff --git a/src/ifcopenshell-python/test/test_sql.py b/src/ifcopenshell-python/test/test_sql.py
index 6d6c85786c..d0f11792c4 100644
--- a/src/ifcopenshell-python/test/test_sql.py
+++ b/src/ifcopenshell-python/test/test_sql.py
@@ -17,11 +17,13 @@
# along with IfcOpenShell. If not, see .
import tempfile
-import ifcpatch
-import ifcopenshell
from pathlib import Path
+
+import ifcpatch
from ifcpatch.recipes import Ifc2Sql
+import ifcopenshell
+
TEST_FILE = Path(__file__).parent / "files" / "basic.ifc"
SQLITE_PATH = None
diff --git a/src/ifcopenshell-python/test/test_stream.py b/src/ifcopenshell-python/test/test_stream.py
index e425fd1583..c463c3ccca 100644
--- a/src/ifcopenshell-python/test/test_stream.py
+++ b/src/ifcopenshell-python/test/test_stream.py
@@ -16,11 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
-import test.bootstrap
-import ifcopenshell
from pathlib import Path
+import pytest
+
+import ifcopenshell
+import test.bootstrap
+
TEST_FILE = Path(__file__).parent / "files" / "basic.ifc"
diff --git a/src/ifcopenshell-python/test/test_streaming_rocksdb_and_simpletyperefs.py b/src/ifcopenshell-python/test/test_streaming_rocksdb_and_simpletyperefs.py
index b0bfb2925a..32ea728df9 100644
--- a/src/ifcopenshell-python/test/test_streaming_rocksdb_and_simpletyperefs.py
+++ b/src/ifcopenshell-python/test/test_streaming_rocksdb_and_simpletyperefs.py
@@ -19,10 +19,12 @@
import gc
import os
import struct
-import pytest
-import ifcopenshell
import tempfile
+import pytest
+
+import ifcopenshell
+
try:
import psutil
except ImportError:
diff --git a/src/ifcopenshell-python/test/test_validate.py b/src/ifcopenshell-python/test/test_validate.py
index 16b12f223d..d3eff78f33 100644
--- a/src/ifcopenshell-python/test/test_validate.py
+++ b/src/ifcopenshell-python/test/test_validate.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import os
import glob
+import os
import pytest
diff --git a/src/ifcopenshell-python/test/test_validate_rocksdb.py b/src/ifcopenshell-python/test/test_validate_rocksdb.py
index 203d0ed2a4..6cfde4fddd 100644
--- a/src/ifcopenshell-python/test/test_validate_rocksdb.py
+++ b/src/ifcopenshell-python/test/test_validate_rocksdb.py
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import os
import glob
+import os
import tempfile
import time
diff --git a/src/ifcopenshell-python/test/test_wall_opening.py b/src/ifcopenshell-python/test/test_wall_opening.py
index 0e8c0d42cf..812a5420e2 100644
--- a/src/ifcopenshell-python/test/test_wall_opening.py
+++ b/src/ifcopenshell-python/test/test_wall_opening.py
@@ -16,17 +16,17 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import os
-import re
import glob
import json
-import typing
+import os
+import re
import shutil
import subprocess
-
+import typing
from dataclasses import dataclass, field
import pytest
+
import ifcopenshell
import ifcopenshell.guid
import ifcopenshell.template
diff --git a/src/ifcopenshell-python/test/test_write.py b/src/ifcopenshell-python/test/test_write.py
index e7a1f76b7c..1e55221d54 100644
--- a/src/ifcopenshell-python/test/test_write.py
+++ b/src/ifcopenshell-python/test/test_write.py
@@ -18,9 +18,10 @@
import tempfile
from pathlib import Path
-import pytest
-import ifcopenshell
+import pytest
+
+import ifcopenshell
TEST_FILE_DIR = Path(__file__).parent / "../../../test/input/"
diff --git a/src/ifcopenshell-python/test/typing_tests.py b/src/ifcopenshell-python/test/typing_tests.py
index c535960348..5b2d789613 100644
--- a/src/ifcopenshell-python/test/typing_tests.py
+++ b/src/ifcopenshell-python/test/typing_tests.py
@@ -22,10 +22,12 @@ Those tests are not automatically checked and just there to make sure overloads
"""
-import ifcopenshell
from typing import Union
+
from typing_extensions import assert_type
+import ifcopenshell
+
def ifcopenshell_open_test(str_: str, bool_: bool):
ifc_file = ifcopenshell.open(str_)
diff --git a/src/ifcopenshell-python/test/util/scripts/test_validate_stub.py b/src/ifcopenshell-python/test/util/scripts/test_validate_stub.py
index 86d18bd356..82b9e02adc 100644
--- a/src/ifcopenshell-python/test/util/scripts/test_validate_stub.py
+++ b/src/ifcopenshell-python/test/util/scripts/test_validate_stub.py
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see .
import pytest
+
import ifcopenshell.util.scripts.validate_stub as subject
diff --git a/src/ifcopenshell-python/test/util/test_attribute.py b/src/ifcopenshell-python/test/util/test_attribute.py
index 494374f565..4b04e8a678 100644
--- a/src/ifcopenshell-python/test/util/test_attribute.py
+++ b/src/ifcopenshell-python/test/util/test_attribute.py
@@ -16,8 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell
import pytest
+
+import ifcopenshell
import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.util.attribute as subject
diff --git a/src/ifcopenshell-python/test/util/test_brick.py b/src/ifcopenshell-python/test/util/test_brick.py
index 61a9f413af..d0cffeaba9 100644
--- a/src/ifcopenshell-python/test/util/test_brick.py
+++ b/src/ifcopenshell-python/test/util/test_brick.py
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api.root
import ifcopenshell.api.type
import ifcopenshell.util.brick as subject
+import test.bootstrap
class TestGetBrickTypeIFC4(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/util/test_classification.py b/src/ifcopenshell-python/test/util/test_classification.py
index 29820dc665..e006773d2a 100644
--- a/src/ifcopenshell-python/test/util/test_classification.py
+++ b/src/ifcopenshell-python/test/util/test_classification.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
+import ifcopenshell.api.classification
import ifcopenshell.api.root
import ifcopenshell.api.type
-import ifcopenshell.api.classification
import ifcopenshell.util.classification as subject
+import test.bootstrap
class TestGetReferences(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/util/test_date.py b/src/ifcopenshell-python/test/util/test_date.py
index b57b2d158b..dd47244ba7 100644
--- a/src/ifcopenshell-python/test/util/test_date.py
+++ b/src/ifcopenshell-python/test/util/test_date.py
@@ -17,8 +17,9 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.util.date as subject
+import test.bootstrap
class TestReadableIFCDuration:
diff --git a/src/ifcopenshell-python/test/util/test_element.py b/src/ifcopenshell-python/test/util/test_element.py
index 2c62c6d7c5..1308e957c1 100644
--- a/src/ifcopenshell-python/test/util/test_element.py
+++ b/src/ifcopenshell-python/test/util/test_element.py
@@ -16,30 +16,31 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import pytest
+
+import ifcopenshell.api.aggregate
+import ifcopenshell.api.classification
+import ifcopenshell.api.context
import ifcopenshell.api.control
import ifcopenshell.api.cost
-import ifcopenshell.api.profile
-import pytest
-import test.bootstrap
+import ifcopenshell.api.document
import ifcopenshell.api.feature
-import ifcopenshell.api.pset
-import ifcopenshell.api.root
-import ifcopenshell.api.type
-import ifcopenshell.api.nest
-import ifcopenshell.api.style
+import ifcopenshell.api.geometry
+import ifcopenshell.api.group
import ifcopenshell.api.layer
import ifcopenshell.api.library
-import ifcopenshell.api.context
-import ifcopenshell.api.spatial
-import ifcopenshell.api.geometry
-import ifcopenshell.api.sequence
-import ifcopenshell.api.classification
import ifcopenshell.api.material
-import ifcopenshell.api.document
-import ifcopenshell.api.aggregate
-import ifcopenshell.api.group
+import ifcopenshell.api.nest
+import ifcopenshell.api.profile
+import ifcopenshell.api.pset
+import ifcopenshell.api.root
+import ifcopenshell.api.sequence
+import ifcopenshell.api.spatial
+import ifcopenshell.api.style
+import ifcopenshell.api.type
import ifcopenshell.guid
import ifcopenshell.util.element as subject
+import test.bootstrap
from ifcopenshell.util.shape_builder import ShapeBuilder
diff --git a/src/ifcopenshell-python/test/util/test_file.py b/src/ifcopenshell-python/test/util/test_file.py
index 6517bbd5d8..b7b34cd097 100644
--- a/src/ifcopenshell-python/test/util/test_file.py
+++ b/src/ifcopenshell-python/test/util/test_file.py
@@ -16,13 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
-import test.bootstrap
-import ifcopenshell.util.file as subject
import tempfile
import zipfile
from pathlib import Path
+import pytest
+
+import ifcopenshell.util.file as subject
+import test.bootstrap
HEADER_EXTRACTOR_TEST_FILE_STR = """
ISO-10303-21;
diff --git a/src/ifcopenshell-python/test/util/test_geolocation.py b/src/ifcopenshell-python/test/util/test_geolocation.py
index 59f70fcd7a..92775963c3 100644
--- a/src/ifcopenshell-python/test/util/test_geolocation.py
+++ b/src/ifcopenshell-python/test/util/test_geolocation.py
@@ -17,11 +17,12 @@
# along with IfcOpenShell. If not, see .
import numpy as np
-import test.bootstrap
-import ifcopenshell.api.root
+
import ifcopenshell.api.context
import ifcopenshell.api.georeference
+import ifcopenshell.api.root
import ifcopenshell.util.geolocation as subject
+import test.bootstrap
class TestXYZ2ENH(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/util/test_placement.py b/src/ifcopenshell-python/test/util/test_placement.py
index af428660fd..8a26c52ee5 100644
--- a/src/ifcopenshell-python/test/util/test_placement.py
+++ b/src/ifcopenshell-python/test/util/test_placement.py
@@ -17,8 +17,8 @@
# along with IfcOpenShell. If not, see .
import ifcopenshell
-import test.bootstrap
import ifcopenshell.util.placement as subject
+import test.bootstrap
class TestGetStoreyElevationIFC4(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/util/test_pset.py b/src/ifcopenshell-python/test/util/test_pset.py
index c99a0b86a6..ccfbcc4970 100644
--- a/src/ifcopenshell-python/test/util/test_pset.py
+++ b/src/ifcopenshell-python/test/util/test_pset.py
@@ -17,8 +17,8 @@
# along with IfcOpenShell. If not, see .
"""Run this test from src/ifcopenshell-python folder: pytest --durations=0 ifcopenshell/util/test_pset.py"""
-from ifcopenshell.util import pset
from ifcopenshell import util
+from ifcopenshell.util import pset
from ifcopenshell.util.pset import ApplicableEntity
diff --git a/src/ifcopenshell-python/test/util/test_schema.py b/src/ifcopenshell-python/test/util/test_schema.py
index aa24de6360..cb45b6e8db 100644
--- a/src/ifcopenshell-python/test/util/test_schema.py
+++ b/src/ifcopenshell-python/test/util/test_schema.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api.project
import ifcopenshell.util.schema as subject
+import test.bootstrap
class TestMigrator(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/util/test_selector.py b/src/ifcopenshell-python/test/util/test_selector.py
index 41bf0649e7..e4de678529 100644
--- a/src/ifcopenshell-python/test/util/test_selector.py
+++ b/src/ifcopenshell-python/test/util/test_selector.py
@@ -16,24 +16,25 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+import numpy as np
import pytest
-import test.bootstrap
-import ifcopenshell.api.spatial
-import ifcopenshell.api.root
-import ifcopenshell.api.unit
-import ifcopenshell.api.classification
-import ifcopenshell.api.pset
-import ifcopenshell.api.type
-import ifcopenshell.api.material
-import ifcopenshell.api.geometry
+
import ifcopenshell.api.aggregate
+import ifcopenshell.api.classification
+import ifcopenshell.api.geometry
import ifcopenshell.api.group
+import ifcopenshell.api.material
+import ifcopenshell.api.pset
+import ifcopenshell.api.root
import ifcopenshell.api.sequence
+import ifcopenshell.api.spatial
+import ifcopenshell.api.type
+import ifcopenshell.api.unit
import ifcopenshell.util.element
-import ifcopenshell.util.selector as subject
import ifcopenshell.util.placement
import ifcopenshell.util.pset
-import numpy as np
+import ifcopenshell.util.selector as subject
+import test.bootstrap
class TestFormat:
diff --git a/src/ifcopenshell-python/test/util/test_shape_builder.py b/src/ifcopenshell-python/test/util/test_shape_builder.py
index a46c014fa7..87499b3288 100644
--- a/src/ifcopenshell-python/test/util/test_shape_builder.py
+++ b/src/ifcopenshell-python/test/util/test_shape_builder.py
@@ -16,27 +16,29 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from math import degrees, radians
+from typing import Any, Union
+
+import numpy as np
+import pytest
+
+import ifcopenshell.api
import ifcopenshell.geom
import ifcopenshell.util
import ifcopenshell.util.shape
-import pytest
import test.bootstrap
-import ifcopenshell.api
-import numpy as np
from ifcopenshell.util.shape_builder import (
ShapeBuilder,
- is_x,
- np_rotation_matrix,
- np_to_3d,
- np_angle,
V,
+ is_x,
+ np_angle,
np_angle_signed,
- np_normal,
np_intersect_line_line,
np_matrix_to_euler,
+ np_normal,
+ np_rotation_matrix,
+ np_to_3d,
)
-from math import degrees, radians
-from typing import Any, Union
class TestMathutilsCompatibleMethods(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/util/test_system.py b/src/ifcopenshell-python/test/util/test_system.py
index 3e8c6d0159..f38971351a 100644
--- a/src/ifcopenshell-python/test/util/test_system.py
+++ b/src/ifcopenshell-python/test/util/test_system.py
@@ -16,14 +16,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from typing import get_args
+
import pytest
-import test.bootstrap
+
import ifcopenshell.api
import ifcopenshell.api.root
import ifcopenshell.api.system
import ifcopenshell.util.schema
import ifcopenshell.util.system as subject
-from typing import get_args
+import test.bootstrap
class TestValidateGroupTypes:
diff --git a/src/ifcopenshell-python/test/util/test_type.py b/src/ifcopenshell-python/test/util/test_type.py
index 6043238e73..54f0e6da16 100644
--- a/src/ifcopenshell-python/test/util/test_type.py
+++ b/src/ifcopenshell-python/test/util/test_type.py
@@ -17,9 +17,10 @@
# along with IfcOpenShell. If not, see .
import pytest
-import test.bootstrap
+
import ifcopenshell.api
import ifcopenshell.util.type as subject
+import test.bootstrap
class TestGetApplicableTypes(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/util/test_unit.py b/src/ifcopenshell-python/test/util/test_unit.py
index 6e28a28e70..5deef1884a 100644
--- a/src/ifcopenshell-python/test/util/test_unit.py
+++ b/src/ifcopenshell-python/test/util/test_unit.py
@@ -16,18 +16,20 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
+from math import pi
+
import numpy as np
+
import ifcopenshell.api.context
-import ifcopenshell.api.unit
-import ifcopenshell.api.root
import ifcopenshell.api.georeference
import ifcopenshell.api.pset
+import ifcopenshell.api.root
+import ifcopenshell.api.unit
import ifcopenshell.util.element
import ifcopenshell.util.geolocation
import ifcopenshell.util.unit as subject
+import test.bootstrap
from ifcopenshell.util.shape_builder import ShapeBuilder
-from math import pi
class TestCacheUnits(test.bootstrap.IFC4):
diff --git a/src/ifcopenshell-python/test/util/test_unit_conversion.py b/src/ifcopenshell-python/test/util/test_unit_conversion.py
index fa95260607..a3c8b702ef 100644
--- a/src/ifcopenshell-python/test/util/test_unit_conversion.py
+++ b/src/ifcopenshell-python/test/util/test_unit_conversion.py
@@ -16,9 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
import pathlib
-import pytest
-import ifcopenshell.util.unit
+
import numpy as np
+import pytest
+
+import ifcopenshell.util.unit
UNITS_FIXTURE_DIR = pathlib.Path(__file__).parent.parent / "fixtures" / "units"
diff --git a/src/ifcpatch/bootstrap.py b/src/ifcpatch/bootstrap.py
index 263da876ec..368d7b5cff 100644
--- a/src/ifcpatch/bootstrap.py
+++ b/src/ifcpatch/bootstrap.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
-import toposort
-import ifcpatch
-import ifcpatch.recipes
-import ifcopenshell.util.selector
import ifcopenshell.util.element
import ifcopenshell.util.schema
-
+import ifcopenshell.util.selector
import ifcpatch.__main__
+import ifcpatch.recipes
+import toposort
+
+import ifcpatch
diff --git a/src/ifcpatch/ifcpatch/__init__.py b/src/ifcpatch/ifcpatch/__init__.py
index 91acba3bd4..7ea668d55e 100644
--- a/src/ifcpatch/ifcpatch/__init__.py
+++ b/src/ifcpatch/ifcpatch/__init__.py
@@ -18,22 +18,22 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
-import os
-import shutil
-import sys
-import ifcopenshell
-import logging
-import typing
-import inspect
import collections
import importlib
import importlib.util
+import inspect
+import logging
+import os
import re
-from pathlib import Path
-from typing import Union, Optional, Any, TypedDict
-from typing_extensions import NotRequired
+import shutil
+import sys
+import typing
from collections.abc import Sequence
+from pathlib import Path
+from typing import Any, Optional, TypedDict, Union
+import ifcopenshell
+from typing_extensions import NotRequired
__version__ = version = "0.0.0"
diff --git a/src/ifcpatch/ifcpatch/__main__.py b/src/ifcpatch/ifcpatch/__main__.py
index 178259694d..ae01f9b594 100644
--- a/src/ifcpatch/ifcpatch/__main__.py
+++ b/src/ifcpatch/ifcpatch/__main__.py
@@ -19,9 +19,11 @@
# along with IfcPatch. If not, see .
import argparse
-import ifcpatch
+
import ifcopenshell
+import ifcpatch
+
parser = argparse.ArgumentParser(description="Patches IFC files to fix badly formatted data")
parser.add_argument("-i", "--input", type=str, required=True, help="The IFC file to patch")
parser.add_argument("-o", "--output", type=str, help="The output file to save the patched IFC")
diff --git a/src/ifcpatch/ifcpatch/recipes/AGS2IFC.py b/src/ifcpatch/ifcpatch/recipes/AGS2IFC.py
index 283d83a6b7..8067d2e718 100644
--- a/src/ifcpatch/ifcpatch/recipes/AGS2IFC.py
+++ b/src/ifcpatch/ifcpatch/recipes/AGS2IFC.py
@@ -17,22 +17,23 @@
# along with IfcPatch. If not, see .
-import os
import csv
-import numpy as np
+import os
+from itertools import cycle
+
import ifcopenshell
-import ifcopenshell.api.pset
-import ifcopenshell.api.root
-import ifcopenshell.api.unit
-import ifcopenshell.api.style
+import ifcopenshell.api.aggregate
import ifcopenshell.api.context
import ifcopenshell.api.document
-import ifcopenshell.api.project
-import ifcopenshell.api.spatial
import ifcopenshell.api.geometry
-import ifcopenshell.api.aggregate
+import ifcopenshell.api.project
+import ifcopenshell.api.pset
+import ifcopenshell.api.root
+import ifcopenshell.api.spatial
+import ifcopenshell.api.style
+import ifcopenshell.api.unit
import ifcopenshell.util.shape_builder
-from itertools import cycle
+import numpy as np
from ifcopenshell.util.shape_builder import V
diff --git a/src/ifcpatch/ifcpatch/recipes/AddGeometricRepresentationToAlignment.py b/src/ifcpatch/ifcpatch/recipes/AddGeometricRepresentationToAlignment.py
index b4c9cd2b6c..65f48f899d 100644
--- a/src/ifcpatch/ifcpatch/recipes/AddGeometricRepresentationToAlignment.py
+++ b/src/ifcpatch/ifcpatch/recipes/AddGeometricRepresentationToAlignment.py
@@ -16,13 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
+import typing
+from logging import Logger
+from typing import Union
+
import ifcopenshell
import ifcopenshell.util.alignment
-import ifcpatch
-from logging import Logger
-import typing
-from typing import Union
+import ifcpatch
class Patcher(ifcpatch.BasePatcher):
diff --git a/src/ifcpatch/ifcpatch/recipes/AddLinearPlacementFallbackPosition.py b/src/ifcpatch/ifcpatch/recipes/AddLinearPlacementFallbackPosition.py
index 256dd8f5aa..9ec3f52a6a 100644
--- a/src/ifcpatch/ifcpatch/recipes/AddLinearPlacementFallbackPosition.py
+++ b/src/ifcpatch/ifcpatch/recipes/AddLinearPlacementFallbackPosition.py
@@ -16,13 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
+import typing
+from logging import Logger
+from typing import Union
+
import ifcopenshell
import ifcopenshell.util.alignment
-import ifcpatch
-from logging import Logger
-import typing
-from typing import Union
+import ifcpatch
class Patcher(ifcpatch.BasePatcher):
diff --git a/src/ifcpatch/ifcpatch/recipes/AddZeroLengthSegmentToAlignment.py b/src/ifcpatch/ifcpatch/recipes/AddZeroLengthSegmentToAlignment.py
index aa6870939c..e1f6664cd0 100644
--- a/src/ifcpatch/ifcpatch/recipes/AddZeroLengthSegmentToAlignment.py
+++ b/src/ifcpatch/ifcpatch/recipes/AddZeroLengthSegmentToAlignment.py
@@ -16,13 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
+import typing
+from logging import Logger
+from typing import Union
+
import ifcopenshell
import ifcopenshell.util.alignment
-import ifcpatch
-from logging import Logger
-import typing
-from typing import Union
+import ifcpatch
class Patcher(ifcpatch.BasePatcher):
diff --git a/src/ifcpatch/ifcpatch/recipes/AssignConstituentFractions.py b/src/ifcpatch/ifcpatch/recipes/AssignConstituentFractions.py
index 0989c6bd14..0b105a52f7 100644
--- a/src/ifcpatch/ifcpatch/recipes/AssignConstituentFractions.py
+++ b/src/ifcpatch/ifcpatch/recipes/AssignConstituentFractions.py
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
+from logging import Logger
+
import ifcopenshell
import ifcopenshell.util.element
import ifcopenshell.util.unit
-from logging import Logger
class Patcher:
diff --git a/src/ifcpatch/ifcpatch/recipes/ConvertLengthUnit.py b/src/ifcpatch/ifcpatch/recipes/ConvertLengthUnit.py
index e82f12c281..6b3554b192 100644
--- a/src/ifcpatch/ifcpatch/recipes/ConvertLengthUnit.py
+++ b/src/ifcpatch/ifcpatch/recipes/ConvertLengthUnit.py
@@ -16,17 +16,18 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
+import typing
+from logging import Logger
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.owner.settings
-import ifcopenshell.util.pset
import ifcopenshell.util.element
+import ifcopenshell.util.pset
import ifcopenshell.util.unit
-import ifcpatch
-from logging import Logger
-import typing
-from typing import Union
+import ifcpatch
LengthUnit = typing.Literal[
"ATTOMETER",
diff --git a/src/ifcpatch/ifcpatch/recipes/ConvertPropertiesToQuantities.py b/src/ifcpatch/ifcpatch/recipes/ConvertPropertiesToQuantities.py
index 74c28fb0e3..a9df2c93c4 100644
--- a/src/ifcpatch/ifcpatch/recipes/ConvertPropertiesToQuantities.py
+++ b/src/ifcpatch/ifcpatch/recipes/ConvertPropertiesToQuantities.py
@@ -16,13 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
+from logging import Logger
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.pset
-import ifcopenshell.util.pset
import ifcopenshell.util.element
-from logging import Logger
-from typing import Union
+import ifcopenshell.util.pset
class Patcher:
diff --git a/src/ifcpatch/ifcpatch/recipes/ExtractElements.py b/src/ifcpatch/ifcpatch/recipes/ExtractElements.py
index 6f70a410b3..31f1fb4140 100644
--- a/src/ifcpatch/ifcpatch/recipes/ExtractElements.py
+++ b/src/ifcpatch/ifcpatch/recipes/ExtractElements.py
@@ -16,14 +16,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
+from logging import Logger
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.project
import ifcopenshell.guid
import ifcopenshell.util.selector
+
import ifcpatch
-from typing import Union
-from logging import Logger
class Patcher(ifcpatch.BasePatcher):
diff --git a/src/ifcpatch/ifcpatch/recipes/ExtractPropertiesToSQLite.py b/src/ifcpatch/ifcpatch/recipes/ExtractPropertiesToSQLite.py
index 226052ae19..5df98c4ab4 100644
--- a/src/ifcpatch/ifcpatch/recipes/ExtractPropertiesToSQLite.py
+++ b/src/ifcpatch/ifcpatch/recipes/ExtractPropertiesToSQLite.py
@@ -17,11 +17,12 @@
# along with IfcPatch. If not, see .
+import json
import os
import re
-import json
-import time
import tempfile
+import time
+
import ifcopenshell
import ifcopenshell.util.element
diff --git a/src/ifcpatch/ifcpatch/recipes/FixArchiCADToRevitDoorSwings.py b/src/ifcpatch/ifcpatch/recipes/FixArchiCADToRevitDoorSwings.py
index 28860b58dc..cf602bab0a 100644
--- a/src/ifcpatch/ifcpatch/recipes/FixArchiCADToRevitDoorSwings.py
+++ b/src/ifcpatch/ifcpatch/recipes/FixArchiCADToRevitDoorSwings.py
@@ -22,13 +22,14 @@ import math
import os
from typing import Union
-import ifcpatch
import ifcopenshell
import ifcopenshell.geom
import ifcopenshell.util.element
import ifcopenshell.util.schema
import ifcopenshell.util.unit
+import ifcpatch
+
class Patcher(ifcpatch.BasePatcher):
def __init__(self, file: ifcopenshell.file, logger: Union[logging.Logger, None] = None):
diff --git a/src/ifcpatch/ifcpatch/recipes/FixArchiCADToRevitSpaces.py b/src/ifcpatch/ifcpatch/recipes/FixArchiCADToRevitSpaces.py
index d19bc8b26c..c6ea871c7b 100644
--- a/src/ifcpatch/ifcpatch/recipes/FixArchiCADToRevitSpaces.py
+++ b/src/ifcpatch/ifcpatch/recipes/FixArchiCADToRevitSpaces.py
@@ -17,6 +17,7 @@
# along with IfcPatch. If not, see .
import logging
+
import ifcopenshell
@@ -67,11 +68,11 @@ class Patcher:
self.filepath = filepath
def patch(self) -> None:
- import bpy
import bonsai.tool as tool
+ import bpy
import ifcopenshell
import ifcopenshell.util.element
- from mathutils import Vector, Matrix
+ from mathutils import Matrix, Vector
if len(bpy.data.objects) > 0:
bpy.data.batch_remove(bpy.data.objects)
diff --git a/src/ifcpatch/ifcpatch/recipes/FixRevit2025TINs.py b/src/ifcpatch/ifcpatch/recipes/FixRevit2025TINs.py
index e18b4eed39..d6dc49be18 100644
--- a/src/ifcpatch/ifcpatch/recipes/FixRevit2025TINs.py
+++ b/src/ifcpatch/ifcpatch/recipes/FixRevit2025TINs.py
@@ -17,12 +17,13 @@
# along with IfcPatch. If not, see .
+import logging
+from typing import Optional
+
import ifcopenshell
import ifcopenshell.util.schema
import ifcopenshell.util.shape_builder
import ifcopenshell.util.unit
-import logging
-from typing import Optional
class Patcher:
@@ -110,9 +111,9 @@ class Patcher:
self.should_create_edges = should_create_edges
def patch(self) -> None:
- import bpy
import bmesh
import bonsai.tool as tool
+ import bpy
import ifcopenshell.util.shape_builder
bpy.context.scene.BIMProjectProperties.should_use_native_meshes = True
@@ -161,15 +162,15 @@ class Patcher:
self.file = tool.Ifc.get()
def create_edges(self, obj):
- import bpy
import bmesh
import bonsai.tool as tool
+ import bpy
+ import ifcopenshell.api.geometry
+ import ifcopenshell.api.root
+ import ifcopenshell.api.spatial
+ import ifcopenshell.api.type
import ifcopenshell.util.element
import ifcopenshell.util.representation
- import ifcopenshell.api.root
- import ifcopenshell.api.type
- import ifcopenshell.api.spatial
- import ifcopenshell.api.geometry
element = tool.Ifc.get_entity(obj)
data = obj.data
@@ -229,16 +230,17 @@ class Patcher:
def create_face_sampleable_object(self, obj):
# No sharp faces
- import bpy
+ from math import degrees
+
import bmesh
import bonsai.tool as tool
+ import bpy
+ import ifcopenshell.api.geometry
+ import ifcopenshell.api.root
+ import ifcopenshell.api.spatial
+ import ifcopenshell.api.type
import ifcopenshell.util.element
import ifcopenshell.util.representation
- import ifcopenshell.api.root
- import ifcopenshell.api.type
- import ifcopenshell.api.spatial
- import ifcopenshell.api.geometry
- from math import degrees
print("working on ", obj.name)
element = tool.Ifc.get_entity(obj)
@@ -278,16 +280,17 @@ class Patcher:
def create_edge_sampleable_object(self, obj):
# This is crazy but we need a sharp face per island
- import bpy
+ from math import degrees, radians, sin
+
import bmesh
import bonsai.tool as tool
+ import bpy
+ import ifcopenshell.api.geometry
+ import ifcopenshell.api.root
+ import ifcopenshell.api.spatial
+ import ifcopenshell.api.type
import ifcopenshell.util.element
import ifcopenshell.util.representation
- import ifcopenshell.api.root
- import ifcopenshell.api.type
- import ifcopenshell.api.spatial
- import ifcopenshell.api.geometry
- from math import degrees, radians, sin
from mathutils import Matrix
# Get the active object (assumed to have a mesh)
diff --git a/src/ifcpatch/ifcpatch/recipes/FixRevitTINs.py b/src/ifcpatch/ifcpatch/recipes/FixRevitTINs.py
index a673bf377c..872b1a0091 100644
--- a/src/ifcpatch/ifcpatch/recipes/FixRevitTINs.py
+++ b/src/ifcpatch/ifcpatch/recipes/FixRevitTINs.py
@@ -17,9 +17,10 @@
# along with IfcPatch. If not, see .
-import ifcopenshell
import logging
+import ifcopenshell
+
class Patcher:
def __init__(self, file: None, logger: logging.Logger, filepath: str, is_solid: bool = True):
@@ -79,10 +80,11 @@ class Patcher:
self.is_solid = is_solid
def patch(self) -> None:
- import bpy
+ from math import degrees
+
import bmesh
import bonsai.tool as tool
- from math import degrees
+ import bpy
props = tool.Project.get_project_props()
props.should_use_native_meshes = True
diff --git a/src/ifcpatch/ifcpatch/recipes/Ifc2Sql.py b/src/ifcpatch/ifcpatch/recipes/Ifc2Sql.py
index 1e8ac55b7c..74744f3487 100644
--- a/src/ifcpatch/ifcpatch/recipes/Ifc2Sql.py
+++ b/src/ifcpatch/ifcpatch/recipes/Ifc2Sql.py
@@ -17,16 +17,18 @@
# along with IfcPatch. If not, see .
+import itertools
+import json
+import logging
+import multiprocessing
import os
import re
-import json
-import time
import tempfile
+import time
import typing
-import itertools
-import logging
-import numpy as np
-import multiprocessing
+from pathlib import Path
+from typing import TYPE_CHECKING, Any, Literal, Union
+
import ifcopenshell
import ifcopenshell.geom
import ifcopenshell.ifcopenshell_wrapper as W
@@ -37,15 +39,16 @@ import ifcopenshell.util.representation
import ifcopenshell.util.schema
import ifcopenshell.util.shape
import ifcopenshell.util.unit
-import ifcpatch
-from pathlib import Path
-from typing import Any, TYPE_CHECKING, Literal, Union
+import numpy as np
from typing_extensions import assert_never
+import ifcpatch
+
SQLTypes = typing.Literal["SQLite", "MySQL"]
if TYPE_CHECKING:
import sqlite3
+
import mysql.connector
import mysql.connector.abstracts
else:
diff --git a/src/ifcpatch/ifcpatch/recipes/MergeDuplicateTypes.py b/src/ifcpatch/ifcpatch/recipes/MergeDuplicateTypes.py
index fe82b33cfb..2c8385066b 100644
--- a/src/ifcpatch/ifcpatch/recipes/MergeDuplicateTypes.py
+++ b/src/ifcpatch/ifcpatch/recipes/MergeDuplicateTypes.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
+from logging import Logger
+from typing import Any
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.type
import ifcopenshell.util.element
-from logging import Logger
-from typing import Any
class Patcher:
diff --git a/src/ifcpatch/ifcpatch/recipes/MergeProjects.py b/src/ifcpatch/ifcpatch/recipes/MergeProjects.py
index 9372f1d75f..ffb8e2e65b 100644
--- a/src/ifcpatch/ifcpatch/recipes/MergeProjects.py
+++ b/src/ifcpatch/ifcpatch/recipes/MergeProjects.py
@@ -16,14 +16,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
-import numpy as np
+from logging import Logger
+from typing import Union
+
import ifcopenshell
-import ifcopenshell.util.unit
import ifcopenshell.util.element
import ifcopenshell.util.geolocation
+import ifcopenshell.util.unit
+import numpy as np
+
from ifcpatch.recipes.SetFalseOrigin import Patcher as SetFalseOrigin
-from typing import Union
-from logging import Logger
class Patcher:
diff --git a/src/ifcpatch/ifcpatch/recipes/MergeStyles.py b/src/ifcpatch/ifcpatch/recipes/MergeStyles.py
index 5c1fa2f4fa..c6df956bbe 100644
--- a/src/ifcpatch/ifcpatch/recipes/MergeStyles.py
+++ b/src/ifcpatch/ifcpatch/recipes/MergeStyles.py
@@ -16,12 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
-import ifcopenshell
-import ifcopenshell.util.element
-import ifcpatch
import logging
from typing import Union
+import ifcopenshell
+import ifcopenshell.util.element
+
+import ifcpatch
+
class Patcher(ifcpatch.BasePatcher):
def __init__(self, file: ifcopenshell.file, logger: Union[logging.Logger, None] = None):
diff --git a/src/ifcpatch/ifcpatch/recipes/Migrate.py b/src/ifcpatch/ifcpatch/recipes/Migrate.py
index 9f330e9016..6b5c18ff11 100644
--- a/src/ifcpatch/ifcpatch/recipes/Migrate.py
+++ b/src/ifcpatch/ifcpatch/recipes/Migrate.py
@@ -16,12 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
+import typing
+from logging import Logger
+from typing import Union
+
import ifcopenshell
import ifcopenshell.util.schema
+
import ifcpatch
-import typing
-from typing import Union
-from logging import Logger
class Patcher(ifcpatch.BasePatcher):
diff --git a/src/ifcpatch/ifcpatch/recipes/OffsetObjectPlacements.py b/src/ifcpatch/ifcpatch/recipes/OffsetObjectPlacements.py
index e147b783d2..a575fc4eac 100644
--- a/src/ifcpatch/ifcpatch/recipes/OffsetObjectPlacements.py
+++ b/src/ifcpatch/ifcpatch/recipes/OffsetObjectPlacements.py
@@ -17,10 +17,11 @@
# along with IfcPatch. If not, see .
import math
-import numpy as np
+import typing
+
import ifcopenshell
import ifcopenshell.util.placement
-import typing
+import numpy as np
from ifcopenshell.util.shape_builder import ShapeBuilder
diff --git a/src/ifcpatch/ifcpatch/recipes/PatchStationReferentPosition.py b/src/ifcpatch/ifcpatch/recipes/PatchStationReferentPosition.py
index 556c43a094..cd3a4fb523 100644
--- a/src/ifcpatch/ifcpatch/recipes/PatchStationReferentPosition.py
+++ b/src/ifcpatch/ifcpatch/recipes/PatchStationReferentPosition.py
@@ -1,11 +1,12 @@
+import typing
+from logging import Logger
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api.alignment
import ifcopenshell.util.element
-import ifcpatch
-from logging import Logger
-import typing
-from typing import Union
+import ifcpatch
class Patcher(ifcpatch.BasePatcher):
diff --git a/src/ifcpatch/ifcpatch/recipes/PurgeData.py b/src/ifcpatch/ifcpatch/recipes/PurgeData.py
index 5ef1af6102..3c34927a63 100644
--- a/src/ifcpatch/ifcpatch/recipes/PurgeData.py
+++ b/src/ifcpatch/ifcpatch/recipes/PurgeData.py
@@ -17,9 +17,10 @@
# along with IfcPatch. If not, see .
import datetime
-import ifcopenshell
from logging import Logger
+import ifcopenshell
+
class Patcher:
def __init__(self, file: ifcopenshell.file, logger: Logger):
diff --git a/src/ifcpatch/ifcpatch/recipes/RecycleNonRootedElements.py b/src/ifcpatch/ifcpatch/recipes/RecycleNonRootedElements.py
index 93ab762778..f66b375ae3 100644
--- a/src/ifcpatch/ifcpatch/recipes/RecycleNonRootedElements.py
+++ b/src/ifcpatch/ifcpatch/recipes/RecycleNonRootedElements.py
@@ -16,8 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
-from collections import deque
import logging
+from collections import deque
+
import ifcopenshell.util.element
diff --git a/src/ifcpatch/ifcpatch/recipes/RegenerateGlobalIds.py b/src/ifcpatch/ifcpatch/recipes/RegenerateGlobalIds.py
index 0c3475725d..8e0a8ab976 100644
--- a/src/ifcpatch/ifcpatch/recipes/RegenerateGlobalIds.py
+++ b/src/ifcpatch/ifcpatch/recipes/RegenerateGlobalIds.py
@@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
+from logging import Logger
+
import ifcopenshell
import ifcopenshell.guid
-from logging import Logger
class Patcher:
diff --git a/src/ifcpatch/ifcpatch/recipes/ResetAbsoluteCoordinates.py b/src/ifcpatch/ifcpatch/recipes/ResetAbsoluteCoordinates.py
index 0136a6de9c..641ba928b1 100644
--- a/src/ifcpatch/ifcpatch/recipes/ResetAbsoluteCoordinates.py
+++ b/src/ifcpatch/ifcpatch/recipes/ResetAbsoluteCoordinates.py
@@ -17,10 +17,11 @@
# along with IfcPatch. If not, see .
import logging
+from typing import Literal, Optional, Union
+
+import ifcopenshell
import numpy as np
import numpy.typing as npt
-import ifcopenshell
-from typing import Literal, Optional, Union
class Patcher:
diff --git a/src/ifcpatch/ifcpatch/recipes/ResetSpatialElementLocations.py b/src/ifcpatch/ifcpatch/recipes/ResetSpatialElementLocations.py
index fca2a5ee11..0f7c3933b4 100644
--- a/src/ifcpatch/ifcpatch/recipes/ResetSpatialElementLocations.py
+++ b/src/ifcpatch/ifcpatch/recipes/ResetSpatialElementLocations.py
@@ -16,8 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
-import ifcopenshell
import logging
+
+import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.geometry
import ifcopenshell.util
diff --git a/src/ifcpatch/ifcpatch/recipes/SetFalseOrigin.py b/src/ifcpatch/ifcpatch/recipes/SetFalseOrigin.py
index e22f4787d1..72218e5ecf 100644
--- a/src/ifcpatch/ifcpatch/recipes/SetFalseOrigin.py
+++ b/src/ifcpatch/ifcpatch/recipes/SetFalseOrigin.py
@@ -16,11 +16,17 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
+import typing
+
import ifcopenshell
import ifcopenshell.api.georeference
import ifcopenshell.util.geolocation
-from ifcpatch.recipes import OffsetObjectPlacements, SetWorldCoordinateSystem, ResetSpatialElementLocations
-import typing
+
+from ifcpatch.recipes import (
+ OffsetObjectPlacements,
+ ResetSpatialElementLocations,
+ SetWorldCoordinateSystem,
+)
class Patcher:
diff --git a/src/ifcpatch/ifcpatch/recipes/SetWorldCoordinateSystem.py b/src/ifcpatch/ifcpatch/recipes/SetWorldCoordinateSystem.py
index d5c2e8da94..080da3ef7f 100644
--- a/src/ifcpatch/ifcpatch/recipes/SetWorldCoordinateSystem.py
+++ b/src/ifcpatch/ifcpatch/recipes/SetWorldCoordinateSystem.py
@@ -17,9 +17,10 @@
# along with IfcPatch. If not, see .
import math
-import numpy as np
import typing
+import numpy as np
+
class Patcher:
def __init__(
diff --git a/src/ifcpatch/ifcpatch/recipes/SplitByBuildingStorey.py b/src/ifcpatch/ifcpatch/recipes/SplitByBuildingStorey.py
index 1d0b4c02f0..2f83fbb208 100644
--- a/src/ifcpatch/ifcpatch/recipes/SplitByBuildingStorey.py
+++ b/src/ifcpatch/ifcpatch/recipes/SplitByBuildingStorey.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
-import os
import logging
-import ifcopenshell
+import os
from pathlib import Path
from typing import Union
+import ifcopenshell
+
class Patcher:
def __init__(self, file: ifcopenshell.file, logger: logging.Logger, output_dir: Union[str, None] = None):
@@ -45,10 +46,11 @@ class Patcher:
self.output_dir = output_dir
def patch(self) -> None:
- import ifcopenshell
import tempfile
from shutil import copyfile
+ import ifcopenshell
+
if self.output_dir is None:
output_dir = Path()
else:
diff --git a/src/ifcpatch/ifcpatch/recipes/TessellateElements.py b/src/ifcpatch/ifcpatch/recipes/TessellateElements.py
index 0638568fe4..14ee80aec2 100644
--- a/src/ifcpatch/ifcpatch/recipes/TessellateElements.py
+++ b/src/ifcpatch/ifcpatch/recipes/TessellateElements.py
@@ -16,16 +16,17 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
+import multiprocessing
+from logging import Logger
+from typing import Union
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.geometry
import ifcopenshell.geom
+import ifcopenshell.util.representation
import ifcopenshell.util.selector
import ifcopenshell.util.shape
-import ifcopenshell.util.representation
-import multiprocessing
-from logging import Logger
-from typing import Union
class Patcher:
diff --git a/src/ifcpatch/ifcpatch/recipes/UnsharePsets.py b/src/ifcpatch/ifcpatch/recipes/UnsharePsets.py
index fa7f1b083c..e7a1ad9eb1 100644
--- a/src/ifcpatch/ifcpatch/recipes/UnsharePsets.py
+++ b/src/ifcpatch/ifcpatch/recipes/UnsharePsets.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcPatch. If not, see .
+from logging import Logger
+
import ifcopenshell
import ifcopenshell.api.pset
import ifcopenshell.guid
import ifcopenshell.util.element
import ifcopenshell.util.selector
-from logging import Logger
class Patcher:
diff --git a/src/ifcpatch/test/bootstrap.py b/src/ifcpatch/test/bootstrap.py
index d4d1d07c2e..7c6dfec558 100644
--- a/src/ifcpatch/test/bootstrap.py
+++ b/src/ifcpatch/test/bootstrap.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import pytest
import ifcopenshell
import ifcopenshell.api
-import ifcopenshell.api.project
import ifcopenshell.api.owner.settings
+import ifcopenshell.api.project
+import pytest
class IFC4X3:
diff --git a/src/ifcpatch/test/test_ConvertLengthUnit.py b/src/ifcpatch/test/test_ConvertLengthUnit.py
index 85e451110a..a4f586512f 100644
--- a/src/ifcpatch/test/test_ConvertLengthUnit.py
+++ b/src/ifcpatch/test/test_ConvertLengthUnit.py
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api
import ifcopenshell.api.root
import ifcopenshell.api.unit
import ifcopenshell.util.unit
+
import ifcpatch
+import test.bootstrap
class TestConvertLengthUnit(test.bootstrap.IFC4):
diff --git a/src/ifcpatch/test/test_ConvertPropertiesToQuantities.py b/src/ifcpatch/test/test_ConvertPropertiesToQuantities.py
index 830495f74f..d25dcd9d1d 100644
--- a/src/ifcpatch/test/test_ConvertPropertiesToQuantities.py
+++ b/src/ifcpatch/test/test_ConvertPropertiesToQuantities.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcpatch
import ifcopenshell
import ifcopenshell.api.pset
import ifcopenshell.api.root
import ifcopenshell.util.element
+
+import ifcpatch
import test.bootstrap
diff --git a/src/ifcpatch/test/test_ExtractElements.py b/src/ifcpatch/test/test_ExtractElements.py
index 8df5095256..fe2e9350dd 100644
--- a/src/ifcpatch/test/test_ExtractElements.py
+++ b/src/ifcpatch/test/test_ExtractElements.py
@@ -17,14 +17,16 @@
# along with IfcOpenShell. If not, see .
import os
-import pytest
-import ifcpatch
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.aggregate
import ifcopenshell.api.root
import ifcopenshell.api.spatial
import ifcopenshell.util.element
+import pytest
+
+import ifcpatch
import test.bootstrap
diff --git a/src/ifcpatch/test/test_Ifc2Sql.py b/src/ifcpatch/test/test_Ifc2Sql.py
index e5c40fe245..79257a69c3 100644
--- a/src/ifcpatch/test/test_Ifc2Sql.py
+++ b/src/ifcpatch/test/test_Ifc2Sql.py
@@ -17,7 +17,8 @@
# along with IfcOpenShell. If not, see .
import tempfile
-import ifcpatch
+from pathlib import Path
+
import ifcopenshell
import ifcopenshell.api.context
import ifcopenshell.api.geometry
@@ -28,7 +29,8 @@ import ifcopenshell.util.placement
import ifcopenshell.util.representation
import ifcopenshell.util.shape
import ifcopenshell.util.shape_builder
-from pathlib import Path
+
+import ifcpatch
class TestIfc2Sql:
diff --git a/src/ifcpatch/test/test_MergeDuplicateTypes.py b/src/ifcpatch/test/test_MergeDuplicateTypes.py
index 37e37d39b4..439f7a0c06 100644
--- a/src/ifcpatch/test/test_MergeDuplicateTypes.py
+++ b/src/ifcpatch/test/test_MergeDuplicateTypes.py
@@ -17,8 +17,7 @@
# along with IfcOpenShell. If not, see .
import os
-import pytest
-import ifcpatch
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.geometry
@@ -27,6 +26,9 @@ import ifcopenshell.api.root
import ifcopenshell.api.type
import ifcopenshell.util.element
import ifcopenshell.util.representation
+import pytest
+
+import ifcpatch
import test.bootstrap
diff --git a/src/ifcpatch/test/test_MergeProject.py b/src/ifcpatch/test/test_MergeProject.py
index 6384e98dd8..35fcb0719f 100644
--- a/src/ifcpatch/test/test_MergeProject.py
+++ b/src/ifcpatch/test/test_MergeProject.py
@@ -16,7 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcpatch
+import tempfile
+from pathlib import Path
+from typing import Optional
+
import ifcopenshell
import ifcopenshell.api.context
import ifcopenshell.api.geometry
@@ -29,11 +32,10 @@ import ifcopenshell.util.placement
import ifcopenshell.util.representation
import ifcopenshell.util.shape
import ifcopenshell.util.shape_builder
-import test.bootstrap
-import tempfile
import numpy as np
-from pathlib import Path
-from typing import Optional
+
+import ifcpatch
+import test.bootstrap
class TestMergeProjects(test.bootstrap.IFC4):
diff --git a/src/ifcpatch/test/test_Migrate.py b/src/ifcpatch/test/test_Migrate.py
index afefd9d3fb..319e01d91b 100644
--- a/src/ifcpatch/test/test_Migrate.py
+++ b/src/ifcpatch/test/test_Migrate.py
@@ -16,8 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcpatch
import ifcopenshell
+
+import ifcpatch
import test.bootstrap
diff --git a/src/ifcpatch/test/test_RegenerateGlobalIds.py b/src/ifcpatch/test/test_RegenerateGlobalIds.py
index 3cc4d9026f..e51e4c7a9c 100644
--- a/src/ifcpatch/test/test_RegenerateGlobalIds.py
+++ b/src/ifcpatch/test/test_RegenerateGlobalIds.py
@@ -17,12 +17,14 @@
# along with IfcOpenShell. If not, see .
import os
-import pytest
-import ifcpatch
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.root
import ifcopenshell.util.element
+import pytest
+
+import ifcpatch
import test.bootstrap
diff --git a/src/ifcpatch/test/test_ResetSpatialElementLocations.py b/src/ifcpatch/test/test_ResetSpatialElementLocations.py
index 1ae7c63c6f..5d446c9128 100644
--- a/src/ifcpatch/test/test_ResetSpatialElementLocations.py
+++ b/src/ifcpatch/test/test_ResetSpatialElementLocations.py
@@ -16,16 +16,17 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api
import ifcopenshell.api.aggregate
import ifcopenshell.api.geometry
import ifcopenshell.api.root
import ifcopenshell.api.unit
import ifcopenshell.util.placement
-import ifcpatch
import numpy as np
+import ifcpatch
+import test.bootstrap
+
class TestResetSpatialElementLocations(test.bootstrap.IFC4):
def test_run(self):
diff --git a/src/ifcpatch/test/test_SetFalseOrigin.py b/src/ifcpatch/test/test_SetFalseOrigin.py
index da4e621f04..1357ec39b0 100644
--- a/src/ifcpatch/test/test_SetFalseOrigin.py
+++ b/src/ifcpatch/test/test_SetFalseOrigin.py
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import test.bootstrap
import ifcopenshell.api
import ifcopenshell.api.aggregate
import ifcopenshell.api.context
@@ -27,9 +26,11 @@ import ifcopenshell.api.unit
import ifcopenshell.util.element
import ifcopenshell.util.geolocation
import ifcopenshell.util.placement
-import ifcpatch
import numpy as np
+import ifcpatch
+import test.bootstrap
+
class TestSetFalseOrigin(test.bootstrap.IFC4):
def test_run(self):
diff --git a/src/ifcpatch/test/test_TesselateElements.py b/src/ifcpatch/test/test_TesselateElements.py
index 83ea349137..7acdc899a7 100644
--- a/src/ifcpatch/test/test_TesselateElements.py
+++ b/src/ifcpatch/test/test_TesselateElements.py
@@ -16,19 +16,20 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcopenshell.util.representation
-import ifcpatch
import ifcopenshell
import ifcopenshell.api.context
import ifcopenshell.api.geometry
import ifcopenshell.api.profile
import ifcopenshell.api.root
import ifcopenshell.api.unit
-import test.bootstrap
import ifcopenshell.geom
import ifcopenshell.util.element
+import ifcopenshell.util.representation
from ifcopenshell.util.shape_builder import ShapeBuilder
+import ifcpatch
+import test.bootstrap
+
class TestTesselateElements(test.bootstrap.IFC4):
def test_run(self):
diff --git a/src/ifcpatch/test/test_UnsharePsets.py b/src/ifcpatch/test/test_UnsharePsets.py
index d2226223bc..fc40bdb74d 100644
--- a/src/ifcpatch/test/test_UnsharePsets.py
+++ b/src/ifcpatch/test/test_UnsharePsets.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-import ifcpatch
import ifcopenshell
import ifcopenshell.api.pset
import ifcopenshell.geom
import ifcopenshell.util.element
+
+import ifcpatch
import test.bootstrap
diff --git a/src/ifcpatch/test/test_ifcpatch.py b/src/ifcpatch/test/test_ifcpatch.py
index 90ff3937fa..4d7e98e55a 100644
--- a/src/ifcpatch/test/test_ifcpatch.py
+++ b/src/ifcpatch/test/test_ifcpatch.py
@@ -17,10 +17,12 @@
# along with IfcOpenShell. If not, see .
import tempfile
-import ifcopenshell.api.root
-import ifcpatch
from pathlib import Path
+import ifcopenshell.api.root
+
+import ifcpatch
+
class Test:
def test_parsing_docs(self):
diff --git a/src/ifcsverchok/__init__.py b/src/ifcsverchok/__init__.py
index c655baed52..660ea6f707 100644
--- a/src/ifcsverchok/__init__.py
+++ b/src/ifcsverchok/__init__.py
@@ -31,6 +31,7 @@ bl_info = {
import importlib
import logging
import types
+
import bpy
from bpy_extras.io_utils import ExportHelper
@@ -141,12 +142,14 @@ imported_modules = make_node_list()
reload_event = False
from os.path import splitext
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.aggregate
import ifcopenshell.api.root
import ifcopenshell.api.spatial
import ifcopenshell.util.element
+
from ifcsverchok.ifcstore import SvIfcStore
diff --git a/src/ifcsverchok/helper.py b/src/ifcsverchok/helper.py
index 411809e025..d20626f365 100644
--- a/src/ifcsverchok/helper.py
+++ b/src/ifcsverchok/helper.py
@@ -16,11 +16,12 @@
# You should have received a copy of the GNU General Public License
# along with IfcSverchok. If not, see .
+from typing import Any, TypeVar, Union
+
import bpy
import ifcopenshell
import sverchok.core.sockets
from sverchok.data_structure import zip_long_repeat
-from typing import Any, Union, TypeVar
T_socket = TypeVar("T_socket", bound=sverchok.core.sockets.SvSocketCommon)
diff --git a/src/ifcsverchok/ifcstore.py b/src/ifcsverchok/ifcstore.py
index e99a97aa6d..6fda9b2cea 100644
--- a/src/ifcsverchok/ifcstore.py
+++ b/src/ifcsverchok/ifcstore.py
@@ -16,13 +16,14 @@
# You should have received a copy of the GNU General Public License
# along with IfcSverchok. If not, see .
+from typing import Any, Union
+
import bpy
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.context
import ifcopenshell.util.representation
from ifcopenshell import template
-from typing import Union, Any
class SvIfcStore:
diff --git a/src/ifcsverchok/nodes/ifc/add.py b/src/ifcsverchok/nodes/ifc/add.py
index 5aab0da1f1..c6ed124eb7 100644
--- a/src/ifcsverchok/nodes/ifc/add.py
+++ b/src/ifcsverchok/nodes/ifc/add.py
@@ -18,11 +18,12 @@
import bpy
import ifcopenshell
+from bpy.props import StringProperty
+from sverchok.data_structure import updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
import ifcsverchok.helper as helper
-from bpy.props import StringProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode
class SvIfcAdd(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/add_pset.py b/src/ifcsverchok/nodes/ifc/add_pset.py
index 4e6f0d7674..3cd25cd4dc 100644
--- a/src/ifcsverchok/nodes/ifc/add_pset.py
+++ b/src/ifcsverchok/nodes/ifc/add_pset.py
@@ -16,22 +16,20 @@
# You should have received a copy of the GNU General Public License
# along with IfcSverchok. If not, see .
-import bpy
-
-import ifcopenshell
-import sverchok.core.sockets
-import ifcsverchok.helper
-import ifcsverchok.helper as helper
-from ifcsverchok.ifcstore import SvIfcStore
-
import json
+
+import bpy
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.pset
-
+import sverchok.core.sockets
from bpy.props import StringProperty
+from sverchok.data_structure import flatten_data, updateNode
from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode, flatten_data
+
+import ifcsverchok.helper
+import ifcsverchok.helper as helper
+from ifcsverchok.ifcstore import SvIfcStore
class SvIfcAddPset(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/add_spatial_element.py b/src/ifcsverchok/nodes/ifc/add_spatial_element.py
index c96b5e2d14..f53dc3fa16 100644
--- a/src/ifcsverchok/nodes/ifc/add_spatial_element.py
+++ b/src/ifcsverchok/nodes/ifc/add_spatial_element.py
@@ -16,27 +16,26 @@
# You should have received a copy of the GNU General Public License
# along with IfcSverchok. If not, see .
-import bpy
-
from itertools import chain
+import bpy
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.aggregate
import ifcopenshell.api.root
import ifcopenshell.api.spatial
import ifcopenshell.util.element
-import ifcsverchok.helper
-from ifcsverchok.ifcstore import SvIfcStore
-
from bpy.props import StringProperty
-from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import (
- updateNode,
+ ensure_min_nesting,
flatten_data,
repeat_last_for_length,
- ensure_min_nesting,
+ updateNode,
)
+from sverchok.node_tree import SverchCustomTreeNode
+
+import ifcsverchok.helper
+from ifcsverchok.ifcstore import SvIfcStore
class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/api.py b/src/ifcsverchok/nodes/ifc/api.py
index af0b8766dd..ce75275db4 100644
--- a/src/ifcsverchok/nodes/ifc/api.py
+++ b/src/ifcsverchok/nodes/ifc/api.py
@@ -16,17 +16,19 @@
# You should have received a copy of the GNU General Public License
# along with IfcSverchok. If not, see .
+import logging
+from typing import Any, Union
+
import bpy
import ifcopenshell
import ifcopenshell.api
import sverchok.core.sockets
+from bpy.props import EnumProperty, StringProperty
+from sverchok.data_structure import updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
import ifcsverchok.helper as helper
-from bpy.props import StringProperty, EnumProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode
-import logging
-from typing import Union, Any
logger = logging.getLogger("sverchok.ifc")
diff --git a/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py b/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py
index ab748ecd50..8d623ffe1e 100644
--- a/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py
+++ b/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py
@@ -19,31 +19,38 @@
from copy import deepcopy
from decimal import Context
from email.policy import default
+from itertools import chain, cycle
+
+import bonsai.core.geometry as core
+import bonsai.tool as tool
import bpy
import ifcopenshell
-import ifcsverchok.helper
import ifcopenshell.api
import ifcopenshell.api.context
import ifcopenshell.api.geometry
import ifcopenshell.util.representation
-from ifcsverchok.ifcstore import SvIfcStore
-import bonsai.tool as tool
-import bonsai.core.geometry as core
+from bonsai.bim.module.root.prop import get_contexts
from bpy.props import (
- StringProperty,
+ BoolProperty,
EnumProperty,
IntProperty,
- BoolProperty,
PointerProperty,
+ StringProperty,
+)
+from mathutils import Matrix
+from sverchok.core.socket_data import sv_get_socket
+from sverchok.data_structure import (
+ fixed_iter,
+ flat_iter,
+ flatten_data,
+ node_id,
+ updateNode,
+ zip_long_repeat,
)
from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode, flatten_data, fixed_iter, flat_iter
-from bonsai.bim.module.root.prop import get_contexts
-from sverchok.data_structure import zip_long_repeat, node_id
-from sverchok.core.socket_data import sv_get_socket
-from itertools import chain, cycle
-from mathutils import Matrix
+import ifcsverchok.helper
+from ifcsverchok.ifcstore import SvIfcStore
class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/by_guid.py b/src/ifcsverchok/nodes/ifc/by_guid.py
index 43bea96c84..029b1b11a5 100644
--- a/src/ifcsverchok/nodes/ifc/by_guid.py
+++ b/src/ifcsverchok/nodes/ifc/by_guid.py
@@ -20,12 +20,13 @@ import itertools
import bpy
import ifcopenshell
+from bpy.props import StringProperty
+from sverchok.data_structure import flatten_data, updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
import ifcsverchok.helper as helper
from ifcsverchok.ifcstore import SvIfcStore
-from bpy.props import StringProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode, flatten_data
class SvIfcByGuid(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/by_id.py b/src/ifcsverchok/nodes/ifc/by_id.py
index e985f4d0e6..78ce51415f 100644
--- a/src/ifcsverchok/nodes/ifc/by_id.py
+++ b/src/ifcsverchok/nodes/ifc/by_id.py
@@ -18,12 +18,13 @@
import bpy
+from bpy.props import StringProperty
+from sverchok.data_structure import flatten_data, updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
import ifcsverchok.helper as helper
from ifcsverchok.ifcstore import SvIfcStore
-from bpy.props import StringProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode, flatten_data
class SvIfcById(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/by_query.py b/src/ifcsverchok/nodes/ifc/by_query.py
index 95f9ca654f..1bdd88054a 100644
--- a/src/ifcsverchok/nodes/ifc/by_query.py
+++ b/src/ifcsverchok/nodes/ifc/by_query.py
@@ -19,11 +19,12 @@
import bpy
import ifcopenshell
import ifcopenshell.util.selector
+from bpy.props import StringProperty
+from sverchok.data_structure import updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
from ifcsverchok.ifcstore import SvIfcStore
-from bpy.props import StringProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode
class SvIfcByQuery(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/by_type.py b/src/ifcsverchok/nodes/ifc/by_type.py
index c4c6f9bdb7..2e6d9b43f4 100644
--- a/src/ifcsverchok/nodes/ifc/by_type.py
+++ b/src/ifcsverchok/nodes/ifc/by_type.py
@@ -18,11 +18,12 @@
import bpy
import ifcopenshell
-import ifcsverchok.helper
-from bpy.props import StringProperty, EnumProperty
-from ifcsverchok.ifcstore import SvIfcStore
-from sverchok.node_tree import SverchCustomTreeNode
+from bpy.props import EnumProperty, StringProperty
from sverchok.data_structure import updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
+import ifcsverchok.helper
+from ifcsverchok.ifcstore import SvIfcStore
def get_ifc_products(self, context):
diff --git a/src/ifcsverchok/nodes/ifc/create_entity.py b/src/ifcsverchok/nodes/ifc/create_entity.py
index 0bfb88b786..bc63b3bc08 100644
--- a/src/ifcsverchok/nodes/ifc/create_entity.py
+++ b/src/ifcsverchok/nodes/ifc/create_entity.py
@@ -17,25 +17,25 @@
# along with IfcSverchok. If not, see .
import bpy
-from mathutils import Matrix
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.geometry
import ifcopenshell.api.root
import ifcopenshell.util.schema
+from bpy.props import BoolProperty, StringProperty
+from mathutils import Matrix
+from sverchok.data_structure import (
+ ensure_min_nesting,
+ flatten_data,
+ repeat_last_for_length,
+ updateNode,
+)
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
import ifcsverchok.helper as helper
from ifcsverchok.ifcstore import SvIfcStore
-from bpy.props import StringProperty, BoolProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import (
- updateNode,
- flatten_data,
- repeat_last_for_length,
- ensure_min_nesting,
-)
-
class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
bl_idname = "SvIfcCreateEntity"
diff --git a/src/ifcsverchok/nodes/ifc/create_file.py b/src/ifcsverchok/nodes/ifc/create_file.py
index 50a77a5198..1d10d0fd3e 100644
--- a/src/ifcsverchok/nodes/ifc/create_file.py
+++ b/src/ifcsverchok/nodes/ifc/create_file.py
@@ -19,12 +19,13 @@
import bpy
import ifcopenshell
import ifcopenshell.guid
-import ifcsverchok.helper
-import ifcsverchok.helper as helper
import sverchok.core.sockets
from bpy.props import StringProperty
-from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
+import ifcsverchok.helper
+import ifcsverchok.helper as helper
class SvIfcCreateFileRefresh(bpy.types.Operator):
diff --git a/src/ifcsverchok/nodes/ifc/create_project.py b/src/ifcsverchok/nodes/ifc/create_project.py
index cc782de19d..4f0b19a398 100644
--- a/src/ifcsverchok/nodes/ifc/create_project.py
+++ b/src/ifcsverchok/nodes/ifc/create_project.py
@@ -22,9 +22,10 @@ import ifcopenshell.api
import ifcopenshell.api.context
import ifcopenshell.api.root
import ifcopenshell.api.unit
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
import ifcsverchok.helper as helper
-from sverchok.node_tree import SverchCustomTreeNode
class SvIfcCreateProject(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/create_shape.py b/src/ifcsverchok/nodes/ifc/create_shape.py
index 381fc1e11c..7b94008952 100644
--- a/src/ifcsverchok/nodes/ifc/create_shape.py
+++ b/src/ifcsverchok/nodes/ifc/create_shape.py
@@ -16,16 +16,18 @@
# You should have received a copy of the GNU General Public License
# along with IfcSverchok. If not, see .
-import bpy
import logging
+
+import bonsai.bim.import_ifc
+import bpy
import ifcopenshell
import ifcopenshell.geom
+from bpy.props import BoolProperty, PointerProperty, StringProperty
+from sverchok.data_structure import flatten_data, updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
from ifcsverchok.ifcstore import SvIfcStore
-import bonsai.bim.import_ifc
-from bpy.props import StringProperty, PointerProperty, BoolProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode, flatten_data
class SvIfcCreateShape(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/generate_guid.py b/src/ifcsverchok/nodes/ifc/generate_guid.py
index cd706bc6a4..26f50e8ae6 100644
--- a/src/ifcsverchok/nodes/ifc/generate_guid.py
+++ b/src/ifcsverchok/nodes/ifc/generate_guid.py
@@ -19,9 +19,10 @@
import bpy
import ifcopenshell
import ifcopenshell.guid
-import ifcsverchok.helper
from sverchok.node_tree import SverchCustomTreeNode
+import ifcsverchok.helper
+
class SvIfcGenerateGuid(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
bl_idname = "SvIfcGenerateGuid"
diff --git a/src/ifcsverchok/nodes/ifc/get_attribute.py b/src/ifcsverchok/nodes/ifc/get_attribute.py
index c4ec65e30e..e809500de3 100644
--- a/src/ifcsverchok/nodes/ifc/get_attribute.py
+++ b/src/ifcsverchok/nodes/ifc/get_attribute.py
@@ -19,11 +19,12 @@
import bpy
import ifcopenshell
import ifcopenshell.util.element
+from bpy.props import StringProperty
+from sverchok.data_structure import flatten_data, updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
from ifcsverchok.ifcstore import SvIfcStore
-from bpy.props import StringProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode, flatten_data
class SvIfcGetAttribute(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/get_property.py b/src/ifcsverchok/nodes/ifc/get_property.py
index a9a78e15b9..f99dff7aa3 100644
--- a/src/ifcsverchok/nodes/ifc/get_property.py
+++ b/src/ifcsverchok/nodes/ifc/get_property.py
@@ -19,11 +19,12 @@
import bpy
import ifcopenshell
import ifcopenshell.util.element
+from bpy.props import StringProperty
+from sverchok.data_structure import flatten_data, updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
from ifcsverchok.ifcstore import SvIfcStore
-from bpy.props import StringProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode, flatten_data
class SvIfcGetProperty(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/pick_ifc_class.py b/src/ifcsverchok/nodes/ifc/pick_ifc_class.py
index 3cbbf03af0..b24d499708 100644
--- a/src/ifcsverchok/nodes/ifc/pick_ifc_class.py
+++ b/src/ifcsverchok/nodes/ifc/pick_ifc_class.py
@@ -18,11 +18,12 @@
import bpy
import ifcopenshell
-import ifcsverchok.helper
from bpy.props import EnumProperty
-from ifcsverchok.ifcstore import SvIfcStore
-from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
+import ifcsverchok.helper
+from ifcsverchok.ifcstore import SvIfcStore
def get_ifc_products(self, context):
diff --git a/src/ifcsverchok/nodes/ifc/quick_project_setup.py b/src/ifcsverchok/nodes/ifc/quick_project_setup.py
index 49c621d8ba..5787e29187 100644
--- a/src/ifcsverchok/nodes/ifc/quick_project_setup.py
+++ b/src/ifcsverchok/nodes/ifc/quick_project_setup.py
@@ -18,15 +18,17 @@
from email.mime import application
+
import bpy
import ifcopenshell
import sverchok.core.sockets
+from bpy.props import StringProperty
+from ifcopenshell import template
+from sverchok.data_structure import updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
import ifcsverchok.helper as helper
-from bpy.props import StringProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode
-from ifcopenshell import template
class SvIfcQuickProjectSetup(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/read_entity.py b/src/ifcsverchok/nodes/ifc/read_entity.py
index 9ea2fa3490..38a703151d 100644
--- a/src/ifcsverchok/nodes/ifc/read_entity.py
+++ b/src/ifcsverchok/nodes/ifc/read_entity.py
@@ -18,11 +18,12 @@
import bpy
import ifcopenshell
+from bpy.props import StringProperty
+from sverchok.data_structure import ensure_min_nesting, flatten_data, updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
from ifcsverchok.ifcstore import SvIfcStore
-from bpy.props import StringProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode, ensure_min_nesting, flatten_data
class SvIfcReadEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/read_file.py b/src/ifcsverchok/nodes/ifc/read_file.py
index ab754d7278..758bd6b14f 100644
--- a/src/ifcsverchok/nodes/ifc/read_file.py
+++ b/src/ifcsverchok/nodes/ifc/read_file.py
@@ -19,11 +19,12 @@
import bpy
import ifcopenshell
import ifcopenshell.guid
+from bpy.props import StringProperty
+from sverchok.data_structure import updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
import ifcsverchok.helper as helper
-from bpy.props import StringProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode
class SvIfcReadFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/remove.py b/src/ifcsverchok/nodes/ifc/remove.py
index 2e76d28896..6a85086fd2 100644
--- a/src/ifcsverchok/nodes/ifc/remove.py
+++ b/src/ifcsverchok/nodes/ifc/remove.py
@@ -16,14 +16,16 @@
# You should have received a copy of the GNU General Public License
# along with IfcSverchok. If not, see .
+from typing import Union
+
import bpy
import ifcopenshell
+from bpy.props import StringProperty
+from sverchok.data_structure import updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
import ifcsverchok.helper as helper
-from bpy.props import StringProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode
-from typing import Union
class SvIfcRemove(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/select_blender_objects.py b/src/ifcsverchok/nodes/ifc/select_blender_objects.py
index 5067db7ccf..3a0053a514 100644
--- a/src/ifcsverchok/nodes/ifc/select_blender_objects.py
+++ b/src/ifcsverchok/nodes/ifc/select_blender_objects.py
@@ -16,15 +16,16 @@
# You should have received a copy of the GNU General Public License
# along with IfcSverchok. If not, see .
+import bonsai.tool as tool
import bpy
import ifcopenshell
import ifcopenshell.util.selector
-import bonsai.tool as tool
+from bpy.props import StringProperty
+from sverchok.data_structure import updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
import ifcsverchok.helper as helper
-from bpy.props import StringProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode
class SvIfcSelectBlenderObjectsRefresh(bpy.types.Operator):
diff --git a/src/ifcsverchok/nodes/ifc/sverchok_to_ifc.py b/src/ifcsverchok/nodes/ifc/sverchok_to_ifc.py
index f9a6701432..69ac5f37f3 100644
--- a/src/ifcsverchok/nodes/ifc/sverchok_to_ifc.py
+++ b/src/ifcsverchok/nodes/ifc/sverchok_to_ifc.py
@@ -18,15 +18,16 @@
import bpy
import ifcopenshell
-import ifcsverchok.helper
import ifcopenshell.api
import ifcopenshell.api.context
import ifcopenshell.api.geometry
import ifcopenshell.util.representation
-from ifcsverchok.ifcstore import SvIfcStore
-from bpy.props import StringProperty, EnumProperty, IntProperty, FloatVectorProperty
+from bpy.props import EnumProperty, FloatVectorProperty, IntProperty, StringProperty
+from sverchok.data_structure import ensure_min_nesting, updateNode
from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode, ensure_min_nesting
+
+import ifcsverchok.helper
+from ifcsverchok.ifcstore import SvIfcStore
class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifcsverchok/nodes/ifc/write_file.py b/src/ifcsverchok/nodes/ifc/write_file.py
index 245c8a9d62..3a25cd99cc 100644
--- a/src/ifcsverchok/nodes/ifc/write_file.py
+++ b/src/ifcsverchok/nodes/ifc/write_file.py
@@ -17,6 +17,7 @@
# along with IfcSverchok. If not, see .
from os.path import abspath, splitext
+
import bpy
import ifcopenshell
import ifcopenshell.api
@@ -24,12 +25,13 @@ import ifcopenshell.api.aggregate
import ifcopenshell.api.root
import ifcopenshell.api.spatial
import ifcopenshell.util.element
+from bpy.props import BoolProperty, StringProperty
+from sverchok.data_structure import flatten_data, updateNode
+from sverchok.node_tree import SverchCustomTreeNode
+
import ifcsverchok.helper
import ifcsverchok.helper as helper
from ifcsverchok.ifcstore import SvIfcStore
-from bpy.props import StringProperty, BoolProperty
-from sverchok.node_tree import SverchCustomTreeNode
-from sverchok.data_structure import updateNode, flatten_data
class SvIfcWriteFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
diff --git a/src/ifctester/ifctester/__main__.py b/src/ifctester/ifctester/__main__.py
index e0acdd5468..d961b5e667 100644
--- a/src/ifctester/ifctester/__main__.py
+++ b/src/ifctester/ifctester/__main__.py
@@ -18,13 +18,14 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcTester. If not, see .
-import time
import argparse
-import ifcopenshell
-from . import ids
-from . import reporter
+import time
from pathlib import Path
+import ifcopenshell
+
+from . import ids, reporter
+
parser = argparse.ArgumentParser(description="Uses an IDS to audit an IFC")
parser.add_argument("ids", type=str, help="Path to an IDS")
parser.add_argument("ifc", type=str, help="Path to an IFC", nargs="?")
diff --git a/src/ifctester/ifctester/facet.py b/src/ifctester/ifctester/facet.py
index 6b5536299d..b8c3ebad5d 100644
--- a/src/ifctester/ifctester/facet.py
+++ b/src/ifctester/ifctester/facet.py
@@ -17,15 +17,17 @@
# along with IfcTester. If not, see .
from __future__ import annotations
-import re
+
import builtins
-import ifcopenshell.util.unit
-import ifcopenshell.util.element
-import ifcopenshell.util.classification
+import re
from functools import lru_cache
-from xmlschema.validators import identities
-from typing import Union, Optional, Any, Literal, TYPE_CHECKING, TypedDict
from logging import Logger
+from typing import TYPE_CHECKING, Any, Literal, Optional, TypedDict, Union
+
+import ifcopenshell.util.classification
+import ifcopenshell.util.element
+import ifcopenshell.util.unit
+from xmlschema.validators import identities
if TYPE_CHECKING:
from .ids import Specification
diff --git a/src/ifctester/ifctester/ids.py b/src/ifctester/ifctester/ids.py
index 7aecf040d3..ea21aa15fd 100644
--- a/src/ifctester/ifctester/ids.py
+++ b/src/ifctester/ifctester/ids.py
@@ -17,28 +17,30 @@
# along with IfcTester. If not, see .
from __future__ import annotations
-import os
+
import datetime
-import ifcopenshell
-from xmlschema.validators.exceptions import XMLSchemaValidationError
-from xmlschema import XMLSchema
-from xmlschema import etree_tostring
+import os
+from typing import Any, Optional, Union
from xml.etree import ElementTree as ET
+
+import ifcopenshell
+from xmlschema import XMLSchema, etree_tostring
+from xmlschema.validators.exceptions import XMLSchemaValidationError
+
from .facet import (
- Facet,
- Entity,
Attribute,
+ Cardinality,
Classification,
- Property,
- PartOf,
+ Entity,
+ Facet,
+ FacetFailure,
Material,
+ PartOf,
+ Property,
Restriction,
get_pset,
get_psets,
- Cardinality,
- FacetFailure,
)
-from typing import Optional, Union, Any
cwd = os.path.dirname(os.path.realpath(__file__))
schema = None
diff --git a/src/ifctester/ifctester/reporter.py b/src/ifctester/ifctester/reporter.py
index 2ce8a8c45f..220d0f96a9 100644
--- a/src/ifctester/ifctester/reporter.py
+++ b/src/ifctester/ifctester/reporter.py
@@ -17,18 +17,21 @@
# along with IfcTester. If not, see .
from __future__ import annotations
+
+import datetime
+import math
import os
import re
import sys
-import math
-import datetime
+from typing import Literal, Optional, TypedDict, Union
+
import ifcopenshell
import ifcopenshell.util.element
import ifcopenshell.util.placement
import ifcopenshell.util.unit
-from .ids import Specification, Ids
+
from .facet import Facet, FacetFailure
-from typing import TypedDict, Union, Literal, Optional
+from .ids import Ids, Specification
cwd = os.path.dirname(os.path.realpath(__file__))
@@ -555,7 +558,7 @@ class Ods(Json):
def to_file(self, filepath: str) -> None:
from odf.opendocument import OpenDocumentSpreadsheet
from odf.style import Style, TableCellProperties
- from odf.table import Table, TableRow, TableCell
+ from odf.table import Table, TableCell, TableRow
from odf.text import P
self.doc = OpenDocumentSpreadsheet()
@@ -696,7 +699,7 @@ class OdsSummary(Json):
def to_file(self, filepath: str) -> None:
from odf.opendocument import OpenDocumentSpreadsheet
from odf.style import Style, TableCellProperties
- from odf.table import Table, TableRow, TableCell
+ from odf.table import Table, TableCell, TableRow
from odf.text import P
self.doc = OpenDocumentSpreadsheet()
diff --git a/src/ifctester/test/ids_doc_generator.py b/src/ifctester/test/ids_doc_generator.py
index fa95854d35..a8323fbeed 100644
--- a/src/ifctester/test/ids_doc_generator.py
+++ b/src/ifctester/test/ids_doc_generator.py
@@ -16,11 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcTester. If not, see .
+import functools
import os
import re
import uuid
-import pytest
-import functools
+from pathlib import Path
+from xml.dom.minidom import parseString
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.aggregate
@@ -32,15 +34,15 @@ import ifcopenshell.api.spatial
import ifcopenshell.api.type
import ifcopenshell.api.unit
import ifcopenshell.guid
-import ifctester
+import numpy as np
+import pytest
import test_facet
import test_ids
-import numpy as np
-from pathlib import Path
-from xml.dom.minidom import parseString
-from ifctester import ids
from ifcopenshell import validate
+import ifctester
+from ifctester import ids
+
outdir = "build"
diff --git a/src/ifctester/test/test_facet.py b/src/ifctester/test/test_facet.py
index 3d7518d99f..2e0a16ec85 100644
--- a/src/ifctester/test/test_facet.py
+++ b/src/ifctester/test/test_facet.py
@@ -18,6 +18,7 @@
import uuid
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.aggregate
@@ -33,9 +34,17 @@ import ifcopenshell.api.type
import ifcopenshell.api.unit
import ifcopenshell.guid
import ifcopenshell.util.pset
-import ifctester.ids
import ifctester.facet
-from ifctester.facet import Entity, Attribute, Classification, Property, PartOf, Material, Restriction
+import ifctester.ids
+from ifctester.facet import (
+ Attribute,
+ Classification,
+ Entity,
+ Material,
+ PartOf,
+ Property,
+ Restriction,
+)
def set_facet(facet):
diff --git a/src/ifctester/test/test_ids.py b/src/ifctester/test/test_ids.py
index 9985a14a2c..0a851a355c 100644
--- a/src/ifctester/test/test_ids.py
+++ b/src/ifctester/test/test_ids.py
@@ -17,13 +17,15 @@
# along with IfcTester. If not, see .
import os
-import pytest
-import xmlschema
+from typing import Optional
+
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.material
+import pytest
+import xmlschema
+
from ifctester import ids
-from typing import Optional
def run(
diff --git a/src/ifctester/webapp/public/worker/api.py b/src/ifctester/webapp/public/worker/api.py
index d5b77d846d..dafc61c646 100644
--- a/src/ifctester/webapp/public/worker/api.py
+++ b/src/ifctester/webapp/public/worker/api.py
@@ -1,11 +1,12 @@
+import xml.etree.ElementTree as ET
+
import ifcopenshell
import ifcopenshell.util
import ifcopenshell.util.attribute
import ifcopenshell.util.pset
import ifcopenshell.util.schema
-import xml.etree.ElementTree as ET
-from xmlschema.validators.exceptions import XMLSchemaValidationError
from ifctester.ids import Ids, IdsXmlValidationError, get_schema
+from xmlschema.validators.exceptions import XMLSchemaValidationError
# https://github.com/buildingSMART/IDS/blob/9914d568c7ac037acd97e58a0d16e9f93c3e3416/Schema/ids.xsd#L232
ifc_schemas = ["IFC2X3", "IFC4", "IFC4X3_ADD2"]
diff --git a/src/ifctester/webapp/serve.py b/src/ifctester/webapp/serve.py
index 245d50c38f..5b18f15545 100644
--- a/src/ifctester/webapp/serve.py
+++ b/src/ifctester/webapp/serve.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcTester. If not, see .
-import os
-import sys
import argparse
import mimetypes
+import os
+import sys
bonsai_lib_path = os.environ.get("BONSAI_LIB_PATH")
print(os.environ)
@@ -29,7 +29,7 @@ bonsai_version = os.environ.get("BONSAI_VERSION")
if bonsai_lib_path:
sys.path.insert(0, bonsai_lib_path)
-from flask import Flask, send_from_directory, send_file
+from flask import Flask, send_file, send_from_directory
# Browsers expecting this specific MIME type for .mjs files,
# otherwise they fail to load.
diff --git a/src/opencdeserver/api/app/api/bcf.py b/src/opencdeserver/api/app/api/bcf.py
index 58a907730f..81047e1f23 100644
--- a/src/opencdeserver/api/app/api/bcf.py
+++ b/src/opencdeserver/api/app/api/bcf.py
@@ -1,19 +1,16 @@
from uuid import UUID
-from fastapi import APIRouter, Depends, UploadFile, HTTPException
+
+from fastapi import APIRouter, Depends, HTTPException, UploadFile
from fastapi.responses import FileResponse
-
-from security.secure import get_current_active_user
-
from models.bcf_request import *
from models.bcf_response import *
-from models.request import *
from models.other import *
-
+from models.request import *
from repository.bcf import bcf_db
+from security.secure import get_current_active_user
from api.logging import LoggingRoute
-
router = APIRouter(route_class=LoggingRoute)
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
diff --git a/src/opencdeserver/api/app/api/documents.py b/src/opencdeserver/api/app/api/documents.py
index c22ab0506f..2c60fe0139 100644
--- a/src/opencdeserver/api/app/api/documents.py
+++ b/src/opencdeserver/api/app/api/documents.py
@@ -1,27 +1,22 @@
import collections
import os
import shutil
-import traceback
import sys
-
-from fastapi import HTTPException, status, APIRouter, Request, Depends
-from fastapi import UploadFile, Form
-from fastapi.responses import FileResponse, HTMLResponse
-from fastapi.templating import Jinja2Templates
-from fastapi.encoders import jsonable_encoder
-
+import traceback
from typing import Union
from uuid import UUID, uuid4
-from pydantic import ValidationError
-from security.secure import get_current_active_user
-
-from repository.documents import doc_db
-
-from models.documents_request import *
-from models.documents_response import *
+from fastapi import APIRouter, Depends, Form, HTTPException, Request, UploadFile, status
+from fastapi.encoders import jsonable_encoder
+from fastapi.responses import FileResponse, HTMLResponse
+from fastapi.templating import Jinja2Templates
from models.documents_common import *
from models.documents_other import *
+from models.documents_request import *
+from models.documents_response import *
+from pydantic import ValidationError
+from repository.documents import doc_db
+from security.secure import get_current_active_user
from api.logging import LoggingRoute
diff --git a/src/opencdeserver/api/app/api/foundation.py b/src/opencdeserver/api/app/api/foundation.py
index 25c6036ac8..7d63eb749d 100644
--- a/src/opencdeserver/api/app/api/foundation.py
+++ b/src/opencdeserver/api/app/api/foundation.py
@@ -1,21 +1,16 @@
import os
-
from typing import Optional
-
-from fastapi import APIRouter, Request, Form
-from fastapi import Depends, HTTPException, status
-from fastapi.security import HTTPBasicCredentials, HTTPBasic
-from fastapi.responses import HTMLResponse
-from fastapi.templating import Jinja2Templates
-
-from models.request import *
-
-from repository.foundation import foundation_db
-from security.secure import authenticate_user, get_current_active_user
-
from uuid import uuid4
+
+from fastapi import APIRouter, Depends, Form, HTTPException, Request, status
+from fastapi.responses import HTMLResponse
+from fastapi.security import HTTPBasic, HTTPBasicCredentials
+from fastapi.templating import Jinja2Templates
+from models.request import *
+from repository.foundation import foundation_db
+from security.secure import authenticate_user, get_current_active_user, get_secrets
+
from api.logging import LoggingRoute
-from security.secure import get_secrets
secrets = get_secrets()
diff --git a/src/opencdeserver/api/app/api/logging.py b/src/opencdeserver/api/app/api/logging.py
index de368ccb9c..8d85cbf80b 100644
--- a/src/opencdeserver/api/app/api/logging.py
+++ b/src/opencdeserver/api/app/api/logging.py
@@ -1,11 +1,12 @@
-from fastapi import FastAPI, APIRouter, Response, Request
+import logging
+from collections.abc import Callable
+
+import httpx
+from fastapi import APIRouter, FastAPI, Request, Response
+from fastapi.routing import APIRoute
from starlette.background import BackgroundTask
from starlette.responses import StreamingResponse
-from fastapi.routing import APIRoute
from starlette.types import Message
-from collections.abc import Callable
-import logging
-import httpx
def log_info(req_body, res_body, route_url):
diff --git a/src/opencdeserver/api/app/api/user.py b/src/opencdeserver/api/app/api/user.py
index 5628a4cf05..def1a1573e 100644
--- a/src/opencdeserver/api/app/api/user.py
+++ b/src/opencdeserver/api/app/api/user.py
@@ -1,23 +1,19 @@
import collections
import os
-import traceback
import sys
-
-from fastapi import APIRouter, Request, Depends
-from fastapi.responses import FileResponse, HTMLResponse
-from fastapi.templating import Jinja2Templates
-from fastapi.encoders import jsonable_encoder
-
+import traceback
from uuid import UUID
-from pydantic import ValidationError
-from security.secure import get_current_active_user
-
-from repository.documents import doc_db
-
+from fastapi import APIRouter, Depends, Request
+from fastapi.encoders import jsonable_encoder
+from fastapi.responses import FileResponse, HTMLResponse
+from fastapi.templating import Jinja2Templates
+from models.documents_other import *
from models.documents_request import *
from models.documents_response import *
-from models.documents_other import *
+from pydantic import ValidationError
+from repository.documents import doc_db
+from security.secure import get_current_active_user
from api.logging import LoggingRoute
diff --git a/src/opencdeserver/api/app/database/neo4j.py b/src/opencdeserver/api/app/database/neo4j.py
index 9ad68759d2..ff8a4e7cde 100644
--- a/src/opencdeserver/api/app/database/neo4j.py
+++ b/src/opencdeserver/api/app/database/neo4j.py
@@ -1,15 +1,12 @@
-import jsonpickle
import os
-import pytz
-
-from dateutil import parser
-from uuid import uuid4, UUID
-
-from neo4j import GraphDatabase
-
from datetime import datetime, timezone
+from uuid import UUID, uuid4
+import jsonpickle
+import pytz
+from dateutil import parser
from models.request import UserInDB
+from neo4j import GraphDatabase
from security.secrets import get_secrets
get_secrets()
diff --git a/src/opencdeserver/api/app/ifcgraph/ifcgraph.py b/src/opencdeserver/api/app/ifcgraph/ifcgraph.py
index afe1c36749..e39878a286 100644
--- a/src/opencdeserver/api/app/ifcgraph/ifcgraph.py
+++ b/src/opencdeserver/api/app/ifcgraph/ifcgraph.py
@@ -18,11 +18,12 @@
# Some modifications have been made to the code.
#
-from py2neo.data import Node, Relationship
from uuid import uuid4
+
import ifcopenshell
import ifcopenshell.util.schema
from py2neo import Graph
+from py2neo.data import Node, Relationship
# Create the basic node with literal attributes and the class hierarchy
diff --git a/src/opencdeserver/api/app/main.py b/src/opencdeserver/api/app/main.py
index 4862106a55..2d189b8198 100644
--- a/src/opencdeserver/api/app/main.py
+++ b/src/opencdeserver/api/app/main.py
@@ -1,12 +1,9 @@
+from api import bcf, documents, foundation
from fastapi import FastAPI, Request
-from fastapi.responses import HTMLResponse, FileResponse
from fastapi.middleware.cors import CORSMiddleware
+from fastapi.responses import FileResponse, HTMLResponse
from fastapi.templating import Jinja2Templates
-from api import foundation
-from api import bcf
-from api import documents
-
endpoint_metadata = [
{"name": "api_versions_get", "description": "/foundation/versions"},
{"name": "foundation_auth_get", "description": "/foundation/1.0/auth"},
diff --git a/src/opencdeserver/api/app/models/bcf_common.py b/src/opencdeserver/api/app/models/bcf_common.py
index 30df15b565..d93d2c3dff 100644
--- a/src/opencdeserver/api/app/models/bcf_common.py
+++ b/src/opencdeserver/api/app/models/bcf_common.py
@@ -1,6 +1,7 @@
-from pydantic import BaseModel
-from typing import Optional
from enum import Enum
+from typing import Optional
+
+from pydantic import BaseModel
class BimSnippet(BaseModel):
diff --git a/src/opencdeserver/api/app/models/bcf_request.py b/src/opencdeserver/api/app/models/bcf_request.py
index 52fd9cad84..aa14bedd83 100644
--- a/src/opencdeserver/api/app/models/bcf_request.py
+++ b/src/opencdeserver/api/app/models/bcf_request.py
@@ -1,7 +1,21 @@
-from pydantic import BaseModel
from typing import Optional
-from models.bcf_common import BimSnippet, BitmapType, Location, Direction, SnapshotType, Component
-from models.bcf_common import Coloring, OrthogonalCamera, Visibility, PerspectiveCamera, Line, ClippingPlane
+
+from pydantic import BaseModel
+
+from models.bcf_common import (
+ BimSnippet,
+ BitmapType,
+ ClippingPlane,
+ Coloring,
+ Component,
+ Direction,
+ Line,
+ Location,
+ OrthogonalCamera,
+ PerspectiveCamera,
+ SnapshotType,
+ Visibility,
+)
class ProjectPUT(BaseModel):
diff --git a/src/opencdeserver/api/app/models/documents_common.py b/src/opencdeserver/api/app/models/documents_common.py
index 1e269babad..a32a3551be 100644
--- a/src/opencdeserver/api/app/models/documents_common.py
+++ b/src/opencdeserver/api/app/models/documents_common.py
@@ -1,6 +1,6 @@
-from pydantic import BaseModel, Field, constr
from typing import Optional
+from pydantic import BaseModel, Field, constr
# This file contains models used in both requests and responses during upload and download of documents.
diff --git a/src/opencdeserver/api/app/models/documents_not_used.py b/src/opencdeserver/api/app/models/documents_not_used.py
index e0c78ba09f..902eb23137 100644
--- a/src/opencdeserver/api/app/models/documents_not_used.py
+++ b/src/opencdeserver/api/app/models/documents_not_used.py
@@ -1,7 +1,8 @@
from typing import Optional
-from pydantic import BaseModel
-from models.documents_common import Document, DocumentVersion
+from pydantic import BaseModel
+
+from models.documents_common import Document, DocumentVersion
# This file contains models that are not used at all, at least not yet.
diff --git a/src/opencdeserver/api/app/models/documents_other.py b/src/opencdeserver/api/app/models/documents_other.py
index 9530268df7..253e5ecd80 100644
--- a/src/opencdeserver/api/app/models/documents_other.py
+++ b/src/opencdeserver/api/app/models/documents_other.py
@@ -1,10 +1,10 @@
-from pydantic import BaseModel, Field
from typing import Optional
-from models.documents_common import CallbackLink, Document
-from models.documents_request import FileToUpload, DocumentMetadataEntry
-from models.request import User
+from pydantic import BaseModel, Field
+from models.documents_common import CallbackLink, Document
+from models.documents_request import DocumentMetadataEntry, FileToUpload
+from models.request import User
# This file contains models that are neither used in requests nor in responses,
# and they can be used during both upload and download of documents.
diff --git a/src/opencdeserver/api/app/models/documents_request.py b/src/opencdeserver/api/app/models/documents_request.py
index 6eb9210a63..e58fe3af2a 100644
--- a/src/opencdeserver/api/app/models/documents_request.py
+++ b/src/opencdeserver/api/app/models/documents_request.py
@@ -1,10 +1,10 @@
-from pydantic import BaseModel, Field, constr
-from typing import Optional
from enum import Enum
+from typing import Optional
+
+from pydantic import BaseModel, Field, constr
from models.documents_common import CallbackLink
-
# This file contains models used in requests during upload and download of documents.
diff --git a/src/opencdeserver/api/app/models/documents_response.py b/src/opencdeserver/api/app/models/documents_response.py
index 2e98c70583..a2a53381ca 100644
--- a/src/opencdeserver/api/app/models/documents_response.py
+++ b/src/opencdeserver/api/app/models/documents_response.py
@@ -1,10 +1,10 @@
-from pydantic import BaseModel, Field, constr
-from typing import Optional
from enum import Enum
+from typing import Optional
+
+from pydantic import BaseModel, Field, constr
from models.documents_common import DocumentVersion, LinkData
-
# This file contains models used in responses during upload and download of documents.
diff --git a/src/opencdeserver/api/app/models/foundation_other.py b/src/opencdeserver/api/app/models/foundation_other.py
index 486a9b82f2..f6a894b5ad 100644
--- a/src/opencdeserver/api/app/models/foundation_other.py
+++ b/src/opencdeserver/api/app/models/foundation_other.py
@@ -1,4 +1,5 @@
from __future__ import annotations
+
from pydantic import BaseModel
diff --git a/src/opencdeserver/api/app/models/other.py b/src/opencdeserver/api/app/models/other.py
index c71593ce70..024db30398 100644
--- a/src/opencdeserver/api/app/models/other.py
+++ b/src/opencdeserver/api/app/models/other.py
@@ -1,4 +1,5 @@
from __future__ import annotations
+
from pydantic import BaseModel
diff --git a/src/opencdeserver/api/app/models/request.py b/src/opencdeserver/api/app/models/request.py
index 40271cf37a..616df5ef15 100644
--- a/src/opencdeserver/api/app/models/request.py
+++ b/src/opencdeserver/api/app/models/request.py
@@ -1,4 +1,5 @@
from __future__ import annotations
+
from pydantic import BaseModel
diff --git a/src/opencdeserver/api/app/repository/bcf.py b/src/opencdeserver/api/app/repository/bcf.py
index 80f9d172a1..a65c43d115 100644
--- a/src/opencdeserver/api/app/repository/bcf.py
+++ b/src/opencdeserver/api/app/repository/bcf.py
@@ -1,13 +1,10 @@
import base64
import os
-import jsonpickle
-
-from fastapi import UploadFile, HTTPException
-
from uuid import UUID, uuid4
+import jsonpickle
from database.neo4j import MyDB, driver
-
+from fastapi import HTTPException, UploadFile
from models.bcf_request import *
from models.bcf_response import *
from models.request import *
diff --git a/src/opencdeserver/api/app/repository/documents.py b/src/opencdeserver/api/app/repository/documents.py
index 39f5576065..95c669a7bc 100644
--- a/src/opencdeserver/api/app/repository/documents.py
+++ b/src/opencdeserver/api/app/repository/documents.py
@@ -1,22 +1,17 @@
-import os
import math
-
-from uuid import UUID, uuid4
+import os
from typing import Union
-
-from fastapi import HTTPException
-
-from database.neo4j import MyDB, driver
-
-from models.documents_request import *
-from models.documents_response import *
-from models.documents_common import *
-from models.documents_other import *
+from uuid import UUID, uuid4
import ifcopenshell
-from py2neo import Graph
-
+from database.neo4j import MyDB, driver
+from fastapi import HTTPException
from ifcgraph.ifcgraph import create_full_graph
+from models.documents_common import *
+from models.documents_other import *
+from models.documents_request import *
+from models.documents_response import *
+from py2neo import Graph
class DOCDB(MyDB):
diff --git a/src/opencdeserver/api/app/repository/foundation.py b/src/opencdeserver/api/app/repository/foundation.py
index 2554bfee8d..d80dc78c24 100644
--- a/src/opencdeserver/api/app/repository/foundation.py
+++ b/src/opencdeserver/api/app/repository/foundation.py
@@ -1,19 +1,14 @@
-import os
import hashlib
-
+import os
from datetime import timedelta
-from fastapi import HTTPException
-
from database.neo4j import MyDB, driver
-from security.secure import create_access_token
+from fastapi import HTTPException
from jose import jwt
-
-from security.secrets import get_secrets
-from security.secure import credentials_exception
-
from models.foundation_other import *
from models.other import *
+from security.secrets import get_secrets
+from security.secure import create_access_token, credentials_exception
secrets = get_secrets()
diff --git a/src/opencdeserver/api/app/security/secure.py b/src/opencdeserver/api/app/security/secure.py
index 77c225ee24..fec837b868 100644
--- a/src/opencdeserver/api/app/security/secure.py
+++ b/src/opencdeserver/api/app/security/secure.py
@@ -1,17 +1,15 @@
from __future__ import annotations
-from fastapi import Depends, HTTPException, status, Security
-from fastapi.security import OAuth2AuthorizationCodeBearer, SecurityScopes
+import os
from datetime import datetime, timedelta
-from passlib.context import CryptContext
-from jose import jwt, JWTError
-
-from models.other import TokenData
-from models.request import User
from database.neo4j import db
-import os
-
+from fastapi import Depends, HTTPException, Security, status
+from fastapi.security import OAuth2AuthorizationCodeBearer, SecurityScopes
+from jose import JWTError, jwt
+from models.other import TokenData
+from models.request import User
+from passlib.context import CryptContext
from security.secrets import get_secrets
secrets = get_secrets()
diff --git a/src/pyodide/demo-app/context.py b/src/pyodide/demo-app/context.py
index 8cece9ef68..f330c21940 100644
--- a/src/pyodide/demo-app/context.py
+++ b/src/pyodide/demo-app/context.py
@@ -1,4 +1,5 @@
import ifcopenshell
+import ifcopenshell.api
import ifcopenshell.api.aggregate
import ifcopenshell.api.context
import ifcopenshell.api.feature
@@ -8,12 +9,9 @@ import ifcopenshell.api.spatial
import ifcopenshell.api.type
import ifcopenshell.api.unit
import ifcopenshell.geom
-import ifcopenshell.api
import ifcopenshell.util.representation
import ifcopenshell.util.unit
-
import numpy as np
-
import propertygroups
O = 0.0, 0.0, 0.0
diff --git a/src/pyodide/demo-app/tests/missing_files.py b/src/pyodide/demo-app/tests/missing_files.py
index ab603fa09e..87f7cbdbf8 100644
--- a/src/pyodide/demo-app/tests/missing_files.py
+++ b/src/pyodide/demo-app/tests/missing_files.py
@@ -1,6 +1,6 @@
async def test_pset():
- import ifcopenshell.api.pset
import ifcopenshell.api.material
+ import ifcopenshell.api.pset
errors = []
try:
diff --git a/test/bpy.py b/test/bpy.py
index 44389c36b7..b706c23e58 100644
--- a/test/bpy.py
+++ b/test/bpy.py
@@ -24,16 +24,20 @@
###############################################################################
import os
-import bpy
import sys
import time
-try: from io_import_scene_ifc import import_ifc
-except:
+
+import bpy
+
+try:
+ from io_import_scene_ifc import import_ifc
+except:
print("[Error] Unable to import IfcOpenShell")
sys.exit(1)
-from mathutils import Vector as V
from math import radians
+from mathutils import Vector as V
+
scn = bpy.context.scene
for ob in bpy.data.objects:
@@ -49,8 +53,8 @@ if not succes:
sys.exit(1)
dt = time.time()-t1
-print ("[Notice] Conversion took %.2f seconds"%dt)
-
+print ("[Notice] Conversion took %.2f seconds"%dt)
+
cam = bpy.data.cameras.new('cam')
cam.angle = radians(45)
cam_ob = bpy.data.objects.new('cam',cam)
@@ -72,7 +76,7 @@ def material(name,settings):
if not m: return
for k,v in settings.items():
setattr(m,k,v)
-
+
material("IfcWall",{"diffuse_color":[1,1,1],"diffuse_intensity":1})
material("IfcWallStandardCase",{"diffuse_color":[1,1,1],"diffuse_intensity":1})
material("IfcSite",{"diffuse_color":[0.4,0.5,0.25]})
diff --git a/test/run.py b/test/run.py
index 102529d9f9..320b8decc4 100644
--- a/test/run.py
+++ b/test/run.py
@@ -26,13 +26,13 @@
# #
###############################################################################
-import os
-import sys
-import shutil
import inspect
+import os
+import shutil
import subprocess
-from zipfile import ZipFile
+import sys
from urllib.request import urlretrieve
+from zipfile import ZipFile
# Test whether Blender and IfcOpenShell are installed
if subprocess.call(['blender','-b','-P','bpy.py','TEST']) != 0:
diff --git a/win/build-all-win.py b/win/build-all-win.py
index 5c2c6ababa..087f869ac4 100644
--- a/win/build-all-win.py
+++ b/win/build-all-win.py
@@ -11,7 +11,7 @@ from zipfile import ZipFile
assert Path.cwd() == Path(__file__).parent, "Run this script from the 'win' directory."
-PYTHON_VERSIONS = ["3.9.13", "3.10.3", "3.11.8", "3.12.1", "3.13.0", "3.14.0"]
+PYTHON_VERSIONS = ["3.10.3", "3.11.8", "3.12.1", "3.13.0", "3.14.0"]
REPO_PATH = Path(__file__).parent.parent
REPO_WIN = REPO_PATH / "win"
VERSION = (REPO_PATH / "VERSION").read_text().strip()