warnings --- کنترل هشدار

کد منبع: Lib/warnings.py


پیام‌های هشدار معمولاً در موقعیت‌هایی نشان داده می‌شوند که آگاه کردن کاربر از وضعیتی در برنامه مفید است، جایی که آن وضعیت (معمولاً) توجیهی برای پرتاب یک استثنا و خاتمه دادن به برنامه ندارد. برای مثال، ممکن است بخواهید زمانی که برنامه‌ای از یک ماژول منسوخ استفاده می‌کند، هشداری نشان دهید.

برنامه‌نویسان پایتون با فراخوانی تابع warn() تعریف‌شده در این ماژول، هشدارها را نشان می‌دهند. (برنامه‌نویسان C از PyErr_WarnEx() استفاده می‌کنند؛ برای جزئیات، مدیریت استثنا را ببینید).

پیام‌های هشدار معمولاً در sys.stderr نوشته می‌شوند، اما نحوه‌ی برخورد با آن‌ها می‌تواند به‌صورت انعطاف‌پذیر تغییر کند؛ از نادیده گرفتن همه‌ی هشدارها گرفته تا تبدیل آن‌ها به استثنا. نحوه‌ی برخورد با هشدارها می‌تواند بر اساس دسته‌ی هشدار، متن پیام هشدار، و مکان منبعی که هشدار در آن صادر می‌شود متفاوت باشد. تکرارهای یک هشدار مشخص برای همان مکان منبع معمولاً سرکوب می‌شوند.

کنترل هشدار دو مرحله دارد: نخست، هر بار که هشداری نشان داده می‌شود، تعیین می‌شود که آیا پیامی باید نشان داده شود یا خیر؛ سپس، اگر قرار باشد پیامی نشان داده شود، آن پیام با استفاده از یک قلاب قابل تنظیم توسط کاربر قالب‌بندی و چاپ می‌شود.

تصمیم درباره‌ی صدور یک پیام هشدار را پالایه‌ی هشدار کنترل می‌کند، که دنباله‌ای از قواعد تطبیق و اقدام‌ها است. می‌توان با فراخوانی filterwarnings() قواعدی را به پالایه افزود و با فراخوانی resetwarnings() آن را به حالت پیش‌فرض بازنشانی کرد.

چاپ پیام‌های هشدار با فراخوانی showwarning() انجام می‌شود، که می‌توان آن را بازنویسی کرد؛ پیاده‌سازی پیش‌فرض این تابع، پیام را با فراخوانی formatwarning() قالب‌بندی می‌کند، که برای استفاده‌ی پیاده‌سازی‌های سفارشی نیز در دسترس است.

همچنین ملاحظه نمائید

logging.captureWarnings() به شما اجازه می‌دهد تمام هشدارها را با زیرساخت استاندارد گزارش‌گیری مدیریت کنید.

دسته‌های هشدار

تعدادی استثناهای توکار وجود دارند که نشان‌دهنده‌ی دسته‌های هشدار هستند. این دسته‌بندی مفید است تا بتوان گروه‌هایی از هشدارها را فیلتر کرد.

اگرچه این موارد از نظر فنی استثناهای توکار هستند، اما در اینجا مستند شده‌اند، زیرا از نظر مفهومی به سازوکار هشدارها تعلق دارند.

کد کاربر می‌تواند دسته‌بندی‌های هشدار اضافی را با ایجاد زیرکلاسی از یکی از دسته‌بندی‌های هشدار استاندارد تعریف کند. هر دسته‌بندی هشدار باید همیشه زیرکلاسی از کلاس Warning باشد.

کلاس‌های دسته‌بندی هشدار زیر در حال حاضر تعریف شده‌اند:

کلاس

توضیحات

Warning

Base class for warning categories. It is a subclass of Exception.

UserWarning

Base class for warnings generated by user code. The default category for warn().

DeprecationWarning

Base class for warnings about deprecated features when those warnings are intended for other Python developers (ignored by default, unless triggered by code in __main__).

PendingDeprecationWarning

Base class for warnings about features that will be deprecated in the future (ignored by default).

SyntaxWarning

Base class for warnings about dubious syntax (typically emitted when compiling Python source code, and hence may not be suppressed by runtime filters).

RuntimeWarning

Base class for warnings about dubious runtime behavior.

FutureWarning

Base class for warnings about deprecated features when those warnings are intended for end users of applications that are written in Python.

ImportWarning

Base class for warnings triggered during the process of importing a module (ignored by default).

UnicodeWarning

Base class for warnings related to Unicode.

EncodingWarning

Base class for warnings related to encodings. See فعال‌سازی اختیاری هشدار کدگذاری (EncodingWarning) for details.

