warnings — 경고 제어

소스 코드: Lib/warnings.py


경고 메시지는 일반적으로 프로그램에서 사용자에게 (일반적으로) 예외를 발생시키거나 프로그램을 종료하는 것을 보증하지 않는 특정 조건에 대해 경고하는 것이 유용한 상황 상황에서 발행됩니다. 예를 들어, 프로그램이 더는 사용되지 않는 모듈을 사용할 때 경고를 발행하려고 할 수 있습니다.

파이썬 프로그래머는 이 모듈에 정의된 warn() 함수를 호출하여 경고를 발행합니다. (C 프로그래머는 PyErr_WarnEx()를 사용합니다; 자세한 내용은 예외 처리를 참조하십시오).

경고 메시지는 일반적으로 sys.stderr에 기록되지만, 모든 경고를 무시하는 것에서 예외로 변경하는 것에 이르기까지 배치를 유연하게 변경할 수 있습니다. 경고의 처리는 경고 범주, 경고 메시지의 텍스트 및 발행된 소스 위치에 따라 달라질 수 있습니다. 같은 소스 위치에 대한 특정 경고의 반복은 일반적으로 억제됩니다.

경고 제어에는 두 가지 단계가 있습니다; 첫째, 경고가 발행될 때마다, 메시지를 발행할지를 결정합니다; 다음으로, 메시지가 발행된다면, 사용자 설정 가능한 훅을 사용하여 포맷되고 인쇄됩니다.

경고 메시지를 발행할지는 경고 필터에 의해 제어되며, 이는 일치 규칙과 조치의 시퀀스입니다. filterwarnings()를 호출하여 규칙을 필터에 추가하고 resetwarnings()를 호출하여 기본 상태로 재설정할 수 있습니다.

경고 메시지의 인쇄는 showwarning()을 호출하여 수행되며, 이는 재정의될 수 있습니다; 이 함수의 기본 구현은 formatwarning()을 호출하여 메시지를 포맷하며, 사용자 정의 구현에서도 사용할 수 있습니다.

더 보기

logging.captureWarnings()를 사용하면 표준 로깅 인프라로 모든 경고를 처리할 수 있습니다.

경고 범주

경고 범주를 나타내는 여러 가지 내장 예외가 있습니다. 이 범주화는 경고 그룹을 필터링하는 데 유용합니다.

이들은 기술적으로 내장 예외이지만, 개념적으로 경고 메커니즘에 속하기 때문에 여기에서 설명합니다.

사용자 코드는 표준 경고 범주 중 하나를 서브 클래싱 하여 추가 경고 범주를 정의할 수 있습니다. 경고 범주는 항상 Warning 클래스의 서브 클래스여야 합니다.

다음과 같은 경고 범주 클래스가 현재 정의되어 있습니다:

클래스

설명

Warning

이것은 모든 경고 범주 클래스의 베이스 클래스입니다. Exception의 서브 클래스입니다.

UserWarning

warn()의 기본 범주.

DeprecationWarning

폐지된 기능에 대한 경고의 베이스 범주, 경고가 다른 파이썬 개발자를 대상으로 할 때 (__main__에 있는 코드로 트리거 되지 않는 한 기본적으로 무시됩니다).

SyntaxWarning

모호한 구문 기능에 대한 경고의 베이스 범주.

RuntimeWarning

모호한 런타임 기능에 대한 경고의 베이스 범주.

FutureWarning

폐지된 기능에 대한 경고의 베이스 범주, 경고가 파이썬으로 작성된 응용 프로그램의 최종 사용자를 대상으로 할 때.

PendingDeprecationWarning

향후 폐지될 기능에 대한 경고의 베이스 범주 (기본적으로 무시됩니다).

ImportWarning

모듈을 임포트 하는 과정에서 트리거 되는 경고의 베이스 범주 (기본적으로 무시됩니다).

UnicodeWarning

유니코드와 관련된 경고의 베이스 범주.

