comparison upreckon/problem.py @ 193:a76cdc26ba9d

Added conf. var. match and match='regexp' for non-archives Specify match='regexp', and your tests and dummies will be treated as regular expressions describing test case identifiers. Every file that is in a suitable location and whose name matches {testcase,dummy}inname and the given regexp will be treated as a file with test case input data. You are free to use backreferences in the regexps, but group numbering starts at two rather than one. If you want test groups, you can get them magically created for you by putting a part of the test ID in a group in the regexp sense and specifying the tests variable as a pair consisting of the regexp itself and the number of this regexp group (remember group numbers start at two).
author Oleg Oshmyan <chortos@inbox.lv>
date Thu, 11 Aug 2011 23:20:52 +0300
parents 0480dfa50366
children 67088c1765b4
comparison
equal deleted inserted replaced
192:6e6b0ea63fa1 193:a76cdc26ba9d
2 2
3 from __future__ import division, with_statement 3 from __future__ import division, with_statement
4 4
5 from .compat import * 5 from .compat import *
6 from .exceptions import * 6 from .exceptions import *
7 from . import config, testcases 7 from . import config, files, testcases
8 from __main__ import options 8 from __main__ import options
9 9
10 import os, re, sys 10 import os, re, sys
11 11
12 try: 12 try:
245 prob.config.dummies = tuple(prob.config.dummies) 245 prob.config.dummies = tuple(prob.config.dummies)
246 try: 246 try:
247 len(prob.config.tests) 247 len(prob.config.tests)
248 except Exception: 248 except Exception:
249 prob.config.tests = tuple(prob.config.tests) 249 prob.config.tests = tuple(prob.config.tests)
250
251 if prob.config.match == 're':
252 if not prob.config.usegroups:
253 prob.config.tests = prob.config.tests, None
254 elif isinstance(prob.config.tests, basestring):
255 prob.config.tests = prob.config.tests, 2
256 parts = tuple(map(re.escape, prob.config.dummyinname.split('$')))
257 probname = re.escape(prob.name) + '/' if prob.name != os.curdir else ''
258 path = '%s%s(%s)' % (probname, parts[0], prob.config.dummies)
259 path += r'\1'.join(parts[1:])
260 prob.config.dummies = regexp(path, None)
261 parts = tuple(map(re.escape, prob.config.testcaseinname.split('$')))
262 path = '%s%s(%s)' % (probname, parts[0], prob.config.tests[0])
263 path += r'\1'.join(parts[1:])
264 prob.config.tests = regexp(path, prob.config.tests[1])
250 265
251 if options.legacy: 266 if options.legacy:
252 prob.config.usegroups = False 267 prob.config.usegroups = False
253 newtests = [] 268 newtests = []
254 for name in prob.config.tests: 269 for name in prob.config.tests:
333 yield 348 yield
334 for j, i in enumerate(prob.config.tests): 349 for j, i in enumerate(prob.config.tests):
335 s = str(i).zfill(prob.config.padtests) 350 s = str(i).zfill(prob.config.padtests)
336 if (yield _types[prob.config.kind](prob, s, False, getpoints(i, j))): 351 if (yield _types[prob.config.kind](prob, s, False, getpoints(i, j))):
337 yield 352 yield
353
354 def regexp(pattern, group):
355 reobj = re.compile(pattern, re.UNICODE)
356 if not group:
357 ids = []
358 for path, vpath in files.regexp(pattern):
359 ids.append(re.match(reobj, vpath).group(1))
360 return natsorted(ids)
361 else:
362 ids = {}
363 for path, vpath in files.regexp(pattern):
364 m = re.match(reobj, vpath)
365 g = m.group(group)
366 ids.setdefault(g, [])
367 ids[g].append(m.group(1))
368 for g in ids:
369 ids[g] = natsorted(ids[g])
370 return [ids[g] for g in natsorted(keys(ids))]
371
372 def natsorted(l):
373 return sorted(l, key=lambda s: [int(t) if t.isdigit() else t for t in re.split('(\d+)', s)])