diff --git a/pelix/ipopo/contexts.py b/pelix/ipopo/contexts.py index 6699e95d..922f6b41 100644 --- a/pelix/ipopo/contexts.py +++ b/pelix/ipopo/contexts.py @@ -423,7 +423,7 @@ class ComponentContext(object): Represents the data stored in a component instance """ # Try to reduce memory footprint (many instances) - __slots__ = ('factory_context', 'name', 'properties', 'hidden_properties') + __slots__ = ('factory_context', 'name', 'properties', '__hidden_properties') def __init__(self, factory_context, name, properties): """ @@ -445,8 +445,8 @@ def __init__(self, factory_context, name, properties): hidden_props_keys = set(properties).intersection( factory_context.hidden_properties) - self.hidden_properties = factory_context.hidden_properties.copy() - self.hidden_properties.update({ + self.__hidden_properties = factory_context.hidden_properties.copy() + self.__hidden_properties.update({ key: value for key, value in properties.items() if key in hidden_props_keys}) @@ -510,3 +510,24 @@ def get_handler(self, handler_id): :return: The handler configuration, or None """ return self.factory_context.get_handler(handler_id, None) + + def has_hidden_properties(self): + """ + Returns True if the component must support hidden properties + """ + return bool(self.__hidden_properties) + + def grab_hidden_properties(self): + """ + A one-shot access to hidden properties (the field is then destroyed) + + :return: A copy of the hidden properties dictionary on the first call + :raise AttributeError: On any call after the first one + """ + # Copy properties + result = self.__hidden_properties.copy() + + # Destroy the field + self.__hidden_properties.clear() + del self.__hidden_properties + return result diff --git a/pelix/ipopo/handlers/properties.py b/pelix/ipopo/handlers/properties.py index c0bc7786..35d1e7f6 100644 --- a/pelix/ipopo/handlers/properties.py +++ b/pelix/ipopo/handlers/properties.py @@ -122,7 +122,8 @@ def _field_property_generator(self, public_properties): properties = stored_instance.context.properties update_notifier = stored_instance.update_property else: - properties = stored_instance.context.hidden_properties + # Copy Hidden properties and remove them from the context + properties = stored_instance.context.grab_hidden_properties() update_notifier = stored_instance.update_hidden_property def get_value(_, name): @@ -190,7 +191,7 @@ def manipulate(self, stored_instance, component_instance): flags_to_generate.add(True) # (False for hidden ones) - if stored_instance.context.hidden_properties: + if stored_instance.context.has_hidden_properties(): flags_to_generate.add(False) # Inject properties getters and setters