22
33import sys
44from pathlib import Path
5- from typing import Any , Dict , List , Optional
5+ from typing import Any , Dict , List , Optional , Union
66
77from typeguard import check_argument_types
88
1111from psij .utils import path_object_to_full_path as o2p
1212
1313
14+ StrOrPath = Union [str , Path ]
15+
16+
17+ def _to_path (arg : Optional [StrOrPath ]) -> Optional [Path ] :
18+ if isinstance (arg , Path ):
19+ return arg
20+ elif arg is None :
21+ return None
22+ else :
23+ assert isinstance (arg , str )
24+ return Path (arg )
25+
26+
1427class JobSpec (object ):
1528 """A class to hold information about the characteristics of a:class:`~psij.Job`."""
1629
1730 def __init__ (self , name : Optional [str ] = None , executable : Optional [str ] = None ,
18- arguments : Optional [List [str ]] = None , directory : Optional [str | Path ] = None ,
31+ arguments : Optional [List [str ]] = None , directory : Optional [StrOrPath ] = None ,
1932 inherit_environment : bool = True , environment : Optional [Dict [str , str ]] = None ,
20- stdin_path : Optional [str | Path ] = None , stdout_path : Optional [str | Path ] = None ,
21- stderr_path : Optional [str | Path ] = None , resources : Optional [ResourceSpec ] = None ,
22- attributes : Optional [JobAttributes ] = None , pre_launch : Optional [str | Path ] = None ,
23- post_launch : Optional [str | Path ] = None , launcher : Optional [str ] = None ):
33+ stdin_path : Optional [StrOrPath ] = None , stdout_path : Optional [StrOrPath ] = None ,
34+ stderr_path : Optional [StrOrPath ] = None , resources : Optional [ResourceSpec ] = None ,
35+ attributes : Optional [JobAttributes ] = None , pre_launch : Optional [StrOrPath ] = None ,
36+ post_launch : Optional [StrOrPath ] = None , launcher : Optional [str ] = None ):
2437 """
2538 Constructs a `JobSpec` object while allowing its properties to be initialized.
2639
@@ -101,16 +114,18 @@ def __init__(self, name: Optional[str] = None, executable: Optional[str] = None,
101114 self ._name = name
102115 self .executable = executable
103116 self .arguments = arguments
104- self .directory = Path (directory ) if directory is not None else None
117+ # I would do self.directory = directory, because that goes through the setter, which takes
118+ # care of the conversion, but mypy gets confused
119+ self ._directory = _to_path (directory )
105120 self .inherit_environment = inherit_environment
106121 self .environment = environment
107- self .stdin_path = Path (stdin_path ) if stdin_path is not None else None
108- self .stdout_path = Path (stdout_path ) if stdout_path is not None else None
109- self .stderr_path = Path (stderr_path ) if stderr_path is not None else None
122+ self ._stdin_path = _to_path (stdin_path )
123+ self ._stdout_path = _to_path (stdout_path )
124+ self ._stderr_path = _to_path (stderr_path )
110125 self .resources = resources
111126 self .attributes = attributes if attributes is not None else JobAttributes ()
112- self .pre_launch = Path (pre_launch ) if pre_launch is not None else None
113- self .post_launch = Path (post_launch ) if post_launch is not None else None
127+ self ._pre_launch = _to_path (pre_launch )
128+ self ._post_launch = _to_path (post_launch )
114129 self .launcher = launcher
115130
116131 # TODO: `resources` is of type `ResourceSpec`, not `ResourceSpecV1`. An
@@ -126,6 +141,53 @@ def name(self) -> Optional[str]:
126141 return self ._name
127142
128143 @property
144+ def directory (self ) -> Optional [Path ]:
145+ return self ._directory
146+
147+ @directory .setter
148+ def directory (self , directory : Optional [StrOrPath ]) -> None :
149+ self ._directory = _to_path (directory )
150+
151+ @property
152+ def stdin_path (self ) -> Optional [Path ]:
153+ return self ._stdin_path
154+
155+ @stdin_path .setter
156+ def stdin_path (self , stdin_path : Optional [StrOrPath ]) -> None :
157+ self ._stdin_path = _to_path (stdin_path )
158+
159+ @property
160+ def stdout_path (self ) -> Optional [Path ]:
161+ return self ._stdout_path
162+
163+ @stdout_path .setter
164+ def stdout_path (self , stdout_path : Optional [StrOrPath ]) -> None :
165+ self ._stdout_path = _to_path (stdout_path )
166+
167+ @property
168+ def stderr_path (self ) -> Optional [Path ]:
169+ return self ._stderr_path
170+
171+ @stderr_path .setter
172+ def stderr_path (self , stderr_path : Optional [StrOrPath ]) -> None :
173+ self ._stderr_path = _to_path (stderr_path )
174+
175+ @property
176+ def pre_launch (self ) -> Optional [Path ]:
177+ return self ._pre_launch
178+
179+ @pre_launch .setter
180+ def pre_launch (self , pre_launch : Optional [StrOrPath ]) -> None :
181+ self ._pre_launch = _to_path (pre_launch )
182+
183+ @property
184+ def post_launch (self ) -> Optional [Path ]:
185+ return self ._post_launch
186+
187+ @post_launch .setter
188+ def post_launch (self , post_launch : Optional [StrOrPath ]) -> None :
189+ self ._post_launch = _to_path (post_launch )
190+
129191 def _init_job_spec_dict (self ) -> Dict [str , Any ]:
130192 """Returns jobspec structure as dict."""
131193 # convention:
0 commit comments