BytesWarning

Base class for warnings related to bytes and bytearray.

ResourceWarning

Base class for warnings related to resource usage (ignored by default).

تغییر یافته در نسخه‌ی 3.7: در گذشته، DeprecationWarning و FutureWarning بر اساس اینکه آیا یک قابلیت به‌طور کامل حذف می‌شد یا رفتار آن تغییر می‌کرد، از هم متمایز می‌شدند. اکنون آن‌ها بر اساس مخاطبان مورد نظرشان و شیوه‌ای که فیلترهای پیش‌فرض هشدارها آن‌ها را مدیریت می‌کنند، از هم متمایز می‌شوند.

فیلتر هشدارها

فیلتر هشدارها تعیین می‌کند که هشدارها نادیده گرفته شوند، نمایش داده شوند یا به خطا تبدیل شوند (با پرتاب یک استثنا).

از نظر مفهومی، فیلتر هشدارها یک فهرست مرتب از مشخصه‌های فیلتر را نگه می‌دارد؛ هر هشدار خاص به‌نوبت با هر مشخصه‌ی فیلتر در فهرست تطابق داده می‌شود تا تطابقی یافت شود؛ فیلتر تکلیف تطابق را مشخص می‌کند. هر ورودی یک تاپل به شکل (action, message, category, module, lineno) است، که در آن:

  • action یکی از رشته‌های زیر است:

    مقدار

    نحوه برخورد

    "default"

    چاپ نخستین رخداد هشدارهای منطبق برای هر موقعیت (ماژول + شماره خط) که هشدار در آن نشان داده می‌شود

    "error"

    تبدیل هشدارهای منطبق به استثناها

    "ignore"

    هرگز هشدارهای منطبق را چاپ نمی‌کند

    "always"

    همیشه هشدارهای منطبق را چاپ می‌کند

    "all"

    نام مستعار برای "always"

    "module"

    چاپ نخستین رخداد هشدارهای منطبق برای هر ماژولی که هشدار در آن نشان داده می‌شود (صرف‌نظر از شماره خط)

    "once"

    فقط اولین رخداد هشدارهای منطبق را چاپ می‌کند، صرف‌نظر از مکان

  • message یک رشته حاوی یک عبارت باقاعده است که ابتدای پیام هشدار باید بدون حساسیت به بزرگی و کوچکی حروف با آن مطابقت داشته باشد. در -W و PYTHONWARNINGS، message یک رشته‌ی لفظی است که ابتدای پیام هشدار باید شامل آن باشد (بدون حساسیت به بزرگی و کوچکی حروف)، و هر فضای سفید در ابتدا یا انتهای message نادیده گرفته می‌شود.

  • category یک کلاس (یک زیرکلاس از Warning) است که دسته‌بندی هشدار باید برای تطابق، زیرکلاسی از آن باشد.

  • module رشته‌ای حاوی عبارت باقاعده است که آغاز نام کامل ماژول باید با آن مطابقت داشته باشد، و این مطابقت حساس به بزرگی و کوچکی حروف است. در -W و PYTHONWARNINGS، module رشته‌ای لفظی است که نام کامل ماژول باید با آن برابر باشد (حساس به بزرگی و کوچکی حروف)، و هرگونه فضای سفید در آغاز یا پایان module نادیده گرفته می‌شود.

  • lineno یک عدد صحیح است که شماره‌ی سطری که هشدار در آن رخ داده است باید با آن مطابقت کند، یا 0 برای مطابقت با همه‌ی شماره‌های خط.

از آنجا که کلاس Warning از کلاس توکار Exception مشتق شده است، برای تبدیل هشدار به خطا، به‌سادگی category(message) را پرتاب می‌کنیم.

اگر هشداری گزارش شود و با هیچ فیلتر ثبت‌شده‌ای مطابقت نداشته باشد، اقدام «default» اعمال می‌شود (از این رو این نام را دارد).

معیارهای فرونشانی هشدارهای تکراری

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

  • "default": یک هشدار تنها در صورتی تکراری محسوب می‌شود که (message، category، module، lineno) همگی یکسان باشند.

  • "module": اگر (message، category، module) یکسان باشند، با نادیده گرفتن شماره خط، هشدار تکراری در نظر گرفته می‌شود.

  • "once": اگر (message, category) یکسان باشند، با نادیده گرفتن ماژول و شماره خط، هشدار تکراری در نظر گرفته می‌شود.

توصیف پالایه‌های هشدار