BytesWarning

bytesbytearray와 관련된 경고의 베이스 범주.

ResourceWarning

자원 사용과 관련된 경고의 베이스 범주.

버전 3.7에서 변경: 이전에는 DeprecationWarningFutureWarning은 기능이 완전히 제거되었는지 또는 동작을 변경하는지에 따라 구별되었습니다. 이제 의도한 대상과 기본 경고 필터에서 처리하는 방식에 따라 구별됩니다.

경고 필터

경고 필터는 경고를 무시, 표시 또는 에러로 전환(예외 발생)할지를 제어합니다.

개념적으로, 경고 필터는 필터 명세의 순서 있는 목록을 유지합니다; 일치가 발견될 때까지 목록의 각 필터 명세에 대해 특정 경고를 일치시킵니다; 필터는 일치의 처리를 결정합니다. 각 항목은 (action, message, category, module, lineno) 형식의 튜플입니다, 여기서:

  • action은 다음 문자열 중 하나입니다:

    처리

    "default"

    경고가 발행된 각 위치(모듈 + 줄 번호)에 대해 일치하는 경고의 첫 번째 발생을 인쇄합니다

    "error"

    일치하는 경고를 예외로 바꿉니다

    "ignore"

    일치하는 경고를 인쇄하지 않습니다

    "always"

    일치하는 경고를 항상 인쇄합니다

    "module"

    경고가 발행된 모듈마다 (줄 번호와 관계없이) 일치하는 경고의 첫 번째 발생을 인쇄합니다

    "once"

    위치와 관계없이 일치하는 경고의 첫 번째 발생만 인쇄합니다

  • message는 경고 메시지의 시작이 일치해야 하는 정규식을 포함하는 문자열입니다. 정규식은 항상 대소 문자를 구분하지 않도록 컴파일됩니다.

  • category는 클래스(Warning의 서브 클래스)이며, 일치하는 경고 범주는 이것의 서브 클래스여야 합니다.

  • module은 모듈 이름이 일치해야 하는 정규식을 포함하는 문자열입니다. 정규식은 대소 문자를 구분하도록 컴파일됩니다.

  • lineno는 경고가 발생한 줄 번호가 일치해야 하는 정수이거나, 모든 줄 번호와 일치하려면 0입니다.

Warning 클래스는 내장 Exception 클래스에서 파생되므로, 경고를 에러로 바꾸려면 단순히 category(message)를 raise 합니다.

경고가 보고되고 등록된 필터와 일치하지 않으면 《default》 조치가 적용됩니다 (그래서 그런 이름을 갖고 있습니다).

경고 필터 설명

경고 필터는 파이썬 인터프리터 명령 줄로 전달된 -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"
                             # and any subpackages of "mymodule"

기본 경고 필터

기본적으로, 파이썬은 -W 명령 줄 옵션, PYTHONWARNINGS 환경 변수 및 filterwarnings() 호출로 재정의할 수 있는 몇 가지 경고 필터를 설치합니다.

정규 릴리스 빌드에서, 기본 경고 필터에는 다음과 같은 항목이 있습니다 (우선순위 순서로):

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

In a debug build, the list of default warning filters is empty.

버전 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")

파이썬 코드용 테스트 실행기 개발자는 대신 다음과 같은 코드를 사용하여 테스트 대상 코드에 대해 기본적으로 모든 경고가 표시되도록 하는 것이 좋습니다:

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)

always 대신 error를 사용하여 모든 경고를 예외로 만들 수도 있습니다. 한 가지 알아야 할 것은 once / default 규칙으로 인해 경고가 이미 발생했으면, 어떤 필터가 설정되어 있더라도 경고와 관련된 경고 레지스트리가 지워지지 않으면 경고가 다시 표시되지 않는다는 것입니다.

