@@ -212,40 +212,33 @@ def emit_preamble(self, job):
212212 )
213213 )
214214
215- constraints = []
216- constraint_parser = ArgumentParser ()
217- constraint_parser .add_argument ('-C' , '--constraint' )
218- if not self ._sched_access_in_submit :
219- for opt in job .sched_access :
220- if not opt .strip ().startswith (('-C' , '--constraint' )):
221- preamble .append ('%s %s' % (self ._prefix , opt ))
222-
223- # To avoid overriding a constraint that's passed into
224- # `sched_access`, we AND it with the `--constraint` option
225- # passed either in `options` or in `cli_options`
226- parsed_options , _ = constraint_parser .parse_known_args (
227- job .sched_access
228- )
229- if parsed_options .constraint :
230- constraints .append (parsed_options .constraint .strip ())
231-
232- # NOTE: Here last of the passed --constraint job options is taken
233- # into account in order to respect the behavior of slurm.
234- parsed_options , _ = constraint_parser .parse_known_args (
235- job .options + job .cli_options
236- )
237- if parsed_options .constraint :
238- constraints .append (parsed_options .constraint .strip ())
239-
240- if constraints :
241- if len (constraints ) == 1 :
242- constr = constraints [0 ]
215+ # Combine constraints in `sched_access`
216+ #
217+ # We AND the constraints defined in `sched_access` with those in
218+ # either the `job.options` or `job.cli_options`. We essentially "move"
219+ # the option from the source option list to `sched_access` as if the
220+ # user has specified all the constraint in `sched_access`. We can then
221+ # move with the preamble generation or the submission normally.
222+ c_parser = ArgumentParser ()
223+ c_parser .add_argument ('-C' , '--constraint' )
224+ access , access_other = c_parser .parse_known_args (job .sched_access )
225+ job_opts , other_job_opts = c_parser .parse_known_args (job .options )
226+ cli_opts , other_cli_opts = c_parser .parse_known_args (job .cli_options )
227+ if access .constraint and (job_opts .constraint or cli_opts .constraint ):
228+ constraints = [access .constraint ]
229+ if job_opts .constraint :
230+ constraints .append (job_opts .constraint )
231+ job .options = other_job_opts
243232 else :
244- # Parenthesize the constraints prior to joining them with `&`
245- # to make sure that precedence is respected.
246- constr = '&' .join (f'({ c } )' for c in constraints )
233+ constraints .append (cli_opts .constraint )
234+ job ._cli_options = other_cli_opts
235+
236+ arg = '&' .join (f'({ c .strip ()} )' for c in constraints )
237+ job ._sched_access = [f'--constraint={ arg } ' ]
247238
248- preamble .append (self ._format_option (constr , '--constraint={0}' ))
239+ if not self ._sched_access_in_submit :
240+ for opt in job .sched_access :
241+ preamble .append (f'{ self ._prefix } { opt } ' )
249242
250243 preamble .append (self ._format_option (hint , '--hint={0}' ))
251244 prefix_patt = re .compile (r'(#\w+)' )
0 commit comments