Skip to content

Commit

Permalink
#225: use pathlib
Browse files Browse the repository at this point in the history
  • Loading branch information
kmyk committed Jan 2, 2019
1 parent 230b391 commit d2c28a7
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 34 deletions.
9 changes: 5 additions & 4 deletions onlinejudge/implementation/command/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from typing import *
if TYPE_CHECKING:
import argparse
import pathlib

def convert_sample_to_dict(sample: onlinejudge.type.TestCase) -> dict:
data = {}
Expand Down Expand Up @@ -59,18 +60,18 @@ def download(args: 'argparse.Namespace') -> None:
table['n'] = name
table['b'] = os.path.basename(name)
table['d'] = os.path.dirname(name)
path = os.path.join(args.directory, utils.parcentformat(args.format, table))
path = args.directory / utils.parcentformat(args.format, table) # type: pathlib.Path
log.status('%sput: %s', ext, name)
log.emit(colorama.Style.BRIGHT + data.rstrip() + colorama.Style.RESET_ALL)
if args.dry_run:
continue
if os.path.exists(path):
if path.exists():
log.warning('file already exists: %s', path)
if not args.overwrite:
log.warning('skipped')
continue
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, 'w') as fh:
path.parent.mkdir(parents=True, exist_ok=True)
with path.open('w') as fh:
fh.write(data)
log.success('saved to: %s', path)

Expand Down
6 changes: 3 additions & 3 deletions onlinejudge/implementation/command/generate_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def generate_output(args: 'argparse.Namespace') -> None:
log.info('output file already exists.')
log.info('skipped.')
continue
with open(it['in']) as inf:
with it['in'].open() as inf:
begin = time.perf_counter()
answer, proc = utils.exec_command(args.command, shell=True, stdin=inf)
end = time.perf_counter()
Expand All @@ -33,6 +33,6 @@ def generate_output(args: 'argparse.Namespace') -> None:
log.emit(log.bold(answer.decode().rstrip()))
name = cutils.match_with_format(args.directory, args.format, it['in']).groupdict()['name'] # type: ignore
path = cutils.path_from_format(args.directory, args.format, name=name, ext='out')
with open(path, 'w') as fh:
fh.buffer.write(answer)
with path.open('wb') as fh:
fh.write(answer)
log.success('saved to: %s', path)
9 changes: 5 additions & 4 deletions onlinejudge/implementation/command/submit.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import subprocess
import os
import re
import pathlib
from typing import *
if TYPE_CHECKING:
import argparse
Expand All @@ -21,8 +22,8 @@ def submit(args: 'argparse.Namespace') -> None:
sys.exit(1)

