# `warnings` — 경고 제어

소스 코드: Lib/warnings.py

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

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

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

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

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

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

더 보기

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

## 경고 범주

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

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

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

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

클래스 | 설명
--- | ---
`Warning` | 이것은 모든 경고 범주 클래스의 베이스 클래스입니다. `Exception`의 서브 클래스입니다.
`UserWarning` | `warn()`의 기본 범주.
`DeprecationWarning` | 폐지된 기능에 대한 경고의 베이스 범주, 경고가 다른 파이썬 개발자를 대상으로 할 때 (`__main__`에 있는 코드로 트리거 되지 않는 한 기본적으로 무시됩니다).
`SyntaxWarning` | Base category for warnings about dubious syntactic features (typically emitted when compiling Python source code, and hence may not be suppressed by runtime filters)
`RuntimeWarning` | 모호한 런타임 기능에 대한 경고의 베이스 범주.
`FutureWarning` | 폐지된 기능에 대한 경고의 베이스 범주, 경고가 파이썬으로 작성된 응용 프로그램의 최종 사용자를 대상으로 할 때.
`PendingDeprecationWarning` | 향후 폐지될 기능에 대한 경고의 베이스 범주 (기본적으로 무시됩니다).
`ImportWarning` | 모듈을 임포트 하는 과정에서 트리거 되는 경고의 베이스 범주 (기본적으로 무시됩니다).
`UnicodeWarning` | 유니코드와 관련된 경고의 베이스 범주.
`BytesWarning` | `bytes`와 `bytearray`와 관련된 경고의 베이스 범주.
`ResourceWarning` | 자원 사용과 관련된 경고의 베이스 범주 (기본적으로 무시됩니다).

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

## 경고 필터

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

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

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

  값 | 처리
  --- | ---
  `"default"` | 경고가 발행된 각 위치(모듈 + 줄 번호)에 대해 일치하는 경고의 첫 번째 발생을 인쇄합니다
  `"error"` | 일치하는 경고를 예외로 바꿉니다
  `"ignore"` | 일치하는 경고를 인쇄하지 않습니다
  `"always"` | 일치하는 경고를 항상 인쇄합니다
  `"all"` | alias to “always”
  `"module"` | 경고가 발행된 모듈마다 (줄 번호와 관계없이) 일치하는 경고의 첫 번째 발생을 인쇄합니다
  `"once"` | 위치와 관계없이 일치하는 경고의 첫 번째 발생만 인쇄합니다

- message는 경고 메시지의 시작 부분이 대소문자를 구분 없이 일치해야 하는 정규식을 포함하는 문자열입니다. `-W`와 `PYTHONWARNINGS`에서, message는 경고 메시지의 시작 부분에 (대소문자 구분 없이) 포함되어야 하는 리터럴 문자열로, message의 시작이나 끝에 있는 공백은 무시합니다.

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

- module은 완전히 정규화된 모듈 이름의 시작 부분이 대소문자를 구분하여 일치해야 하는 정규식을 포함하는 문자열입니다. `-W`와 `PYTHONWARNINGS`에서, module은 완전히 정규화된 모듈 이름과 (대소문자 구분하여) 같아야 하는 리터럴 문자열로, module의 시작이나 끝에 있는 공백은 무시합니다.

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

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

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

### Repeated Warning Suppression Criteria

The filters that suppress repeated warnings apply the following criteria to determine if a warning is considered a repeat:

- `"default"`: A warning is considered a repeat only if the (message, category, module, lineno) are all the same.

- `"module"`: A warning is considered a repeat if the (message, category, module) are the same, ignoring the line number.

- `"once"`: A warning is considered a repeat if the (message, category) are the same, ignoring the module and line number.

### 경고 필터 설명

The warnings filter is initialized by `-W` options passed to the Python interpreter command line and the `PYTHONWARNINGS` environment variable. The interpreter saves the arguments for all supplied entries without interpretation in `sys.warnoptions`; the `warnings` module parses these when it is first imported (invalid options are ignored, after printing a message to `sys.stderr`).