فیلتر هشدارها با گزینه‌های -W که به خط فرمان مفسر پایتون داده می‌شوند و متغیر محیطی PYTHONWARNINGS مقداردهی اولیه می‌شود. مفسر آرگومان‌های تمام ورودی‌های ارائه‌شده را بدون تفسیر در sys.warnoptions ذخیره می‌کند؛ ماژول warnings این موارد را هنگامی که برای اولین بار ایمپورت می‌شود تجزیه می‌کند (گزینه‌های نامعتبر پس از چاپ یک پیام در sys.stderr نادیده گرفته می‌شوند).

تک‌تک فیلترهای هشدار به‌صورت دنباله‌ای از فیلدها که با دونقطه از هم جدا شده‌اند، مشخص می‌شوند:

action:message:category:module:line

معنای هر یک از این فیلدها همان‌گونه است که در فیلتر هشدارها شرح داده شده است. هنگام فهرست کردن چندین فیلتر در یک خط (مانند PYTHONWARNINGS)، فیلترهای جداگانه با کاما از هم جدا می‌شوند و فیلترهایی که بعداً فهرست شده‌اند بر فیلترهایی که پیش از آن‌ها فهرست شده‌اند اولویت دارند (زیرا آن‌ها از چپ به راست اعمال می‌شوند و آخرین فیلترهای اعمال‌شده بر فیلترهای پیشین اولویت دارند).

فیلترهای هشدار رایج، یا به همه‌ی هشدارها اعمال می‌شوند، یا به هشدارهای یک دسته خاص، یا به هشدارهایی که به‌وسیله‌ی ماژول‌ها یا بسته‌های خاصی پرتاب می‌شوند. برخی مثال‌ها:

default                      # Show all warnings (even those ignored by default)
ignore                       # Ignore all warnings
error                        # Convert all warnings to errors
error::ResourceWarning       # Treat ResourceWarning messages as errors
default::DeprecationWarning  # Show DeprecationWarning messages
ignore,default:::mymodule    # Only report warnings triggered by "mymodule"
error:::mymodule             # Convert warnings to errors in "mymodule"

فیلتر هشدار پیش‌فرض

به‌طور پیش‌فرض، پایتون چندین فیلتر هشدار را نصب می‌کند که می‌توان آن‌ها را با گزینه‌ی خط فرمان -W، متغیر محیطی PYTHONWARNINGS و فراخوانی‌های filterwarnings() بازنویسی کرد.

در ساخت‌های انتشار عادی، پالایه هشدار پیش‌فرض دارای ورودی‌های زیر است (به‌ترتیب اولویت):

default::DeprecationWarning:__main__
ignore::DeprecationWarning
ignore::PendingDeprecationWarning
ignore::ImportWarning
ignore::ResourceWarning

در یک ساخت اشکال‌زدایی، فهرست فیلترهای هشدار پیش‌فرض خالی است.

تغییر یافته در نسخه‌ی 3.2: DeprecationWarning اکنون علاوه بر PendingDeprecationWarning به‌طور پیش‌فرض نادیده گرفته می‌شود.

تغییر یافته در نسخه‌ی 3.7: DeprecationWarning بار دیگر به‌طور پیش‌فرض زمانی نمایش داده می‌شود که مستقیماً توسط کد در __main__ فعال شود.

تغییر یافته در نسخه‌ی 3.7: BytesWarning دیگر در فهرست فیلتر پیش‌فرض ظاهر نمی‌شود و در عوض هنگامی که -b دو بار داده شود، از طریق sys.warnoptions پیکربندی می‌شود.

نادیده گرفتن فیلتر پیش‌فرض

توسعه‌دهندگان برنامه‌های نوشته‌شده با پایتون ممکن است بخواهند همه‌ی هشدارهای سطح پایتون را به‌طور پیش‌فرض از کاربران خود پنهان کنند و آن‌ها را فقط هنگام اجرای آزمون‌ها یا در سایر حالت‌های کار روی برنامه نمایش دهند. ویژگی sys.warnoptions که برای انتقال پیکربندی‌های فیلتر به مفسر استفاده می‌شود، می‌تواند به‌عنوان نشانگری برای مشخص کردن این‌که آیا هشدارها باید غیرفعال شوند یا خیر به کار رود:

import sys

if not sys.warnoptions:
    import warnings
    warnings.simplefilter("ignore")

به توسعه‌دهندگان اجراکننده‌های آزمون (test runners) برای کد پایتون توصیه می‌شود که در عوض اطمینان حاصل کنند که همه هشدارها به‌صورت پیش‌فرض برای کد تحت آزمون نمایش داده شوند، با استفاده از کدی مانند:

import sys

if not sys.warnoptions:
    import os, warnings
    warnings.simplefilter("default") # Change the filter in this process
    os.environ["PYTHONWARNINGS"] = "default" # Also affect subprocesses

