تكرار السؤال: …
الإجابة المختصرة
استخدم صيغة الاتحاد X | Y و X | None (منذ Python 3.10)، أو Union و Optional من typing في الإصدارات الأقدم؛ و Optional[X] تعني X | None وليست "معاملًا اختياريًا".
الشرح
يجب أن يظهر احتمال None في التوقيع بدل إخفائه خلف Any، حتى يجبرك الـ type checker على معالجته. بعد فحص مثل if user is None: return يضيّق الـ checker النوع تلقائيًا (narrowing) في بقية الكود. لاحظ أن كون المعامل له قيمة افتراضية لا يعني أن نوعه Optional؛ فالـ Optional تتعلق بقبول None فقط.
مثال بالكود
def find_user(user_id: int) -> User | None:
...
user = find_user(42)
print(user.name) # mypy: Item "None" has no attribute "name"
if user is not None:
print(user.name) # النوع الآن Userأخطاء شائعة
- إرجاع None من دالة نوعها المعلن User فقط دون تحديث التوقيع.
- الخلط بين المعامل الاختياري (له قيمة افتراضية) والنوع Optional.