Skip to content

Commit e326bb8

Browse files
authored
Merge pull request #395 from arosen93/str
Allow for `str` paths as inputs to `JobSpec`
2 parents 64282e0 + 81cba9f commit e326bb8

File tree

2 files changed

+88
-14
lines changed

2 files changed

+88
-14
lines changed

src/psij/job_spec.py

Lines changed: 76 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,39 @@
1+
from __future__ import annotations
2+
13
import sys
24
from pathlib import Path
3-
from typing import Optional, List, Dict, Any
5+
from typing import Any, Dict, List, Optional, Union
46

57
from typeguard import check_argument_types
68

79
from psij.job_attributes import JobAttributes
810
from psij.resource_spec import ResourceSpec
9-
1011
from psij.utils import path_object_to_full_path as o2p
1112

1213

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+
1327
class JobSpec(object):
1428
"""A class to hold information about the characteristics of a:class:`~psij.Job`."""
1529

1630
def __init__(self, executable: Optional[str] = None, arguments: Optional[List[str]] = None,
17-
directory: Optional[Path] = None, name: Optional[str] = None,
31+
directory: Optional[StrOrPath] = None, name: Optional[str] = None,
1832
inherit_environment: bool = True, environment: Optional[Dict[str, str]] = None,
19-
stdin_path: Optional[Path] = None, stdout_path: Optional[Path] = None,
20-
stderr_path: Optional[Path] = None, resources: Optional[ResourceSpec] = None,
21-
attributes: Optional[JobAttributes] = None, pre_launch: Optional[Path] = None,
22-
post_launch: Optional[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):
2337
"""
2438
Constructs a `JobSpec` object while allowing its properties to be initialized.
2539
@@ -100,16 +114,18 @@ def __init__(self, executable: Optional[str] = None, arguments: Optional[List[st
100114
self._name = name
101115
self.executable = executable
102116
self.arguments = arguments
103-
self.directory = directory
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)
104120
self.inherit_environment = inherit_environment
105121
self.environment = environment
106-
self.stdin_path = stdin_path
107-
self.stdout_path = stdout_path
108-
self.stderr_path = stderr_path
122+
self._stdin_path = _to_path(stdin_path)
123+
self._stdout_path = _to_path(stdout_path)
124+
self._stderr_path = _to_path(stderr_path)
109125
self.resources = resources
110126
self.attributes = attributes if attributes is not None else JobAttributes()
111-
self.pre_launch = pre_launch
112-
self.post_launch = post_launch
127+
self._pre_launch = _to_path(pre_launch)
128+
self._post_launch = _to_path(post_launch)
113129
self.launcher = launcher
114130

115131
# TODO: `resources` is of type `ResourceSpec`, not `ResourceSpecV1`. An
@@ -125,6 +141,53 @@ def name(self) -> Optional[str]:
125141
return self._name
126142

127143
@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+
128191
def _init_job_spec_dict(self) -> Dict[str, Any]:
129192
"""Returns jobspec structure as dict."""
130193
# convention:

tests/test_job_spec.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import os
2+
from pathlib import Path
13

24
import pytest
35

4-
from psij import JobSpec, JobExecutor, Job
6+
from psij import Job, JobExecutor, JobSpec
57

68

79
def _test_spec(spec: JobSpec) -> None:
@@ -36,4 +38,13 @@ def test_environment_types() -> None:
3638
assert spec.environment['foo'] == 'biz'
3739

3840

41+
def test_path_conversion() -> None:
42+
assert JobSpec(directory=os.path.join("test", "path")).directory == Path("test") / "path"
43+
assert JobSpec(stdin_path=os.path.join("test", "path")).stdin_path == Path("test") / "path"
44+
assert JobSpec(stdout_path=os.path.join("test", "path")).stdout_path == Path("test") / "path"
45+
assert JobSpec(stderr_path=os.path.join("test", "path")).stderr_path == Path("test") / "path"
46+
assert JobSpec(pre_launch=os.path.join("test", "path")).pre_launch == Path("test") / "path"
47+
assert JobSpec(post_launch=os.path.join("test", "path")).post_launch == Path("test") / "path"
48+
49+
3950
test_environment_types()

0 commit comments

Comments
 (0)