Skip to content

Commit

Permalink
Support Python 3.12 + PEP 695 (type statement, new type parameter s…
Browse files Browse the repository at this point in the history
…yntax) (#135)

* Support Python 3.12, add new-style generics example + test

* Add support for for `type` statement

* Use Python 3.12 for mypy

* `tuple` => `Tuple` in test

* ruff

* Specify Python 3.12 for docs

* Python 3.12 for coverage

* Suppress mypy errors

* Ignore leading comments in docs update script

* Update type param example
  • Loading branch information
brentyi authored Apr 4, 2024
1 parent b43c668 commit eafae2e
Show file tree
Hide file tree
Showing 26 changed files with 317 additions and 52 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v2
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.10
- name: Set up Python 3.12
uses: actions/setup-python@v4
with:
python-version: "3.10"
python-version: "3.12"
- name: Install dependencies
run: |
pip install --upgrade pip
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ jobs:
# Check out source
- uses: actions/checkout@v2

# Set up Python
- name: "Set up Python 3.12"
uses: actions/setup-python@v4
with:
python-version: "3.12"

# Build documentation
- name: Building documentation
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/mypy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: "Set up Python 3.10"
- name: "Set up Python 3.12"
uses: actions/setup-python@v4
with:
python-version: "3.10"
python-version: "3.12"
- name: Install dependencies
run: |
pip install --upgrade pip
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.8'
python-version: '3.10'
- name: Install dependencies
run: |
pip install --upgrade pip
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pyright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11"]
python-version: ["3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v2
Expand Down
52 changes: 52 additions & 0 deletions docs/source/examples/04_additional/06_generics_py312.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.. Comment: this file is automatically generated by `update_example_docs.py`.
It should not be modified manually.
Generic Types (Python 3.12+ syntax)
==========================================


Example of parsing for generic dataclasses using syntax introduced in Python
3.12. Note: this is not compatible with ``from __future__ import annotations``.



.. code-block:: python
:linenos:
import dataclasses
import tyro
@dataclasses.dataclass(frozen=True)
class Point3[ScalarType: (int, float)]:
x: ScalarType
y: ScalarType
z: ScalarType
frame_id: str
@dataclasses.dataclass(frozen=True)
class Triangle:
a: Point3[float]
b: Point3[float]
c: Point3[float]
@dataclasses.dataclass(frozen=True)
class Args[ShapeType]:
shape: ShapeType
if __name__ == "__main__":
args = tyro.cli(Args[Triangle])
print(args)
------------

.. raw:: html

<kbd>python 04_additional/06_generics_py312.py --help</kbd>

.. program-output:: python ../../examples/04_additional/06_generics_py312.py --help
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ Features here are supported, but generally unnecessary and should be used sparin

.. raw:: html

<kbd>python 04_additional/06_conf.py --help</kbd>
<kbd>python 04_additional/07_conf.py --help</kbd>

.. program-output:: python ../../examples/04_additional/06_conf.py --help
.. program-output:: python ../../examples/04_additional/07_conf.py --help

------------

.. raw:: html

<kbd>python 04_additional/06_conf.py 5 --boolean True</kbd>
<kbd>python 04_additional/07_conf.py 5 --boolean True</kbd>

.. program-output:: python ../../examples/04_additional/06_conf.py 5 --boolean True
.. program-output:: python ../../examples/04_additional/07_conf.py 5 --boolean True
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ directly from ``tyro.cli``.

.. raw:: html

<kbd>python 04_additional/07_flax.py --help</kbd>
<kbd>python 04_additional/10_flax.py --help</kbd>

.. program-output:: python ../../examples/04_additional/07_flax.py --help
.. program-output:: python ../../examples/04_additional/10_flax.py --help

------------

.. raw:: html

<kbd>python 04_additional/07_flax.py --model.layers 4</kbd>
<kbd>python 04_additional/10_flax.py --model.layers 4</kbd>

.. program-output:: python ../../examples/04_additional/07_flax.py --model.layers 4
.. program-output:: python ../../examples/04_additional/10_flax.py --model.layers 4
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,22 @@ which makes it easier to load complex objects.

.. raw:: html

<kbd>python 04_additional/10_custom_constructors.py --help</kbd>
<kbd>python 04_additional/11_custom_constructors.py --help</kbd>

.. program-output:: python ../../examples/04_additional/10_custom_constructors.py --help
.. program-output:: python ../../examples/04_additional/11_custom_constructors.py --help

------------

.. raw:: html

<kbd>python 04_additional/10_custom_constructors.py --dict1.json '{"hello": "world"}'</kbd>
<kbd>python 04_additional/11_custom_constructors.py --dict1.json '{"hello": "world"}'</kbd>

.. program-output:: python ../../examples/04_additional/10_custom_constructors.py --dict1.json '{"hello": "world"}'
.. program-output:: python ../../examples/04_additional/11_custom_constructors.py --dict1.json '{"hello": "world"}'

------------

.. raw:: html

<kbd>python 04_additional/10_custom_constructors.py --dict1.json '{"hello": "world"}`' --dict2.json '{"hello": "world"}'</kbd>
<kbd>python 04_additional/11_custom_constructors.py --dict1.json '{"hello": "world"}`' --dict2.json '{"hello": "world"}'</kbd>

.. program-output:: python ../../examples/04_additional/10_custom_constructors.py --dict1.json '{"hello": "world"}`' --dict2.json '{"hello": "world"}'
.. program-output:: python ../../examples/04_additional/11_custom_constructors.py --dict1.json '{"hello": "world"}`' --dict2.json '{"hello": "world"}'
Original file line number Diff line number Diff line change
Expand Up @@ -45,54 +45,54 @@ Argument aliases

.. raw:: html

<kbd>python 04_additional/11_aliases.py --help</kbd>
<kbd>python 04_additional/12_aliases.py --help</kbd>

.. program-output:: python ../../examples/04_additional/11_aliases.py --help
.. program-output:: python ../../examples/04_additional/12_aliases.py --help

------------

.. raw:: html

<kbd>python 04_additional/11_aliases.py commit --help</kbd>
<kbd>python 04_additional/12_aliases.py commit --help</kbd>

.. program-output:: python ../../examples/04_additional/11_aliases.py commit --help
.. program-output:: python ../../examples/04_additional/12_aliases.py commit --help

------------

.. raw:: html

<kbd>python 04_additional/11_aliases.py commit --message hello --all</kbd>
<kbd>python 04_additional/12_aliases.py commit --message hello --all</kbd>

.. program-output:: python ../../examples/04_additional/11_aliases.py commit --message hello --all
.. program-output:: python ../../examples/04_additional/12_aliases.py commit --message hello --all

------------

.. raw:: html

<kbd>python 04_additional/11_aliases.py commit -m hello -a</kbd>
<kbd>python 04_additional/12_aliases.py commit -m hello -a</kbd>

.. program-output:: python ../../examples/04_additional/11_aliases.py commit -m hello -a
.. program-output:: python ../../examples/04_additional/12_aliases.py commit -m hello -a

------------

.. raw:: html

<kbd>python 04_additional/11_aliases.py checkout --help</kbd>
<kbd>python 04_additional/12_aliases.py checkout --help</kbd>

.. program-output:: python ../../examples/04_additional/11_aliases.py checkout --help
.. program-output:: python ../../examples/04_additional/12_aliases.py checkout --help

------------

.. raw:: html

<kbd>python 04_additional/11_aliases.py checkout --branch main</kbd>
<kbd>python 04_additional/12_aliases.py checkout --branch main</kbd>

.. program-output:: python ../../examples/04_additional/11_aliases.py checkout --branch main
.. program-output:: python ../../examples/04_additional/12_aliases.py checkout --branch main

------------

.. raw:: html

<kbd>python 04_additional/11_aliases.py checkout -b main</kbd>
<kbd>python 04_additional/12_aliases.py checkout -b main</kbd>

.. program-output:: python ../../examples/04_additional/11_aliases.py checkout -b main
.. program-output:: python ../../examples/04_additional/12_aliases.py checkout -b main
52 changes: 52 additions & 0 deletions docs/source/examples/04_additional/13_type_statement.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.. Comment: this file is automatically generated by `update_example_docs.py`.
It should not be modified manually.
Type aliases (Python 3.12+)
==========================================


In Python 3.12, the ``type`` statement is introduced to create type aliases.



.. code-block:: python
:linenos:
import dataclasses
import tyro
# Lazily-evaluated type alias.
type Field1Type = Inner
@dataclasses.dataclass
class Inner:
a: int
b: str
@dataclasses.dataclass
class Args:
"""Description.
This should show up in the helptext!"""
field1: Field1Type
"""A field."""
field2: int = 3
"""A numeric field, with a default value."""
if __name__ == "__main__":
args = tyro.cli(Args)
print(args)
------------

.. raw:: html

<kbd>python 04_additional/13_type_statement.py --help</kbd>

.. program-output:: python ../../examples/04_additional/13_type_statement.py --help
2 changes: 1 addition & 1 deletion docs/update_example_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def from_path(path: pathlib.Path) -> ExampleMetadata:
return ExampleMetadata(
index=index,
index_with_zero=index_with_zero,
source=source[3:].partition('"""')[2].strip(),
source=source.partition('"""')[2].partition('"""')[2].strip(),
title=title,
usages=example_usages,
description=description.strip(),
Expand Down
40 changes: 40 additions & 0 deletions examples/04_additional/06_generics_py312.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# mypy: ignore-errors
#
# PEP 695 isn't yet supported in mypy. (April 4, 2024)
"""Generic Types (Python 3.12+ syntax)
Example of parsing for generic dataclasses using syntax introduced in Python
3.12. Note: this is not compatible with `from __future__ import annotations`.
Usage:
`python ./05_generics.py --help`
"""

import dataclasses

import tyro


@dataclasses.dataclass(frozen=True)
class Point3[ScalarType: (int, float)]:
x: ScalarType
y: ScalarType
z: ScalarType
frame_id: str


@dataclasses.dataclass(frozen=True)
class Triangle:
a: Point3[float]
b: Point3[float]
c: Point3[float]


@dataclasses.dataclass(frozen=True)
class Args[ShapeType]:
shape: ShapeType


if __name__ == "__main__":
args = tyro.cli(Args[Triangle])
print(args)
File renamed without changes.
File renamed without changes.
File renamed without changes.
40 changes: 40 additions & 0 deletions examples/04_additional/13_type_statement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# mypy: ignore-errors
#
# PEP 695 isn't yet supported in mypy. (April 4, 2024)
"""Type aliases (Python 3.12+)
In Python 3.12, the `type` statement is introduced to create type aliases.
Usage:
`python ./13_type_statement.py --help`
"""

import dataclasses

import tyro

# Lazily-evaluated type alias.
type Field1Type = Inner


@dataclasses.dataclass
class Inner:
a: int
b: str


@dataclasses.dataclass
class Args:
"""Description.
This should show up in the helptext!"""

field1: Field1Type
"""A field."""

field2: int = 3
"""A numeric field, with a default value."""


if __name__ == "__main__":
args = tyro.cli(Args)
print(args)
Loading

0 comments on commit eafae2e

Please sign in to comment.