129129import itertools
130130import re
131131import sys
132+ from collections .abc import Iterator
133+ from collections .abc import Mapping
134+ from collections .abc import MutableMapping
132135from dataclasses import dataclass
133136from dataclasses import field
134137from dataclasses import replace
135138from enum import unique
136139from pathlib import Path
140+ from re import Pattern
137141from typing import Any
138- from typing import Dict
139- from typing import Iterator
140- from typing import List
141- from typing import Mapping
142- from typing import MutableMapping
143- from typing import Pattern
144142from typing import overload
145143
146144from fgpyo import sam
@@ -177,7 +175,7 @@ class Keys(StrEnum):
177175 URI = "UR"
178176
179177 @staticmethod
180- def attributes () -> List [str ]:
178+ def attributes () -> list [str ]:
181179 """
182180 The list of keys that are allowed to be attributes in `SequenceMetadata`.
183181
@@ -253,7 +251,7 @@ class SequenceMetadata(MutableMapping[Keys | str, str]):
253251 name : str
254252 length : int
255253 index : int
256- attributes : Dict [Keys | str , str ] = field (default_factory = dict )
254+ attributes : dict [Keys | str , str ] = field (default_factory = dict )
257255
258256 def __post_init__ (self ) -> None :
259257 """Any post initialization validation should go here."""
@@ -267,13 +265,13 @@ def __post_init__(self) -> None:
267265 raise ValueError (f"'{ Keys .SEQUENCE_LENGTH } ' should not given in the list of attributes" )
268266
269267 @property
270- def aliases (self ) -> List [str ]:
268+ def aliases (self ) -> list [str ]:
271269 """The aliases (not including the primary) name."""
272270 aliases = self .attributes .get (Keys .ALIASES )
273271 return [] if aliases is None else aliases .split ("," )
274272
275273 @property
276- def all_names (self ) -> List [str ]:
274+ def all_names (self ) -> list [str ]:
277275 """A list of all names, including the primary name and aliases, in that order."""
278276 return [self .name ] + self .aliases
279277
@@ -344,14 +342,14 @@ def same_as(self, other: "SequenceMetadata") -> bool:
344342 else :
345343 return self_m5 == other_m5
346344
347- def to_sam (self ) -> Dict [str , Any ]:
345+ def to_sam (self ) -> dict [str , Any ]:
348346 """
349347 Converts the sequence metadata to a SAM-formatted dictionary.
350348
351349 Equivalent to one item in the list of sequences from
352350 `pysam.AlignmentHeader#to_dict()["SQ"]`.
353351 """
354- meta_dict : Dict [str , Any ] = {
352+ meta_dict : dict [str , Any ] = {
355353 f"{ Keys .SEQUENCE_NAME } " : self .name ,
356354 f"{ Keys .SEQUENCE_LENGTH } " : self .length ,
357355 }
@@ -361,7 +359,7 @@ def to_sam(self) -> Dict[str, Any]:
361359 return meta_dict
362360
363361 @staticmethod
364- def from_sam (meta : Dict [Keys | str , Any ], index : int ) -> "SequenceMetadata" :
362+ def from_sam (meta : dict [Keys | str , Any ], index : int ) -> "SequenceMetadata" :
365363 """
366364 Builds a `SequenceMetadata` from a dictionary.
367365
@@ -436,13 +434,13 @@ class SequenceDictionary(Mapping[str | int, SequenceMetadata]):
436434 infos: the ordered collection of sequence metadata
437435 """
438436
439- infos : List [SequenceMetadata ]
440- _dict : Dict [str , SequenceMetadata ] = field (init = False , repr = False )
437+ infos : list [SequenceMetadata ]
438+ _dict : dict [str , SequenceMetadata ] = field (init = False , repr = False )
441439
442440 def __post_init__ (self ) -> None :
443441 """Builds the internal name-to-metadata lookup dictionary."""
444442 # Initialize a mapping from sequence name to the sequence metadata for all names
445- self_dict : Dict [str , SequenceMetadata ] = {}
443+ self_dict : dict [str , SequenceMetadata ] = {}
446444 for index , info in enumerate (self .infos ):
447445 if info .index != index :
448446 raise ValueError (
@@ -466,13 +464,13 @@ def same_as(self, other: "SequenceDictionary") -> bool:
466464 return False
467465 return all (this .same_as (that ) for this , that in zip (self .infos , other .infos , strict = True ))
468466
469- def to_sam (self ) -> List [ Dict [str , Any ]]:
467+ def to_sam (self ) -> list [ dict [str , Any ]]:
470468 """Converts the list of dictionaries, one per sequence."""
471469 return [meta .to_sam () for meta in self .infos ]
472470
473471 def to_sam_header (
474472 self ,
475- extra_header : Dict [str , Any ] | None = None ,
473+ extra_header : dict [str , Any ] | None = None ,
476474 ) -> pysam .AlignmentHeader :
477475 """
478476 Converts the sequence dictionary to a `pysam.AlignmentHeader`.
@@ -481,7 +479,7 @@ def to_sam_header(
481479 extra_header: a dictionary of extra values to add to the header, None otherwise. See
482480 `:~pysam.AlignmentHeader` for more details.
483481 """
484- header_dict : Dict [str , Any ] = {
482+ header_dict : dict [str , Any ] = {
485483 "HD" : {"VN" : "1.5" },
486484 "SQ" : self .to_sam (),
487485 }
@@ -503,11 +501,11 @@ def from_sam(data: pysam.AlignmentHeader) -> "SequenceDictionary": ...
503501
504502 @staticmethod
505503 @overload
506- def from_sam (data : List [ Dict [str , Any ]]) -> "SequenceDictionary" : ...
504+ def from_sam (data : list [ dict [str , Any ]]) -> "SequenceDictionary" : ...
507505
508506 @staticmethod
509507 def from_sam (
510- data : Path | pysam .AlignmentFile | pysam .AlignmentHeader | List [ Dict [str , Any ]],
508+ data : Path | pysam .AlignmentFile | pysam .AlignmentHeader | list [ dict [str , Any ]],
511509 ) -> "SequenceDictionary" :
512510 """
513511 Creates a `SequenceDictionary` from a SAM file or its header.
@@ -531,7 +529,7 @@ def from_sam(
531529 seq_dict = SequenceDictionary .from_sam (fh .header )
532530 else : # assuming `data` is a `list[dict[str, Any]]`
533531 try :
534- infos : List [SequenceMetadata ] = [
532+ infos : list [SequenceMetadata ] = [
535533 SequenceMetadata .from_sam (meta = meta , index = index )
536534 for index , meta in enumerate (data )
537535 ]
0 commit comments