- when asked to write a test, write just the test without trying to fix it
Avoid writing useless comments: if you need to write a comment, explain WHY the code does something instead of WHAT it does.
Examples of USELESS comments (they just describe what the code obviously does):
# Convert to py.path.local
path = py.path.local(str(path_item))
# Loop through all files
for file in files:
...
# Check if path is a directory
if path.check(dir=True):
...Examples of USEFUL comments (they explain WHY or provide context):
This is USEFUL because it's not immediately obvious that capture_output=True
influencese also stderr:
# Use capture_output=True to capture stdout and stderr separately
proc = subprocess.run(cmdline_s, capture_output=True)This is USEFUL because it explains why decided to apply or not apply the conversion:
if w_typeconv is None:
# no conversion needed, hooray
return wam
elif self.redshifting:
# we are performing redshifting: the conversion will be handlded
# by FuncDoppler
return wam
else:
# apply the conversion immediately
w_val = self.vm.fast_call(w_typeconv, [wam.w_val])This is USEFUL because by just looking at exec_stmt it's not immediately obvious that
we are talking about method definitions:
# execute method definitions
for stmt in self.classdef.body:
self.exec_stmt(stmt)When in doubt: if the comment can be removed and the code is still clear, remove it.
- Organize imports by standard Python conventions
- Prefer specific imports:
from spy.errors import SPyError - Prefer module-level imports, unless there is a good reason to put them inside functions
For example:
def foo():
# don't do this: put "import time" at the top level"
import time- When running tests, always use the venv: e.g. `./venv/bin/pytest'
- Run all tests:
pytest - Run single test:
pytest spy/tests/path/to/test_file.py::TestClass::test_function - Run backend-specific tests:
pytest -m interpor-m Cor-m doppler - Type checking:
mypy
spy your_file.spy # Execute (default)
spy -C your_file.spy # Generate C code
spy -c your_file.spy # Compile to executable
spy -O 1 -g your_file.spy # With optimization and debug symbols-
Use strict typing (mypy enforced)
-
Classes: PascalCase (
CompilerTest) -
Functions/methods: snake_case (
compile_module()) -
Constants: SCREAMING_SNAKE_CASE (
ALL_BACKENDS) -
Tests inherit from
CompilerTestbase class -
Use backend-specific decorators for test filtering (
@only_interp,@skip_backends) -
prefer using py.path.local over pathlib.Path. The only exception is cli.py, because typer has special logic to handle Path objects.
-
when using triple-quoted docstrings, always put the text in its own line. E.g.:
def foo(): """ docstring here """ -
when writing tests, do NOT put a docstring to explain what the test does, especially if the test name is already explicit. E.g.:
# this is BAD: the docstring is redundant def test_cache_preserves_symtable(self): """Test that symtable is preserved in cache""" ... # this is GOOD: def test_cache_preserves_symtable(self): ...
- When creating a PR, describe what you did, but don't include the "test plan" section.