개별 경고 필터는 콜론으로 구분된 필드의 시퀀스로 지정됩니다:

    action:message:category:module:line

이러한 각 필드의 의미는 경고 필터에 설명된 대로입니다. 한 줄에 여러 필터를 나열할 때 (`PYTHONWARNINGS`와 같이), 개별 필터는 쉼표로 구분되고 나중에 나열된 필터가 그 앞에 나열된 필터보다 우선합니다 (왼쪽에서 오른쪽으로 적용되고, 가장 최근에 적용된 필터가 앞서 나온 필터에 우선하기 때문입니다).

일반적으로 사용되는 경고 필터는 모든 경고, 특정 범주의 경고 또는 특정 모듈이나 패키지에서 발생하는 경고에 적용됩니다. 몇 가지 예:

    default                      # 모든 경고를 표시합니다 (설사 기본적으로 무시되더라도)
    ignore                       # 모든 경고를 무시합니다
    error                        # 모든 경고를 에러로 변환합니다
    error::ResourceWarning       # ResourceWarning 메시지를 에러로 취급합니다
    default::DeprecationWarning  # DeprecationWarning 메시지를 표시합니다
    ignore,default:::mymodule    # "mymodule"이 트리거 한 경고만 보고합니다
    error:::mymodule             # "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")

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

    import sys

    if not sys.warnoptions:
        import os, warnings
        warnings.simplefilter("default") # 이 프로세스의 필터를 변경합니다
        os.environ["PYTHONWARNINGS"] = "default" # 서브 프로세스에도 영향을 줍니다

마지막으로, `__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()

While within the context manager all warnings will simply be ignored. This allows you to use known-deprecated code without having to see the warning while not suppressing the warning for other code that might not be aware of its use of deprecated code.

> 참고

> See Concurrent safety of Context Managers for details on the concurrency-safety of the `catch_warnings` context manager when used in programs using multiple threads or async functions.

## 경고 테스트

코드가 발생시키는 경고를 테스트하려면, `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` 규칙으로 인해 경고가 이미 발생했으면, 어떤 필터가 설정되어 있더라도 경고와 관련된 경고 레지스트리가 지워지지 않으면 경고가 다시 표시되지 않는다는 것입니다.

Once the context manager exits, the warnings filter is restored to its state when the context was entered. This prevents tests from changing the warnings filter in unexpected ways between tests and leading to indeterminate test results.

> 참고

> See Concurrent safety of Context Managers for details on the concurrency-safety of the `catch_warnings` context manager when used in programs using multiple threads or async functions.

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

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

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

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

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

덜 이상적인 경우, `-Wd` 를 파이썬 인터프리터에 전달하거나 (`-W default`의 줄임 표현입니다), 환경에 `PYTHONWARNINGS=default`를 설정하여 응용프로그램이 폐지된 인터페이스를 사용하는지를 확인할 수 있습니다. 이를 통해 기본적으로 무시되는 경고를 포함한 모든 경고에 대한 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`의 호출자를 참조하게 합니다 (전자는 경고 메시지의 목적을 무효로 하기 때문입니다).

  The skip_file_prefixes keyword argument can be used to indicate which stack frames are ignored when counting stack levels. This can be useful when you want the warning to always appear at call sites outside of a package when a constant stacklevel does not fit all call paths or is otherwise challenging to maintain. If supplied, it must be a tuple of strings. When prefixes are supplied, stacklevel is implicitly overridden to be `max(2, stacklevel)`. To cause a warning to be attributed to the caller from outside of the current package you might write:

      # 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)

  This makes the warning refer to both the `example.lower.one_way()` and `example.higher.another_way()` call sites only from calling code living outside of `example` package.

  제공되면, source는 `ResourceWarning`을 방출한 파괴된 객체입니다.

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

  버전 3.12에서 변경: Added skip_file_prefixes.

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

  This is a low-level interface to the functionality of `warn()`, passing in explicitly the message, category, filename and line number, and optionally other arguments. message must be a string and category a subclass of `Warning` or message may be a `Warning` instance, in which case category will be ignored.

  module, if supplied, should be the module name. If no module is passed, the filename with `.py` stripped is used.

  registry, if supplied, should be the `__warningregistry__` dictionary of the module. If no registry is passed, each warning is treated as the first occurrence, that is, filter actions `"default"`, `"module"` and `"once"` are handled as `"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에 씁니다, 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()

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

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

  Decorator to indicate that a class, function or overload is deprecated.

  When this decorator is applied to an object, deprecation warnings may be emitted at runtime when the object is used. static type checkers will also generate a diagnostic on usage of the deprecated object.

  사용법:

      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: ...

  The warning specified by category will be emitted at runtime on use of deprecated objects. For functions, that happens on calls; for classes, on instantiation and on creation of subclasses. If the category is `None`, no warning is emitted at runtime. The stacklevel determines where the warning is emitted. If it is `1` (the default), the warning is emitted at the direct caller of the deprecated object; if it is higher, it is emitted further up the stack. Static type checker behavior is not affected by the category and stacklevel arguments.

  The deprecation message passed to the decorator is saved in the `__deprecated__` attribute on the decorated object. If applied to an overload, the decorator must be after the `@~typing.overload` decorator for the attribute to exist on the overload as returned by `typing.get_overloads()`.

  Added in version 3.13: See 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.stdout` 으로의 출력도 억제합니다). 리스트의 각 객체에는 `showwarning()`에 대한 인자와 이름이 같은 어트리뷰트가 있습니다.

  The module argument takes a module that will be used instead of the module returned when you import `warnings` whose filter will be protected. This argument exists primarily for testing the `warnings` module itself.

  If the action argument is not `None`, the remaining arguments are passed to `simplefilter()` as if it were called immediately on entering the context.

  See 경고 필터 for the meaning of the category and lineno parameters.

  참고

  See Concurrent safety of Context Managers for details on the concurrency-safety of the `catch_warnings` context manager when used in programs using multiple threads or async functions.

  버전 3.11에서 변경: Added the action, category, lineno, and append parameters.

