Skip to content

Commit 1e9ba4e

Browse files
authored
Merge branch '3.13' into copilot/fix-690
2 parents 8e0f950 + 7ecda97 commit 1e9ba4e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+7183
-5728
lines changed

.github/workflows/ci.yml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
name: build
22

3+
concurrency: preview-${{ github.ref }}
4+
5+
permissions:
6+
contents: write
7+
pull-requests: write
8+
39
on:
410
pull_request:
511

@@ -19,5 +25,16 @@ jobs:
1925
- name: Install uv
2026
uses: astral-sh/setup-uv@v6
2127

22-
- name: Validate
28+
- name: Build HTML Docs
2329
run: VERSION=${{ github.event.repository.default_branch }} JOBS=4 MODE=html make all
30+
31+
- name: Deploy PR Doc Preview
32+
# PR from the forked repo would be denied as the permission is not granted.
33+
# Allow only PR from this repo.
34+
if: ${{ ( github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name ) }}
35+
uses: rossjrw/pr-preview-action@v1
36+
with:
37+
source-dir: ../cpython/Doc/build/html
38+
preview-branch: gh-pages
39+
umbrella-dir: pr-preview
40+
action: auto

.github/workflows/deploy-gh-page.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ jobs:
2323
- name: Deploy to gh page
2424
uses: JamesIves/github-pages-deploy-action@v4.7.3
2525
with:
26-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
27-
BRANCH: gh-pages
28-
FOLDER: ../cpython/Doc/build/html
29-
CLEAN: true
26+
token: ${{ secrets.GITHUB_TOKEN }}
27+
branch: gh-pages
28+
folder: ../cpython/Doc/build/html
29+
clean: true
30+
clean-exclude: pr-preview/

.github/workflows/py313-sync-cpython.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,17 @@ jobs:
3636
- name: Sync with CPython
3737
run: make clone merge rm_cpython wrap
3838

39-
- uses: tibdex/github-app-token@v2
40-
id: generate-token
39+
- uses: actions/create-github-app-token@v2
40+
id: app-token
4141
with:
42-
app_id: ${{ secrets.APP_ID }}
43-
private_key: ${{ secrets.APP_PRIVATE_KEY }}
42+
app-id: ${{ secrets.APP_ID }}
43+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
4444

4545
- name: Create Pull Request
4646
id: cpr
4747
uses: peter-evans/create-pull-request@v6
4848
with:
49-
token: ${{ steps.generate-token.outputs.token }}
49+
token: ${{ steps.app-token.outputs.token }}
5050
commit-message: sync with cpython ${{ env.LATEST_COMMIT_ID }}
5151
committer: GitHub <noreply@github.com>
5252
author: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

.scripts/summarize_progress/main.py

Lines changed: 55 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,6 @@
66
from pathlib import Path
77

88