일단 컨텍스트 관리자가 종료되면, 경고 필터가 컨텍스트에 진입했을 때의 상태로 복원됩니다. 이것은 테스트 간에 경고 필터가 예기치 않은 방식으로 변경되어 테스트 결과가 불확실해지는 것을 방지합니다. 모듈의 showwarning() 함수도 원래 값으로 복원됩니다. 참고: 이것은 단일 스레드 응용 프로그램에서만 보장될 수 있습니다. 둘 이상의 스레드가 catch_warnings 컨텍스트 관리자를 동시에 사용하면, 동작이 정의되지 않습니다.

같은 종류의 경고를 발생시키는 여러 작업을 테스트할 때, 각 작업이 새로운 경고를 발생시키는지 확인하는 방식으로 테스트하는 것이 중요합니다 (예를 들어 경고가 예외를 발생시키도록 설정하고 작업이 예외를 일으키는지 확인합니다, 각 작업 후에 경고 목록의 길이가 계속 증가하는지 확인합니다, 또는 각 새 작업 전에 경고 목록에서 이전 항목을 삭제합니다).

새 버전의 종속성에 대한 코드 갱신

(파이썬으로 작성된 응용 프로그램의 최종 사용자가 아닌) 파이썬 개발자가 주로 관심을 두는 경고 범주는 기본적으로 무시됩니다.

특히, 이 《기본적으로 무시됨》 목록에는 DeprecationWarning(__main__을 제외한 모든 모듈에서)가 포함되어 있습니다. 이는 개발자가 (표준 라이브러리와 제삼자 패키지 모두에서) 호환성을 깨는 향후 API 변경에 대한 시기적절한 알림을 받기 위해 일반적으로 무시되는 경고를 가시화해서 코드를 테스트해야 한다는 것을 의미합니다.

이상적인 경우, 코드에 적절한 테스트 스위트가 있고, 테스트 실행기는 테스트를 실행할 때 모든 경고를 묵시적으로 활성화합니다 (unittest 모듈에서 제공하는 테스트 실행기가 이렇게 합니다).

덜 이상적인 경우, -Wd 를 파이썬 인터프리터에 전달하거나 (-W default의 줄임 표현입니다), 환경에 PYTHONWARNINGS=default를 설정하여 응용프로그램이 폐지된 인터페이스를 사용하는지를 확인할 수 있습니다. 이를 통해 기본적으로 무시되는 경고를 포함한 모든 경고에 대한 default 처리가 가능합니다. 발생한 경고에 대해 수행할 조치를 변경하려면 -W로 전달되는 인자를 변경할 수 있습니다 (예를 들어 -W error). 어떤 것이 가능한지에 대한 자세한 내용은 -W 플래그를 참조하십시오.

사용 가능한 함수

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

경고를 발행하거나, 무시하거나 예외를 발생시킵니다. 주어지면 category 인자는 경고 범주 클래스여야 합니다; 기본값은 UserWarning입니다. 또는, messageWarning 인스턴스일 수 있으며, 이 경우 category는 무시되고 message.__class__가 사용됩니다. 이 경우, 메시지 텍스트는 str(message)입니다. 이 함수는 발행된 특정 경고가 경고 필터에 의해 에러로 변경되면 예외를 발생시킵니다. stacklevel 인자는 다음과 같이 파이썬으로 작성된 래퍼 함수에서 사용할 수 있습니다:

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

이것은 경고가 deprecation() 자체의 소스가 아닌 deprecation()의 호출자를 참조하게 합니다 (전자는 경고 메시지의 목적을 무효로 하기 때문입니다).

제공되면, sourceResourceWarning을 방출한 파괴된 객체입니다.

버전 3.6에서 변경: source 매개 변수를 추가했습니다.

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

