Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b0bc88a
Add YAML support to Stata mock
tobiasraabe Jun 6, 2026
1c97c75
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 6, 2026
b6c9b27
Include Stata mock in typing environment
tobiasraabe Jun 6, 2026
167e802
Add YAML configuration interface
tobiasraabe Jun 6, 2026
ecbb9e1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 6, 2026
35e78a0
Align YAML example with real Stata
tobiasraabe Jun 12, 2026
21426d4
Merge remote-tracking branch 'origin/main' into codex/stata-mock-yaml
tobiasraabe Jun 14, 2026
c59f97b
update lock
tobiasraabe Jun 14, 2026
44ee38e
Test supported YAML value types
tobiasraabe Jun 14, 2026
bfdded1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 14, 2026
3ac373f
fix readme
tobiasraabe Jun 14, 2026
01edfac
fix readme
tobiasraabe Jun 14, 2026
8568a73
Merge branch 'codex/stata-mock-yaml' of https://github.com/pytask-dev…
tobiasraabe Jun 14, 2026
2207545
fix
tobiasraabe Jun 19, 2026
7b52195
Merge remote-tracking branch 'origin' into codex/stata-mock-yaml
tobiasraabe Aug 15, 2026
b522df0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 15, 2026
d52ce9c
fix
tobiasraabe Sep 12, 2026
f1a94cb
Merge remote-tracking branch 'origin/main' into codex/stata-mock-yaml
tobiasraabe Sep 12, 2026
ad25346
Fix explicit None Stata options
tobiasraabe Sep 12, 2026
a9bb3ae
Preserve underscore-prefixed Stata arguments
tobiasraabe Sep 12, 2026
9318ee3
Preserve Unicode in serialized Stata YAML
tobiasraabe Sep 12, 2026
35d66e6
Reject empty Stata YAML collections
tobiasraabe Sep 12, 2026
af4780c
Preserve quoted YAML scalar types in mock
tobiasraabe Sep 12, 2026
7f193c6
Support snake case YAML attributes in mock
tobiasraabe Sep 12, 2026
cd35680
Allow colons in scalar YAML list items
tobiasraabe Sep 12, 2026
9c9aaca
Match scalar yaml get return interface
tobiasraabe Sep 12, 2026
b207f3c
Fix direct serialization import
tobiasraabe Sep 19, 2026
5f96da4
Allow Stata tasks without arguments
tobiasraabe Sep 19, 2026
40a1e39
Read mock YAML files as UTF-8
tobiasraabe Sep 19, 2026
6a0df15
Unescape apostrophes in mock YAML
tobiasraabe Sep 19, 2026
ef8d23a
Merge remote-tracking branch 'origin/main' into codex/stata-mock-yaml
tobiasraabe Sep 19, 2026
8eeaef9
Fix YAML scalar parsing and document defaults
tobiasraabe Sep 19, 2026
b65c99d
Add changelog for version 0.6.0
tobiasraabe Sep 19, 2026
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
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
- name: Install just
uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0
with:
just-version: "1.43.1"
just-version: "1.58.0"
- run: just typing

run-tests:
Expand All @@ -62,7 +62,7 @@ jobs:
- name: Install just
uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0
with:
just-version: "1.43.1"
just-version: "1.58.0"

