Represents a named list of fields sharing the same domain.
| 367 | |
| 368 | |
| 369 | class Struct(Field): |
| 370 | """Represents a named list of fields sharing the same domain. |
| 371 | """ |
| 372 | |
| 373 | __slots__: Sequence[str] = ("fields", "_frozen") |
| 374 | |
| 375 | def __init__(self, *fields): |
| 376 | """ fields is a list of tuples in format of (name, field). The name is |
| 377 | a string of nested name, e.g., `a`, `a:b`, `a:b:c`. For example |
| 378 | |
| 379 | Struct( |
| 380 | ('a', Scalar()), |
| 381 | ('b:c', Scalar()), |
| 382 | ('b:d:e', Scalar()), |
| 383 | ('b', Struct( |
| 384 | ('f', Scalar()), |
| 385 | )), |
| 386 | ) |
| 387 | |
| 388 | is equal to |
| 389 | |
| 390 | Struct( |
| 391 | ('a', Scalar()), |
| 392 | ('b', Struct( |
| 393 | ('c', Scalar()), |
| 394 | ('d', Struct(('e', Scalar()))), |
| 395 | ('f', Scalar()), |
| 396 | )), |
| 397 | ) |
| 398 | """ |
| 399 | for field in fields: |
| 400 | assert len(field) == 2 |
| 401 | assert field[0], 'Field names cannot be empty' |
| 402 | assert field[0] != 'lengths', ( |
| 403 | 'Struct cannot contain a field named `lengths`.' |
| 404 | ) |
| 405 | fields = [(name, _normalize_field(field)) for name, field in fields] |
| 406 | self.fields = OrderedDict() |
| 407 | for name, field in fields: |
| 408 | if FIELD_SEPARATOR in name: |
| 409 | name, field = self._struct_from_nested_name(name, field) |
| 410 | if name not in self.fields: |
| 411 | self.fields[name] = field |
| 412 | continue |
| 413 | if ( |
| 414 | not isinstance(field, Struct) or |
| 415 | not isinstance(self.fields[name], Struct) |
| 416 | ): |
| 417 | raise ValueError('Duplicate field name: %s' % name) |
| 418 | self.fields[name] = self.fields[name] + field |
| 419 | for id, (_, field) in enumerate(self.fields.items()): |
| 420 | field._set_parent(self, id) |
| 421 | super().__init__(self.fields.values()) |
| 422 | self._frozen = True |
| 423 | |
| 424 | def _struct_from_nested_name(self, nested_name, field): |
| 425 | def create_internal(nested_name, field): |
| 426 | names = nested_name.split(FIELD_SEPARATOR, 1) |
no outgoing calls
searching dependent graphs…