9-
def entry_check(pofile: polib.POFile) -> str:
10-
'''
11-
Check the po file with how many entries are translated or not.
12-
'''
13-
14-
lines_tranlated = len(pofile.translated_entries())
15-
lines_untranlated = len(pofile.untranslated_entries())
16-
17-
if lines_tranlated == 0:
18-
result = "❌"
19-
elif lines_untranlated == 0:
20-
result = "✅"
21-
else:
22-
lines_all = lines_tranlated + lines_untranlated
23-
progress = lines_tranlated / lines_all
24-
progress_percentage = round(progress * 100, 2)
25-
result = f"{progress_percentage} %"
26-
27-
return result
28-
29-
309
def get_open_issues_count() -> int:
3110
'''
3211
Fetch GitHub API to get the number of OPEN ISSUES.
@@ -89,21 +68,23 @@ def get_github_issues() -> list:
8968

9069

9170
def format_line_table_header() -> list:
92-
return [f"|Filename|Progress|Issue|Assignee|\r\n",
71+
return [f"|Filename|Progress (#string)|Issue|Assignee|\r\n",
9372
f"|-------:|:-------|:----|:-------|\r\n"]
9473

9574

96-
def format_issue_link(url: str) -> str:
97-
return f"[{url.split('/')[-1]}]({url})" if len(url) > 0 else ''
98-
99-
100-
def format_line_file(dirname: str, filename: str, data: dict) -> str:
101-
return f"|[`{filename}`](https://github.com/python/python-docs-zh-tw/tree/3.13/{dirname}/{filename})" + \
102-
f"|{data['progress']}|{format_issue_link(data['issue'])}|{data['assignee']}|\r\n"
75+
def format_line_po_issue_display(issue_link: str, issue_number: str, progress: float, create_issue_link: str) -> str:
76+
if issue_link:
77+
return f"[{issue_number}]({issue_link})"
78+
if progress != 100.:
79+
return f"[create issue]({create_issue_link})"
80+
return ""
10381

10482

105-
def format_line_directory(dirname: str) -> str:
106-
return f"## {dirname}\r\n"
83+
def format_line_po(filename: str, po_link: str, progress: str, num_entries: str, issue_display: str, assignee: str) -> str:
84+
progress_display = f"{progress} %"
85+
if progress == 100:
86+
progress_display = "✅"
87+
return f"|[`{filename}`]({po_link})|{progress_display} ({num_entries:,})|{issue_display}|{assignee}|\r\n"
10788

10889

10990
if __name__ == "__main__":
@@ -118,11 +99,17 @@ def format_line_directory(dirname: str) -> str:
11899
for filepath in glob.glob(str(BASE_DIR / "**/*.po"), recursive=True):
119100
path = Path(filepath)
120101
filename = path.name
121-
dirname = path.parent.name if path.parent.name != BASE_DIR.name else '/'
102+
dirname = path.parent.name if path.parent.name != BASE_DIR.name else 'root'
122103
po = polib.pofile(filepath)
123104

105+
num_entries = len(list(filter(lambda e: not e.obsolete, po)))
106+
num_translated = len(po.translated_entries())
124107
summary.setdefault(dirname, {})[filename] = {
125-
'progress': entry_check(po),
108+
'po_info': {
109+
'num_entries': num_entries,
110+
'num_translated': num_translated,
111+
'progress': round(num_translated / num_entries * 100, 2),
112+
},
126113
'issue': '',
127114
'assignee': '',
128115
}
@@ -138,25 +125,47 @@ def format_line_directory(dirname: str) -> str:
138125
pass
139126

140127
'''
141-
Adding Space for Formatting Markdown Link
142-
'''
143-
144-
'''
145-
Format the lines that will write into the markdown file,
128+
Format the lines that will be written into the markdown file,
146129
also sort the directory name and file name.
147130
'''
148131
writeliner = []
149132
summary_sorted = dict(sorted(summary.items()))
133+
total_entries, total_translated = 0, 0
150134
for dirname, filedict in summary_sorted.items():
151-
writeliner.append(format_line_directory(dirname))
152-
writeliner.extend(format_line_table_header())
153-
135+
dir_total_entries, dir_total_translated = 0, 0
136+
lines = []
154137
filedict_sorted = dict(sorted(filedict.items()))
155138
for filename, filedata in filedict_sorted.items():
156-
writeliner.append(format_line_file(dirname, filename, filedata))
139+
file_path = f"{dirname}/{filename}" if dirname else filename
140+
po_link = f"https://github.com/python/python-docs-zh-tw/tree/3.13/{file_path}"
141+
issue_link = filedata['issue']
142+
issue_number = f"#{issue_link.split('/')[-1]}"
143+
create_issue_link = f"https://github.com/python/python-docs-zh-tw/issues/new?title=Translate%20`{file_path}`"
144+
issue_display = format_line_po_issue_display(issue_link, issue_number, filedata['po_info']['progress'], create_issue_link)
145+
line_po = format_line_po(
146+
filename,
147+
po_link,
148+
filedata['po_info']['progress'],
149+
filedata['po_info']['num_entries'],
150+
issue_display,
151+
filedata['assignee'],
152+
)
153+
lines.append(line_po)
154+
155+
dir_total_entries += filedata['po_info']['num_entries']
156+
dir_total_translated += filedata['po_info']['num_translated']
157+
158+
dir_progress = round(dir_total_translated / dir_total_entries * 100, 2)
159+
writeliner.append(f"## {dirname} ({dir_progress}%)\r\n")
160+
writeliner.extend(format_line_table_header())
161+
writeliner.extend(lines)
162+
163+
total_entries += dir_total_entries
164+
total_translated += dir_total_translated
165+
166+
overall_progress = round(total_translated / total_entries * 100, 2)
167+
title = f"## Overall Progress: {overall_progress}% ({total_translated:,} / {total_entries:,})\r\n"
168+
writeliner = [title] + writeliner
157169

158-
with open(
159-
f"summarize_progress/result.md",
160-
"w",
161-
) as file:
170+
with open(f"summarize_progress/result.md", "w") as file:
162171
file.writelines(writeliner)

TERMINOLOGY_DICTIONARY.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Python Documentation Translation Dictionary
2+
3+
This document describes the terminology dictionaries for maintaining translation consistency across the Python documentation project.
4+
5+
## Overview
6+
7+
The translation dictionary project provides curated key terms and their translations to help translators maintain consistent terminology usage across different documents. The dictionaries are maintained using LLM knowledge to identify and categorize important Python terminology.
8+
9+
## Generated Files
10+
11+
### terminology_dictionary.csv
12+
The complete terminology dictionary containing important terms identified from Python documentation. Contains:
13+
- **source_term**: The original English term
14+
- **translated_term**: The corresponding Chinese (Traditional) translation
15+
- **frequency**: Number of occurrences across all files
16+
- **files_count**: Number of different files containing this term
17+
- **source_file**: Example file where this term was found
18+
- **directory**: Directory of the source file
19+
- **example_files**: List of up to 5 files containing this term
20+
21+
Total entries: ~196 essential Python terms
22+
23+
### focused_terminology_dictionary.csv
24+
A curated subset of ~118 terms focusing on the most important Python terminology. Includes additional columns:
25+
- **priority**: High/Medium priority classification
26+
- **category**: Term classification
27+
28+
#### Categories:
29+
- **Core Concepts** (7 terms): class, function, method, module, package, object, type
30+
- **Built-in Types** (9 terms): int, str, list, dict, tuple, set, float, bool, complex
31+
- **Keywords/Constants** (25 terms): None, True, False, return, import, def, async, await, and other Python keywords
32+
- **Exceptions** (29 terms): Common *Error and *Exception classes
33+
- **Code Elements** (14 terms): Magic methods like __init__, __str__, etc.
34+
- **Common Terms** (34 terms): Important technical concepts like decorator, generator, iterator
35+
36+
## Maintenance
37+
38+
The terminology dictionaries are maintained using LLM knowledge to identify important Python terms and their translations. The dictionaries can be updated as needed to reflect new terminology or improved translations.
39+
40+
## Integration with Translation Workflow
41+
42+
### For New Translators
43+
1. Start with `focused_terminology_dictionary.csv`
44+
2. Learn standard translations for core Python concepts
45+
3. Reference high-frequency terms for consistency
46+
47+
### For Translation Review
48+
1. Check new translations against the dictionary
49+
2. Verify consistent terminology usage
50+
3. Update dictionary when establishing new standard translations
51+
52+
### For Project Management
53+
1. Track translation progress for key technical terms
54+
2. Identify terminology needing standardization
55+
3. Prioritize translation efforts using frequency data
56+
57+
### Output Format
58+
CSV files use UTF-8 encoding to properly handle Chinese characters. Compatible with Excel, Google Sheets, and other spreadsheet applications.
59+
60+
## Maintenance
61+
62+
### Adding New Terms
63+
New terms can be identified and added based on:
64+
- Frequency of appearance in documentation
65+
- Importance to Python concepts
66+
- Consistency needs across translation files
67+
68+
### Manual Curation Process
69+
The dictionaries are maintained through careful analysis of:
70+
- Core Python terminology in official documentation
71+
- Existing translation patterns in .po files
72+
- Category-based organization for translator efficiency
73+
74+
### Quality Assurance
75+
- Regular review of term translations for consistency
76+
- Cross-reference with official Python terminology
77+
- Validation against established translation conventions
78+
79+
This documentation provides comprehensive guidance for maintaining and using the translation dictionary system to ensure consistent, high-quality Python documentation translation.

c-api/allocation.po

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2001-2024, Python Software Foundation
1+
# Copyright (C) 2001-2025, Python Software Foundation
22
# This file is distributed under the same license as the Python package.
33
#
44
# Translators:
@@ -62,6 +62,8 @@ msgid ""
6262
"`Py_TPFLAGS_HAVE_GC` set. For such objects, use :c:func:`PyObject_GC_New` "
6363
"instead."
6464
msgstr ""
65+
"注意,如果 *typeobj* 有 :c:macro:`Py_TPFLAGS_HAVE_GC` 設定,則此函式不適用。"
66+
"對於這種物件,請改用 :c:func:`PyObject_GC_New`。"
6567

6668
#: ../../c-api/allocation.rst:45
6769
msgid ""
@@ -88,6 +90,8 @@ msgid ""
8890
"`Py_TPFLAGS_HAVE_GC` set. For such objects, use :c:func:`PyObject_GC_NewVar` "
8991
"instead."
9092
msgstr ""
93+
"注意,如果 *typeobj* 有 :c:macro:`Py_TPFLAGS_HAVE_GC` 設定,則此函式不適用。"
94+
"對於這種物件,請改用 :c:func:`PyObject_GC_NewVar`。"
9195

9296
#: ../../c-api/allocation.rst:63
9397
msgid ""

c-api/bool.po

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
# SOME DESCRIPTIVE TITLE.
2-
# Copyright (C) 2001-2022, Python Software Foundation
1+
# Copyright (C) 2001-2025, Python Software Foundation
32
# This file is distributed under the same license as the Python package.
43
#
54
# Translators:
@@ -42,6 +41,8 @@ msgid ""
4241
"This instance of :c:type:`PyTypeObject` represents the Python boolean type; "
4342
"it is the same object as :class:`bool` in the Python layer."
4443
msgstr ""
44+
"此 :c:type:`PyTypeObject` 實例代表 Python 的布林型別;它與 Python 層級中的 "
45+
":class:`bool` 是同一個物件。"
4546

4647
#: ../../c-api/bool.rst:22
4748
msgid ""

c-api/call.po

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2001-2023, Python Software Foundation
1+
# Copyright (C) 2001-2025, Python Software Foundation
22
# This file is distributed under the same license as the Python package.
33
#
44
# Translators:
@@ -122,6 +122,11 @@ msgid ""
122122
"versions, vectorcall should only be used with :c:macro:`immutable "
123123
"<Py_TPFLAGS_IMMUTABLETYPE>` or static types."
124124
msgstr ""
125+
"當一個類別的 :py:meth:`~object.__call__` 方法被重新賦值時,:c:macro:"
126+
"`Py_TPFLAGS_HAVE_VECTORCALL` 旗標現在會被移除。(這會在內部設定 :c:member:"
127+
"`~PyTypeObject.tp_call`,因此可能會使它與 vectorcall 函式有不同的行為。)"
128+
"在較早的 Python 版本中,vectorcall 應該只與 :c:macro:"
129+
"`immutable <Py_TPFLAGS_IMMUTABLETYPE>` 或靜態型別一起使用。"
125130

126131
#: ../../c-api/call.rst:69
127132
msgid ""

0 commit comments

Comments
 (0)