Files
MyUtils/src/myutils/ProxyObject.py

73 lines
2.1 KiB
Python

class ProxyObject:
def __init__(self, obj, mappings):
self._obj = obj
self._mappings = mappings
self._props = {}
self._create_props()
def __getattr__(self, item):
if item not in self._props:
raise AttributeError(item)
return self._props[item]
def __hasattr__(self, item):
return item in self._props
def as_dict(self):
return self._props.copy()
def __repr__(self):
if "key" in self._props:
return f"ProxyObject(key={self._props["key"]})"
props_as_str = str(self._props)
if len(props_as_str) > 50:
props_as_str = props_as_str[:50] + "..."
return f"ProxyObject({props_as_str})"
def __eq__(self, other):
if not isinstance(other, ProxyObject):
return False
return self._props == other._props
def __hash__(self):
return hash(tuple(sorted(self._props.items())))
def _create_props(self):
for prop_name, path in self._mappings.items():
attrs = path.split(".")
current = self._obj
# Check if path ends with wildcard
has_wildcard_in_path = attrs[-1] == "*"
# Navigate to the target object
for attr in attrs:
if attr == "*":
break
if hasattr(current, attr):
current = getattr(current, attr)
else:
break
# Handle wildcard cases
if prop_name == "*" or has_wildcard_in_path:
# Copy all properties from current object
if hasattr(current, '__dict__'):
for attr_name, attr_value in current.__dict__.items():
if not attr_name.startswith('_'):
# If attr_value is an object with properties, expand them
if has_wildcard_in_path and hasattr(attr_value, '__dict__'):
for sub_attr_name, sub_attr_value in attr_value.__dict__.items():
if not sub_attr_name.startswith('_'):
self._props[sub_attr_name] = sub_attr_value
else:
# Simple value or prop_name == "*"
self._props[attr_name] = attr_value
else:
# Normal mapping (no wildcard)
self._props[prop_name] = current