Skip to content

Commit a399d07

Browse files
committed
allow int env values in job spec
1 parent 5b6eb02 commit a399d07

File tree

8 files changed

+26
-20
lines changed

8 files changed

+26
-20
lines changed

src/psij/executors/batch/batch_scheduler_executor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ def _env_to_mustache(job: Job) -> List[Dict[str, str]]:
5353

5454
r = []
5555
for k, v in job.spec.environment.items():
56-
r.append({'name': k, 'value': bash_escape(v)})
56+
r.append({'name': k, 'value': bash_escape(str(v))})
57+
5758
return r
5859

5960

src/psij/executors/local.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ def _get_env(spec: JobSpec) -> Optional[Dict[str, str]]:
9898
# merge current env with spec env
9999
env = os.environ.copy()
100100
env.update(spec.environment)
101+
# convert integers to strings
102+
for k, v in env.items():
103+
if isinstance(v, int):
104+
env[k] = str(v)
101105
return env
102106
else:
103107
# only spec env

src/psij/job_executor.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def _check_job(self, job: Job) -> JobSpec:
6767
Verifies that various aspects of the job are correctly specified. This includes precisely
6868
the following checks:
6969
* the job has a non-null specification
70-
* job.spec.environment is a Dict[str, str]
70+
* job.spec.environment is a Dict[str, [str | int]]
7171
7272
While this method makes a fair attempt at ensuring the validity of the job, it makes no
7373
such guarantees. Specifically, if an executor implementation requires checks not listed
@@ -101,9 +101,9 @@ def _check_job(self, job: Job) -> JobSpec:
101101
if not isinstance(k, str):
102102
raise TypeError('environment key "%s" is not a string (%s)'
103103
% (k, type(k).__name__))
104-
if not isinstance(v, str):
105-
raise TypeError('environment key "%s" has non-string value (%s)'
106-
% (k, type(v).__name__))
104+
if not isinstance(v, (str, int)):
105+
raise TypeError('environment value for key "%s" must be string '
106+
'or int type (%s)' % (k, type(v).__name__))
107107

108108
job.executor = self
109109
return spec

src/psij/job_spec.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import sys
22
from pathlib import Path
3-
from typing import Optional, List, Dict, Any
3+
from typing import Optional, List, Dict, Any, Union
44

55
from typeguard import check_argument_types
66

@@ -15,7 +15,8 @@ class JobSpec(object):
1515

1616
def __init__(self, name: Optional[str] = None, executable: Optional[str] = None,
1717
arguments: Optional[List[str]] = None, directory: Optional[Path] = None,
18-
inherit_environment: bool = True, environment: Optional[Dict[str, str]] = None,
18+
inherit_environment: bool = True,
19+
environment: Optional[Dict[str, Union[str, int]]] = None,
1920
stdin_path: Optional[Path] = None, stdout_path: Optional[Path] = None,
2021
stderr_path: Optional[Path] = None, resources: Optional[ResourceSpec] = None,
2122
attributes: Optional[JobAttributes] = None, pre_launch: Optional[Path] = None,

tests/plugins1/_batch_test/test/test.mustache

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ export {{key}}="{{value}}"
2222
{{/custom_attributes.test}}
2323
{{/job.spec.attributes}}
2424

25-
{{#job.spec.inherit_environment}}env \{{/job.spec.inherit_environment}}{{^job.spec.inherit_environment}}env --ignore-environment \{{/job.spec.inherit_environment}}{{#env}}
26-
{{name}}="{{value}}" \
25+
{{#job.spec.inherit_environment}}env \
26+
{{/job.spec.inherit_environment}}{{^job.spec.inherit_environment}}env --ignore-environment \{{/job.spec.inherit_environment}}{{#env}} {{name}}="{{value}}" \
2727
{{/env}}{{#psij.launch_command}}{{.}} {{/psij.launch_command}}
2828

29-
echo "$?" > "{{psij.script_dir}}/$PSIJ_BATCH_TEST_JOB_ID.ec"
29+
echo "$?" > "{{psij.script_dir}}/$PSIJ_BATCH_TEST_JOB_ID.ec"

tests/test_doc_examples.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def test_job_parameters() -> None:
112112
psij.JobSpec(
113113
executable="/bin/hostname",
114114
stdout_path=output_path,
115-
environment={"FOOBAR": "BAZ"}, # custom environment has no effect here
115+
environment={"FOOBAR": "BAZ", "BUZ": 1}, # custom environment has no effect here
116116
directory=pathlib.Path(td), # CWD has no effect on result here
117117
)
118118
)

tests/test_executor.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,19 @@ def test_env_var(execparams: ExecutorTestParams) -> None:
117117
_make_test_dir()
118118
with TemporaryDirectory(dir=Path.home() / '.psij' / 'test') as td:
119119
outp = Path(td, 'stdout.txt')
120-
job = Job(JobSpec(executable='/bin/bash', arguments=['-c', 'echo -n $TEST_VAR'],
120+
job = Job(JobSpec(executable='/bin/bash',
121+
arguments=['-c', 'env > /tmp/t; echo -n $TEST_VAR$TEST_INT'],
121122
stdout_path=outp))
122123
assert job.spec is not None
123-
job.spec.environment = {'TEST_VAR': '_y_'}
124+
job.spec.environment = {'TEST_INT': 1, 'TEST_VAR': '_y_'}
124125
ex = _get_executor_instance(execparams, job)
125126
ex.submit(job)
126127
status = job.wait(timeout=_get_timeout(execparams))
127128
assert_completed(job, status)
128129
f = outp.open("r")
129130
contents = f.read()
130131
f.close()
131-
assert contents == '_y_'
132+
assert contents == '_y_1'
132133

133134

134135
def test_stdin_redirect(execparams: ExecutorTestParams) -> None:

tests/test_job_spec.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,14 @@ def _test_spec(spec: JobSpec) -> None:
1010

1111

1212
def test_environment_types() -> None:
13-
with pytest.raises(TypeError):
14-
_test_spec(JobSpec(environment={'foo': 1})) # type: ignore
1513

1614
with pytest.raises(TypeError):
17-
_test_spec(JobSpec(environment={1: 'foo'})) # type: ignore
15+
_test_spec(JobSpec(executable='true', environment={1: 'foo'})) # type: ignore
1816

1917
with pytest.raises(TypeError):
20-
spec = JobSpec()
18+
spec = JobSpec(executable='true')
2119
spec.environment = {'foo': 'bar'}
22-
spec.environment['buz'] = 2 # type: ignore
20+
spec.environment['buz'] = [2] # type: ignore
2321
_test_spec(spec)
2422

2523
spec = JobSpec()
@@ -32,8 +30,9 @@ def test_environment_types() -> None:
3230
spec.environment = {'foo': 'bar'}
3331
assert spec.environment['foo'] == 'bar'
3432

35-
spec.environment = {'foo': 'biz'}
33+
spec.environment = {'foo': 'biz', 'bar': 42}
3634
assert spec.environment['foo'] == 'biz'
35+
assert spec.environment['bar'] == 42
3736

3837

3938
test_environment_types()

0 commit comments

Comments
 (0)