|
1 | 1 | """DiffSync front-end classes and logic. |
2 | 2 |
|
3 | | -Copyright (c) 2020 Network To Code, LLC <[email protected]> |
| 3 | +Copyright (c) 2020-2021 Network To Code, LLC <[email protected]> |
4 | 4 |
|
5 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); |
6 | 6 | you may not use this file except in compliance with the License. |
|
16 | 16 | """ |
17 | 17 | from collections import defaultdict |
18 | 18 | from inspect import isclass |
19 | | -from typing import ClassVar, Dict, List, Mapping, MutableMapping, Optional, Text, Tuple, Type, Union |
| 19 | +from typing import Callable, ClassVar, Dict, List, Mapping, MutableMapping, Optional, Text, Tuple, Type, Union |
20 | 20 |
|
21 | 21 | from pydantic import BaseModel, PrivateAttr |
22 | 22 | import structlog # type: ignore |
@@ -359,7 +359,7 @@ def remove_child(self, child: "DiffSyncModel"): |
359 | 359 | class DiffSync: |
360 | 360 | """Class for storing a group of DiffSyncModel instances and diffing/synchronizing to another DiffSync instance.""" |
361 | 361 |
|
362 | | - # Add mapping of names to specific model classes here: |
| 362 | + # In any subclass, you would add mapping of names to specific model classes here: |
363 | 363 | # modelname1 = MyModelClass1 |
364 | 364 | # modelname2 = MyModelClass2 |
365 | 365 |
|
@@ -418,6 +418,10 @@ def __str__(self): |
418 | 418 | def __repr__(self): |
419 | 419 | return f"<{str(self)}>" |
420 | 420 |
|
| 421 | + def __len__(self): |
| 422 | + """Total number of elements stored in self._data.""" |
| 423 | + return sum(len(entries) for entries in self._data.values()) |
| 424 | + |
421 | 425 | def load(self): |
422 | 426 | """Load all desired data from whatever backend data source into this instance.""" |
423 | 427 | # No-op in this generic class |
@@ -502,29 +506,43 @@ def sync_complete( |
502 | 506 | # ------------------------------------------------------------------------------ |
503 | 507 |
|
504 | 508 | def diff_from( |
505 | | - self, source: "DiffSync", diff_class: Type[Diff] = Diff, flags: DiffSyncFlags = DiffSyncFlags.NONE |
| 509 | + self, |
| 510 | + source: "DiffSync", |
| 511 | + diff_class: Type[Diff] = Diff, |
| 512 | + flags: DiffSyncFlags = DiffSyncFlags.NONE, |
| 513 | + callback: Optional[Callable[[int, int], None]] = None, |
506 | 514 | ) -> Diff: |
507 | 515 | """Generate a Diff describing the difference from the other DiffSync to this one. |
508 | 516 |
|
509 | 517 | Args: |
510 | 518 | source (DiffSync): Object to diff against. |
511 | 519 | diff_class (class): Diff or subclass thereof to use for diff calculation and storage. |
512 | 520 | flags (DiffSyncFlags): Flags influencing the behavior of this diff operation. |
| 521 | + callback (function): Function with parameters (current, total), to be called at intervals as the |
| 522 | + calculation of the diff proceeds. |
513 | 523 | """ |
514 | | - differ = DiffSyncDiffer(src_diffsync=source, dst_diffsync=self, flags=flags, diff_class=diff_class) |
| 524 | + differ = DiffSyncDiffer( |
| 525 | + src_diffsync=source, dst_diffsync=self, flags=flags, diff_class=diff_class, callback=callback |
| 526 | + ) |
515 | 527 | return differ.calculate_diffs() |
516 | 528 |
|
517 | 529 | def diff_to( |
518 | | - self, target: "DiffSync", diff_class: Type[Diff] = Diff, flags: DiffSyncFlags = DiffSyncFlags.NONE |
| 530 | + self, |
| 531 | + target: "DiffSync", |
| 532 | + diff_class: Type[Diff] = Diff, |
| 533 | + flags: DiffSyncFlags = DiffSyncFlags.NONE, |
| 534 | + callback: Optional[Callable[[int, int], None]] = None, |
519 | 535 | ) -> Diff: |
520 | 536 | """Generate a Diff describing the difference from this DiffSync to another one. |
521 | 537 |
|
522 | 538 | Args: |
523 | 539 | target (DiffSync): Object to diff against. |
524 | 540 | diff_class (class): Diff or subclass thereof to use for diff calculation and storage. |
525 | 541 | flags (DiffSyncFlags): Flags influencing the behavior of this diff operation. |
| 542 | + callback (function): Function with parameters (current, total), to be called at intervals as the |
| 543 | + calculation of the diff proceeds. |
526 | 544 | """ |
527 | | - return target.diff_from(self, diff_class=diff_class, flags=flags) |
| 545 | + return target.diff_from(self, diff_class=diff_class, flags=flags, callback=callback) |
528 | 546 |
|
529 | 547 | # ------------------------------------------------------------------------------ |
530 | 548 | # Object Storage Management |
@@ -567,21 +585,21 @@ def get( |
567 | 585 | raise ObjectNotFound(f"{modelname} {uid} not present in {self.name}") |
568 | 586 | return self._data[modelname][uid] |
569 | 587 |
|
570 | | - def get_all(self, obj: Union[Text, DiffSyncModel, Type[DiffSyncModel]]): |
| 588 | + def get_all(self, obj: Union[Text, DiffSyncModel, Type[DiffSyncModel]]) -> List[DiffSyncModel]: |
571 | 589 | """Get all objects of a given type. |
572 | 590 |
|
573 | 591 | Args: |
574 | 592 | obj: DiffSyncModel class or instance, or modelname string, that defines the type of the objects to retrieve |
575 | 593 |
|
576 | 594 | Returns: |
577 | | - ValuesList[DiffSyncModel]: List of Object |
| 595 | + List[DiffSyncModel]: List of Object |
578 | 596 | """ |
579 | 597 | if isinstance(obj, str): |
580 | 598 | modelname = obj |
581 | 599 | else: |
582 | 600 | modelname = obj.get_type() |
583 | 601 |
|
584 | | - return self._data[modelname].values() |
| 602 | + return list(self._data[modelname].values()) |
585 | 603 |
|
586 | 604 | def get_by_uids( |
587 | 605 | self, uids: List[Text], obj: Union[Text, DiffSyncModel, Type[DiffSyncModel]] |
|
0 commit comments