Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

executors: fully type every single executor #1147

Merged
merged 47 commits into from
Dec 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
7f2aef8
executors: refactor runtime versions and autoconfig types
quantum5 Sep 22, 2021
5ba5d57
executors: simplify autoconfig types in Assembly executors
quantum5 Sep 22, 2021
10d0a7e
executors: simplify autoconfig types in GCC executors
quantum5 Sep 22, 2021
b6aba68
executors: use f-strings in ScriptExecutor
quantum5 Sep 22, 2021
f6a912e
executors: use f-strings __init__.py
quantum5 Sep 22, 2021
52b8a84
executors: add types to Ada executor
quantum5 Sep 22, 2021
2542711
executors: add types to awk executor
quantum5 Sep 22, 2021
6389fd3
executors: add types to bash executor
quantum5 Sep 22, 2021
13423e6
executors: add types to COBOL executor
quantum5 Sep 22, 2021
4a0f036
executors: detect newer versions of clang
quantum5 Sep 22, 2021
7d9c594
executors: add types to CoffeeScript executor
quantum5 Sep 22, 2021
af96dac
executors: add types to C++ executors
quantum5 Sep 22, 2021
e17de35
executors: fix types in Clang executors
kiritofeng Dec 25, 2023
85fa20c
executors: add types to D executor
quantum5 Sep 22, 2021
66fc364
executors: add types to Dart executor
quantum5 Sep 22, 2021
57760f7
executors: add types to Forth executor
quantum5 Sep 22, 2021
a67dd5e
executors: add types to Go executor
quantum5 Sep 22, 2021
b8e8160
executors: fix types in Java executor
quantum5 Sep 22, 2021
ae72ea9
executors: add types to Groovy executor
quantum5 Sep 22, 2021
5a3bd2a
executors: add types to Haskell executor
quantum5 Sep 22, 2021
59cfeff
executors: add types to Kotlin executor
quantum5 Sep 22, 2021
66fe7b9
executors: fix types in LLC executor
kiritofeng Dec 25, 2023
63b120a
executors: add types to Lua executor
quantum5 Sep 22, 2021
e5c354a
executors: add types to INTERCAL executor
quantum5 Sep 22, 2021
5682b6c
executors: add types to executor mixins
quantum5 Sep 22, 2021
2961ba1
executors: add types to Mono executors
quantum5 Sep 22, 2021
8dbae08
executors: add types to Objective C executor
quantum5 Sep 22, 2021
07315a5
executors: add types to OCaml executor
quantum5 Sep 22, 2021
8cdf4d2
executors: add types to Pascal executor
quantum5 Sep 22, 2021
7173dca
executors: add types to Perl executor
quantum5 Sep 22, 2021
f856a46
executors: add types to PHP executor
quantum5 Sep 22, 2021
6450cf1
executors: add types to Prolog executor
quantum5 Sep 22, 2021
2397ef1
executors: fix types in Python executors
kiritofeng Dec 25, 2023
ddfa464
executors: detect newer versions of Python 3
quantum5 Sep 22, 2021
c67986c
executors: add types to PyPy executor
quantum5 Sep 22, 2021
2a3bd01
executors: add types to Racket executor
quantum5 Sep 22, 2021
06132bc
executors: add types to Ruby executor
quantum5 Sep 22, 2021
81d4261
executors: add types to Rust executor
quantum5 Sep 22, 2021
52f337d
executors: add types to Scala executor
quantum5 Sep 22, 2021
eb5ae4e
executors: add types to Scheme executor
quantum5 Sep 22, 2021
50d8dcf
executors: add types to Sed executor
quantum5 Sep 22, 2021
f3724f0
executors: add types to Swift executor
quantum5 Sep 22, 2021
3f343ce
executors: add types to Tcl executor
quantum5 Sep 22, 2021
744b052
executors: add types to Turing executor
quantum5 Sep 22, 2021
1e5067c
executors: add types to v8 executor
quantum5 Sep 22, 2021
d55f325
executors: add types to Zig executor
quantum5 Sep 22, 2021
06e9043
executors: make autoconfig use f-strings
quantum5 Sep 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion dmoj/executors/ADA.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from typing import List

from dmoj.executors.base_executor import VersionFlags
from .gcc_executor import GCCExecutor


Expand All @@ -13,5 +16,5 @@ class Executor(GCCExecutor):
"""

@classmethod
def get_version_flags(cls, command):
def get_version_flags(cls, command: str) -> List[VersionFlags]:
return ['--version']
11 changes: 8 additions & 3 deletions dmoj/executors/AWK.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from typing import List

from dmoj.executors.base_executor import VersionFlags
from dmoj.executors.script_executor import ScriptExecutor


Expand All @@ -8,9 +11,11 @@ class Executor(ScriptExecutor):
syscalls = ['getgroups'] # gawk is annoying.
test_program = '{ print $0 }'

def get_cmdline(self, **kwargs):
return [self.get_command(), '-f', self._code]
def get_cmdline(self, **kwargs) -> List[str]:
command = self.get_command()
assert command is not None
return [command, '-f', self._code]

@classmethod
def get_version_flags(cls, command):
def get_version_flags(cls, command: str) -> List[VersionFlags]:
return ['-Wversion', '--version']
4 changes: 3 additions & 1 deletion dmoj/executors/BASH.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import List

from dmoj.executors.shell_executor import ShellExecutor


Expand All @@ -6,5 +8,5 @@ class Executor(ShellExecutor):
command = 'bash'
test_program = 'exec cat'

def get_cmdline(self, **kwargs):
def get_cmdline(self, **kwargs) -> List[str]:
return ['bash', self._code]
12 changes: 8 additions & 4 deletions dmoj/executors/CBL.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import subprocess
from typing import Any, Dict, List

from dmoj.cptbox.filesystem_policies import ExactFile
from dmoj.executors.compiled_executor import CompiledExecutor
Expand All @@ -20,13 +21,16 @@ class Executor(CompiledExecutor):
STOP RUN.
""" # noqa: W191

def get_compile_args(self):
return [self.get_command(), '-x', '-free', self._code]
def get_compile_args(self) -> List[str]:
command = self.get_command()
assert command is not None
assert self._code is not None
return [command, '-x', '-free', self._code]

def get_compile_popen_kwargs(self):
def get_compile_popen_kwargs(self) -> Dict[str, Any]:
return {'stdout': subprocess.PIPE, 'stderr': subprocess.STDOUT}

def get_compile_output(self, process):
def get_compile_output(self, process) -> bytes:
output = super().get_compile_output(process)
# Some versions of the compiler have the first letter capitalized, and
# others don't.
Expand Down
4 changes: 2 additions & 2 deletions dmoj/executors/CLANG.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from dmoj.executors.C import Executor as CExecutor
from dmoj.executors.clang_executor import ClangExecutor
from dmoj.executors.clang_executor import CLANG_VERSIONS, ClangExecutor


class Executor(ClangExecutor, CExecutor):
command = 'clang'
command_paths = ['clang-%s' % i for i in ['3.9', '3.8', '3.7', '3.6', '3.5']] + ['clang']
command_paths = [f'clang-{i}' for i in CLANG_VERSIONS] + ['clang']
4 changes: 2 additions & 2 deletions dmoj/executors/CLANGX.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from dmoj.executors.CPP14 import Executor as CPP14Executor
from dmoj.executors.clang_executor import ClangExecutor
from dmoj.executors.clang_executor import CLANG_VERSIONS, ClangExecutor


class Executor(ClangExecutor, CPP14Executor):
command = 'clang++'
command_paths = ['clang++-%s' % i for i in ['3.9', '3.8', '3.7', '3.6', '3.5']] + ['clang++']
command_paths = [f'clang++-{i}' for i in CLANG_VERSIONS] + ['clang++']
19 changes: 11 additions & 8 deletions dmoj/executors/COFFEE.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
from typing import Dict, List, Optional, Tuple

from dmoj.cptbox.filesystem_policies import ExactFile
from dmoj.cptbox.filesystem_policies import ExactFile, FilesystemAccessRule
from dmoj.executors.script_executor import ScriptExecutor


Expand All @@ -26,21 +27,23 @@ class Executor(ScriptExecutor):
address_grace = 1048576

@classmethod
def initialize(cls):
def initialize(cls) -> bool:
if 'coffee' not in cls.runtime_dict or not os.path.isfile(cls.runtime_dict['coffee']):
return False
return super().initialize()

def get_cmdline(self, **kwargs):
return [self.get_command(), self.runtime_dict['coffee'], self._code]
def get_cmdline(self, **kwargs) -> List[str]:
command = self.get_command()
assert command is not None
return [command, self.runtime_dict['coffee'], self._code]

def get_fs(self):
def get_fs(self) -> List[FilesystemAccessRule]:
return super().get_fs() + [ExactFile(self.runtime_dict['coffee']), ExactFile(self._code)]

@classmethod
def get_versionable_commands(cls):
return ('coffee', cls.runtime_dict['coffee']), ('node', cls.runtime_dict['node'])
def get_versionable_commands(cls) -> List[Tuple[str, str]]:
return [('coffee', cls.runtime_dict['coffee']), ('node', cls.runtime_dict['node'])]

@classmethod
def get_find_first_mapping(cls):
def get_find_first_mapping(cls) -> Optional[Dict[str, List[str]]]:
return {'node': ['nodejs', 'node'], 'coffee': ['coffee']}
9 changes: 7 additions & 2 deletions dmoj/executors/D.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import List

from dmoj.cptbox.filesystem_policies import ExactFile
from dmoj.executors.compiled_executor import CompiledExecutor

Expand All @@ -18,5 +20,8 @@ class Executor(CompiledExecutor):
"""
source_filename_format = 'main.{ext}'

def get_compile_args(self):
return [self.get_command(), '-O', '-inline', '-release', '-w', self._code, '-of%s' % self.problem]
def get_compile_args(self) -> List[str]:
command = self.get_command()
assert command is not None
assert self._code is not None
return [command, '-O', '-inline', '-release', '-w', self._code, f'-of{self.problem}']
15 changes: 11 additions & 4 deletions dmoj/executors/DART.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import List

from dmoj.cptbox.filesystem_policies import ExactFile, RecursiveDir
from dmoj.executors.compiled_executor import CompiledExecutor

Expand Down Expand Up @@ -27,11 +29,16 @@ class Executor(CompiledExecutor):
'ftruncate',
]

def get_compile_args(self):
return [self.get_command(), '--snapshot=%s' % self.get_compiled_file(), self._code]
def get_compile_args(self) -> List[str]:
command = self.get_command()
assert command is not None
assert self._code is not None
return [command, f'--snapshot={self.get_compiled_file()}', self._code]

def get_cmdline(self, **kwargs):
return [self.get_command(), self.get_compiled_file()]
def get_cmdline(self, **kwargs) -> List[str]:
command = self.get_command()
assert command is not None
return [command, self.get_compiled_file()]

def get_executable(self):
return self.get_command()
9 changes: 7 additions & 2 deletions dmoj/executors/FORTH.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import List

from dmoj.executors.script_executor import ScriptExecutor


Expand All @@ -10,5 +12,8 @@ class Executor(ScriptExecutor):
HELLO
"""

def get_cmdline(self, **kwargs):
return [self.get_command(), self._code, '-e', 'bye']
def get_cmdline(self, **kwargs) -> List[str]:
command = self.get_command()
assert command is not None
assert self._code is not None
return [command, self._code, '-e', 'bye']
18 changes: 12 additions & 6 deletions dmoj/executors/GO.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import os
import re
from typing import Dict, List

from dmoj.cptbox.filesystem_policies import ExactFile
from dmoj.error import CompileError
from dmoj.executors.base_executor import VersionFlags
from dmoj.executors.compiled_executor import CompiledExecutor

reinline_comment = re.compile(br'//.*?(?=[\r\n])')
recomment = re.compile(br'/\*.*?\*/', re.DOTALL)
repackage = re.compile(br'\s*package\s+main\b')


def decomment(x):
def decomment(x: bytes) -> bytes:
return reinline_comment.sub(b'', recomment.sub(b'', x))


Expand Down Expand Up @@ -41,7 +43,8 @@ class Executor(CompiledExecutor):
fmt.Print(text)
}"""

def get_compile_env(self):
def get_compile_env(self) -> Dict[str, str]:
assert self._dir is not None
return {
# Disable cgo, as it may be used for nefarious things, like linking
# against arbitrary libraries.
Expand All @@ -52,14 +55,17 @@ def get_compile_env(self):
'GOPATH': '/nonexistent-path',
}

def get_compile_args(self):
return [self.get_command(), 'build', self._code]
def get_compile_args(self) -> List[str]:
command = self.get_command()
assert command is not None
assert self._code is not None
return [command, 'build', self._code]

@classmethod
def get_version_flags(cls, command):
def get_version_flags(cls, command: str) -> List[VersionFlags]:
return ['version']

def create_files(self, problem_id, source_code, *args, **kwargs):
def create_files(self, problem_id: str, source_code: bytes, *args, **kwargs) -> None:
source_lines = decomment(source_code).strip().split(b'\n')
if not repackage.match(source_lines[0]):
raise CompileError(b'Your code must be defined in package main.\n')
Expand Down
41 changes: 28 additions & 13 deletions dmoj/executors/GROOVY.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import os
import subprocess
from pathlib import Path
from typing import Dict, List, Tuple

from dmoj.executors.base_executor import AutoConfigOutput, AutoConfigResult
from dmoj.executors.java_executor import JavaExecutor
from dmoj.utils.unicode import utf8text

Expand All @@ -16,34 +18,43 @@ class Executor(JavaExecutor):
println System.in.newReader().readLine()
"""

def create_files(self, problem_id, source_code, *args, **kwargs):
def create_files(self, problem_id: str, source_code: bytes, *args, **kwargs) -> None:
super().create_files(problem_id, source_code, *args, **kwargs)
self._class_name = problem_id

def get_cmdline(self, **kwargs):
def get_cmdline(self, **kwargs) -> List[str]:
res = super().get_cmdline(**kwargs)

res[-2:-1] = self.runtime_dict['groovy_args']
return res

def get_compile_args(self):
return [self.get_compiler(), self._code]
compiler = self.get_compiler()
assert compiler is not None
assert self._code is not None
return [compiler, self._code]

def get_compile_env(self):
return {'JAVA_HOME': str(Path(os.path.realpath(self.get_vm())).parent.parent)}
def get_compile_env(self) -> Dict[str, str]:
vm = self.get_vm()
assert vm is not None
return {'JAVA_HOME': str(Path(os.path.realpath(vm)).parent.parent)}

@classmethod
def get_versionable_commands(cls):
return [('groovyc', cls.get_compiler()), ('java', cls.get_vm())]
def get_versionable_commands(cls) -> List[Tuple[str, str]]:
compiler = cls.get_compiler()
vm = cls.get_vm()
assert compiler is not None
assert vm is not None
return [('groovyc', compiler), ('java', vm)]

@classmethod
def autoconfig(cls):
result = {}
def autoconfig(cls) -> AutoConfigOutput:
result: AutoConfigResult = {}

for key, files in {'groovyc': ['groovyc'], 'groovy': ['groovy']}.items():
file = cls.find_command_from_list(files)
if file is None:
return result, False, 'Failed to find "%s"' % key
return result, False, f'Failed to find "{key}"', ''
result[key] = file

groovy = result.pop('groovy')
Expand All @@ -53,15 +64,19 @@ def autoconfig(cls):
log = [i for i in output.split('\n') if 'org.codehaus.groovy.tools.GroovyStarter' in i and '-classpath' in i]

if not log:
return result, False, 'Failed to parse: %s' % groovy
return result, False, f'Failed to parse: {groovy}', ''

cmdline = log[-1].lstrip('+ ').split()

result['groovy_vm'] = cls.unravel_java(cls.find_command_from_list([cmdline[1]]))
vm = cls.find_command_from_list([cmdline[1]])
if not vm:
return result, False, f'Failed to find: {cmdline[1]}', ''

result['groovy_vm'] = cls.unravel_java(vm)
i = cmdline.index('-classpath')
result['groovy_args'] = ['-classpath', f'.:{cmdline[i + 1]}']

data = cls.autoconfig_run_test(result)
if data[1]:
data = data[:2] + ('Using %s' % groovy,) + data[3:]
data = data[:2] + (f'Using {groovy}',) + data[3:]
return data
9 changes: 7 additions & 2 deletions dmoj/executors/HASK.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import List

from dmoj.cptbox.filesystem_policies import RecursiveDir
from dmoj.executors.compiled_executor import CompiledExecutor
from dmoj.executors.mixins import NullStdoutMixin
Expand All @@ -18,5 +20,8 @@ class Executor(NullStdoutMixin, CompiledExecutor):
putStr a
"""

def get_compile_args(self):
return [self.get_command(), '-O2', '-o', self.problem, self._code]
def get_compile_args(self) -> List[str]:
command = self.get_command()
assert command is not None
assert self._code is not None
return [command, '-O2', '-o', self.problem, self._code]
9 changes: 7 additions & 2 deletions dmoj/executors/ICK.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import List

from dmoj.executors.compiled_executor import CompiledExecutor


Expand Down Expand Up @@ -29,8 +31,11 @@ class Executor(CompiledExecutor):
(30) PLEASE READ OUT ,1
"""

def get_compile_args(self):
flags = [self.get_command(), '-O', self._code]
def get_compile_args(self) -> List[str]:
command = self.get_command()
assert command is not None
assert self._code is not None
flags = [command, '-O', self._code]
if self.problem == self.test_name:
# Do not fail self-test to random compiler bug.
flags.insert(1, '-b')
Expand Down
3 changes: 0 additions & 3 deletions dmoj/executors/JAVA.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,3 @@ class Executor(JavacExecutor):
});
}
}"""

def get_compile_args(self):
return [self.get_compiler(), '-encoding', 'UTF-8', self._code]
9 changes: 7 additions & 2 deletions dmoj/executors/JAVA8.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import List

from dmoj.executors.java_executor import JavacExecutor


Expand Down Expand Up @@ -28,5 +30,8 @@ class Executor(JavacExecutor):
}
}"""

def get_compile_args(self):
return [self.get_compiler(), '-encoding', 'UTF-8', '-profile', 'compact1', self._code]
def get_compile_args(self) -> List[str]:
compiler = self.get_compiler()
assert compiler is not None
assert self._code is not None
return [compiler, '-encoding', 'UTF-8', '-profile', 'compact1', self._code]
Loading
Loading