[Final] PEP 3131 - Supporting Non-ASCII Identifiers

원문 링크: PEP 3131 - Supporting Non-ASCII Identifiers

상태: Final 유형: Standards Track 작성일: 01-May-2007

PEP 3131 – 비(Non)-ASCII 식별자 지원 (Supporting Non-ASCII Identifiers)

  • 작성자: Martin von Löwis
  • 상태: 최종 (Final)
  • 유형: 표준 트랙 (Standards Track)
  • 생성일: 2007년 5월 1일
  • Python 버전: 3.0

개요 (Abstract)

이 PEP는 Python 식별자(identifier)에 악센트 문자, 키릴 문자, 그리스 문자, 한자 등과 같은 비(non)-ASCII 문자를 지원할 것을 제안합니다.

도입 배경 (Rationale)

Python 코드는 영어에 익숙하지 않거나 라틴 문자 체계에 익숙하지 않은 전 세계 많은 사람들에 의해 작성됩니다. 이러한 개발자들은 종종 이름을 부여하려는 개념에 대해 (종종 부정확한) 영어 번역을 고안하는 대신, 모국어로 클래스와 함수 이름을 정의하기를 원합니다. 모국어로 식별자를 사용함으로써 해당 언어를 사용하는 사람들 사이에서 코드의 명확성과 유지보수성이 향상됩니다.

일부 언어의 경우, 일반적인 음역(transliteration) 시스템이 존재하지만(특히 라틴어 기반 문자 체계의 경우), 다른 언어의 사용자들은 라틴 문자를 사용하여 모국어를 쓰는 데 더 큰 어려움을 겪습니다.

일반적인 반대 의견 (Common Objections)

이와 유사한 제안에 대해 종종 제기되는 몇 가지 반대 의견이 있습니다.

일부 사람들은 키보드로 입력할 수 없는 문자를 사용해야 한다면 라이브러리를 사용할 수 없을 것이라고 주장합니다. 그러나 라이브러리 사용에 대한 다양한 제약 조건을 결정하는 것은 라이브러리 설계자의 선택입니다. 예를 들어, 소스 코드에 물리적으로 접근할 수 없거나(공개되지 않아서), 라이선스가 사용을 금지하거나, 문서가 이해할 수 없는 언어로 되어 있어서 라이브러리를 사용하지 못할 수도 있습니다. 라이브러리를 널리 사용 가능하게 만들고자 하는 개발자는 게시, 라이선스, 문서의 언어, 식별자의 언어 등 여러 명시적인 결정을 내려야 합니다. 이러한 결정은 항상 언어 설계자가 아닌 저자의 선택이어야 합니다.

특히, 폭넓은 사용을 목표로 하는 프로젝트는 모든 식별자, 주석(comments), 문서가 영어로 작성되어야 한다는 정책을 수립할 수 있습니다 (GNU 코딩 스타일 가이드가 이러한 정책의 예시입니다). 언어를 ASCII 전용 식별자로 제한한다고 해서 주석과 문서가 영어가 되거나, 식별자가 실제로 영어 단어가 되도록 강제하는 것은 아니므로, 어쨌든 추가적인 정책이 필요합니다.

언어 변경 사항 명세 (Specification of Language Changes)

Python에서 식별자의 문법은 유니코드 표준 부록 UAX-31을 기반으로 하며, 아래에 정의된 대로 추가적인 설명과 변경 사항이 적용됩니다.

ASCII 범위(U+0001..U+007F) 내에서 식별자에 유효한 문자는 Python 2.5와 동일합니다. 이 명세는 ASCII 범위 외부의 추가 문자만 도입합니다. 다른 문자의 경우, 분류는 unicodedata 모듈에 포함된 유니코드 문자 데이터베이스 버전을 사용합니다.

식별자 문법은 <XID_Start> <XID_Continue>* 입니다.

어떤 문자가 XID_Start 또는 XID_Continue 속성을 가지는지에 대한 정확한 명세는 Python이 사용하는 유니코드 데이터(이 PEP가 작성될 당시 4.1 버전)의 DerivedCoreProperties 파일에서 찾을 수 있습니다. 참조를 위해, 이러한 집합의 구성 규칙은 아래와 같습니다. XID_* 속성은 ID_Start/ID_Continue에서 파생되며, 이는 자체적으로 파생됩니다.

  • ID_Start는 대문자 (Lu), 소문자 (Ll), 제목 문자 (Lt), 수정자 문자 (Lm), 기타 문자 (Lo), 숫자 문자 (Nl), 밑줄(underscore) 및 Other_ID_Start 속성을 가진 문자와 같은 일반 카테고리 중 하나를 가진 모든 문자로 정의됩니다. XID_Start는 NFKC 정규화(normalization)가 더 이상 ID_Start ID_Continue* 형태가 아닌 모든 문자를 제거함으로써 정규화에 따라 이 집합을 닫습니다.
  • ID_ContinueID_Start의 모든 문자와 비간격 마크 (Mn), 간격 결합 마크 (Mc), 십진 숫자 (Nd), 연결 구두점 (Pc) 및 Other_ID_Continue 속성을 가진 문자로 정의됩니다. 다시 말해, XID_Continue는 NFKC 정규화에 따라 이 집합을 닫습니다. 또한 카탈로니아어를 지원하기 위해 U+00B7을 추가합니다.

