def compile_inputs_outputs(runs, inputs, outputs): """Gives names to input/output files and creates InputOutputFile objects. """ # {path: (run_nb, arg_nb) or None} runs_with_file = {} # run_nb: number_of_file_arguments nb_file_args = [] # {path: [runs]} readers = {} writers = {} for run_nb, run, in_files, out_files in zip(count(), runs, inputs, outputs): # List which runs read or write each file for p in in_files: readers.setdefault(p, []).append(run_nb) for p in out_files: writers.setdefault(p, []).append(run_nb) # Locate files that appear on a run's command line files_set = set(in_files) | set(out_files) nb_files = 0 for arg_nb, arg in enumerate(run['argv']): p = Path(run['workingdir'], arg).resolve() if p in files_set: nb_files += 1 if p not in runs_with_file: runs_with_file[p] = run_nb, arg_nb elif runs_with_file[p] is not None: runs_with_file[p] = None nb_file_args.append(nb_files) file_names = {} make_unique = UniqueNames() for fi in flatten(2, (inputs, outputs)): if fi in file_names: continue # If it appears in at least one of the command-lines if fi in runs_with_file: # If it only appears once in the command-lines if runs_with_file[fi] is not None: run_nb, arg_nb = runs_with_file[fi] parts = [] # Run number, if there are more than one runs if len(runs) > 1: parts.append(run_nb) # Argument number, if there are more than one file arguments if nb_file_args[run_nb] > 1: parts.append(arg_nb) file_names[fi] = make_unique('arg%s' % '_'.join('%s' % s for s in parts)) else: file_names[fi] = make_unique('arg_%s' % fi.unicodename) else: file_names[fi] = make_unique(fi.unicodename) return dict((n, InputOutputFile(p, readers.get(p, []), writers.get(p, []))) for p, n in file_names.items())
def test_uniquenames(self): """Tests UniqueNames.""" u = UniqueNames() self.assertEqual(u('test'), 'test') self.assertEqual(u('test'), 'test_2') self.assertEqual(u('test'), 'test_3') self.assertEqual(u('test_2'), 'test_2_2') self.assertEqual(u('test_'), 'test_') self.assertEqual(u('test_'), 'test__2')