## Concurrent safety of Context Managers

The behavior of `catch_warnings` context manager depends on the `sys.flags.context_aware_warnings` flag. If the flag is true, the context manager behaves in a concurrent-safe fashion and otherwise not. Concurrent-safe means that it is both thread-safe and safe to use within asyncio coroutines and tasks. Being thread-safe means that behavior is predictable in a multi-threaded program. The flag defaults to true for free-threaded builds and false otherwise.

If the `context_aware_warnings` flag is false, then `catch_warnings` will modify the global attributes of the `warnings` module. This is not safe if used within a concurrent program (using multiple threads or using asyncio coroutines). For example, if two or more threads use the `catch_warnings` class at the same time, the behavior is undefined.

If the flag is true, `catch_warnings` will not modify global attributes and will instead use a `ContextVar` to store the newly established warning filtering state. A context variable provides thread-local storage and it makes the use of `catch_warnings` thread-safe.

The record parameter of the context handler also behaves differently depending on the value of the flag. When record is true and the flag is false, the context manager works by replacing and then later restoring the module’s `showwarning()` function. That is not concurrent-safe.

When record is true and the flag is true, the `showwarning()` function is not replaced. Instead, the recording status is indicated by an internal property in the context variable. In this case, the `showwarning()` function will not be restored when exiting the context handler.

The `context_aware_warnings` flag can be set the `-X context_aware_warnings` command-line option or by the `PYTHON_CONTEXT_AWARE_WARNINGS` environment variable.

> 참고

> It is likely that most programs that desire thread-safe behaviour of the warnings module will also want to set the `thread_inherit_context` flag to true. That flag causes threads created by `threading.Thread` to start with a copy of the context variables from the thread starting it. When true, the context established by `catch_warnings` in one thread will also apply to new threads started by it. If false, new threads will start with an empty warnings context variable, meaning that any filtering that was established by a `catch_warnings` context manager will no longer be active.

버전 3.14에서 변경: Added the `sys.flags.context_aware_warnings` flag and the use of a context variable for `catch_warnings` if the flag is true. Previous versions of Python acted as if the flag was always set to false.