Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 473 – 내장 예외에 구조화된 데이터 추가하기

Author:
Sebastian Kreft <skreft at deezer.com>
Status:
Rejected
Type:
Standards Track
Created:
29-Mar-2014
Post-History:

Resolution:
Python-Dev message

Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

초록

AttributeError, IndexError, KeyError, LookupError, NameError, TypeError, ValueError 같은 예외는 프로그래머가 디버깅하고 예외의 원인을 더 잘 이해하는 데 필요한 정보를 모두 제공하지는 않습니다. 게다가 어떤 경우에는 메시지 형식마저 조금씩 달라서, 도구가 문제 진단에 필요한 추가 정보를 자동으로 제공하기가 매우 어렵습니다. 전자를 해결하고 후자의 기반을 마련하기 위해, 이러한 예외가 문제를 일으킨 개체와 영향을 받은 개체를 모두 담도록 확장할 것을 제안합니다.

근거

이 PEP가 해결하고자 하는 주된 문제는 현재 오류 메시지의 표현력이 그다지 좋지 않고, 예외를 해결하는 데 필요한 핵심 정보가 일부 빠져 있다는 점입니다. 또한 오류 메시지에 담긴 정보가 항상 같은 형식은 아니어서, 서드파티 라이브러리가 오류를 자동으로 진단하기가 매우 어렵습니다.

예를 들어 이러한 자동화 도구는 오타를 감지하거나, 추가 디버그 정보를 표시하거나 로그로 남길 수 있습니다. 이는 테스트를 실행할 때나 오래 실행되는 애플리케이션에서 특히 유용할 수 있습니다.

이론적으로는 이러한 라이브러리를 만들 수 있지만, 목표를 달성하려면 편법에 의존해야 합니다. 그러한 예 중 하나로 python-improved-exceptions [1] 가 있는데, 이 라이브러리는 예외 정보를 개선하기 위해 바이트코드를 수정하여 관심 대상이 될 수 있는 객체에 대한 참조를 유지하고, 오류 메시지를 파싱하여 타입이나 이름과 같은 정보를 추출합니다. 안타깝게도 이러한 방식은 극도로 취약하며 이식성이 없습니다.

비슷한 제안 [2]이 ImportError에 대해 구현된 바 있으며, 같은 방식으로 이 아이디어도 지지를 받았습니다 [3]. 또한 거의 10년 전에 Guido는 [11]에서 KeyError, AttributeError, NameError, IndexError 같은 예외에서 영향을 받은 객체에 접근할 수 있는 깔끔한 API를 요청했습니다. 지난 1년 동안에도 비슷한 이슈와 제안 아이디어가 작성되었습니다. 그 밖에도 몇몇 이슈가 만들어졌지만, 지지를 받았음에도 결국 방치되었습니다. 만들어진 이슈에 대한 참조는 아래와 같습니다:

개발을 진척시키고 정보와 논의를 한곳에 모으기 위해, 이 PEP는 위의 모든 논의와 아이디어를 요약하는 메타 이슈 역할을 하고자 합니다.

예시

IndexError

오류 메시지는 리스트의 길이도, 사용된 인덱스도 언급하지 않습니다.

a = [1, 2, 3, 4, 5]
a[5]
IndexError: list index out of range

KeyError

관례상 키는 오류 인자의 첫 번째 요소이지만, 영향을 받은 딕셔너리에 관한 다른 정보(키 타입, 크기 등)는 없습니다.

b = {'foo': 1}
b['fo']
KeyError: 'fo'

AttributeError

객체의 타입과 문제가 된 속성은 오류 메시지에 포함됩니다. 그러나 메시지 형식이 서로 다른 경우가 있으며, 이 정보를 항상 얻을 수 있는 것도 아닙니다. 또한 객체 타입이 유용한 경우도 있지만, Python의 동적인 특성을 고려하면 객체 자체에 대한 참조가 있는 편이 훨씬 더 유용합니다. 게다가 타입에 대한 참조는 완전한 정규화 이름이 아닙니다. 또한 모듈의 속성에 접근하는 경우처럼 타입이 너무 일반적이어서 유용한 정보를 제공하지 못하는 경우도 있습니다.

c = object()
c.foo
AttributeError: 'object' object has no attribute 'foo'

import string
string.foo
AttributeError: 'module' object has no attribute 'foo'

a = string.Formatter()
a.foo
AttributeError: 'Formatter' object has no attribute 'foo'

NameError

오류 메시지는 일반적으로 이름을 제공합니다.

foo = 1
fo
NameError: global name 'fo' is not defined

기타 경우

대상 객체가 다른 표현식의 결과일 때는 문제를 디버깅하기가 더욱 어렵습니다. 예를 들면 다음과 같습니다:

a[b[c[0]]]

이 문제는 옵코드에 오프셋 정보는 없고 줄 번호 정보만 있다는 사실과도 관련이 있습니다. 이 제안은 이러한 경우에 도움이 되겠지만, 오프셋 정보가 있는 것만큼 도움이 되지는 않습니다.

제안

예외 AttributeError, IndexError, KeyError, LookupError, NameError, TypeError, ValueError를 다음과 같이 확장합니다:

  • AttributeError: 대상 w, 속성
  • IndexError: target w, key w, index (key의 별칭일 뿐입니다)
  • KeyError: target w, key w
  • LookupError: target w, key w
  • NameError: name, scope?
  • TypeError: unexpected_type
  • ValueError: unexpected_value w

위첨자 w가 붙은 속성은 메모리 순환을 방지하기 위해 약한 참조 [12]여야 할 수도 있습니다. 그러나 이는 불필요한 복잡성을 더할 수 있으며, 이는 R. David Murray [13]가 지적한 바와 같습니다. 내장 타입은 약한 참조를 지원하지 않는다는 점을 고려하면 특히 그렇습니다.

TODO(skreft): 경계 사례의 예시를 추가하여 이 부분을 확장하십시오.

하위 호환성을 유지하기 위해 이 새로운 속성들은 선택 사항이며 키워드 전용입니다.

단순히 오류를 개선하기보다 이 정보를 추가할 것을 제안합니다. 이 정보를 추가하면 새로운 디버깅 프레임워크와 도구를 만들 수 있고, 향후 지연 생성 메시지로 전환할 수도 있기 때문입니다. 생성 메시지는 [2]에서 논의되었지만, 현재는 구현되어 있지 않습니다. 생성 메시지는 자원을 일부 절약할 뿐만 아니라 메시지를 통일해 줄 것입니다.

그런 다음 표준 라이브러리가 이 새로운 속성들을 사용하도록 점진적으로 변경될 것입니다.

잠재적 용도

예를 들어 자동화된 도구는 객체 안에서 비슷한 키를 검색하여 다음과 같은 내용을 표시할 수 있습니다::

a = {'foo': 1}
a['fo']
KeyError: 'fo'. Did you mean 'foo'?

foo = 1
fo
NameError: global name 'fo' is not defined. Did you mean 'foo'?

TestRunner가 표시할 수 있는 출력은 [3]을 참조하십시오.

성능

새 속성들을 채우는 데는 이미 있는 데이터를 담은 매개변수 두 개만 추가하면 되므로 영향은 미미할 것입니다. 그러나 다음 패턴이 이미 널리 쓰이고 있으므로 KeyError에는 특별한 주의가 필요할 수 있습니다.

try:
  a[foo] = a[foo] + 1
except:
  a[foo] = 0

또한 [2]에서 논의한 것처럼, 이 객체들을 오류 자체에 저장하면 오류 메시지를 지연 생성할 수 있다는 점에도 유의하십시오.

참고 문헌