# HG changeset patch # User Oleg Oshmyan # Date 1380752349 -10800 # Node ID f5847d29e838078fe6722ad242c1db1e7912f229 # Parent 6dd29475ae9b2ba302fe43950e85b3cbf3c506ab# Parent 1bc89faac9418b3e57bc9520b92ba8512161c4d8 Fixed: match='re' could produce duplicate test identifiers files.Files.regexp(pattern) now makes sure to return only one metafile for each matching virtual path, namely, the one that would be returned for that virtual path by files.Files.from_virtual_path. diff -r 1bc89faac941 -r f5847d29e838 .hgtags --- a/.hgtags Thu Oct 03 01:19:09 2013 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -478d4217fe0381a1bffc636d7e823dba41cc0f25 2.04.0 diff -r 1bc89faac941 -r f5847d29e838 setup-exe.py --- a/setup-exe.py Thu Oct 03 01:19:09 2013 +0300 +++ b/setup-exe.py Thu Oct 03 01:19:09 2013 +0300 @@ -30,7 +30,7 @@ os.rename('upreckon/unix.py', 'upreckon/unix.py~') try: setup(name='Upreckon', - version='2.04.0', + version='2.05.0dev', author='Oleg Oshmyan', author_email='chortos@inbox.lv', url='http://chortos.selfip.net/~astiob/upreckon/', diff -r 1bc89faac941 -r f5847d29e838 setup.py --- a/setup.py Thu Oct 03 01:19:09 2013 +0300 +++ b/setup.py Thu Oct 03 01:19:09 2013 +0300 @@ -28,7 +28,7 @@ ext_modules = [] setup(name='upreckon', - version='2.04.0', + version='2.05.0dev', author='Oleg Oshmyan', author_email='chortos@inbox.lv', url='http://chortos.selfip.net/~astiob/upreckon/', diff -r 1bc89faac941 -r f5847d29e838 upreckon/files.py --- a/upreckon/files.py Thu Oct 03 01:19:09 2013 +0300 +++ b/upreckon/files.py Thu Oct 03 01:19:09 2013 +0300 @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2011 Chortos-2 +# Copyright (c) 2010-2013 Chortos-2 """File access routines and classes with support for archives.""" @@ -8,7 +8,7 @@ import contextlib, os, posixpath, re, shutil # You don't need to know about anything else. -__all__ = 'File', 'regexp' +__all__ = 'File', # In these two variables, use full stops no matter what os.extsep is; # all full stops will be converted to os.extsep on the fly @@ -279,11 +279,11 @@ return None cand = (self + virtpath[0])._realize_path(virtpath[1:], allow_root) if cand: return cand - if not cand and not self._has_tests: + if not self._has_tests: for metafile in self._add_tests(): cand = metafile._realize_path(virtpath, allow_root) if cand: return cand - if not cand and len(virtpath) > 1: + if len(virtpath) > 1: metafile = self._add_virtual(virtpath[0]) cand = metafile._realize_path(virtpath[1:], allow_root) if cand: return cand diff -r 1bc89faac941 -r f5847d29e838 upreckon/upreckon-vcs --- a/upreckon/upreckon-vcs Thu Oct 03 01:19:09 2013 +0300 +++ b/upreckon/upreckon-vcs Thu Oct 03 01:19:09 2013 +0300 @@ -7,12 +7,14 @@ from upreckon import compat from upreckon.compat import * -parser = optparse.OptionParser(version='Upreckon 2.04.0 ($$REV$$)', epilog='Python 2.6 or newer is required.') +parser = optparse.OptionParser(version='Upreckon 2.05.0 ($$REV$$)', epilog='Python 2.6 or newer is required.') parser.add_option('-1', dest='legacy', action='store_true', default=False, help='handle configuration files in a way more compatible with test.py 1.x') parser.add_option('-p', '--problem', dest='problems', metavar='PROBLEM', action='append', help='test only the PROBLEM (this option can be specified more than once with different problem names, all of which will be tested)') parser.add_option('--list-problems', action='store_true', default=False, help='just list all problem names') +parser.add_option('-c', '--cleanup', dest='cleanup', action='store_true', default=False, help='delete the copies of input/output files and exit') +parser.add_option('-m', '--copy-io', dest='copyonly', action='store_true', default=False, help='create a copy of the input/output files of the last test case for manual testing and exit') parser.add_option('-x', '--auto-exit', dest='pause', action='store_false', default=True, help='do not wait for a key to be pressed after finishing testing') -parser.add_option('-s', '--save-io', dest='erase', action='store_false', default=True, help='do not delete the copies of input/output files after the last test case; create copies of input files and store output in files even if the solution uses standard I/O') +parser.add_option('-s', '--save-io', dest='erase', action='store_false', default=True, help='do not delete the copies of input/output files after the last test case; create copies of input files and store output in files even if the solution uses standard I/O; delete the stored input/output files if the solution uses standard I/O and the -c/--cleanup option is specified') parser.add_option('-k', '--skim', action='store_true', default=False, help='skip test groups as soon as one test case is failed') parser.add_option('--no-time-limits', dest='no_maxtime', action='store_true', default=False, help='disable all time limits') @@ -74,16 +76,24 @@ for taskname in options.problems or globalconf.problems: problem = Problem(taskname) - if ntasks: say() + if ntasks and not (options.cleanup or options.copyonly): say() if shouldprintnames: say(taskname) - real, max = problem.test() + if options.cleanup: + problem.cleanup() + elif options.copyonly: + problem.copytestdata() + else: + real, max = problem.test() ntasks += 1 nfulltasks += real == max realscore += real maxscore += max + if options.cleanup or options.copyonly: + sys.exit() + if ntasks != 1: say() say('Grand total: %g/%g weighted points; %d/%d problems solved fully' % (realscore, maxscore, nfulltasks, ntasks))