Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
55 changes: 55 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Tests

on: [push, pull_request, workflow_dispatch]

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python: ["3.11", "3.12", "3.13", "3.14", "3.15", "3.16"]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
if: matrix.python != '3.16'
with:
python-version: ${{ matrix.python }}
allow-prereleases: true
# Build the recorded development snapshot before 3.16 has binary releases.
- name: Read Python 3.16 source revision
if: matrix.python == '3.16'
id: source
run: |
python3 -c 'import json; print("ref=" + json.load(open("sources/turtle.json"))["versions"]["3.16"]["commit"])' >> "$GITHUB_OUTPUT"
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
if: matrix.python == '3.16'
with:
repository: python/cpython
ref: ${{ steps.source.outputs.ref }}
path: .cpython
persist-credentials: false
- name: Build Python 3.16
if: matrix.python == '3.16'
working-directory: .cpython
run: |
sudo apt-get update
sudo apt-get install -y tk-dev
./configure --prefix="$RUNNER_TEMP/turtle-python"
make -j2
make install
echo "$RUNNER_TEMP/turtle-python/bin" >> "$GITHUB_PATH"
- name: Install package and test dependencies
run: python3 -m pip install . babel hatchling
- name: Test catalogs, extraction, and turtle integration
run: python3 -m unittest discover -s tests -v
- name: Verify installed shim outside the checkout
working-directory: ${{ runner.temp }}
run: |
python3 -I -c 'import sys, turtle_docstringdict_pl as pl; assert isinstance(pl.docsdict, dict); assert "tkinter" not in sys.modules; assert "babel" not in sys.modules'
python3 -I -c 'import turtle_translations; assert "pl" in turtle_translations.available()'
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Compiled from po/*.po
/turtle_docstringdict_*.py
/turtle_translations/*.py
!/turtle_translations/__init__.py

Expand Down
84 changes: 74 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,27 @@ Translations live in gettext catalogs in the `po/` directory.

### Extracting the template

The template is extracted from the `turtle` module of the Python you run the
script with, so use the latest Python version available:
The shared template contains all distinct English docstrings for Python 3.11–3.16.
Regenerate it from the committed source mappings (no Tkinter required):

```console
$ python scripts/i18n.py extract
po/turtle.pot: 103 docstrings from Python 3.16.0a0
po/turtle.pot: 118 distinct docstrings from Python 3.11–3.16
```

To refresh the mappings first, use a local CPython checkout with `upstream/3.11`
through `upstream/3.15` and `upstream/main` (3.16):

```console
$ python scripts/i18n.py extract --cpython ../cpython
```

This reads Git objects without switching branches or changing the CPython checkout.
The committed [compatibility report](sources/README.md) records source revisions,
method-level changes, and shared dictionary groups. The analysis covers these
branch snapshots, not every historical patch release. Source indentation is
normalized consistently across Python versions.

### Adding a language

Create a new catalog from the template for your language:
Expand All @@ -28,9 +41,13 @@ Created: po/ga.po

You can now translate it with your tool of choice.

Add `turtle_docstringdict_<lang>.py` (with a lowercase language code) to
`tool.check-wheel-contents.toplevel` in `pyproject.toml` so package inspection
expects the new language's generated shim.

### Updating the catalogs

After re-extracting the template against a newer Python, merge the changes
After refreshing the source mappings and template, merge the changes
into the existing catalogs:

```console
Expand All @@ -47,17 +64,64 @@ that no longer exist in the template rather than keeping them commented out.

```console
$ python scripts/i18n.py stats
pl 42/103 translated (40%), 3 fuzzy
pl 0/118 translated (0%), 0 fuzzy
```

### Compiling

Each PO file compiles to a `turtle_translations/<lang>.py` module containing a
`docsdict`, which is what `turtle` loads. The generated modules are built
automatically when the wheel is built, so you normally only need this to test
locally:
Each PO file compiles to a top-level `turtle_docstringdict_<lang>.py` shim and
internal version-specific dictionaries under
`turtle_translations/<lang>/py3<minor>.py`. The shim exports `docsdict`,
which is what `turtle` loads. Compilation matches each method's English source
text, omitting untranslated and fuzzy entries so their help stays English.
One PO entry can serve multiple methods and versions; extracted comments identify
each use. All English variants remain in the shared catalog.

The generated modules are built automatically when the wheel is built, so you
normally only need this to test locally:

```console
$ python scripts/i18n.py compile
Compiled: turtle_translations/pl.py
Compiled: turtle_translations/pl/py311.py
Compiled: turtle_translations/pl/py312.py
Compiled: turtle_translations/pl/py313.py
Compiled: turtle_translations/pl/py314.py
Compiled: turtle_docstringdict_pl.py
```

The shim uses `sys.version_info[:2]`:

| Python | Dictionary |
| --- | --- |
| 3.10 and older | 3.11 |
| 3.11 | 3.11 |
| 3.12 | 3.12 |
| 3.13 | 3.13 |
| 3.14 and newer | Shared 3.14–3.16 |

Python 3.11–3.16 is supported. The older-version fallback does not extend the
package's `>=3.11` installation requirement. Future Python versions use the newest
dictionary until their sources are analyzed. No runtime dependencies are needed
to import the shim; builds require Babel and Hatchling, but neither Tkinter nor a
CPython checkout. `turtle_translations.available()` lists language codes.

## Using translations

Install the package and place a `turtle.cfg` file in your working directory:

```ini
language = pl
```

Start a fresh Python process there and import `turtle`. Its class and module-level
help will use the available translations.

## Tests

Install Babel and Hatchling and run:

```console
$ python -m unittest discover -s tests -v
```

Runtime integration tests require Tkinter, but do not create a window.
Loading
Loading