Track ifcopenshell.file creation time for unique iden

This commit is contained in:
Thomas Krijnen
2025-08-16 13:33:10 +02:00
parent bd0e16cee5
commit 126accd6a2
+18 -3
View File
@@ -20,12 +20,13 @@ from __future__ import annotations
import os import os
import re import re
import numbers import numbers
import time
import zipfile import zipfile
import functools import functools
import ifcopenshell import ifcopenshell
import weakref import weakref
from pathlib import Path from pathlib import Path
from typing import Any, Optional, TYPE_CHECKING, Union, overload, Literal, TypedDict from typing import Any, Optional, TYPE_CHECKING, Union, overload, Literal, TypedDict, Tuple
from collections.abc import Callable, Generator from collections.abc import Callable, Generator
# py39 compat: re-enable when support is dropped # py39 compat: re-enable when support is dropped
@@ -354,7 +355,21 @@ class file:
self.future = [] self.future = []
self.transaction: Optional[Transaction] = None self.transaction: Optional[Transaction] = None
file_dict[self.wrapped_data.file_pointer()] = weakref.ref(self) # we store a tuple of C++ file pointer address and creation time stamp so that
# when memory addresses get recycled we do not run into collisions when the
# address is used as a cache key.
file_dict[self.wrapped_data.file_pointer()] = (weakref.ref(self), time.monotonic_ns())
@property
def identifier(self) -> Tuple[int, int]:
"""Pair of C++ file pointer address and creation time stamp to uniquely identify a file
over the life time of ifcopenshell module that should be mostly safe except in pathological
cases
Returns:
Tuple[int, int]: Pair of C++ file pointer address and creation time stamp
"""
return (self.wrapped_data.file_pointer(), file_dict[self.wrapped_data.file_pointer()][1])
def __del__(self) -> None: def __del__(self) -> None:
# Avoid infinite recursion if file is failed to initialize # Avoid infinite recursion if file is failed to initialize
@@ -772,7 +787,7 @@ class file:
@staticmethod @staticmethod
def from_pointer(address: int) -> file: def from_pointer(address: int) -> file:
assert (f := file_dict[address]()) is not None assert (f := file_dict[address][0]()) is not None
return f return f
def to_string(self) -> str: def to_string(self) -> str: