Skip to content

Commit

Permalink
Add docstring and typing to Submission. Fix flake8 pre-commit and tak…
Browse files Browse the repository at this point in the history
…e into account pyproject.toml.
  • Loading branch information
fkdosilovic committed Nov 29, 2024
1 parent 1343fb1 commit 941b463
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 36 deletions.
3 changes: 1 addition & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ repos:
rev: 7.1.1
hooks:
- id: flake8
args:
- --docstring-convention=numpydoc
additional_dependencies:
- "flake8-pyproject"
- flake8-docstrings
- pydocstyle
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pre-commit = "==3.8.0"
pytest = "==8.3.3"
python-dotenv = "==1.0.1"
pytest-cov = "6.0.0"
flake8-docstrings = "1.7.0"

[requires]
python_version = "3.9"
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ Issues = "https://github.com/judge0/judge0-python/issues"
test = ["pytest", "mkdocs"]

[tool.flake8]
docstring-convention = "numpydoc"
extend-ignore = ["D205", "D400", "D105"]
docstring-convention = "numpy"
extend-ignore = ["D205", "D400", "D105", "D100", "F821"]
max-line-length = 88
137 changes: 105 additions & 32 deletions src/judge0/submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,31 +69,86 @@
class Submission:
"""
Stores a representation of a Submission to/from Judge0.
Parameters
----------
source_code : str, optional
The source code to be executed.
language : LanguageAlias or int, optional
The programming language of the source code. Defaults to `LanguageAlias.PYTHON`.
additional_files : base64 encoded string, optional
Additional files that should be available alongside the source code.
Value of this string should represent the content of a .zip that
contains additional files. This attribute is required for multi-file
programs.
compiler_options : str, optional
Options for the compiler (i.e. compiler flags).
command_line_arguments : str, optional
Command line arguments for the program.
stdin : str, optional
Input to be fed via standard input during execution.
expected_output : str, optional
The expected output of the program.
cpu_time_limit : float, optional
Maximum CPU time allowed for execution, in seconds. Time in which the
OS assigns the processor to different tasks is not counted. Depends on
configuration.
cpu_extra_time : float, optional
Additional CPU time allowance in case of time extension. Depends on
configuration.
wall_time_limit : float, optional
Maximum wall clock time allowed for execution, in seconds. Depends on
configuration.
memory_limit : float, optional
Maximum memory allocation allowed for the process, in kilobytes.
Depends on configuration.
stack_limit : int, optional
Maximum stack size allowed, in kilobytes. Depends on configuration.
max_processes_and_or_threads : int, optional
Maximum number of processes and/or threads program can create. Depends
on configuration.
enable_per_process_and_thread_time_limit : bool, optional
If True, enforces time limits per process/thread. Depends on
configuration.
enable_per_process_and_thread_memory_limit : bool, optional
If True, enforces memory limits per process/thread. Depends on
configuration.
max_file_size : int, optional
Maximum file size allowed for output files, in kilobytes. Depends on
configuration.
redirect_stderr_to_stdout : bool, optional
If True, redirects standard error output to standard output.
enable_network : bool, optional
If True, enables network access during execution.
number_of_runs : int, optional
Number of times the code should be executed.
callback_url : str, optional
URL for a callback to report execution results or status.
"""

def __init__(
self,
*,
source_code: Optional[str] = None,
language: Union[LanguageAlias, int] = LanguageAlias.PYTHON,
additional_files=None,
compiler_options=None,
command_line_arguments=None,
stdin=None,
expected_output=None,
cpu_time_limit=None,
cpu_extra_time=None,
wall_time_limit=None,
memory_limit=None,
stack_limit=None,
max_processes_and_or_threads=None,
enable_per_process_and_thread_time_limit=None,
enable_per_process_and_thread_memory_limit=None,
max_file_size=None,
redirect_stderr_to_stdout=None,
enable_network=None,
number_of_runs=None,
callback_url=None,
additional_files: Optional[str] = None,
compiler_options: Optional[str] = None,
command_line_arguments: Optional[str] = None,
stdin: Optional[str] = None,
expected_output: Optional[str] = None,
cpu_time_limit: Optional[float] = None,
cpu_extra_time: Optional[float] = None,
wall_time_limit: Optional[float] = None,
memory_limit: Optional[float] = None,
stack_limit: Optional[int] = None,
max_processes_and_or_threads: Optional[int] = None,
enable_per_process_and_thread_time_limit: Optional[bool] = None,
enable_per_process_and_thread_memory_limit: Optional[bool] = None,
max_file_size: Optional[int] = None,
redirect_stderr_to_stdout: Optional[bool] = None,
enable_network: Optional[bool] = None,
number_of_runs: Optional[int] = None,
callback_url: Optional[str] = None,
):
self.source_code = source_code
self.language = language
Expand Down Expand Up @@ -123,22 +178,31 @@ def __init__(
self.callback_url = callback_url

# Post-execution submission attributes.
self.stdout = None
self.stderr = None
self.compile_output = None
self.message = None
self.exit_code = None
self.exit_signal = None
self.status = None
self.created_at = None
self.finished_at = None
self.token = ""
self.time = None
self.wall_time = None
self.memory = None
self.post_execution_filesystem = None
self.stdout: Optional[str] = None
self.stderr: Optional[str] = None
self.compile_output: Optional[str] = None
self.message: Optional[str] = None
self.exit_code: Optional[int] = None
self.exit_signal: Optional[int] = None
self.status: Optional[Status] = None
self.created_at: Optional[datetime] = None
self.finished_at: Optional[datetime] = None
self.token: str = ""
self.time: Optional[float] = None
self.wall_time: Optional[float] = None
self.memory: Optional[float] = None
self.post_execution_filesystem: Optional[Filesystem] = None

def set_attributes(self, attributes: dict[str, Any]) -> None:
"""Set Submissions attributes while taking into account different
attribute's types.
Parameters
----------
attributes : dict
Key-value pairs of Submission attributes and the corresponding
value.
"""
for attr, value in attributes.items():
if attr in SKIP_FIELDS:
continue
Expand All @@ -157,6 +221,9 @@ def set_attributes(self, attributes: dict[str, Any]) -> None:
setattr(self, attr, value)

def as_body(self, client: "Client") -> dict:
"""Prepare Submission as a dictionary while taking into account
the `client`'s restrictions.
"""
body = {
"source_code": encode(self.source_code),
"language_id": client.get_language_id(self.language),
Expand All @@ -175,12 +242,18 @@ def as_body(self, client: "Client") -> dict:
return body

def is_done(self) -> bool:
"""Check if submission is finished processing.
Submission is considered finished if the submission status is not
IN_QUEUE and not PROCESSING.
"""
if self.status is None:
return False
else:
return self.status not in (Status.IN_QUEUE, Status.PROCESSING)

def pre_execution_copy(self) -> "Submission":
"""Create a deep copy of a submission."""
new_submission = Submission()
for attr in REQUEST_FIELDS:
setattr(new_submission, attr, copy.deepcopy(getattr(self, attr)))
Expand Down

0 comments on commit 941b463

Please sign in to comment.