Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8286ee7
feat: Add translation tests import to test suite
xinvxueyuan Jan 17, 2026
0f52666
refactor: Remove unnecessary blank line in test suite initialization
xinvxueyuan Jan 17, 2026
696a9c2
feat: 迁移测试框架至pytest并更新相关测试用例
xinvxueyuan Jan 17, 2026
b3743b5
Refactor i18n tests: remove deprecated files and migrate to new test …
xinvxueyuan Jan 17, 2026
24378a8
fix: 修复Travis CI安装步骤和更新pyproject.toml中的测试包包含规则
xinvxueyuan Jan 17, 2026
6ca161f
refactor: 移除setup.py和测试文件中的不必要注释以清理代码
xinvxueyuan Jan 17, 2026
d65e5bd
fix: 更新CI配置以确保正确安装pytest并调整lint和测试命令
xinvxueyuan Jan 17, 2026
8954134
feat: 添加自动分配和显示顶级问题的GitHub工作流
xinvxueyuan Jan 17, 2026
4f0f027
fix: 更新README以警告项目过时并需要现代化;移除测试文件中的类型忽略注释
xinvxueyuan Jan 19, 2026
2ca53a5
fix: 移除pytest依赖从pyproject.toml中并将其添加到开发依赖组;更新requirements.txt以包含pytest
xinvxueyuan Jan 19, 2026
a3c6904
Update pyproject.toml
xinvxueyuan Jan 19, 2026
0bea323
fix: 更新翻译加载逻辑以支持顶层为 locale 的结构;重构测试用例以使用 pytest 进行全局设置
xinvxueyuan Jan 19, 2026
952c6df
Apply suggestion from @Copilot
xinvxueyuan Jan 19, 2026
f70d6c0
Apply suggestion from @Copilot
xinvxueyuan Jan 19, 2026
d2da05b
Apply suggestions from code review
xinvxueyuan Jan 19, 2026
957605a
fix: 修复测试用例中的拼写错误并更新自动分配工作流以支持重新打开的请求
xinvxueyuan Jan 19, 2026
91bfb6c
fix: 添加重置状态的测试夹具以确保测试之间的配置隔离;优化临时文件的创建和清理逻辑
xinvxueyuan Jan 19, 2026
dca293b
fix: 更新工作流以使用最新的 Ubuntu 版本;优化测试夹具以确保状态重置
xinvxueyuan Jan 19, 2026
94a886a
fix: 修复文件格式解析错误并优化翻译功能;更新测试用例以修正拼写错误
xinvxueyuan Jan 19, 2026
c8b9ffc
fix: 更新翻译搜索功能以支持新的文件名格式
xinvxueyuan Jan 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
17 changes: 17 additions & 0 deletions .github/workflows/auto-assign.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Auto Assign

on:
issues:
types: [opened, reopened]
pull_request_target:
types: [opened, reopened]

permissions:
issues: write
pull-requests: write

jobs:
assign-author:
runs-on: ubuntu-latest
steps:
- uses: toshimaru/auto-author-assign@v3.0.1
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install .[yaml]
pip install ruff pyright
pip install ruff pyright pytest
- name: Lint with ruff
run: ruff check i18n
- name: Lint with pyright
run: pyright .
- name: Run tests
run: python -m i18n.tests.run_tests
run: pytest --maxfail=1 --disable-warnings --tb=short
49 changes: 49 additions & 0 deletions .github/workflows/issues-top.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Top issues action.
on:
schedule:
- cron: "0 0 */1 * *"

jobs:
check:
name: Check for open issues
runs-on: ubuntu-latest
permissions:
issues: read
contents: read
outputs:
has_open_issues: ${{ steps.check.outputs.result }}
steps:
- id: check
name: Check open issues
uses: actions/github-script@v6
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const issues = await github.rest.issues.listForRepo({ owner, repo, state: 'open', per_page: 5 });
// Exclude pull requests — only count real issues
const hasIssue = issues.data.some(i => !i.pull_request);
return hasIssue ? 'true' : 'false';

ShowAndLabelTopIssues:
name: Display and label top issues.
needs: check
if: needs.check.outputs.has_open_issues == 'true'
permissions:
contents: read
issues: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Run top issues action
uses: rickstaa/top-issues-action@v1
env:
github_token: ${{ secrets.GITHUB_TOKEN }}
with:
label: true
dashboard: true
dashboard_show_total_reactions: true
top_issues: true
top_bugs: true
top_features: true
top_pull_requests: true
16 changes: 10 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
language: python
python:
- "2.7"
- "3.6"
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
# command to install dependencies
install: "pip install -r requirements.txt"
install:
- pip install -r requirements.txt
- pip install -e .
# command to run tests
script:
- python setup.py test
- coverage run --source=i18n setup.py test
- pytest --maxfail=1 --disable-warnings --tb=short
- coverage run -m pytest
after_success:
- coveralls
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

This library provides i18n functionality for Python 3 out of the box. The usage is mostly based on Rails i18n library.

> [!WARNING]
> This project is outdated and urgently needs modernization due to lack of maintenance.

## Installation

Just run
Expand Down
23 changes: 16 additions & 7 deletions i18n/resource_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,14 @@ def get_namespace_from_filepath(filename):
)
if "{namespace}" in config.get("filename_format"):
try:
format_parts = config.get("filename_format").split(".")
namespace_index = format_parts.index("{namespace}")
splitted_filename = os.path.basename(filename).split(".")
if namespace_index >= len(splitted_filename):
raise I18nFileLoadError("incorrect file format.")
if namespace:
namespace += config.get("namespace_delimiter")
namespace += splitted_filename[
config.get("filename_format").index("{namespace}")
]
namespace += splitted_filename[namespace_index]
except ValueError:
raise I18nFileLoadError("incorrect file format.")
return namespace
Expand All @@ -85,13 +87,20 @@ def load_translation_file(filename, base_directory, locale=config.get("locale"))


def load_translation_dic(dic, namespace, locale):
if namespace:
namespace += config.get("namespace_delimiter")
if isinstance(dic, dict) and len(dic) == 1 and locale in dic:
dic = dic[locale]
Comment on lines +90 to +91
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The load_translation_dic function has been refactored to avoid string concatenation by using a helper function 'join_ns'. The logic on line 90-91 attempts to unwrap a dictionary if it contains only one key matching the locale. However, this check uses 'len(dic) == 1' which will unwrap the dictionary even if it legitimately contains only one top-level key that happens to match the locale name. This could cause unexpected behavior when translation files have a single top-level key matching a locale code.

Copilot uses AI. Check for mistakes.
delimiter = config.get("namespace_delimiter")

def join_ns(ns, k):
if not ns:
return k
return ns + delimiter + k

for key, value in dic.items():
if isinstance(value, dict) and len(set(PLURALS).intersection(value)) < 2:
load_translation_dic(value, namespace + key, locale)
load_translation_dic(value, join_ns(namespace, key), locale)
else:
translations.add(namespace + key, value, locale)
translations.add(join_ns(namespace, key), value, locale)


def load_directory(directory, locale=config.get("locale")):
Expand Down
Empty file removed i18n/tests/__init__.py
Empty file.
Loading
Loading