Agent skill
mdf-majo
meadow Docstring Format (MDF) specification for Python documentation. Use when writing, editing, or reviewing docstrings for Python code. Provides a plaintext-first, readable format that closely follows Python syntax. Trigger when the user mentions docstrings, Python documentation, function documentation, class documentation, or writing documentation for Python code.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/mdf-majo
Metadata
Additional technical details for this skill
- author
- mark@joshwel.co
- version
- 2026.2.2
SKILL.md
meadow Docstring Format (MDF)
Goal
Standardize Python docstring formatting to be plaintext-first, readable, and closely aligned with Python syntax. MDF provides an intuitive documentation style that works across editors while maintaining clarity and consistency.
When to Use This Skill
Use this skill when:
- Writing new docstrings for Python functions, classes, or modules
- Editing or reviewing existing Python documentation
- The user asks about docstring format or Python documentation style
- Adding documentation to Python codebases following the meadow standards
- Reviewing code that lacks proper documentation
Do NOT use
- For general markdown documentation (use
writing-docs-majoinstead) - For non-Python languages
- For external API documentation not embedded in Python code
- When the user explicitly requests a different docstring format (Google, NumPy, Sphinx)
- For standalone README files (use
writing-docs-majo)
Process
- Identify what needs documentation: Check if functions, classes, or methods lack docstrings
- Determine section requirements: Check the Format Overview table to see which sections are needed
- Write the preamble: One-line description that starts with a lowercase letter
- Add optional body: Longer explanation if the functionality is complex
- Document signatures: Add
attributes,arguments, orparametersfor incoming data - Document exports: Add
functionsormethodsfor outgoing APIs - Add returns and raises: Document return types and exceptions
- Include usage examples: Add code examples for complex functionality
- Review against constraints: Ensure Python syntax is modern and all code uses backticks
Constraints
- Always use latest Python syntax: Use
T | Noneinstead ofOptional[T], even for older Python versions - Always wrap code in backticks: All Python code in docstrings must be surrounded by backticks
- Preamble starts lowercase: The first line should begin with a lowercase letter
- Follow section order: Preamble → Body → Signatures → Functions/Methods → Returns → Raises → Usage
Testing Skills
- Verify docstrings follow the Format Overview section order
- Check that all Python syntax uses modern patterns (
|union syntax) - Ensure backticks wrap all code elements in the docstring
- Confirm one-line preamble starts with a lowercase letter
- Test that usage examples are valid Python code
A plaintext-first alternative documentation string style for Python.
Why MDF?
- Easy and intuitive to read and write — it's just plaintext
- Closely follows Python syntax, including type annotations
- Works well across editors (best on Zed, good on VS Code)
Format Overview
MDF docstrings are composed of sections in a specific order:
| Section | Required | Position | Purpose |
|---|---|---|---|
| preamble | Yes | Start | One-line description |
| body | No | Start or End | Longer explanation |
| attributes/arguments/parameters | If applicable | Middle | Incoming signatures |
| functions/methods | If applicable | Middle | Outgoing signatures |
| returns | If not None | Middle | Return type with description |
| raises | If applicable | Middle | Exceptions |
| usage | No | Start or End | Code example |
Section Details
1. Preamble (Required)
A mandatory short one-line description:
"""a baker's confectionery, usually baked, a lie"""
2. Body (Optional)
A longer, potentially multi-line description:
"""a baker's confectionery, usually baked, a lie
this is a longer description that explains more about cakes
and why they might be lies in certain contexts.
"""
3. Accepted (Incoming) Signatures
For classes: attributes
For functions: arguments or parameters
General format:
{attributes,arguments,parameters}:
`<python variable declaration syntax>`
<description>
Example:
"""
attributes:
`name: str`
name of the cake
`ingredients: list[Ingredient]`
ingredients of the cake
`baking_temperature: int = 4000`
temperature in degrees kelvin
"""
4. Exported (Outgoing) Signatures
For modules: functions
For classes: methods
General format:
{functions,methods}:
`<python function declaration syntax without trailing colon>`
<description of the function>
Example:
"""
methods:
`def bake(self, override: BakingOverride | None = None) -> bool`
bakes the cake and returns True if successful
"""
5. Returns and Raises
Single type format:
{returns,raises}: `<return type annotation>`
<description>
Multiple types format:
{returns,raises}:
`<first possible return type annotation/exception class>`
<description>
`<second possible return type annotation/exception class>`
<description>
Example:
def certain_unsafe_div(a: int | float, b: int | float) -> float:
"""divide a by b
arguments:
`a: int | float`
numerator
`b: int | float`
denominator
raises:
`ZeroDivisionError`
raised when denominator is 0
`OverflowError`
raised when the resulting number is too big
returns: `float`
the result, a divided by b
"""
return a / b
6. Usage (Optional)
A markdown triple backtick block with usage examples:
"""
usage:
```python
cake = Cake(name="Chocolate", ingredients=[...])
result = cake.bake()
```
"""
Guidelines
Use Latest Syntax
Use modern Python syntax in docstrings, even if the codebase targets older versions:
# Always use
optional_argument: T | None = None
# Not
optional_argument: Optional[T] = None
External References
Reference third-party classes in full for attributes, but use short names in method signatures:
class ThirdPartyExample(Exception):
"""blah blah
attributes:
`field_day: external.ExternalClass`
blah blah
methods:
`def __init__(self, field_day: ExternalClass) -> None: ...`
blah blah
"""
Overloads
For overloaded functions, use variable declaration syntax that makes sense:
@overload
def get_field(self) -> object: ...
@overload
def get_field(self, default: DefaultT) -> Union[object, DefaultT]: ...
def get_field(self, default: object = None) -> object:
"""...
arguments:
`default: object | None = None`
...
returns: `object`
"""
Long Declarations
Split long declarations across multiple lines within the same indentation:
methods:
`def woah_many_argument_function(
...
) -> None`
blah blah blah blah blah blah
When NOT to Document
1. Namespace Classes
Simple exception hierarchies or marker classes:
class TomlanticException(Exception):
"""base exception class for all tomlantic errors"""
pass
2. Obvious Returns
When the return is self-explanatory from the preamble:
def difference_between_document(self, incoming_document: TOMLDocument) -> Difference:
"""returns a `tomlantic.Difference` namedtuple object of the incoming and
outgoing fields that were changed between the model and the comparison document
arguments:
`incoming_document: tomlkit.TOMLDocument`
returns: `tomlantic.Difference`
"""
Complete Examples
Class with Attributes and Methods
class Result(NamedTuple, Generic[ResultType]):
"""typing.NamedTuple representing a result for safe value retrieval
attributes:
`value: ResultType`
value to return or fallback value if erroneous
`error: BaseException | None = None`
exception if any
methods:
`def __bool__(self) -> bool: ...`
boolean comparison for truthiness-based exception safety
`def get(self) -> ResultType: ...`
method that raises or returns an error if the Result is erroneous
`def cry(self, string: bool = False) -> str: ...`
method that returns the result value or raises an error
"""
value: ResultType
error: BaseException | None = None
def __bool__(self) -> bool:
"""boolean comparison for truthiness-based exception safety
returns: `bool`
that returns True if `self.error` is not None
"""
...
def cry(self, string: bool = False) -> str:
"""raises or returns an error if the Result is erroneous
arguments:
`string: bool = False`
if `self.error` is an Exception, returns it as a string error message
returns: `str`
returns `self.error` if it is a string, or returns an empty string if
`self.error` is None
"""
...
def get(self) -> ResultType:
"""returns the result value or raises an error
returns: `ResultType`
returns `self.value` if `self.error` is None
raises: `BaseException`
if `self.error` is not None
"""
...
Complex Class with Usage
class ModelBoundTOML(Generic[M]):
"""glue class for pydantic models and tomlkit documents
attributes:
`model: BaseModel`
methods:
`def __init__(self, model: type[M], document: TOMLDocument, handle_errors: bool = True) -> None: ...`
instantiates the class with a `pydantic.BaseModel` and a `tomlkit.TOMLDocument`
`def model_dump_toml(self) -> TOMLDocument: ...`
dumps the model as a style-preserved `tomlkit.TOMLDocument`
`def get_field(self, location: str | Sequence[str], default: object | None = None) -> object | None: ...`
safely retrieve a field by it's location
`def set_field(self, location: str | Sequence[str], value: object) -> None: ...`
sets a field by it's location
`def from_another_model_bound_toml(cls, model_bound_toml: ModelBoundToml[M]) -> "ModelBoundToml": ...`
classmethod that fully initialises from the data from another ModelBoundToml
usage:
```py
# instantiate the class
toml = ModelBoundTOML(YourModel, tomlkit.parse(...))
# access your model with .model
toml.model.message = "blowy red vixens fight for a quick jump"
# dump the model back to a toml document
toml_document = toml.model_dump_toml()
# or to a toml string
toml_string = toml.model_dump_toml().as_string()
```
"""
def set_field(
self,
location: Union[str, tuple[str, ...]],
value: object,
handle_errors: bool = True,
) -> None:
"""sets a field by it's location.
not recommended for general use due to a lack of type safety, but useful when
setting fields programatically
will handle `pydantic.ValidationError` into more toml-friendly error messages.
set `handle_errors` to `False` to raise the original `pydantic.ValidationError`
arguments:
`location: Union[str, tuple[str, ...]]`
dot-separated location of the field to set
`value: object`
value to set at the specified location
`handle_errors: bool = True`
whether to convert pydantic ValidationErrors to tomlantic errors
raises:
`AttributeError`
if the field does not exist
`tomlantic.TOMLValidationError`
if the document does not validate with the model
`pydantic.ValidationError`
if the document does not validate with the model and `handle_errors` is `False`
"""
...
Quick Reference
| Section | Syntax |
|---|---|
| preamble | Plain text (first line) |
| body | Plain text |
| attributes/arguments/parameters | `name: Type` + description |
| functions/methods | `def name(...) -> Return` + description |
| returns | `ReturnType` + description |
| raises | `ExceptionClass` + description |
| usage | Code block with example |
Key rule: Always use backticks around Python code in docstrings.
Integration
This skill is standalone but commonly used with:
python-majo— Python development standardsmdf-md-api-docs-majo— MDF-style API reference documentation in markdownwriting-docs-majo— Documentation writing standards
Didn't find tool you were looking for?