모든 식별자는 파싱(parsing)하는 동안 정규화 형식(normal form) NFKC로 변환되며, 식별자 비교는 NFKC를 기반으로 합니다.

유니코드 4.1에 대한 모든 유효한 식별자 문자를 나열하는 비정규(non-normative) HTML 파일은 아카이브된 링크에서 확인할 수 있습니다.

정책 명세 (Policy Specification)

Python 코딩 스타일(Python Coding style)에 추가하여 다음 정책이 규정됩니다: Python 표준 라이브러리(standard library)의 모든 식별자는 반드시 ASCII 전용 식별자를 사용해야 하며(MUST), 가능한 경우 영어 단어를 사용해야 합니다(SHOULD) (많은 경우 약어와 기술 용어는 영어가 아닙니다). 또한 문자열 리터럴(string literals)과 주석(comments)도 ASCII여야 합니다. 유일한 예외는 (a) 비(non)-ASCII 기능을 테스트하는 테스트 케이스와 (b) 저자의 이름입니다. 라틴 알파벳을 기반으로 하지 않는 이름을 가진 저자는 자신의 이름에 대한 라틴 음역을 제공해야 합니다(MUST).

이 명세는 Python 2.x에도 적용될 수 있습니다. 이 경우, ASCII 전용 식별자는 네임스페이스 딕셔너리(namespace dictionaries)에서 바이트 문자열(byte string) 객체로 계속 표현되며, 비(non)-ASCII 문자를 포함하는 식별자는 유니코드 문자열로 표현됩니다.

구현 (Implementation)

파서(parser)에 다음 변경 사항을 적용해야 합니다:

  • 소스 코드의 UTF-8 표현에서 비(non)-ASCII 문자가 발견되면, 첫 번째 ASCII 비(non)-식별자 문자(예: 공백 또는 구두점)를 찾기 위한 전방 탐색(forward scan)이 이루어집니다.
  • 전체 UTF-8 문자열은 문자열을 NFKC로 정규화한 다음 식별자 문법을 따르는지 확인하는 함수로 전달됩니다. 순수 ASCII 식별자의 경우 이러한 호출은 이루어지지 않으며, 현재와 동일한 방식으로 파싱됩니다.
  • 유니코드 데이터베이스는 Other_ID_{Start|Continue} 속성을 포함하기 시작해야 합니다.
  • 이 명세가 2.x에 구현되는 경우, __dict__ 슬롯에 유니코드 문자열이 키로 나타날 때 pydoc과 같은 리플렉티브(reflective) 라이브러리가 계속 작동하는지 확인해야 합니다.

남아있는 문제점 (Open Issues)

John Nagle은 유니코드 식별자의 보안 메커니즘을 다루는 유니코드 기술 표준 #39 (Unicode Technical Standard #39)를 고려할 것을 제안했습니다. 이것이 이 PEP에 정확히 어떻게 적용될 수 있는지는 명확하지 않으며, 가능한 결과는 다음과 같습니다:

  • xidmodifications.txt에 “제한됨(restricted)”으로 나열된 문자에 대해 경고.
  • 혼합된 스크립트(mixed scripts)를 사용하는 식별자에 대해 경고.
  • 혼동 감지(Confusable Detection) 수행.

후자의 두 가지 접근 방식에서 알고리즘이 정확히 어떻게 작동해야 하는지는 명확하지 않습니다. 혼합 스크립트의 경우 특정 유형의 혼합은 허용되어야 할 것입니다. 이것이 섹션 5에 언급된 “Common” 및 “Inherited” 스크립트인지 여부도 고려해야 합니다. 혼동 감지의 경우, 혼동 여부를 비교하려면 두 개의 식별자가 필요한 것으로 보입니다. 단일 식별자에만 적용하여 경고할 수 있는 방법이 있을까요?

후속 논의에서 John Nagle은 사실 UTR#36, “Highly Restrictive” 레벨을 제안하려 했다는 것이 밝혀졌습니다.

