3939 TYPE_CHECKING ,
4040 Any ,
4141 Literal ,
42- Optional ,
4342 TextIO ,
43+ TypeAlias ,
4444 TypeVar ,
4545 Union ,
4646 overload ,
5050from openff .units import Unit
5151from openff .units .elements import MASSES , SYMBOLS
5252from openff .utilities .exceptions import MissingOptionalDependencyError
53- from typing_extensions import TypeAlias
5453
5554from openff .toolkit import Quantity , unit
5655from openff .toolkit .utils .constants import DEFAULT_AROMATICITY_MODEL
105104
106105# TODO: These aliases are duplicated in a few places, might make sense to consolidate them
107106# into a single location, but that'd weirdly nudge them towards first-class existence
108- TKR : TypeAlias = Union [ ToolkitRegistry , ToolkitWrapper ]
107+ TKR : TypeAlias = ToolkitRegistry | ToolkitWrapper
109108MoleculeLike : TypeAlias = Union ["Molecule" , "FrozenMolecule" , "_SimpleMolecule" ]
110109FM = TypeVar ("FM" , bound = "FrozenMolecule" )
111110P = TypeVar ("P" , bound = "Particle" )
@@ -195,7 +194,7 @@ def __init__(self, *args, **kwargs):
195194 def __setitem__ (self , key , value ):
196195 if not isinstance (key , str ):
197196 raise InvalidAtomMetadataError (f"Attempted to set atom metadata with a non-string key. (key: { key } " )
198- if not isinstance (value , ( str , int ) ):
197+ if not isinstance (value , str | int ):
199198 raise InvalidAtomMetadataError (
200199 f"Attempted to set atom metadata with a non-string or integer value. (value: { value } )"
201200 )
@@ -219,9 +218,9 @@ class Atom(Particle):
219218 def __init__ (
220219 self ,
221220 atomic_number : int ,
222- formal_charge : Union [ int , Quantity ] ,
221+ formal_charge : int | Quantity ,
223222 is_aromatic : bool ,
224- name : Optional [ str ] = None ,
223+ name : str | None = None ,
225224 molecule = None ,
226225 stereochemistry : Literal ["R" , "S" , None ] = None ,
227226 metadata : Mapping [str , int | str ] | None = None ,
@@ -301,7 +300,7 @@ def add_bond(self, bond: "Bond"):
301300
302301 self ._bonds .append (bond )
303302
304- def to_dict (self ) -> dict [str , Union [ None , str , int , bool , dict [Any , Any ] ]]:
303+ def to_dict (self ) -> dict [str , None | str | int | bool | dict [Any , Any ]]:
305304 """Return a dict representation of the :class:`Atom` class instance.
306305
307306 Output dictionary keys and values align with parameters used to initialize
@@ -400,7 +399,7 @@ def partial_charge(self, charge):
400399 "please raise an issue describing your use case."
401400 )
402401
403- if not isinstance (charge , ( Quantity , float ) ):
402+ if not isinstance (charge , Quantity | float ):
404403 raise ValueError (
405404 "Cannot set partial charge with an object that is not a openff.unit.Quantity or float. "
406405 f"Found object of type { type (charge )} ."
@@ -693,7 +692,7 @@ def __init__(
693692 self ._is_aromatic = is_aromatic
694693 self ._stereochemistry = stereochemistry
695694
696- def to_dict (self ) -> dict [str , Union [ int , bool , str , float ] ]:
695+ def to_dict (self ) -> dict [str , int | bool | str | float ]:
697696 """Return a ``dict`` representation of the bond.
698697
699698 The output dictionary keys and values align with parameters used to initialize
@@ -895,15 +894,15 @@ class FrozenMolecule(Serializable):
895894
896895 """
897896
898- _partial_charges : Optional [ Quantity ]
899- _conformers : Optional [ list [Quantity ]]
897+ _partial_charges : Quantity | None
898+ _conformers : list [Quantity ] | None
900899 _properties : dict
901900 _hierarchy_schemes : dict
902901
903902 def __init__ (
904903 self ,
905904 other = None ,
906- file_format : Optional [ str ] = None ,
905+ file_format : str | None = None ,
907906 toolkit_registry : TKR = GLOBAL_TOOLKIT_REGISTRY ,
908907 allow_undefined_stereo : bool = False ,
909908 ):
@@ -990,7 +989,7 @@ def __init__(
990989 """
991990
992991 self ._cached_smiles : dict [str , str ] = dict ()
993- self ._ordered_connection_table_hash : Optional [ int ] = None
992+ self ._ordered_connection_table_hash : int | None = None
994993
995994 # Figure out if toolkit_registry is a whole registry, or just a single wrapper
996995 if isinstance (toolkit_registry , ToolkitRegistry ):
@@ -1051,7 +1050,7 @@ def __init__(
10511050 loaded = True
10521051 # TODO: Make this compatible with file-like objects (I couldn't figure out how to make an oemolistream
10531052 # from a fileIO object)
1054- if isinstance (other , ( str , pathlib .Path ) ) or (hasattr (other , "read" ) and not loaded ):
1053+ if isinstance (other , str | pathlib .Path ) or (hasattr (other , "read" ) and not loaded ):
10551054 try :
10561055 mol = Molecule .from_file (
10571056 other ,
@@ -1180,16 +1179,14 @@ def to_dict(self) -> dict:
11801179 # https://mypy.readthedocs.io/en/latest/typed_dict.html#typeddict
11811180 molecule_dict : dict [
11821181 str ,
1183- Union [
1184- None ,
1185- str ,
1186- bytes ,
1187- dict [str , Any ],
1188- list [str ],
1189- list [bytes ],
1190- list [HierarchyElement ],
1191- list [dict [str , Any ]],
1192- ],
1182+ None
1183+ | str
1184+ | bytes
1185+ | dict [str , Any ]
1186+ | list [str ]
1187+ | list [bytes ]
1188+ | list [HierarchyElement ]
1189+ | list [dict [str , Any ]],
11931190 ] = dict ()
11941191 molecule_dict ["name" ] = self ._name
11951192
@@ -1310,7 +1307,7 @@ def _initialize_from_dict(self, molecule_dict: dict):
13101307 )
13111308
13121309 if molecule_dict ["conformers" ] is None :
1313- self ._conformers : Optional [ list [Quantity ]] = None
1310+ self ._conformers : list [Quantity ] | None = None
13141311 else :
13151312 from openff .toolkit .utils .utils import deserialize_numpy
13161313
@@ -1572,7 +1569,7 @@ def delete_hierarchy_scheme(self, iter_name: str):
15721569 )
15731570 self ._hierarchy_schemes .pop (iter_name )
15741571
1575- def update_hierarchy_schemes (self , iter_names : Optional [ list [str ]] = None ):
1572+ def update_hierarchy_schemes (self , iter_names : list [str ] | None = None ):
15761573 """
15771574 Infer a hierarchy from atom metadata according to the existing hierarchy
15781575 schemes.
@@ -2134,7 +2131,7 @@ def edge_match_func(x, y):
21342131 edge_match_func = None # type: ignore
21352132
21362133 # Here we should work out what data type we have, also deal with lists?
2137- def to_networkx (data : Union [ FrozenMolecule , nx .Graph ] ) -> nx .Graph :
2134+ def to_networkx (data : FrozenMolecule | nx .Graph ) -> nx .Graph :
21382135 """For the given data type, return the networkx graph"""
21392136 if strip_pyrimidal_n_atom_stereo :
21402137 SMARTS = "[N+0X3:1](-[*])(-[*])(-[*])"
@@ -2552,7 +2549,7 @@ def assign_partial_charges(
25522549 self ,
25532550 partial_charge_method : str ,
25542551 strict_n_conformers : bool = False ,
2555- use_conformers : Optional [ Iterable [Quantity ]] = None ,
2552+ use_conformers : Iterable [Quantity ] | None = None ,
25562553 toolkit_registry : TKR = GLOBAL_TOOLKIT_REGISTRY ,
25572554 normalize_partial_charges : bool = True ,
25582555 ):
@@ -2720,9 +2717,9 @@ def _normalize_partial_charges(self):
27202717
27212718 def assign_fractional_bond_orders (
27222719 self ,
2723- bond_order_model : Optional [ str ] = None ,
2720+ bond_order_model : str | None = None ,
27242721 toolkit_registry : TKR = GLOBAL_TOOLKIT_REGISTRY ,
2725- use_conformers : Optional [ Iterable [Quantity ]] = None ,
2722+ use_conformers : Iterable [Quantity ] | None = None ,
27262723 ):
27272724 """
27282725 Update and store list of bond orders this molecule.
@@ -2849,7 +2846,7 @@ def to_networkx(self) -> "nx.Graph":
28492846
28502847 def find_rotatable_bonds (
28512848 self ,
2852- ignore_functional_groups : Optional [ list [str ]] = None ,
2849+ ignore_functional_groups : list [str ] | None = None ,
28532850 toolkit_registry : TKR = GLOBAL_TOOLKIT_REGISTRY ,
28542851 ) -> list [Bond ]:
28552852 """
@@ -3805,7 +3802,7 @@ def from_file(
38053802 >>> molecule = Molecule.from_file(sdf_file_path)
38063803
38073804 """
3808- toolkit : Optional [ ToolkitWrapper ]
3805+ toolkit : ToolkitWrapper | None
38093806
38103807 if file_format is None :
38113808 if isinstance (file_path , pathlib .Path ):
@@ -3884,7 +3881,7 @@ def from_file(
38843881
38853882 mols = list ()
38863883
3887- if isinstance (file_path , ( str , pathlib .Path ) ):
3884+ if isinstance (file_path , str | pathlib .Path ):
38883885 if isinstance (file_path , pathlib .Path ):
38893886 file_path = file_path .as_posix ()
38903887 mols = toolkit .from_file ( # type: ignore[call-arg]
@@ -3913,7 +3910,7 @@ def from_file(
39133910 @requires_package ("openmm" )
39143911 def from_polymer_pdb (
39153912 cls : type [FM ],
3916- file_path : Union [ str , pathlib .Path , TextIO ] ,
3913+ file_path : str | pathlib .Path | TextIO ,
39173914 toolkit_registry = GLOBAL_TOOLKIT_REGISTRY ,
39183915 name : str = "" ,
39193916 ) -> FM :
@@ -3982,7 +3979,7 @@ def from_polymer_pdb(
39823979 if isinstance (toolkit_registry , ToolkitWrapper ):
39833980 toolkit_registry = ToolkitRegistry ([type (toolkit_registry )])
39843981
3985- if isinstance (file_path , ( str , io .TextIOWrapper ) ):
3982+ if isinstance (file_path , str | io .TextIOWrapper ):
39863983 pass
39873984 elif isinstance (file_path , pathlib .Path ):
39883985 file_path = file_path .as_posix ()
@@ -4047,7 +4044,7 @@ def _has_multiple_molecules(self) -> bool:
40474044 num_disconnected_subgraphs = sum (1 for _ in nx .connected_components (graph ))
40484045 return num_disconnected_subgraphs > 1
40494046
4050- def _to_xyz_file (self , file_path : Union [ str , IO [str ] ]):
4047+ def _to_xyz_file (self , file_path : str | IO [str ]):
40514048 """
40524049 Write the current molecule and its conformers to a multiframe xyz file, if the molecule
40534050 has no current coordinates all atoms will be set to 0,0,0 in keeping with the behaviour of the
@@ -4069,7 +4066,7 @@ def _to_xyz_file(self, file_path: Union[str, IO[str]]):
40694066 conformers = self ._conformers
40704067
40714068 if len (conformers ) == 1 :
4072- end : Union [ str , int ] = ""
4069+ end : str | int = ""
40734070
40744071 def title (frame ):
40754072 return f"{ self .name if self .name != '' else self .hill_formula } { frame } \n "
@@ -4126,7 +4123,7 @@ def to_file(self, file_path, file_format, toolkit_registry=GLOBAL_TOOLKIT_REGIST
41264123 >>> molecule.to_file('imatinib.pdb', file_format='pdb') # doctest: +SKIP
41274124
41284125 """
4129- toolkit : Optional [ ToolkitRegistry ]
4126+ toolkit : ToolkitRegistry | None
41304127
41314128 if isinstance (toolkit_registry , ToolkitRegistry ):
41324129 pass
@@ -4161,7 +4158,7 @@ def to_file(self, file_path, file_format, toolkit_registry=GLOBAL_TOOLKIT_REGIST
41614158 f"(supported formats: { supported_formats } )"
41624159 )
41634160
4164- if isinstance (file_path , ( str , pathlib .Path ) ):
4161+ if isinstance (file_path , str | pathlib .Path ):
41654162 toolkit .to_file (self , file_path , file_format )
41664163 else :
41674164 toolkit .to_file_obj (self , file_path , file_format )
@@ -5122,7 +5119,7 @@ def _is_bonded(self, atom_index_1: int, atom_index_2: int) -> bool:
51225119 atom2 = self ._atoms [atom_index_2 ]
51235120 return atom2 in self ._bonded_atoms [atom1 ]
51245121
5125- def get_bond_between (self , i : Union [ int , Atom ] , j : Union [ int , Atom ] ) -> Bond :
5122+ def get_bond_between (self , i : int | Atom , j : int | Atom ) -> Bond :
51265123 """Returns the bond between two atoms
51275124
51285125 Parameters
@@ -5226,8 +5223,8 @@ def add_atom(
52265223 formal_charge : int ,
52275224 is_aromatic : bool ,
52285225 stereochemistry : Literal ["R" , "S" , None ] = None ,
5229- name : Optional [ str ] = None ,
5230- metadata : Optional [ dict [str , Union [ int , str ]]] = None ,
5226+ name : str | None = None ,
5227+ metadata : dict [str , int | str ] | None = None ,
52315228 ) -> int :
52325229 """
52335230 Add an atom to the molecule.
@@ -5292,7 +5289,7 @@ def add_bond(
52925289 bond_order : int ,
52935290 is_aromatic : bool ,
52945291 stereochemistry : Literal ["E" , "Z" , None ] = None ,
5295- fractional_bond_order : Optional [ float ] = None ,
5292+ fractional_bond_order : float | None = None ,
52965293 ) -> int :
52975294 """
52985295 Add a bond between two specified atom indices
@@ -5525,7 +5522,7 @@ def visualize(
55255522
55265523 def perceive_residues (
55275524 self ,
5528- substructure_file_path : Optional [ str ] = None ,
5525+ substructure_file_path : str | None = None ,
55295526 strict_chirality : bool = True ,
55305527 ):
55315528 """
@@ -5812,7 +5809,7 @@ def to_dict(self) -> dict:
58125809
58135810 Keys and values align with parameters used to initialize the :class:`HierarchyScheme` class.
58145811 """
5815- return_dict : dict [str , Union [ str , Sequence [Union [ str , int , dict ]] ]] = dict ()
5812+ return_dict : dict [str , str | Sequence [str | int | dict ]] = dict ()
58165813 return_dict ["uniqueness_criteria" ] = self .uniqueness_criteria
58175814 return_dict ["iterator_name" ] = self .iterator_name
58185815 return_dict ["hierarchy_elements" ] = [e .to_dict () for e in self .hierarchy_elements ]
0 commit comments