|
1 | 1 | from collections import defaultdict
|
2 | 2 | from collections.abc import Sequence
|
3 |
| -from typing import Final, NewType, cast |
| 3 | +from typing import Final, NewType, TypeAlias, cast |
4 | 4 |
|
5 | 5 | import chemcoord as cc
|
6 | 6 | from attr import define
|
|
59 | 59 | #:
|
60 | 60 | OriginIdx = NewType("OriginIdx", CenterIdx)
|
61 | 61 |
|
| 62 | +# We would like to have a subtype of Sequence that also behaves generically |
| 63 | +# so that we could write |
| 64 | +# `SeqOverFrag[AOIdx]` for a sequence that contains all AO indices in a fragment |
| 65 | +# or `SeqOverAtom[AOIdx]` for a sequence that contains all AO indices in an atom, |
| 66 | +# where the Sequence types are different, i.e. a function that takes a `SeqOverFrag` |
| 67 | +# would neither accept a `SeqOverAtom` nor a generic `Sequence`. |
| 68 | +# However, this is (currently) not possible in Python, see this issue: |
| 69 | +# https://github.com/python/mypy/issues/3331 |
| 70 | +# |
| 71 | +# Hence we have to use just TypeAliases, which means that `SeqOverFrag`, `SeqOverAtom` |
| 72 | +# and `Sequence` are all the same type. |
| 73 | +# This is not ideal, but it is the best we can do at the moment. |
| 74 | +SeqOverFrag: TypeAlias = Sequence |
| 75 | +SeqOverAtom: TypeAlias = Sequence |
| 76 | + |
62 | 77 |
|
63 | 78 | def merge_seqs(*seqs: Sequence[T]) -> OrderedSet[T]:
|
64 | 79 | """Merge multiple sequences into a single :class:`OrderedSet`.
|
@@ -272,19 +287,19 @@ class FragmentedStructure:
|
272 | 287 | """
|
273 | 288 |
|
274 | 289 | #: The atomic orbital indices per fragment
|
275 |
| - atoms_per_frag: Final[Sequence[OrderedSet[AtomIdx]]] |
| 290 | + atoms_per_frag: Final[SeqOverFrag[OrderedSet[AtomIdx]]] |
276 | 291 | #: The motifs per fragment.
|
277 | 292 | #: Note that the set of motifs in the fragment
|
278 | 293 | #: is the union of centers and edges.
|
279 |
| - motifs_per_frag: Final[Sequence[OrderedSet[MotifIdx]]] |
| 294 | + motifs_per_frag: Final[SeqOverFrag[OrderedSet[MotifIdx]]] |
280 | 295 | #: The centers per fragment.
|
281 | 296 | #: Note that the set of centers is the complement of the edges.
|
282 |
| - center_per_frag: Final[Sequence[OrderedSet[CenterIdx]]] |
| 297 | + center_per_frag: Final[SeqOverFrag[OrderedSet[CenterIdx]]] |
283 | 298 | #: The edges per fragment.
|
284 | 299 | #: Note that the set of edges is the complement of the centers.
|
285 |
| - edge_per_frag: Final[Sequence[OrderedSet[EdgeIdx]]] |
| 300 | + edge_per_frag: Final[SeqOverFrag[OrderedSet[EdgeIdx]]] |
286 | 301 | #: The origins per frag
|
287 |
| - origin_per_frag: Final[Sequence[OrderedSet[OriginIdx]]] |
| 302 | + origin_per_frag: Final[SeqOverFrag[OrderedSet[OriginIdx]]] |
288 | 303 | #: Connectivity data of the molecule.
|
289 | 304 | conn_data: Final[ConnectivityData]
|
290 | 305 | n_BE: Final[int]
|
@@ -378,9 +393,10 @@ class FragmentedMolecule:
|
378 | 393 | mol: Final[Mole]
|
379 | 394 |
|
380 | 395 | #: The atomic orbital indices per atom
|
381 |
| - AO_per_atom: Final[Sequence[Sequence[AOIdx]]] |
| 396 | + AO_per_atom: Final[SeqOverAtom[Sequence[AOIdx]]] |
| 397 | + |
382 | 398 | #: The atomic orbital indices per fragment
|
383 |
| - AO_per_frag: Final[Sequence[Sequence[AOIdx]]] |
| 399 | + AO_per_frag: Final[SeqOverFrag[Sequence[AOIdx]]] |
384 | 400 |
|
385 | 401 | @classmethod
|
386 | 402 | def from_frag_structure(
|
|
0 commit comments