در نهایت، توصیه می‌شود توسعه‌دهندگان پوسته‌های تعاملی که کد کاربر را در فضای نامی غیر از __main__ اجرا می‌کنند، با استفاده از کدی مانند زیر اطمینان حاصل کنند که پیام‌های DeprecationWarning به‌طور پیش‌فرض قابل مشاهده باشند (که در آن user_ns ماژولی است که برای اجرای کدی که به‌صورت تعاملی وارد می‌شود استفاده می‌شود):

import warnings
warnings.filterwarnings("default", category=DeprecationWarning,
                                   module=user_ns.get("__name__"))

فرونشانی موقت هشدارها

اگر از کدی استفاده می‌کنید که می‌دانید هشداری را پرتاب می‌کند، مانند یک تابع منسوخ، اما نمی‌خواهید هشدار را ببینید (حتی زمانی که هشدارها به‌صراحت از طریق خط فرمان پیکربندی شده‌اند)، می‌توانید با استفاده از مدیر زمینه‌ی catch_warnings هشدار را سرکوب کنید:

import warnings

def fxn():
    warnings.warn("deprecated", DeprecationWarning)

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    fxn()

هنگامی که درون مدیر زمینه هستید، همه‌ی هشدارها به‌سادگی نادیده گرفته خواهند شد. این امکان را به شما می‌دهد که بدون نیاز به دیدن هشدار، از کد منسوخ شناخته‌شده استفاده کنید، در حالی که هشدار برای سایر کدهایی که ممکن است از استفاده‌ی خود از کد منسوخ آگاه نباشند، مهار نمی‌شود.

توجه

برای جزئیات درباره‌ی ایمنی همروندیِ مدیر زمینه‌ی catch_warnings هنگامی که در برنامه‌های دارای چندین نخ یا توابع ناهمگام استفاده می‌شود، به ایمنی هم‌روندی مدیران زمینه مراجعه کنید.

آزمایش هشدارها

برای آزمون هشدارهای پرتاب‌شده توسط کد، از مدیر زمینه‌ی catch_warnings استفاده کنید. با استفاده از آن می‌توانید فیلتر هشدارها را به‌طور موقت تغییر دهید تا آزمون شما آسان‌تر شود. برای مثال، برای ضبط تمام هشدارهای پرتاب‌شده جهت بررسی، کار زیر را انجام دهید:

import warnings

def fxn():
    warnings.warn("deprecated", DeprecationWarning)

with warnings.catch_warnings(record=True) as w:
    # Cause all warnings to always be triggered.
    warnings.simplefilter("always")
    # Trigger a warning.
    fxn()
    # Verify some things
    assert len(w) == 1
    assert issubclass(w[-1].category, DeprecationWarning)
    assert "deprecated" in str(w[-1].message)

همچنین می‌توان با استفاده از error به جای always، همه‌ی هشدارها را به استثنا تبدیل کرد. یکی از مواردی که باید به آن توجه داشته باشید این است که اگر یک هشدار قبلاً به دلیل یک قانون once/default پرتاب شده باشد، صرف‌نظر از اینکه چه فیلترهایی تنظیم شده باشند، آن هشدار دوباره دیده نخواهد شد، مگر اینکه ثبت هشدارها (warnings registry) مرتبط با آن هشدار پاک شده باشد.

پس از خروج مدیر زمینه، فیلتر هشدارها به وضعیت خود در زمان ورود به زمینه بازیابی می‌شود. این کار مانع از آن می‌شود که آزمون‌ها فیلتر هشدارها را به‌شکل‌های غیرمنتظره در میان آزمون‌ها تغییر دهند و به نتایج نامعین آزمون منجر شوند.

توجه

برای جزئیات درباره‌ی ایمنی همروندیِ مدیر زمینه‌ی catch_warnings هنگامی که در برنامه‌های دارای چندین نخ یا توابع ناهمگام استفاده می‌شود، به ایمنی هم‌روندی مدیران زمینه مراجعه کنید.

هنگام آزمایش چندین عملیات که همان نوع هشدار را پرتاب می‌کنند، مهم است آن‌ها را به شیوه‌ای آزمایش کنید که تأیید کند هر عملیات یک هشدار جدید پرتاب می‌کند (مثلاً هشدارها را طوری تنظیم کنید که به‌صورت استثنا پرتاب شوند و بررسی کنید که عملیات‌ها استثنا پرتاب می‌کنند، بررسی کنید که طول فهرست هشدارها پس از هر عملیات همچنان افزایش می‌یابد، یا در غیر این صورت ورودی‌های قبلی را پیش از هر عملیات جدید از فهرست هشدارها حذف کنید).