몇몇 사람들은 Java, JavaScript, C#에서와 같이 포맷팅 제어 문자(formatting control characters, 일반 카테고리 Cf)를 허용하고 무시할 것을 제안했습니다. 이것이 상황을 개선할지(RTL 언어의 경우 그럴 수도 있음)는 명확하지 않습니다. 필요하다면 나중에 추가할 수 있습니다.

일부 사람들은 런타임에 이 PEP에 대한 지원을 선택하는 옵션을 원했습니다. 이 옵션이 정확히 무엇이어야 하고 기본값이 무엇이어야 하는지에 대한 의견은 다양합니다. Guido van Rossum은 인터프리터에 전달되는 전역 플래그는 모든 모듈에 적용되므로 허용될 수 없다고 언급했습니다.

논의 (Discussion)

Ka-Ping Yee는 논의와 추가적인 반대 의견을 다음과 같이 요약했습니다:

식별자에 모든 유니코드 문자를 허용해야 하는가?

비(non)-ASCII 식별자를 전면적으로 허용하는 것의 단점은 다음과 같습니다:

  • Python은 화면이나 종이에서 사람이 읽을 수 있는 형태로 안정적인 왕복(round trip) 기능을 잃게 될 것입니다.
  • Python은 새로운 종류의 보안 취약점(security exploits)에 취약해질 것이며, 코드와 제출된 패치(patches)를 검사하기가 훨씬 더 어려워질 것입니다.
  • 사람들은 더 이상 Python 문법을 검증할 수 없게 될 것입니다.
  • 유니코드는 아직 초기 단계이며, 그 문제들이 잘 이해되고 해결되지 않았으며, 도구 지원이 미약합니다.
  • 비(non)-ASCII 식별자를 사용하는 언어는 다른 문자 집합과 정규화 스키마(normalization schemes)를 사용하며, PEP 3131의 선택은 명확하지 않습니다.
  • 유니코드 양방향(bidi) 알고리즘은 숫자나 연산자가 근처에 있을 때 RTL(Right-to-Left) 텍스트에 대해 극도로 혼란스러운 표시 순서를 제공합니다.

기본 동작은 ASCII 식별자만 허용해야 하는가, 아니면 비(non)-ASCII 문자를 포함하는 식별자를 허용해야 하는가?

기본적으로 ASCII만 허용해야 한다는 주장은 다음과 같습니다:

  • 기본적으로 비(non)-ASCII 식별자는 일반적인 관행/가정을 미묘하게/무의식적으로 잘못되게 만들며, 드물게 잘못되는 것이 명백히 잘못되는 것보다 더 나쁩니다.
  • 예상치 못한 상황이 발생했을 때 아무런 경고 없이 실패하는 것보다 경고를 발생시키는 것이 좋습니다.
  • 현재 사용량의 모든 부분은 ASCII 전용이며, 미래 사용량의 대부분도 ASCII 전용일 것입니다.
  • 유니코드 도입을 지지하는 쪽이 지역적이며, ASCII 옹호자들이 아닙니다.
  • Python은 탭-공백 일관성을 감사하는 것과 동일한 이유로 ASCII 전용 식별자를 감사해야 합니다.
  • 점진적인 변경이 더 안전합니다.
  • ASCII 전용 기본값은 오픈 소스 개발 및 소스 코드 공유에 유리합니다.
  • 기존 프로젝트는 유니코드 식별자의 의미에 대해 걱정하느라 에너지를 낭비할 필요가 없습니다.

비(non)-ASCII 식별자는 선택 사항이어야 하는가?

플래그(flag)를 지지하는 다양한 의견이 있었습니다 (기본값에 대한 논쟁은 있었지만, 스위치가 없어야 한다고 말하는 사람은 없는 것 같습니다).

식별자 문자 집합은 구성 가능해야 하는가?

사용자들이 혼동을 일으키거나 익숙하지 않은 문자의 단점 없이 자신의 언어를 사용하는 모든 이점을 얻을 수 있도록 선택 가능한 문자 집합을 제안하고 지지하는 다양한 의견이 있었습니다.

어떤 식별자 문자를 허용해야 하는가?

  • 양방향(bidi) 형식 제어 문자는 어떻게 해야 하는가?
  • 다른 ID_Continue 문자는?
  • 구두점(punctuation)처럼 보이는 문자는?
  • UTS #39의 다른 권장 사항은?
  • 혼합 스크립트(mixed-script) 식별자는?

어떤 정규화 형식(normalization form)을 사용해야 하는가, NFC 또는 NFKC? 소스 코드는 정규화된 형식이어야 하는가?

이 문서는 퍼블릭 도메인(public domain)에 공개되었습니다.

⚠️ 알림: 이 문서는 AI를 활용하여 번역되었으며, 기술적 정확성을 보장하지 않습니다. 정확한 내용은 반드시 원문을 확인하시기 바랍니다.

Comments