diff --git a/pulp-glue/src/pulp_glue/common/context.py b/pulp-glue/src/pulp_glue/common/context.py index 5e6fc3426..ff9a11aa6 100644 --- a/pulp-glue/src/pulp_glue/common/context.py +++ b/pulp-glue/src/pulp_glue/common/context.py @@ -70,7 +70,9 @@ def _inner(f: T) -> T: class PreprocessedEntityDefinition(dict[str, t.Any]): - pass + def __init__(self, /, *args: t.Any, _partial: bool, **kwargs: t.Any): + super().__init__(*args, **kwargs) + self._partial: bool = _partial EntityDefinition = dict[str, t.Any] | PreprocessedEntityDefinition @@ -132,7 +134,8 @@ def preprocess_payload(payload: EntityDefinition) -> EntityDefinition: return payload return PreprocessedEntityDefinition( - {key: _preprocess_value(value) for key, value in payload.items() if value is not None} + {key: _preprocess_value(value) for key, value in payload.items() if value is not None}, + _partial=False, ) @@ -930,6 +933,15 @@ def _preprocess_value(cls, key: str, value: t.Any) -> t.Any: return None return _preprocess_value(value) + def _preprocess_entity(self, body: EntityDefinition, partial: bool = False) -> EntityDefinition: + if isinstance(body, PreprocessedEntityDefinition): + assert body._partial == partial + return body + else: + return PreprocessedEntityDefinition( + self.preprocess_entity(body, partial), _partial=partial + ) + def preprocess_entity(self, body: EntityDefinition, partial: bool = False) -> EntityDefinition: """ Filter to prepare the body for a create or update call. @@ -944,16 +956,11 @@ def preprocess_entity(self, body: EntityDefinition, partial: bool = False) -> En Returns: The body ready to be passed to `call`. """ - if isinstance(body, PreprocessedEntityDefinition): - return body - - return PreprocessedEntityDefinition( - { - key: self._preprocess_value(key, value) - for key, value in body.items() - if value is not None - } - ) + return { + key: self._preprocess_value(key, value) + for key, value in body.items() + if value is not None + } def list_iterator( self, @@ -1096,7 +1103,7 @@ def create( if parameters: _parameters.update(parameters) if body is not None: - body = self.preprocess_entity(body, partial=False) + body = self._preprocess_entity(body, partial=False) if self.pulp_ctx.fake_mode: body["pulp_href"] = "" self._entity = body @@ -1155,7 +1162,7 @@ def update( if parameters: _parameters.update(parameters) if body is not None: - body = self.preprocess_entity(body, partial=True) + body = self._preprocess_entity(body, partial=True) if self.pulp_ctx.fake_mode: assert self._entity is not None if body is not None: @@ -1342,14 +1349,14 @@ def converge( return True, None, self.create(desired_entity) else: update_attributes = {} - for k, v in self.preprocess_entity(desired_attributes, partial=True).items(): + for k, v in self._preprocess_entity(desired_attributes, partial=True).items(): if entity.get(k) != v: update_attributes[k] = v if update_attributes: return ( True, entity, - self.update(PreprocessedEntityDefinition(update_attributes)), + self.update(PreprocessedEntityDefinition(update_attributes, _partial=True)), ) return False, entity, entity diff --git a/pulp-glue/tests/test_entity_context.py b/pulp-glue/tests/test_entity_context.py new file mode 100644 index 000000000..da211461b --- /dev/null +++ b/pulp-glue/tests/test_entity_context.py @@ -0,0 +1,11 @@ +from pulp_glue.common.context import PreprocessedEntityDefinition, PulpContext, PulpEntityContext + + +def test_preprocess_entity_is_only_called_once(mock_pulp_ctx: PulpContext) -> None: + entity_ctx = PulpEntityContext(mock_pulp_ctx) + + preprocessed = entity_ctx._preprocess_entity({}) + assert isinstance(preprocessed, PreprocessedEntityDefinition) + + # Now call it again and see if the returned object is the same, not just equal. + assert preprocessed is entity_ctx._preprocess_entity(preprocessed)