mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 06:58:56 +00:00
Hacks and fixes to get python code back in reasonable state
This commit is contained in:
@@ -87,10 +87,6 @@ class entity_instance_mixin:
|
|||||||
print(wall.__class__) # <class 'ifcopenshell.entity_instance'>
|
print(wall.__class__) # <class 'ifcopenshell.entity_instance'>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@property
|
|
||||||
def file(self):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def __getattr__(self, name: str) -> Any:
|
def __getattr__(self, name: str) -> Any:
|
||||||
if name in ("this", "thisown") or name.startswith("_swig_"):
|
if name in ("this", "thisown") or name.startswith("_swig_"):
|
||||||
return object.__getattr__(self, name)
|
return object.__getattr__(self, name)
|
||||||
@@ -300,15 +296,6 @@ class entity_instance_mixin:
|
|||||||
__rge__ = functools.partialmethod(compare, op=operator.ge, reverse=True)
|
__rge__ = functools.partialmethod(compare, op=operator.ge, reverse=True)
|
||||||
__rgt__ = functools.partialmethod(compare, op=operator.gt, reverse=True)
|
__rgt__ = functools.partialmethod(compare, op=operator.gt, reverse=True)
|
||||||
|
|
||||||
def __hash__(self):
|
|
||||||
# Proper entity instances have a stable identity by means of the numeric
|
|
||||||
# step id. Selected type instances (such as IfcPropertySingleValue.NominalValue
|
|
||||||
# always have id=0, so we hash <type, value, file pointer>
|
|
||||||
if id_ := self.id():
|
|
||||||
return hash((id_, self.file_pointer()))
|
|
||||||
else:
|
|
||||||
return hash((self.is_a(), self[0], self.file_pointer()))
|
|
||||||
|
|
||||||
def __dir__(self):
|
def __dir__(self):
|
||||||
return sorted(
|
return sorted(
|
||||||
set(
|
set(
|
||||||
|
|||||||
@@ -504,13 +504,30 @@ class file_mixin:
|
|||||||
to_delete: Union[set[ifcopenshell.entity_instance], None] = None
|
to_delete: Union[set[ifcopenshell.entity_instance], None] = None
|
||||||
"""Entities for batch removal."""
|
"""Entities for batch removal."""
|
||||||
|
|
||||||
|
registry = {}
|
||||||
|
|
||||||
|
def post_init(self, iden):
|
||||||
|
if state := self.registry.get(iden):
|
||||||
|
self.state = state
|
||||||
|
else:
|
||||||
|
self.state = self.registry[iden] = [[],[],None]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def history(self):
|
||||||
|
return self.state[0]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def future(self):
|
||||||
|
return self.state[1]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def transaction(self):
|
||||||
|
return self.state[2]
|
||||||
|
|
||||||
def post_init(self):
|
@transaction.setter
|
||||||
self.history = []
|
def transaction(self, v):
|
||||||
self.future = []
|
self.state[2] = v
|
||||||
self.transaction: Optional[Transaction] = None
|
|
||||||
|
|
||||||
def set_history_size(self, size: int) -> None:
|
def set_history_size(self, size: int) -> None:
|
||||||
self.history_size = size
|
self.history_size = size
|
||||||
while len(self.history) > self.history_size:
|
while len(self.history) > self.history_size:
|
||||||
@@ -670,7 +687,7 @@ class file_mixin:
|
|||||||
if attr[0:6] == "create":
|
if attr[0:6] == "create":
|
||||||
return functools.partial(self.create_entity, attr[6:])
|
return functools.partial(self.create_entity, attr[6:])
|
||||||
else:
|
else:
|
||||||
return getattr(self, attr)
|
raise AttributeError
|
||||||
|
|
||||||
def __getitem__(self, key: Union[numbers.Integral, str, bytes]) -> entity_instance:
|
def __getitem__(self, key: Union[numbers.Integral, str, bytes]) -> entity_instance:
|
||||||
if isinstance(key, numbers.Integral):
|
if isinstance(key, numbers.Integral):
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from .file import file
|
from ifcopenshell import file
|
||||||
from .guid import compress
|
from .guid import compress
|
||||||
from .ifcopenshell_wrapper import version
|
from .ifcopenshell_wrapper import version
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import ifcopenshell
|
|||||||
import ifcopenshell.ifcopenshell_wrapper as W
|
import ifcopenshell.ifcopenshell_wrapper as W
|
||||||
import ifcopenshell.util.schema
|
import ifcopenshell.util.schema
|
||||||
import ifcopenshell.util.type
|
import ifcopenshell.util.type
|
||||||
from ifcopenshell.entity_instance import entity_instance
|
from ifcopenshell import entity_instance
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from typing import Optional, Literal, NamedTuple, Union
|
from typing import Optional, Literal, NamedTuple, Union
|
||||||
|
|
||||||
|
|||||||
@@ -255,8 +255,8 @@ private:
|
|||||||
|
|
||||||
express::Base create(const std::string& entity_name) {
|
express::Base create(const std::string& entity_name) {
|
||||||
const IfcParse::declaration* decl = $self->schema()->declaration_by_name(entity_name);
|
const IfcParse::declaration* decl = $self->schema()->declaration_by_name(entity_name);
|
||||||
if (!decl || !decl->as_entity()) {
|
if (!decl || !(decl->as_entity() || decl->as_type_declaration())) {
|
||||||
throw IfcParse::IfcException("No such entity declaration: '" + entity_name + "' in schema '" + $self->schema()->name());
|
throw IfcParse::IfcException("No such entity or type declaration: '" + entity_name + "' in schema '" + $self->schema()->name());
|
||||||
}
|
}
|
||||||
return $self->create(decl);
|
return $self->create(decl);
|
||||||
}
|
}
|
||||||
@@ -343,21 +343,22 @@ private:
|
|||||||
%pythoncode %{
|
%pythoncode %{
|
||||||
schema = property(schema_name)
|
schema = property(schema_name)
|
||||||
header = property(header)
|
header = property(header)
|
||||||
|
_registry = {}
|
||||||
|
|
||||||
old_init = __init__
|
_old_init = __init__
|
||||||
def __init__(self, schema=None, schema_version=None):
|
def __init__(self, schema=None, schema_version=None):
|
||||||
self.old_init(*filter(None, (schema, schema_version)))
|
self._old_init(*filter(None, (schema, schema_version)))
|
||||||
self.post_init()
|
|
||||||
|
def __setattr__(self, k, v):
|
||||||
|
object.__setattr__(self, k, v)
|
||||||
|
if k == 'this':
|
||||||
|
# only now we know the identity of the object and we set our python-side attributes based on a python-side map
|
||||||
|
self.post_init(int(v))
|
||||||
%}
|
%}
|
||||||
}
|
}
|
||||||
|
|
||||||
%extend express::Base {
|
%extend express::Base {
|
||||||
|
|
||||||
%pythoncode %{
|
|
||||||
# Will be assigned when `ifcopenshell.entity_instance` is created.
|
|
||||||
file = None
|
|
||||||
%}
|
|
||||||
|
|
||||||
// 0 = not found
|
// 0 = not found
|
||||||
// 1 = regular forward attribute
|
// 1 = regular forward attribute
|
||||||
// 2 = inverse attribute
|
// 2 = inverse attribute
|
||||||
@@ -479,6 +480,22 @@ private:
|
|||||||
return $self->identity() == other.identity();
|
return $self->identity() == other.identity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t __hash__() const {
|
||||||
|
if (!self->declaration().as_entity()) {
|
||||||
|
return boost::hash<std::tuple<uint32_t, void*>>{}({self->identity(), self->file()});
|
||||||
|
} else {
|
||||||
|
return self->get_attribute_value(0).apply_visitor([&](const auto& val){
|
||||||
|
using U = std::decay_t<decltype(val)>;
|
||||||
|
if constexpr (std::is_same_v<U, Blank> || std::is_same_v<U, Derived> || std::is_same_v<U, boost::logic::tribool> || std::is_same_v<U, EnumerationReference> || std::is_same_v<U, empty_aggregate_t> || std::is_same_v<U, empty_aggregate_of_aggregate_t>) {
|
||||||
|
// @todo
|
||||||
|
return boost::hash<std::tuple<size_t, size_t, void*>>{}({self->declaration().index_in_schema(), 0, self->file()});
|
||||||
|
} else {
|
||||||
|
return boost::hash<std::tuple<size_t, decltype(val), void*>>{}({self->declaration().index_in_schema(), val, self->file()});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string __repr__() const {
|
std::string __repr__() const {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
$self->toString(oss);
|
$self->toString(oss);
|
||||||
@@ -820,6 +837,14 @@ private:
|
|||||||
throw IfcParse::IfcException("Attribute not set");
|
throw IfcParse::IfcException("Attribute not set");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IfcParse::IfcFile* file_py() const {
|
||||||
|
return $self->file();
|
||||||
|
}
|
||||||
|
|
||||||
|
%pythoncode %{
|
||||||
|
file = property(file_py)
|
||||||
|
%}
|
||||||
}
|
}
|
||||||
|
|
||||||
%extend IfcParse::IfcSpfHeader {
|
%extend IfcParse::IfcSpfHeader {
|
||||||
|
|||||||
Reference in New Issue
Block a user