A general-purpose autograder written primarily in Python 3.
Project description
lograder
This repository contains the source code for
a general-purpose autograder. The idea from a
high-level view is everything belongs to a pipeline,
which can be found in src/lograder/pipeline/pipeline.py.
The main type that is of note is Step, found in
src/lograder/pipeline/step.py. The steps that make up the
pipeline have a __call__ which is a generator.
The generator may yield values (both errors and info)
which are non-fatal, while return values are either
fatal errors or the data to pass onto the next step.
The central mantra to this library is validation,
validation, validation (because repetition legitimizes).
All calls to processes should be through a
TypedExecutable, which contains validated input
models via CLIArgs. Additionally, any output
needs to be a validated model and needs to be parsed
programmatically and completely. Either the program
must have an API, or the text parser must be bullet-proof.
Additionally, passing errors as values rather than exception based programming (except for developer bugs, staff errors, or validation errors) is preferred.
Finally, all the output is generated by the steps and
will be handled by the loggers, which are responsible for
producing logging output (obviously), but also the .json
or .html or whatever is used by the underlying application.
With that out of the way, we can get a little more into the details.
Installation
pip install -e ".[dev]"
Run tests with pytest.
"The Pipeline"
The autograder must be able to take student files of any type, such as source files for C, C++, Python, Rust, Assembly, and so forth; build the project in as configurable manner (with a natural default, ONLY IF there is an intuitive default); create any sort of artifact, whether that be text output, file output, etc.; and then "test" the artifacts whatever that may mean.
The primary subpackage for this is located in src/lograder/pipeline.
Step generics
Every concrete Step subclass must declare exactly five type parameters:
class MyStep(Step[InputT, OkOutputT, ErrOutputT, OkDisplayT, ErrDisplayT]): ...
OkOutputT becomes the input for the next step. ErrOutputT and ErrDisplayT
are fatal and non-fatal error types respectively, sent to the packet logger.
__init_subclass__ enforces this at class definition time.
Result type
Result[T, E] (see src/lograder/common/result.py) is a Rust-inspired
error-as-value container. Use Ok(value) and Err(value) constructors.
danger_ok / danger_err are assertion-guarded unwrappers. Do not raise
exceptions for expected failure modes — return Err(...) instead.
DeveloperException and StaffException are reserved for internal bugs
and course staff configuration errors respectively.
Manifest
Manifest (see src/lograder/pipeline/types/parcels.py) represents a
project's file/directory tree and is the primary type flowing between
Input and Check steps. It can be constructed from a directory scan
(from_directory), a TOML file (from_toml), or a flat list of paths
(from_flat). == checks exact equality; <= checks subset (received
contains at least the expected files).
Input
These will be the very beginning of the pipeline, taking "no input"
and producing some output (if no error, of course)! For example,
the Gradescope autograder puts uploaded files into a fixed directory,
so a natural input is to enumerate a local directory into a Manifest.
However, there are other examples of inputs, such as a single file
upload.
Check
These are mostly validation that happens before build. An example could be to make sure the project matches a specified manifest. Another example is to do a source file parse to ensure that an illegal library or operator is not used or is used under a certain number of times. The input and output type of these should be able to be chained together.
The simple_project.py check module generates named manifest-check classes
(CMakeManifestCheck, MakefileManifestCheck, PyProjectManifestCheck)
at import time, so they can be used directly.
Mixin
These will be used to inject staff code (such as specified header files) into the students code, or if the student is expected to write some file but not the surrounding build system, then it will inject the necessary files.
Build
These steps actually build the library, such as via cmake or make
or pip install and produce artifacts that are testable or usable in the
next steps.
Implemented builders: CMakeBuild (configure + build + File API artifact
parsing), MakefileBuild (runs make; artifact parsing is not yet
implemented).
Test
These are mostly post-build testing. Examples could be running a number
of instances of the student's executable, passing different arguments and
seeing if the output matches. Another example is checking the bytes of a
binary file to see if they match or running valgrind to check for memory
leaks.
Ideas / Future Work
- Implement
Mixin.__call__(currently a stub). - Add Makefile artifact parsing in
MakefileBuild(returns empty list today). - Create
Layoutforlograder.pipeline.build.makefile.MakefileBuildOutput. - Implement
Pipeline.validate_step_types()call and validation inPipeline.__call__.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lograder-0.2.0.tar.gz.
File metadata
- Download URL: lograder-0.2.0.tar.gz
- Upload date:
- Size: 78.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f838c76bd20482bbeea8ed1ccbd4ecdffe2f0e70bb1f6ded2dfdf53d2fad3c4
|
|
| MD5 |
dbd8b317cc56668b9b843bd364f12f05
|
|
| BLAKE2b-256 |
ce476f03a9812f2a0e4a8dde2c79d2231d94cb338fe256ea106455d657166538
|
File details
Details for the file lograder-0.2.0-py3-none-any.whl.
File metadata
- Download URL: lograder-0.2.0-py3-none-any.whl
- Upload date:
- Size: 110.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50e6926678b56ebf23d68a95f5a4e0c6b3d392cca11366b8a5dafb0a87b8e725
|
|
| MD5 |
6ca353ffbb04c964258795306c34c564
|
|
| BLAKE2b-256 |
30243c99c2c336ab3082dff9923a250e3224bd10a9f56d4542fc2e08f3d2e8e3
|