به‌روزرسانی کد برای نسخه‌های جدید وابستگی‌ها

دسته‌های هشداری که عمدتاً مورد توجه توسعه‌دهندگان پایتون هستند (نه کاربران نهایی برنامه‌های نوشته‌شده با پایتون) به‌طور پیش‌فرض نادیده گرفته می‌شوند.

شایان ذکر است که این فهرست از هشدارهای «به‌طور پیش‌فرض نادیده گرفته‌شده» شامل DeprecationWarning (برای هر ماژول به‌جز __main__) می‌شود؛ یعنی توسعه‌دهندگان باید حتماً کد خود را با قابل مشاهده کردن هشدارهایی که معمولاً نادیده گرفته می‌شوند آزمایش کنند تا اعلان‌های به‌موقع درباره تغییرات ناسازگار آینده API (چه در کتابخانه استاندارد و چه در بسته‌های شخص ثالث) را دریافت کنند.

در حالت ایده‌آل، کد دارای یک بدنه‌ی آزمون مناسب خواهد بود و اجراکننده‌ی آزمون، فعال کردن ضمنی همه‌ی هشدارها را هنگام اجرای آزمون‌ها بر عهده می‌گیرد (اجراکننده‌ی آزمون ارائه‌شده توسط ماژول unittest این کار را انجام می‌دهد).

در موارد کمتر ایده‌آل، می‌توان استفاده از رابط‌های منسوخ را در برنامه‌ها با گذراندن -Wd به مفسر پایتون بررسی کرد (این عبارت کوتاه‌شده‌ی -W default است) یا با تنظیم PYTHONWARNINGS=default در محیط. این کار رسیدگی پیش‌فرض برای همه‌ی هشدارها، از جمله آن‌هایی که به‌طور پیش‌فرض نادیده گرفته می‌شوند را فعال می‌کند. برای تغییر اقدامی که در پاسخ به هشدارهای مواجه‌شده انجام می‌شود، می‌توانید آرگومانی را که به -W گذرانده می‌شود تغییر دهید (مثلاً -W error). برای جزئیات بیشتر درباره‌ی آنچه امکان‌پذیر است، پرچم -W را ببینید.

توابع موجود

warnings.warn(message, category=None, stacklevel=1, source=None, *, skip_file_prefixes=())

هشداری نشان می‌دهد، یا ممکن است از آن صرف‌نظر کند یا استثنایی پرتاب کند. آرگومان category، در صورت داده شدن، باید یک کلاس دسته‌ی هشدار باشد؛ مقدار پیش‌فرض آن UserWarning است. به‌عنوان جایگزین، message می‌تواند نمونه‌ای از Warning باشد، که در این صورت از category صرف‌نظر می‌شود و message.__class__ استفاده خواهد شد. در این حالت، متن پیام str(message) خواهد بود. این تابع در صورتی استثنایی پرتاب می‌کند که هشدار نشان داده شده‌ی خاص به‌وسیله‌ی پالایه‌ی هشدارها به خطا تبدیل شود. توابع پوششی نوشته‌شده به پایتون می‌توانند از آرگومان stacklevel استفاده کنند، مانند این:

def deprecated_api(message):
    warnings.warn(message, DeprecationWarning, stacklevel=2)

این باعث می‌شود هشدار به فراخواننده‌ی deprecated_api اشاره کند، نه به منبع خود deprecated_api (زیرا مورد دوم هدف پیام هشدار را بی‌اثر می‌کند).

می‌توان از آرگومان کلیدواژه‌ای skip_file_prefixes برای مشخص کردن اینکه کدام فریم‌های پشته هنگام شمارش سطح‌های پشته نادیده گرفته می‌شوند، استفاده کرد. این موضوع می‌تواند زمانی مفید باشد که بخواهید هشدار همیشه در محل‌های فراخوانی خارج از یک بسته ظاهر شود، در شرایطی که یک stacklevel ثابت برای تمام مسیرهای فراخوانی مناسب نیست یا نگهداری آن به دلایل دیگر دشوار است. در صورت ارائه، باید تاپلی از رشته‌ها باشد. هنگامی که پیشوندها ارائه شوند، stacklevel به‌طور ضمنی به‌صورت max(2, stacklevel) بازنویسی می‌شود. برای اینکه هشدار به فراخواننده‌ای از خارج از بسته فعلی نسبت داده شود، ممکن است به این شکل بنویسید:

# example/lower.py
_warn_skips = (os.path.dirname(__file__),)

def one_way(r_luxury_yacht=None, t_wobbler_mangrove=None):
    if r_luxury_yacht:
        warnings.warn("Please migrate to t_wobbler_mangrove=.",
                      skip_file_prefixes=_warn_skips)