- name: Run tests
shell: bash -l {0}
Expand Down
11 changes: 1 addition & 10 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,6 @@ repos:
- id: no-commit-to-branch
args: [--branch, main]
- id: trailing-whitespace
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
- id: python-check-blanket-noqa
- id: python-check-mock-methods
- id: python-no-eval
- id: python-no-log-warn
- id: python-use-type-annotations
- id: text-unicode-replacement-char
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.16.7
hooks:
Expand All @@ -45,7 +36,7 @@ repos:
- mdformat-black
args: [--wrap, "88"]
- repo: https://github.com/crate-ci/typos
rev: v1
rev: v1.49.0
hooks:
- id: typos
- repo: meta
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ chronological order. Releases follow [semantic versioning](https://semver.org/)
releases are available on [PyPI](https://pypi.org/project/pytask-stata) and
[Anaconda.org](https://anaconda.org/conda-forge/pytask-stata).

## 0.6.0 - 2026-09-19

- {pull}`107` adds YAML configuration files for passing dependencies, products, and
other task arguments to Stata. YAML is now the default interface; explicitly supplying
`options` selects the command-line compatibility interface.
- {pull}`107` expands the mock Stata runtime with YAML parsing and validation support.
- {pull}`114` uses the canonical `pytask-stata` distribution name in package metadata.

## 0.5.1 - 2026-06-14

- {pull}`50` drops support for Python 3.8 and 3.9 and adds support for Python 3.14.
Expand Down
84 changes: 76 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ ______________________________________________________________________

Run Stata's do-files with pytask.

## Table of Contents

- [Installation](#installation)
- [Usage](#usage)
- [Dependencies and Products](#dependencies-and-products)
- [Accessing dependencies and products in the script](#accessing-dependencies-and-products-in-the-script)
- [YAML Configuration Files](#yaml-configuration-files)
- [Command Line Arguments](#command-line-arguments)
- [Repeating tasks with different scripts or inputs](#repeating-tasks-with-different-scripts-or-inputs)
- [Configuration](#configuration)
- [Changes](#changes)

## Installation

pytask-stata is available on [PyPI](https://pypi.org/project/pytask-stata) and
Expand Down Expand Up @@ -99,9 +111,65 @@ def task_run_do_file(produces: Path = Path("auto.dta")):
### Accessing dependencies and products in the script

Dependencies and products registered in the task function signature are used by pytask
to order tasks and track whether they are up-to-date. They are not automatically passed
to the Stata script. Use the `options` argument of the decorator to pass paths or other
values as command line arguments to your Stata executable.
to order tasks and track whether they are up-to-date. pytask-stata offers two modes to
pass these paths and other task data to the Stata script.

1. Use the default YAML configuration file. This is the recommended mode if your Stata
installation can use the user-written [`yaml`](https://github.com/jpazvd/yaml)
package, which is compatible with Stata 14+.
1. Use the `options` argument of the decorator to pass command line arguments. This is
the compatibility mode for Stata installations where `yaml.ado` is not available or
not supported.

Do not combine both interfaces. If `options` is supplied, pytask-stata assumes the
do-file receives all required values through command line arguments and does not create
a YAML configuration file. Pass `options=None` to select this mode without passing any
command line arguments.

#### YAML Configuration Files

By default, pytask-stata serializes all task keyword arguments and passes the path to
the generated YAML file as the first argument to the do-file. To read the file inside
Stata, install the user-written [`yaml`](https://github.com/jpazvd/yaml) package, which
is compatible with Stata 14+.

See [YAML Data Passed to Stata](docs/yaml.md) for the supported data types and how they
are represented in Stata.

```stata
ssc install yaml
```

Then read the configuration file in the Stata task.

```python
from pathlib import Path

from pytask import mark


@mark.stata(script=Path("script.do"))
def task_run_do_file(
depends_on: Path = Path("input.dta"),
produces: Path = Path("auto.dta"),
):
pass
```

```do
args config
yaml read using "`config'", locals replace
local depends_on = r(yaml_depends_on)
local produces = r(yaml_produces)

use "`depends_on'", clear
save "`produces'"
```

#### Command Line Arguments

Use the `options` argument of the decorator to pass paths or other values as command
line arguments to your Stata executable. This mode does not require the `yaml` package.

For example, pass paths for the dependency and product with

Expand All @@ -119,22 +187,22 @@ def task_run_do_file(
pass
```

And in your `script.do`, you can intercept the value with
And in your `script.do`, you can intercept the values with

```do
* Intercept command line arguments and save them to macros.
args depends_on produces

sysuse auto, clear
use "`depends_on'", clear
save "`produces'"
```

The relative path inside the do-file works only because pytask-stata switches the
current working directory to the directory of the task module before the task is
executed.

To make the task independent from the current working directory, pass the full path as
an command line argument. Here is an example.
To make the task independent from the current working directory, pass the full path as a
command line argument. Here is an example.

```python
# Absolute path to the build directory.
Expand All @@ -153,7 +221,7 @@ def task_run_do_file(produces: Path = BLD / "auto.dta"):
### Repeating tasks with different scripts or inputs

You can also parametrize the execution of scripts, meaning executing multiple do-files
as well as passing different command line arguments to the same do-file.
as well as passing different inputs or task data to the same do-file.

The following task executes two do-files which produce different outputs.

Expand Down
38 changes: 38 additions & 0 deletions docs/yaml.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# YAML Data Passed to Stata

pytask-stata serializes task keyword arguments with PyYAML and passes the path to the
generated YAML file as the first command line argument to the do-file. Inside Stata,
read the file with the user-written `yaml` package.

```stata
args config
yaml read using "`config'", locals replace
```

The `yaml` package stores parsed YAML in a Stata dataset with `key`, `value`, `level`,
`parent`, and `type` columns. With `locals`, scalar leaves are also available as
`r(yaml_<key>)` macros. Nested keys are flattened with underscores.

## Supported Types

| Python value | YAML shape | Stata representation | Access pattern |
| -------------------------------- | ----------------------------- | -------------------------------------------------------------------- | ----------------------------------------- |
| Non-empty `str` | `name: hello` | `type=string`, `value=hello` | `r(yaml_name)` |
| `int` | `count: 42` | `type=numeric`, `value=42` | `r(yaml_count)` |
| `float` | `ratio: 3.14` | `type=numeric`, `value=3.14` | `r(yaml_ratio)` |
| `bool` | `enabled: true` | `type=boolean`, `value=1` or `0` | `r(yaml_enabled)` |
| `None` | `missing: null` | `type=null`, empty value | validate as `null`; no useful macro value |
| `pathlib.Path` | `path: build/out.dta` | `type=string`, POSIX-style path | `r(yaml_path)` |
| Flat `list` / `tuple` of scalars | `items:` plus `- value` lines | parent row plus `items_1`, `items_2`, ... rows with `type=list_item` | use flattened keys such as `items_1` |
| Nested `dict` with scalar leaves | nested mapping | flattened keys such as `config_child` | `yaml get config, attributes(child)` |

## Recommended Limits

Keep the YAML bridge to configuration-like data: scalar values, paths, flat scalar
lists, and nested dictionaries with scalar leaves.

Avoid empty mappings and lists, empty strings, lists of dictionaries, sets, bytes,
decimals, and arbitrary Python objects. Empty collections use YAML flow syntax, which is
outside the Stata parser's supported subset. PyYAML may also emit YAML tags such as
`!!set` or `!!binary`, or fail with a `RepresenterError`; those forms are not useful as
a stable Stata interface.
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ test-ci:

# Run type checking
typing:
uv run --group typing --group test --isolated ty check
uv run --group typing --group test --group test-mock-stata --isolated ty check

# Run linting and formatting
lint:
Expand Down
Loading
Loading