پرش به محتویات

پیشینه

این کتابخانه در نقطهٔ تلاقی دو داستان بلند نشسته است — یکی دربارهٔ این‌که نرم‌افزار چگونه ترجمه می‌شود، دیگری دربارهٔ این‌که پایتون چگونه رشته‌ها را درون‌یابی می‌کند — دو داستانی که سرانجام در ۲۰۲۵ به هم رسیدند و سپس درست همان‌جا از حرکت ایستادند که به یک قرارداد کوچک و سنجیده نیاز بود. این صفحه هر دو داستان را با پیوند به منابع بازمی‌گوید، چون قضاوت دربارهٔ تصمیم‌های طراحی این وب‌گاه وقتی آسان‌تر است که پرسش‌هایی را ببینید که به آن‌ها پاسخ می‌دهند.

زیست‌بوم gettext

GNU gettext از میانهٔ دههٔ ۱۹۹۰ روش ترجمه‌شدن نرم‌افزار آزاد بوده است: رشته‌ها را در کد علامت‌گذاری کن، آن‌ها را در یک الگو استخراج کن، به مترجم‌ها برای هر زبان یک فایل کاتالوگ بده، کامپایل کن، در زمان اجرا بار کن. گرد این چرخه یک زیست‌بوم کامل رویید — ویرایشگرهای PO، گردش‌کارهای بازبینی، و پلتفرم‌های ترجمه که همگی با یک قالب فایل حرف می‌زنند — و پایتون بیش از دو دهه است که یک ماژول gettext در کتابخانهٔ استانداردش دارد. نیمهٔ زمانِ اجرایِ ترجمه هرگز مشکل نبود.