# example/higher.py
from . import lower

def another_way(**kw):
    lower.one_way(**kw)

این باعث می‌شود هشدار تنها به هر دو محل فراخوانی example.lower.one_way() و example.higher.another_way() از کد فراخوانی که خارج از بسته example قرار دارد، اشاره کند.

source، در صورت ارائه شدن، شیء تخریب‌شده‌ای است که یک ResourceWarning نشان داده است.

تغییر یافته در نسخه‌ی 3.6: پارامتر source اضافه شد.

تغییر یافته در نسخه‌ی 3.12: skip_file_prefixes افزوده شد.

warnings.warn_explicit(message, category, filename, lineno, module=None, registry=None, module_globals=None, source=None)

این رابطی سطح پایین برای قابلیت warn() است که پیام، دسته، نام پرونده و شماره خط را به‌صورت صریح و سایر آرگومان‌ها را به‌اختیار دریافت می‌کند. message باید یک رشته باشد و category یک زیرکلاس از Warning، یا ممکن است message یک نمونه از Warning باشد که در این صورت از category چشم‌پوشی می‌شود.

module، در صورت ارائه، باید نام ماژول باشد. اگر ماژولی ارسال نشود، از نام پرونده با حذف .py استفاده می‌شود.

registry، در صورت ارائه، باید دیکشنری __warningregistry__ ماژول باشد. اگر هیچ registry ارسال نشود، با هر هشدار به‌عنوان نخستین رخداد رفتار می‌شود، یعنی اقدام‌های فیلتر "default"، "module" و "once" به‌صورت "always" مدیریت می‌شوند.

module_globals، در صورت ارائه شدن، باید فضای نام سراسری مورد استفاده‌ی کدی باشد که هشدار برای آن نشان داده می‌شود. (این آرگومان برای پشتیبانی از نمایش کد منبع ماژول‌هایی استفاده می‌شود که در پرونده‌های zip یا دیگر منابع ایمپورت غیرسامانه فایل‌بندی‌ای یافت می‌شوند).

source، در صورت ارائه شدن، شیء تخریب‌شده‌ای است که یک ResourceWarning نشان داده است.

تغییر یافته در نسخه‌ی 3.6: پارامتر source اضافه شد.

warnings.showwarning(message, category, filename, lineno, file=None, line=None)

هشداری را در یک پرونده می‌نویسد. پیاده‌سازی پیش‌فرض، formatwarning(message, category, filename, lineno, line) را فراخوانی می‌کند و رشته‌ی حاصل را در file می‌نویسد که به‌طور پیش‌فرض sys.stderr است. شما می‌توانید این تابع را با هر شیء فراخوانی‌پذیر، از طریق انتساب به warnings.showwarning جایگزین کنید. line یک خط از کد منبع است که در پیام هشدار گنجانده می‌شود؛ اگر line ارائه نشده باشد، showwarning() تلاش می‌کند خط مشخص‌شده توسط filename و lineno را بخواند.

warnings.formatwarning(message, category, filename, lineno, line=None)

هشدار را به روش استاندارد قالب‌بندی می‌کند. رشته‌ای برمی‌گرداند که ممکن است حاوی نویسه‌های خط جدید نهفته باشد و با یک نویسه خط جدید پایان می‌یابد. line یک خط از کد منبع است که در پیام هشدار گنجانده می‌شود؛ اگر line ارائه نشده باشد، formatwarning() تلاش می‌کند خط مشخص‌شده با filename و lineno را بخواند.

warnings.filterwarnings(action, message='', category=Warning, module='', lineno=0, append=False)

یک ورودی در فهرست مشخصات فیلترهای هشدار درج کنید. به‌طور پیش‌فرض، ورودی در ابتدای فهرست درج می‌شود؛ اگر append درست باشد، در انتهای فهرست درج می‌شود. این تابع انواع آرگومان‌ها را بررسی می‌کند، عبارت‌های باقاعده message و module را کامپایل می‌کند و آن‌ها را به‌صورت یک تاپل در فهرست فیلترهای هشدار درج می‌کند. اگر هر دو با یک هشدار خاص مطابقت داشته باشند، ورودی‌های نزدیک‌تر به ابتدای فهرست بر ورودی‌های بعدی در فهرست اولویت دارند. آرگومان‌های حذف‌شده به‌طور پیش‌فرض مقداری دارند که با هر چیزی مطابقت دارد.

warnings.simplefilter(action, category=Warning, lineno=0, append=False)

