Skip to content

Commit

Permalink
Add StructureMessage.iter_objects()
Browse files Browse the repository at this point in the history
  • Loading branch information
khaeru committed Apr 16, 2024
1 parent 89a9944 commit 674023d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ repos:
hooks:
- id: mypy
additional_dependencies:
- lxml-stubs
- pandas-stubs
- pytest
- requests-cache
- requests-mock
- types-Jinja2
- types-lxml
- types-python-dateutil
- types-PyYAML
- types-requests
Expand Down
28 changes: 24 additions & 4 deletions sdmx/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,17 @@
from datetime import datetime
from itertools import chain
from operator import attrgetter
from typing import TYPE_CHECKING, List, Optional, Text, Type, Union, get_args
from typing import (
TYPE_CHECKING,
Generator,
List,
Optional,
Text,
Tuple,
Type,
Union,
get_args,
)

from sdmx import model
from sdmx.dictlike import DictLike, summarize_dictlike
Expand Down Expand Up @@ -166,7 +176,7 @@ def __repr__(self):
lines.extend(_summarize(self, ["footer", "response"]))
return "\n ".join(lines)

def compare(self, other, strict=True):
def compare(self, other, strict=True) -> bool:
"""Return :obj:`True` if `self` is the same as `other`.
Two Messages are the same if their :attr:`header` and :attr:`footer` compare
Expand All @@ -179,7 +189,7 @@ def compare(self, other, strict=True):
"""
return self.header.compare(other.header, strict) and (
self.footer is other.footer is None
or self.footer.compare(other.footer, strict)
or self.footer.compare(other.footer, strict) # type: ignore [union-attr]
)


Expand Down Expand Up @@ -313,11 +323,21 @@ def get(

return candidates[0] if len(candidates) == 1 else None

def iter_collections(self):
def iter_collections(self) -> Generator[Tuple[str, type], None, None]:
"""Iterate over collections."""
for f in direct_fields(self.__class__):
yield f.name, get_args(f.type)[1]

def iter_objects(
self, external_reference: bool = True
) -> Generator[common.MaintainableArtefact, None, None]:
"""Iterate over all objects in the message."""
for _, cls in self.iter_collections():
for obj in self.objects(cls).values():
if not external_reference and obj.is_external_reference:
continue
yield obj

def objects(self, cls):
"""Get a reference to the attribute for objects of type `cls`.
Expand Down

0 comments on commit 674023d

Please sign in to comment.