الخلفية¶
تقع هذه المكتبة عند نقطة التقاء قصتين طويلتين — إحداهما عن كيفية ترجمة البرمجيات، والأخرى عن كيفية استيفاء Python للسلاسل النصية — تقاطعتا أخيراً في عام 2025 ثم توقفتا عند النقطة التي كانت الحاجة فيها بالضبط إلى اتفاقية صغيرة ومتأنية. تروي هذه الصفحة القصتين معاً، مع روابط إلى المصادر، لأن الحكم على القرارات التصميمية في هذا الموقع أسهل عندما ترى الأسئلة التي تجيب عنها.
منظومة gettext¶
GNU gettext هو الطريقة التي تُترجم بها البرمجيات الحرة منذ منتصف
التسعينيات: توسم النصوص في الشيفرة، وتُستخرج إلى قالب، ويحصل المترجمون
على ملف كتالوج واحد لكل لغة، ثم يُجمّع ويُحمّل وقت التشغيل. وحول هذه
الحلقة نمت منظومة كاملة — محررات PO وسير عمل المراجعة ومنصات الترجمة
التي تتحدث كلها صيغة الملفات نفسها — وتشحن Python
وحدة gettext في مكتبتها القياسية منذ أكثر من عقدين.
لم يكن النصف الخاص بوقت التشغيل من الترجمة هو المشكلة قط.
أما النصف غير المحسوم فكان دائماً شكل النص في الكتالوج. رسالة
%(name)s تسلّم المترجمين صيغة printf يحوّلها حذف حرف واحد إلى انهيار
في بيئة الإنتاج؛ ورسالة .format() تمنح الكتالوج حق الوصول إلى خصائص
كائنات حية. (تمر صفحة لماذا t-strings بكليهما، مع عرض
الإخفاقات.) أما f-strings — الصيغة التي تفضلها معظم شيفرة Python اليوم —
فلا تستطيع المشاركة إطلاقاً: فحين تراها أي مكتبة تكون قد صارت نصاً
مكتملاً بالفعل. ومع ذلك يحاول الناس، كثيراً إلى درجة أن متتبع مشكلات
Babel يجمع تلك المحاولات (#594 و#715)؛ فالفشل
هنا بنيوي، لا ميزة ناقصة.
مقترحا PEP بفارق عشر سنوات¶
في عام 2015، كتبت Alyssa Coghlan مع Nick Humrich مقترح PEP 501 الذي اقترح قوالب استيفاء كان دافعها الأول المعلن هو i18n — «توفير صيغة أنظف لترجمة i18n» بتعبير الوثيقة نفسها. أُرجئ المقترح، جزئياً لأن النقاش أظهر أن حالة i18n تحمل اعتبارات إضافية كبيرة لا تحملها حالات الاستخدام الأبسط.
وبعد عقد من الزمن، أحيا PEP 750 — من تأليف Jim Baker وGuido van Rossum وPaul Everitt وKoudai Aono وLysandros Nikolaou وDave Peck — الفكرة على شكل t-strings، وقُبل في أبريل 2025، وصدر ضمن Python 3.14 في أكتوبر 2025. ثم سُحب PEP 501 لصالحه. وثمة تفصيل مهم لهذه الصفحة: i18n ليست ضمن الدوافع المعلنة لـPEP 750. لقد عمّم المقترح الآلية — نوع قالب تستطيع أي مكتبة استهلاكه — وترك سؤال الترجمة في المكان الذي أوقفه فيه PEP 501 قبل عشر سنوات بالضبط: مفتوحاً.
وهكذا، اعتباراً من Python 3.14، امتلكت اللغة بالضبط بنية البيانات التي يحتاجها كتالوج الرسائل، ومن دون أي اتفاقية لاستخدامها كذلك.
نقاش المكتبة القياسية¶
قبل شهرين من صدور 3.14، اقترح Adrian Mönnich (المعروف باسم ThiefMaster،
وهو أحد مشرفي مشروع Indico) سد هذه الفجوة في المكتبة القياسية نفسها:
افتُتح موضوع Support t-strings in gettext على
discuss.python.org في أغسطس 2025، مصحوباً بـطلب سحب عامل
يضيف دعم t-string إلى كل من gettext وpygettext.
الموضوع يستحق القراءة كاملاً، لأنه يطرح كل سؤال صعب اضطرت هذه المكتبة لاحقاً إلى الإجابة عنه:
- ما الذي يجوز أن يكون عليه الاستيفاء؟ اسم بسيط فقط، أم خصائص واستدعاءات باسم عنصر نائب مشتق؟ كل إجابة تقايض الراحة بثبات msgid وسلامة الكتالوج.
- ماذا تتطلب صيغ الجمع عندما يختلف نظام الجمع في اللغة الهدف عن نظامه في لغة المصدر؟
- وهل gettext هو الهدف الصحيح أصلاً؟ أشار Barry Warsaw — الذي كان قد
جادل أثناء تطوير PEP 750 بأن t-strings ليست ملائمة لـi18n — إلى مكتبته
flufl.i18nوأسلوب سلاسل$فيها بوصفهما الأداة الأكثر وداً للمترجم؛ وجادل آخرون بترك gettext كلياً لصالح أنظمة أحدث مثل Fluent. - والسؤال الأعلى: أياً كان ما تشحنه المكتبة القياسية، فإنه لا يمكن تغييره عملياً أبداً. واتفاقية بهذا العدد من الخيارات المفتوحة شيء خطر أن يُجمَّد من المحاولة الأولى.
لم يتشكل إجماع. أُغلقت مشكلة CPython بوصفها «غير مخطط لها» وأُغلق طلب السحب دون دمج في أكتوبر 2025، بعد أيام من صدور 3.14. كانت القدرة موجودة في اللغة؛ أما الاتفاقية فلم يكن لها موطن.
لماذا حزمة أولاً¶
تلك هي الفجوة التي اختار هذا المشروع سدّها من خارج المكتبة القياسية، على رهان متعمد: الاتفاقية تنضج أسرع حيث تستطيع الإصدار بحرية وكسب التبني حالة بحالة، والمكتبة القياسية — التي يجب أن تصيب من المرة الأولى — هي المكان الذي ينبغي أن تنتهي إليه الاتفاقية، لا المكان الذي تُصاغ فيه.
عملياً، لكل سؤال متنازع عليه في ذلك الموضوع إجابة مكتوبة هنا، كل منها في صفحته:
- الاستيفاءات أسماء بسيطة فقط، فتبقى msgids مستقرة وذات معنى — يعرض الدليل القاعدة، وتشرح كيف تعمل الأسباب.
- يبقى التنسيق خارج الكتالوج كلياً (لماذا t-strings).
- تتبع صيغ الجمع قاعدة اتحاد وتقاطع تسمح لنظام الجمع في اللغة الهدف بالاختلاف عن نظام المصدر (المواصفة §4).
- الكتالوج المعطوب يتراجع بدلاً من الانهيار، حفاظاً على عقد gettext نفسه (الدليل).
- والاتفاقية بكاملها مواصفة ذات إصدارات مع حزمة توافق قابلة للقراءة آلياً — كُتبت بحيث يستطيع تنفيذ آخر، بما في ذلك تنفيذ مستقبلي في المكتبة القياسية، تبنّيها دون تغيير والعمل معها بتوافق تام.
لم ينته النقاش، وهذا المشروع مشارك فيه لا حكم عليه. إذا كانت لديك خبرة إنتاجية مع gettext تمس هذه الخيارات، فإن الموضوع نفسه ونقاشات هذا المستودع هما حيث يستمر النقاش.
الجدول الزمني¶
| متى | ماذا حدث |
|---|---|
| منتصف التسعينيات | يرسي GNU gettext سير عمل PO/POT/MO الذي لا يزال المترجمون والمنصات يتحدثونه حتى اليوم. |
| 2015 | يقترح PEP 501 قوالب الاستيفاء، وi18n دافعه الأول؛ ثم يُرجأ. |
| 2016 | تصدر f-strings في Python 3.6 — يحصل الاستيفاء على صيغته، ولا تستطيع الترجمة استخدامها. |
| يوليو 2024 | يقترح PEP 750 سلاسل t-strings. |
| أبريل 2025 | يُقبل مقترح PEP 750؛ ويُسحب PEP 501 لصالحه. |
| أغسطس 2025 | يُفتتح موضوع Support t-strings in gettext، مع طلب سحب للمكتبة القياسية. |
| أكتوبر 2025 | يصدر Python 3.14 بسلاسل t-strings؛ وتُغلق مشكلة المكتبة القياسية بوصفها غير مخطط لها. |
| 2026 | تصدر gettext-tstrings بوصفها إصدار alpha، مع الإصدار الأول من المواصفة وحزمة توافقها. |