یک ورودی ساده در فهرست مشخصات فیلتر هشدارها درج کنید. معنای پارامترهای تابع همانند filterwarnings() است، اما نیازی به عبارات باقاعده نیست، زیرا فیلتر درج‌شده همیشه با هر پیامی در هر ماژول مطابقت دارد، مشروط بر اینکه دسته و شماره خط مطابقت داشته باشند.

warnings.resetwarnings()

فیلتر هشدارها را بازنشانی می‌کند. این کار اثر تمام فراخوانی‌های پیشین filterwarnings()، از جمله اثر گزینه‌های خط فرمان -W و فراخوانی‌های simplefilter() را از بین می‌برد.

@warnings.deprecated(message, /, *, category=DeprecationWarning, stacklevel=1)

دکوراتوری برای نشان دادن اینکه یک کلاس، تابع یا overload منسوخ شده است.

هنگامی که این دکوراتور به یک شیء اعمال شود، ممکن است در ران‌تایم هنگام استفاده از آن شیء، هشدارهای از رده خارج شدن نشان داده شوند. بررسی‌کننده‌های نوع ایستا نیز هنگام استفاده از شیء از رده خارج‌شده یک پیام تشخیصی تولید خواهند کرد.

استفاده:

from warnings import deprecated
from typing import overload

@deprecated("Use B instead")
class A:
    pass

@deprecated("Use g instead")
def f():
    pass

@overload
@deprecated("int support is deprecated")
def g(x: int) -> int: ...
@overload
def g(x: str) -> int: ...

هشداری که با category مشخص شده است، در ران‌تایم هنگام استفاده از اشیای منسوخ نشان داده خواهد شد. برای توابع، این امر در زمان فراخوانی رخ می‌دهد؛ برای کلاس‌ها، در زمان نمونه‌سازی و ایجاد زیرکلاس‌ها. اگر category برابر None باشد، هیچ هشداری در ران‌تایم نشان داده نمی‌شود. stacklevel تعیین می‌کند که هشدار در کجا نشان داده شود. اگر 1 باشد (پیش‌فرض)، هشدار در فراخواننده‌ی مستقیم شیء منسوخ نشان داده می‌شود؛ اگر بیشتر باشد، در جای بالاتری از پشته نشان داده می‌شود. رفتار بررسی‌گر نوع ایستا تحت تأثیر آرگومان‌های category و stacklevel قرار نمی‌گیرد.

پیام منسوخ‌شدگی داده‌شده به دکوراتور، در ویژگی __deprecated__ شیء دکوریت‌شده ذخیره می‌شود. اگر روی یک سربارگذاری (overload) اعمال شود، دکوراتور باید بعد از دکوراتور @~typing.overload قرار گیرد تا ویژگی روی سربارگذاری (overload)، برگردانده‌شده توسط typing.get_overloads()، وجود داشته باشد.

اضافه شده در نسخه‌ی 3.13: PEP 702 را ببینید.

مدیرهای زمینه در دسترس

class warnings.catch_warnings(*, record=False, module=None, action=None, category=Warning, lineno=0, append=False)

مدیر زمینه‌ای که فیلتر هشدارها و تابع showwarning() را کپی می‌کند و در هنگام خروج، آن‌ها را بازگردانی می‌کند. اگر آرگومان record برابر False باشد (پیش‌فرض)، مدیر زمینه در هنگام ورود None را برمی‌گرداند. اگر record برابر True باشد، یک فهرست برگردانده می‌شود که به‌تدریج با اشیایی که توسط یک تابع سفارشی showwarning() (که همچنین از خروجی به sys.stderr جلوگیری می‌کند) مشاهده می‌شوند، پر می‌شود. تضمین می‌شود که هر شیء در فهرست دارای ویژگی‌های زیر باشد:

  • message: پیام هشدار (نمونه‌ای از Warning)

  • category: دسته هشدار (زیرکلاسی از Warning)

  • filename: نام پرونده‌ای که هشدار در آن رخ داده است (str)

  • lineno: شماره خط در پرونده (int)

  • file: شیء پرونده استفاده‌شده برای خروجی (در صورت وجود)، یا None

  • line: سطری از کد منبع (در صورت موجود بودن)، یا None

  • source: شیء اصلی که هشدار را تولید کرده است (در صورت موجود بودن)، یا None

تغییر یافته در نسخه‌ی 3.6: ویژگی source اضافه شد.

نوع این اشیاء مشخص نشده است و ممکن است تغییر کند؛ فقط وجود این ویژگی‌ها تضمین می‌شود.

آرگومان module ماژولی را می‌گیرد که به‌جای ماژول برگردانده‌شده هنگامی که warnings را ایمپورت می‌کنید، استفاده خواهد شد و فیلتر آن محافظت خواهد شد. این آرگومان عمدتاً برای آزمون خود ماژول warnings وجود دارد.

