Better i18n with gettext: use class-based API
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 35/100
- Loại issue
- Tính năng
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Đình trệ
- Công nghệ
- python
- Lĩnh vực
- cli, internationalization, localization
Hướng nghiên cứu
Bắt đầu bằng cách xác định các vị trí hiện đang sử dụng from gettext import _ trong Click và các đường dẫn khởi tạo command/group của nó. Tiếp theo, xem xét các API gettext kiểu cổ điển và dựa trên class của Python, rồi xác định phạm vi tương thích cho API cũ và tích hợp click.i18n được đề xuất. Công việc được xem là hoàn tất khi Click không còn thay đổi domain toàn cục của gettext khi import và các consumer có thể tách biệt các domain dịch.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Hi lovely Click maintainers,
Currently, Click implements gettext using the classic GNU gettext API. That looks like this:
from gettext import _
print(_("Hello, world!"))
This API depends on a global state in the gettext module. By calling gettext.textdomain(), the active translation domain is changed for all Python modules that use the classic GNU gettext API.
This side effect is usually desirable, except when your module is imported by another module as a library. So you usually don't want to call gettext.textdomain() without putting it behind some sort of function call. With argparse, this is easy: put it in your main function before you even create the ArgumentParser object. With Click, I'm not sure this is possible:
- Your main group/command is decorated with all manner of Click magic and its contents may not actually be run (e.g.
--help). - There is no way to pre-hook a group/command with a function call that I am aware of.
So you end up having to call gettext.textdomain() on import of your module containing your Click groups/commands.
We can fix that by switching to the class-based API. Because Click will still need to support the old API as well for backwards compatibility, my proposal looks a little as follows. Create a module click.i18n with the following contents (simplified):
import gettext as _gettext_module
TRANSLATIONS = None
def gettext(message):
if TRANSLATIONS is None:
return _gettext_module.gettext(message)
return TRANSLATIONS.gettext(message)
# alias
_ = gettext
Now, elsewhere in Click, you replace all from gettext import _ with from .i18n import _.
Subsequently, we can create a function install_translations(translations) in i18n.py that replaces the TRANSLATIONS global constant with an instantiated GNUTranslations object. This function would still need to be called before the consumer's main function, but it wouldn't change the gettext global state—it would only change Click's. Which, as far perfectionism goes, is probably tolerable. It would be better still if there was a pre-hook, but this is fine.
Furthermore, the consumer could use different domains for Click's TRANSLATIONS object and their own, allowing them to separate their own translations from Click's, and hypothetically reuse the Click translations in other projects.
In fact, having done this plumbing, Click could even ship its own translation strings, getting rid of duplication efforts of translating the same Click strings. Click's own translations could then be activated using e.g. install_click_translations() without any arguments.
In summary, the problems solved by this:
- Importing the Click consumer's module no longer changes the global state of the gettext module.
- Users can separate their own module's translations from Click's.
- Click would be enabled to provide its own translations to reduce duplication of efforts.
I am not aware of other ways to achieve the above that do not require changes to Click. Adding a pre-hook to groups/commands might partially address the problem.
I am willing to make a PR if this issue is validated.
I wrote a blog post here that provides more context on how I use gettext + Click (+ some other components). It has more context than is necessary to understand this issue.
- Ngôn ngữ chính
- Python
- Star
- 17.8k
- Fork
- 3.3k
- Merge trung bình
- 3 ngày 3 giờ
- Pull request đã merge (30 ngày)
- 13
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của pallets/click
-
`show_envvar=True` Drops Environment Variable from Error Messages When Using `auto_envvar_prefix`Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
Maintainer thường phản hồi trong vòng 1 ngày
-
More private utilities that need to be marked and public api deprecatedCó thể làm lại được Pull request cho issue này đã bị đóng mà không được merge. Đang mởtyping
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
pallets/click#3847 · 9 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Automatically append ellipsis (`...`) to metavars when `multiple=True` in optionsCó thể đã có người làm @SparshGarg999 đã nhận 89 ngày trước. Đang mởhelp output
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
pallets/click#3652 · 4 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
`HelpFormatter.write_usage` breaks options at a hyphenCó thể đã có người làm @kdeldycke đã nhận 9 ngày trước. Đang mởhelp output
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
pallets/click#3362 · 4 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Add glossary of terms to click reference docsCó thể đã có người làm @rohitbarhate111-commits đã nhận 55 ngày trước. Đang mởdocs
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
pallets/click#3077 · 5 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của pallets/click
Issue tương tự
-
needs-triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
gke-labs/kube-agents#5671 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
docs(auth): Method B step 4 should tell users to tick "Use this client for an AI-powered agent"Đang mởdocumentation next-release v0.9.6
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
khuisman/mcp-gee-sweet#1446 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
In-box secret files written before their chmod: lc-creds, stacks tee, and the workspace tokenĐang mởmodel:sonnet runtime:claude security size:S
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
FootprintAI/Containarium#3671 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
HolidayBase: reassigning `language` does not re-initialize translations or re-populate holidaysCó thể đã có người làm @shikhabhadoria đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
vacanza/holidays#4116 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug CLI exec
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
Maintainer thường phản hồi trong vòng 1 ngày