# read code
with open(args.file) as fh:
code = fh.buffer.read()
with args.file.open('rb') as fh:
code = fh.read()
format_config = {
'dos2unix': args.format_dos2unix or args.golf,
'rstrip': args.format_dos2unix or args.golf,
Expand Down Expand Up @@ -138,13 +139,13 @@ def select_ids_of_matched_languages(words: List[str], lang_ids: List[str], langu
result.append(lang_id)
return result

def guess_lang_ids_of_file(filename: str, code: bytes, language_dict, cxx_latest: bool = False, cxx_compiler: str = 'all', python_version: str = 'all', python_interpreter: str = 'all') -> List[str]:
def guess_lang_ids_of_file(filename: pathlib.Path, code: bytes, language_dict, cxx_latest: bool = False, cxx_compiler: str = 'all', python_version: str = 'all', python_interpreter: str = 'all') -> List[str]:
assert cxx_compiler.lower() in ( 'gcc', 'clang', 'all' )
assert python_version.lower() in ( '2', '3', 'auto', 'all' )
assert python_interpreter.lower() in ( 'cpython', 'pypy', 'all' )

select = (lambda word, lang_ids, **kwargs: select_ids_of_matched_languages([ word ], lang_ids, language_dict=language_dict, **kwargs))
_, ext = os.path.splitext(filename)
ext = filename.suffix
lang_ids = language_dict.keys()

log.debug('file extension: %s', ext)
Expand Down
4 changes: 2 additions & 2 deletions onlinejudge/implementation/command/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def print_input():
log.info('%s', name)

# run the binary
with open(it['in']) as inf:
with it['in'].open() as inf:
begin = time.perf_counter()
answer_byte, proc = utils.exec_command(args.command, shell=True, stdin=inf, timeout=args.tle)
end = time.perf_counter()
Expand All @@ -97,7 +97,7 @@ def print_input():

# check WA or not
if 'out' in it:
with open(it['out']) as outf:
with it['out'].open() as outf:
correct = outf.read()
# compare
if args.mode == 'all':
Expand Down
31 changes: 16 additions & 15 deletions onlinejudge/implementation/command/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,53 @@
import sys
import os
import os.path
import pathlib
import re
import glob
import collections
from typing import Dict, List, Match, Optional

def glob_with_format(directory: str, format: str) -> List[str]:
def glob_with_format(directory: pathlib.Path, format: str) -> List[pathlib.Path]:
table = {}
table['s'] = '*'
table['e'] = '*'
pattern = os.path.join(directory, utils.parcentformat(format, table))
paths = glob.glob(pattern)
pattern = str(directory / utils.parcentformat(format, table))
paths = list(map(pathlib.Path, glob.glob(pattern)))
for path in paths:
log.debug('testcase globbed: %s', path)
return paths

def match_with_format(directory: str, format: str, path: str) -> Optional[Match[str]]:
def match_with_format(directory: pathlib.Path, format: str, path: pathlib.Path) -> Optional[Match[str]]:
table = {}
table['s'] = '(?P<name>.+)'
table['e'] = '(?P<ext>in|out)'
pattern = re.compile('^' + utils.parcentformat(format, table) + '$')
path = os.path.normpath(os.path.relpath(path, directory))
return pattern.match(path)
path = path.absolute().relative_to(directory.absolute()).resolve()
return pattern.match(str(path))

def path_from_format(directory: str, format: str, name: str, ext: str) -> str:
def path_from_format(directory: pathlib.Path, format: str, name: str, ext: str) -> pathlib.Path:
table = {}
table['s'] = name
table['e'] = ext
return os.path.join(directory, utils.parcentformat(format, table))
return directory / utils.parcentformat(format, table)

def is_backup_or_hidden_file(path: str) -> bool:
basename = os.path.basename(path)
def is_backup_or_hidden_file(path: pathlib.Path) -> bool:
basename = path.stem
return basename.endswith('~') or (basename.startswith('#') and basename.endswith('#')) or basename.startswith('.')

def drop_backup_or_hidden_files(paths: List[str]) -> List[str]:
result = [] # type: List[str]
def drop_backup_or_hidden_files(paths: List[pathlib.Path]) -> List[pathlib.Path]:
result = [] # type: List[pathlib.Path]
for path in paths:
if is_backup_or_hidden_file(path):
log.warning('ignore a backup file: %s', path)
else:
result += [ path ]
return result

def construct_relationship_of_files(paths: List[str], directory: str, format: str) -> Dict[str, Dict[str, str]]:
tests = collections.defaultdict(dict) # type: Dict[str, Dict[str, str]]
def construct_relationship_of_files(paths: List[pathlib.Path], directory: pathlib.Path, format: str) -> Dict[str, Dict[str, pathlib.Path]]:
tests = collections.defaultdict(dict) # type: Dict[str, Dict[str, pathlib.Path]]
for path in paths:
m = match_with_format(directory, format, os.path.normpath(path))
m = match_with_format(directory, format, path.resolve())
if not m:
log.error('unrecognizable file found: %s', path)
sys.exit(1)
Expand Down
12 changes: 6 additions & 6 deletions onlinejudge/implementation/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def get_parser() -> argparse.ArgumentParser:
''')
subparser.add_argument('url')
subparser.add_argument('-f', '--format', help='a format string to specify paths of cases (defaut: "sample-%%i.%%e" if not --system)') # default must be None for --system
subparser.add_argument('-d', '--directory', default='test', help='a directory name for test cases (default: test/)')
subparser.add_argument('-d', '--directory', type=pathlib.Path, default=pathlib.Path('test'), help='a directory name for test cases (default: test/)')
subparser.add_argument('--overwrite', action='store_true')
subparser.add_argument('-n', '--dry-run', action='store_true', help='don\'t write to files')
subparser.add_argument('-a', '--system', action='store_true', help='download system testcases')
Expand Down Expand Up @@ -108,7 +108,7 @@ def get_parser() -> argparse.ArgumentParser:
TopCoder (Marathon Match)
''')
subparser.add_argument('url')
subparser.add_argument('file')
subparser.add_argument('file', type=pathlib.Path)
subparser.add_argument('-l', '--language', help='narrow down language choices if ambiguous')
subparser.add_argument('--no-guess', action='store_false', dest='guess')
subparser.add_argument('-g', '--guess', action='store_true', help='guess the language for your file (default)')
Expand Down Expand Up @@ -143,7 +143,7 @@ def get_parser() -> argparse.ArgumentParser:
''')
subparser.add_argument('-c', '--command', default='./a.out', help='your solution to be tested. (default: "./a.out")')
subparser.add_argument('-f', '--format', default='%s.%e', help='a format string to recognize the relationship of test cases. (default: "%%s.%%e")')
subparser.add_argument('-d', '--directory', default='test', help='a directory name for test cases (default: test/)')
subparser.add_argument('-d', '--directory', type=pathlib.Path, default=pathlib.Path('test'), help='a directory name for test cases (default: test/)')
subparser.add_argument('-m', '--mode', choices=[ 'all', 'line' ], default='all', help='mode to check an output with the correct answer. (default: all)')
subparser.add_argument('-1', '--line', dest='mode', action='store_const', const='line', help='equivalent to --mode line')
subparser.add_argument('--no-rstrip', action='store_false', dest='rstrip')
Expand All @@ -154,7 +154,7 @@ def get_parser() -> argparse.ArgumentParser:
subparser.add_argument('-i', '--print-input', action='store_true', help='print input cases if not AC')
subparser.add_argument('--no-ignore-backup', action='store_false', dest='ignore_backup')
subparser.add_argument('--ignore-backup', action='store_true', help='ignore backup files and hidden files (i.e. files like "*~", "\\#*\\#" and ".*") (default)')
subparser.add_argument('test', nargs='*', help='paths of test cases. (if empty: globbed from --format)')
subparser.add_argument('test', nargs='*', type=pathlib.Path, help='paths of test cases. (if empty: globbed from --format)')

# generate scanner
subparser = subparsers.add_parser('generate-scanner',
Expand Down Expand Up @@ -204,8 +204,8 @@ def get_parser() -> argparse.ArgumentParser:
''')
subparser.add_argument('-c', '--command', default='./a.out', help='your solution to be tested. (default: "./a.out")')
subparser.add_argument('-f', '--format', default='%s.%e', help='a format string to recognize the relationship of test cases. (default: "%%s.%%e")')
subparser.add_argument('-d', '--directory', default='test', help='a directory name for test cases (default: test/)')
subparser.add_argument('test', nargs='*', help='paths of input cases. (if empty: globbed from --format)')
subparser.add_argument('-d', '--directory', type=pathlib.Path, default=pathlib.Path('test'), help='a directory name for test cases (default: test/)')
subparser.add_argument('test', nargs='*', type=pathlib.Path, help='paths of input cases. (if empty: globbed from --format)')
subparser.add_argument('--no-ignore-backup', action='store_false', dest='ignore_backup')
subparser.add_argument('--ignore-backup', action='store_true', help='ignore backup files and hidden files (i.e. files like "*~", "\\#*\\#" and ".*") (default)')

Expand Down

0 comments on commit d2c28a7

Please sign in to comment.