اگر آرگومان action برابر None نباشد، آرگومان‌های باقی‌مانده به simplefilter() ارسال می‌شوند، گویی بلافاصله در هنگام ورود به زمینه فراخوانی شده است.

برای آگاهی از معنای پارامترهای category و lineno، به فیلتر هشدارها مراجعه کنید.

توجه

برای جزئیات درباره‌ی ایمنی همروندیِ مدیر زمینه‌ی catch_warnings هنگامی که در برنامه‌های دارای چندین نخ یا توابع ناهمگام استفاده می‌شود، به ایمنی هم‌روندی مدیران زمینه مراجعه کنید.

تغییر یافته در نسخه‌ی 3.11: پارامترهای action، category، lineno و append افزوده شدند.

ایمنی هم‌روندی مدیران زمینه

رفتار مدیر زمینه‌ی catch_warnings به پرچم sys.flags.context_aware_warnings بستگی دارد. اگر این پرچم درست باشد، مدیر زمینه به‌صورت ایمن در همزمانی (concurrent-safe) رفتار می‌کند و در غیر این صورت، این‌گونه نیست. ایمن در همزمانی به این معنا است که هم ایمن در نخ (thread-safe) است و هم استفاده از آن در هم‌روال‌های asyncio و وظایف ایمن است. ایمن در نخ بودن به این معنا است که رفتار در یک برنامه‌ی چندنخی قابل پیش‌بینی است. مقدار پیش‌فرض این پرچم در ساخت‌های نخ‌آزاد درست و در غیر این صورت نادرست است.

اگر پرچمِ context_aware_warnings نادرست باشد، catch_warnings ویژگی‌های سراسری ماژول warnings را تغییر می‌دهد. این کار در یک برنامه هم‌روند (با استفاده از چند نخ یا هم‌روال‌های asyncio) امن نیست. برای مثال، اگر دو یا چند نخ همزمان از کلاس catch_warnings استفاده کنند، رفتار تعریف‌نشده است.

اگر پرچم درست باشد، catch_warnings ویژگی‌های سراسری را تغییر نمی‌دهد و در عوض از یک ContextVar برای ذخیره‌ی وضعیت تازه‌برقرارشده‌ی فیلتر هشدار استفاده می‌کند. یک متغیر زمینه، فضای ذخیره‌سازی محلی برای نخ فراهم می‌کند و استفاده از catch_warnings را از نظر نخ ایمن می‌سازد.

پارامتر record در مدیر زمینه نیز بسته به مقدار پرچم رفتار متفاوتی دارد. هنگامی که record درست باشد و پرچم نادرست باشد، مدیر زمینه با جایگزین کردن تابع showwarning() ماژول و سپس بازگرداندن آن کار می‌کند. این روش از نظر هم‌روندی ایمن نیست.

هنگامی که record درست باشد و پرچم نیز درست باشد، تابع showwarning() جایگزین نمی‌شود. در عوض، وضعیت ضبط با یک ویژگی داخلی در متغیر زمینه مشخص می‌شود. در این حالت، هنگام خروج از هندلر زمینه، تابع showwarning() بازگردانی نمی‌شود.

پرچم context_aware_warnings را می‌توان با گزینه‌ی خط فرمان -X context_aware_warnings یا متغیر محیطی PYTHON_CONTEXT_AWARE_WARNINGS تنظیم کرد.

توجه

احتمالاً بیشتر برنامه‌هایی که خواهان رفتار نخ‌ایمن برای ماژول warnings هستند، همچنین می‌خواهند پرچم thread_inherit_context را روی true تنظیم کنند. این پرچم باعث می‌شود نخ‌هایی که توسط threading.Thread ایجاد می‌شوند، با یک کپی از متغیرهای زمینه‌ی نخ آغازگر خود آغاز شوند. هنگامی که true باشد، زمینه‌ای که توسط catch_warnings در یک نخ برقرار شده است، بر نخ‌های جدیدی که توسط آن نخ آغاز می‌شوند نیز اعمال خواهد شد. اگر false باشد، نخ‌های جدید با یک متغیر زمینه‌ی warnings خالی آغاز می‌شوند، به این معنا که هرگونه فیلترسازی که توسط یک مدیر زمینه catch_warnings برقرار شده بود، دیگر فعال نخواهد بود.

تغییر یافته در نسخه‌ی 3.14: پرچم sys.flags.context_aware_warnings و استفاده از یک متغیر زمینه برای catch_warnings در صورتی که این پرچم درست باشد، افزوده شد. نسخه‌های پیشین پایتون طوری رفتار می‌کردند که گویی این پرچم همیشه روی نادرست تنظیم شده بود.