73 lines
2.1 KiB
Python
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
|