이것은 warn()의 기능에 대한 저수준 인터페이스로서, 메시지, 범주, 파일명 및 줄 번호, 그리고 선택적으로 모듈 이름과 레지스트리(모듈의 __warningregistry__ 딕셔너리이어야 합니다)를 명시적으로 전달합니다. 모듈 이름의 기본값은 .py가 제거된 파일명입니다; 레지스트리가 전달되지 않으면, 경고는 억제되지 않습니다. message는 문자열이고 categoryWarning의 서브 클래스여야 하고, 또는 messageWarning 인스턴스일 수 있는데, 이 경우 category는 무시됩니다.

제공되면, module_globals는 경고가 발행되는 코드에서 사용 중인 전역 이름 공간이어야 합니다. (이 인자는 zip 파일이나 다른 파일 시스템이 아닌 임포트 소스에서 찾은 모듈의 소스 표시를 지원하는 데 사용됩니다).

제공되면, sourceResourceWarning을 방출한 파괴된 객체입니다.

버전 3.6에서 변경: source 매개 변수를 추가합니다.

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

파일에 경고를 기록합니다. 기본 구현은 formatwarning(message, category, filename, lineno, line)를 호출하고 결과 문자열을 file에 씁니다, file의 기본값은 sys.stderr입니다. warnings.showwarning에 대입하여 이 함수를 임의의 콜러블로 대체할 수 있습니다. line은 경고 메시지에 포함될 소스 코드 줄입니다; line이 제공되지 않으면, showwarning()filenamelineno로 지정된 줄을 읽으려고 시도합니다.

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

표준 방식으로 경고를 포맷합니다. 내장된 개행 문자를 포함하고 개행 문자로 끝날 수 있는 문자열을 반환합니다. line은 경고 메시지에 포함될 소스 코드 줄입니다; line이 제공되지 않으면, formatwarning()filenamelineno로 지정된 줄을 읽으려고 시도합니다.

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

경고 필터 명세 목록에 항목을 삽입합니다. 항목은 기본적으로 앞에 삽입됩니다; append가 참이면, 끝에 삽입됩니다. 인자의 형을 확인하고, messagemodule 정규식을 컴파일한 후 경고 필터 목록에 튜플로 삽입합니다. 둘 다 특정 경고와 일치하면, 목록 앞쪽에 더 가까운 항목이 목록의 뒷부분에 있는 항목보다 우선합니다. 생략된 인자의 기본값은 모든 것과 일치하는 값입니다.

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

경고 필터 명세 목록에 간단한 항목을 삽입합니다. 함수 매개 변수의 의미는 filterwarnings()와 같지만, 범주와 줄 번호가 일치하는 한 삽입 된 필터가 항상 모든 모듈의 메시지와 일치하기 때문에 정규식이 필요하지 않습니다.

warnings.resetwarnings()

경고 필터를 재설정합니다. 이는 -W 명령 줄 옵션과 simplefilter()에 대한 호출을 포함하여 filterwarnings()에 대한 모든 이전 호출의 영향을 되돌립니다.

사용 가능한 컨텍스트 관리자

class warnings.catch_warnings(*, record=False, module=None)

경고 필터와 showwarning() 함수를 복사하고 종료 시 복원하는 컨텍스트 관리자. record 인자가 False(기본값)이면 컨텍스트 관리자는 진입할 때 None을 반환합니다. recordTrue이면, 재정의된 showwarning() 함수에 보이는 객체로 점진적으로 채워지는 리스트가 반환됩니다 (sys.stdout 으로의 출력도 억제합니다). 리스트의 각 객체에는 showwarning()에 대한 인자와 이름이 같은 어트리뷰트가 있습니다.

module 인자는 필터가 보호되는 warnings를 임포트 할 때 반환되는 모듈 대신 사용되는 모듈을 취합니다. 이 인자는 주로 warnings 모듈 자체를 테스트하기 위해 존재합니다.

참고

catch_warnings 관리자는 모듈의 showwarning() 함수와 내부 필터 명세 목록을 교체한 다음 나중에 복원하는 방식으로 작동합니다. 이는 컨텍스트 관리자가 전역 상태를 수정한다는 의미이고, 따라서 스레드 안전하지 않습니다.