نیمهٔ حل‌نشده همیشه این بود که رشتهٔ کاتالوگ چه شکلی باشد. پیامِ %(name)s نحو printf را به دست مترجم می‌دهد که حذف یک حرف آن را به کرش عملیاتی بدل می‌کند؛ پیامِ .format() دسترسی به خصیصه‌های اشیاء زنده را به کاتالوگ می‌سپارد. (چرا t-string؟ هر دو را با نمایش شکست‌هایشان می‌پیماید.) و f-string‌ها — نحوی که اکنون بیشترِ کد پایتون ترجیح می‌دهد — اصلاً نمی‌توانند شرکت کنند: تا کتابخانه‌ای یکی از آن‌ها را ببیند، دیگر یک رشتهٔ تمام‌شده است. با این حال مردم تلاش می‌کنند، آن‌قدر که ردیاب ایشوهای Babel این تلاش‌ها را جمع می‌کند (#594، #715)؛ این شکست ساختاری است، نه یک قابلیتِ غایب.

دو PEP، با ده سال فاصله

در ۲۰۱۵، آلیسا کاگلن و نیک هامریچ PEP 501 را نوشتند و قالب‌های درون‌یابی را پیشنهاد کردند؛ نخستین انگیزهٔ اعلام‌شده‌اش i18n بود — به تعبیر خود PEP، «فراهم کردن نحوی پاکیزه‌تر برای ترجمهٔ i18n». پیشنهاد به تعویق افتاد، تا حدی از آن رو که بحث نشان داد پروندهٔ i18n ملاحظات اضافیِ چشمگیری دارد که کاربردهای ساده‌تر نداشتند.

یک دهه بعد، PEP 750 — نوشتهٔ جیم بیکر، خیدو فان روسوم، پل اوریت، کودای آئونو، لیساندروس نیکولائو و دیو پک — همان ایده را در قالب t-string زنده کرد، در آوریل ۲۰۲۵ پذیرفته شد و در اکتبر ۲۰۲۵ با Python 3.14 منتشر شد. سپس PEP 501 به سود آن پس گرفته شد. یک جزئیات برای این صفحه اهمیت دارد: i18n در میان انگیزه‌های اعلام‌شدهٔ PEP 750 نیست. این PEP سازوکار را عمومی کرد — نوعِ قالبی که هر کتابخانه‌ای بتواند مصرف کند — و پرسش ترجمه را دقیقاً همان‌جا گذاشت که PEP 501 ده سال پیش‌تر پارکش کرده بود: باز.

پس از پایتون 3.14، زبان دقیقاً همان ساختار داده‌ای را داشت که یک کاتالوگ پیام لازم دارد، و هیچ قراردادی برای به‌کاربردنش به این عنوان نداشت.

بحث کتابخانهٔ استاندارد

دو ماه پیش از انتشار 3.14، آدریان مونیش (ThiefMaster، از نگه‌دارندگان پروژهٔ Indico) پیشنهاد کرد این شکاف در خود کتابخانهٔ استاندارد بسته شود: ریسهٔ Support t-strings in gettext در discuss.python.org، که در اوت ۲۰۲۵ گشوده شد، همراه با یک پول‌ریکوئستِ کارا که پشتیبانی t-string را هم به gettext و هم به pygettext می‌افزود.

خواندن کامل آن ریسه می‌ارزد، چون هر پرسش دشواری را رو می‌آورد که این کتابخانه بعدها ناچار شد پاسخ دهد:

  • درون‌یابی چه می‌تواند باشد؟ فقط یک نام ساده، یا خصیصه‌ها و فراخوانی‌ها با نام جای‌نگهدارِ مشتق‌شده؟ هر پاسخی راحتی را با پایداری msgid و امنیت کاتالوگ معامله می‌کند.
  • صورت‌های جمع چه لازم دارند، وقتی نظام جمع زبان مقصد با مبدأ متفاوت است؟
  • آیا gettext اصلاً مقصد درستی است؟ بری وارسا — که در جریان تدوین PEP 750 استدلال کرده بود t-string‌ها برای i18n مناسب نیستند — به flufl.i18nِ خودش و سبک رشته‌های $ آن به‌عنوان ابزار دوستانه‌تر اشاره کرد؛ دیگران از کنار گذاشتن کامل gettext به سود نظام‌های نوتری چون Fluent دفاع کردند.
  • و فراپرسش: هر چه کتابخانهٔ استاندارد عرضه کند، در عمل هرگز نمی‌تواند تغییر کند. قراردادی با این‌همه انتخابِ باز، چیز پرخطری است که در نخستین تلاش منجمدش کنی.

هیچ اجماعی شکل نگرفت. ایشوی CPython با برچسب «not planned» بسته شد و پول‌ریکوئست در اکتبر ۲۰۲۵، چند روز پس از انتشار 3.14، ادغام‌نشده بسته شد. توانایی در زبان وجود داشت؛ قرارداد خانه‌ای نداشت.

چرا اول یک بسته

این همان شکافی است که این پروژه برگزید از بیرونِ کتابخانهٔ استاندارد پرش کند، بر سر یک شرط‌بندی سنجیده: قرارداد جایی زودتر بالغ می‌شود که بتواند آزادانه نسخه بگیرد و پذیرش را مورد به مورد به دست آورد، و کتابخانهٔ استاندارد — که باید بار اول درست باشد — جایی است که قرارداد باید به آن برسد، نه جایی که در آن ساخته‌وپرداخته شود.

به‌طور مشخص، هر پرسش مناقشه‌برانگیز آن ریسه این‌جا پاسخی مکتوب دارد، هر یک در صفحهٔ خودش:

  • درون‌یابی‌ها فقط نام‌های ساده‌اند، تا msgidها پایدار و معنادار بمانند — راهنما قاعده را نشان می‌دهد و چگونه کار می‌کند دلیل‌ها را.
  • قالب‌بندی به‌کلی بیرون از کاتالوگ می‌ماند (چرا t-string؟).
  • صورت‌های جمع از قاعدهٔ اجتماع/اشتراکی پیروی می‌کنند که می‌گذارد نظام جمع زبان مقصد با مبدأ متفاوت باشد (بند ۴ مشخصات).
  • کاتالوگ خراب به‌جای کرش عقب می‌نشیند و پیمان خود gettext را نگه می‌دارد (راهنما).
  • و کل قرارداد یک مشخصات نسخه‌دار با مجموعهٔ انطباق ماشین‌خوان است — چنان نوشته شده که پیاده‌سازی دیگری، از جمله یک پیاده‌سازی آیندهٔ کتابخانهٔ استاندارد، بتواند بی‌تغییر بپذیردش و هم‌کنش‌پذیر بماند.

بحث پایان نیافته است و این پروژه شرکت‌کننده‌ای در آن است، نه حکمی دربارهٔ آن. اگر تجربهٔ عملیاتی gettext دارید که به این انتخاب‌ها مربوط است، همان ریسه و بخش Discussions این مخزن جایی است که بحث در آن ادامه دارد.

گاه‌شمار

چه زمانی چه رخ داد
میانهٔ دههٔ ۱۹۹۰ GNU gettext گردش کار PO/POT/MO را بنیان می‌گذارد که مترجم‌ها و پلتفرم‌ها هنوز با آن حرف می‌زنند.
۲۰۱۵ PEP 501 قالب‌های درون‌یابی را پیشنهاد می‌کند، با i18n به‌عنوان نخستین انگیزه؛ به تعویق می‌افتد.
۲۰۱۶ f-string‌ها با پایتون 3.6 می‌آیند — درون‌یابی صاحب نحو می‌شود و ترجمه نمی‌تواند از آن استفاده کند.
ژوئیهٔ ۲۰۲۴ PEP 750 پیشنهاد t-string را می‌دهد.
آوریل ۲۰۲۵ PEP 750 پذیرفته می‌شود؛ PEP 501 به سود آن پس گرفته می‌شود.
اوت ۲۰۲۵ ریسهٔ Support t-strings in gettext گشوده می‌شود، همراه با یک پول‌ریکوئستِ کتابخانهٔ استاندارد.
اکتبر ۲۰۲۵ Python 3.14 با t-string منتشر می‌شود؛ ایشوی کتابخانهٔ استاندارد با برچسب not planned بسته می‌شود.
۲۰۲۶ gettext-tstrings به‌صورت آلفا منتشر می‌شود، با نسخهٔ ۱ مشخصات و مجموعهٔ انطباقش.