PEP 3131 – 비ASCII 식별자 지원
- Author:
- Martin von Löwis <martin at v.loewis.de>
- Status:
- Final
- Type:
- Standards Track
- Created:
- 01-May-2007
- Python-Version:
- 3.0
- Post-History:
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 PEP는 Python 식별자에 비ASCII 문자(악센트가 붙은 문자, 키릴 문자, 그리스 문자, 한자 등)를 허용할 것을 제안합니다.
근거
Python 코드는 전 세계의 많은 사람이 작성합니다. 그중에는 영어에 익숙하지 않거나 라틴 문자 체계조차 잘 알지 못하는 사람이 많습니다. 이러한 개발자는 이름을 붙이려는 개념의 영어 번역어를 (종종 부정확하게) 억지로 만들어 내기보다, 모국어로 된 이름으로 클래스와 함수를 정의하기를 원하는 경우가 많습니다. 모국어로 된 식별자를 사용하면 그 언어를 쓰는 사람들 사이에서 코드의 명확성과 유지 보수성이 향상됩니다.
일부 언어에는 (특히 라틴 문자 기반 문자 체계의 경우) 널리 쓰이는 음역 체계가 있습니다. 그 밖의 언어에서는 사용자가 모국어 단어를 라틴 문자로 적는 데 더 큰 어려움을 겪습니다.
흔한 반론
이와 유사한 제안에는 몇 가지 반론이 자주 제기됩니다.
어떤 사람들은 라이브러리를 사용하는 데 자신의 키보드로 입력할 수 없는 문자가 필요하다면 그 라이브러리를 사용할 수 없을 것이라고 주장합니다. 그러나 라이브러리 사용에 따르는 여러 제약을 정하는 것은 라이브러리 설계자의 선택입니다. 소스 코드가 공개되지 않아 물리적으로 접근할 수 없거나, 라이선스가 사용을 금지하거나, 문서가 자신이 이해할 수 없는 언어로 되어 있어서 라이브러리를 사용하지 못할 수도 있습니다. 라이브러리를 널리 사용할 수 있게 하려는 개발자는 여러 가지 사항(공개 여부, 라이선스, 문서의 언어, 식별자의 언어 등)을 명시적으로 선택해야 합니다. 이러한 결정은 언제나 언어 설계자가 아니라 작성자가 선택할 문제여야 합니다.
특히 널리 사용되기를 바라는 프로젝트라면 모든 식별자, 주석, 문서를 영어로 작성한다는 정책을 세우고 싶을 것입니다(이러한 정책의 예는 GNU 코딩 스타일 가이드를 참고하십시오). 언어에서 식별자를 ASCII로만 제한한다고 해서 주석과 문서가 영어로 작성되거나 식별자가 실제로 영어 단어가 되도록 강제되지는 않으므로, 어차피 별도의 정책이 필요합니다.
언어 변경 명세
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/ID_Continue 자체도 파생 속성입니다.
ID_Start는 일반 범주 대문자(Lu), 소문자(Ll), 제목 문자(Lt), 수식 문자(Lm), 기타 문자(Lo), 문자 숫자(Nl) 중 하나에 속하는 모든 문자와 밑줄, 그리고 Other_ID_Start 속성을 가진 문자로 정의됩니다. 그런 다음 XID_Start는 NFKC 정규화 결과가 더 이상 ID_Start ID_Continue* 형태가 아닌 문자를 모두 제거하여 이 집합이 정규화에 대해 닫혀 있도록 만듭니다.
ID_Continue는 ID_Start의 모든 문자에 비간격 부호(Mn), 간격 결합 부호(Mc), 십진 숫자(Nd), 연결 구두점(Pc), 그리고 Other_ID_Continue 속성을 가진 문자를 더한 것으로 정의됩니다. 마찬가지로 XID_Continue는 이 집합이 NFKC 정규화에 대해 닫혀 있도록 만들며, 카탈루냐어를 지원하기 위해 U+00B7도 추가합니다.
모든 식별자는 구문 분석 중에 정규형 NFKC로 변환되며, 식별자 비교는 NFKC를 기준으로 합니다.
유니코드 4.1에서 유효한 모든 식별자 문자를 나열한 비규범적 HTML 파일은 https://web.archive.org/web/20081016132748/http://www.dcl.hpi.uni-potsdam.de/home/loewis/table-3131.html 에서 찾을 수 있습니다.
정책 명세
Python 코딩 스타일에 추가하여 다음 정책을 규정합니다: Python 표준 라이브러리의 모든 식별자는 반드시(MUST) ASCII 전용 식별자를 사용해야 하며, 가능한 한 영어 단어를 사용해야 합니다(SHOULD)(많은 경우 영어가 아닌 약어와 기술 용어가 사용됩니다). 또한 문자열 리터럴과 주석도 ASCII로 작성해야 합니다. 유일한 예외는 (a) 비 ASCII 기능을 테스트하는 테스트 케이스와 (b) 저자의 이름입니다. 이름이 라틴 알파벳에 기반하지 않은 저자는 반드시(MUST) 자기 이름의 라틴 문자 음역을 제공해야 합니다.
선택 사항으로, 이 명세를 Python 2.x에 적용할 수 있습니다. 그 경우 ASCII 전용 식별자는 네임스페이스 딕셔너리에서 계속 바이트 문자열 객체로 표현되고, 비 ASCII 문자를 포함한 식별자는 유니코드 문자열로 표현됩니다.
구현
파서를 다음과 같이 변경해야 합니다:
- 소스 코드의 UTF-8 표현에서 비 ASCII 문자가 발견되면, 식별자가 아닌 첫 번째 ASCII 문자(예: 공백이나 구두점 문자)를 찾기 위해 앞쪽으로 스캔합니다
- 전체 UTF-8 문자열을 함수에 전달하여 문자열을 NFKC로 정규화한 다음, 식별자 문법을 따르는지 검증합니다. 순수 ASCII 식별자에 대해서는 이러한 호출을 하지 않으며, 이러한 식별자는 현재와 같은 방식으로 계속 파싱됩니다. 유니코드 데이터베이스는 이제부터 Other_ID_{Start|Continue} 속성을 포함해야 합니다.
- 이 명세를 2.x에 구현한다면, 유니코드 문자열이
__dict__슬롯에 키로 나타날 때에도 리플렉션 라이브러리(pydoc 등)가 계속 동작하는지 검증해야 합니다.
미해결 문제
John Nagle은 유니코드 식별자의 보안 메커니즘을 다루는 Unicode Technical Standard #39를 검토할 것을 제안했습니다. 이것을 이 PEP에 정확히 어떻게 적용할 수 있는지는 분명하지 않습니다. 가능한 결과는 다음과 같습니다
- xidmodifications.txt에 “restricted”로 나열된 문자에 대해 경고합니다
- 여러 스크립트를 혼합하여 사용하는 식별자에 대해 경고합니다
- 어떤 방식으로든 혼동 문자 탐지(Confusable Detection)를 수행합니다
뒤의 두 접근 방식에서는 알고리즘이 정확히 어떻게 동작해야 하는지 분명하지 않습니다. 혼합 스크립트의 경우 특정 종류의 혼합은 아마 허용해야 할 것입니다. 이것이 5절에서 언급된 “Common” 및 “Inherited” 스크립트입니까? 혼동 문자 탐지의 경우, 혼동 여부를 비교하려면 두 개의 식별자가 필요한 것으로 보입니다. 이를 어떻게든 단일 식별자에만 적용하여 경고하는 것이 가능합니까?
후속 논의에서 John Nagle이 실제로 제안하려던 것은 UTR#36의 “Highly Restrictive” 수준이었음이 밝혀졌습니다.
몇몇 사람들은 Java, JavaScript, C#에서처럼 서식 제어 문자(일반 범주 Cf)를 허용하되 무시하자고 제안했습니다. 이것이 상황을 개선할지는 분명하지 않습니다(RTL 언어에서는 개선될 수도 있습니다). 필요하다면 나중에 추가할 수 있습니다.
어떤 사람들은 이 PEP의 지원 여부를 런타임에 선택하는 옵션이 있기를 원합니다. 그 옵션이 정확히 무엇이어야 하는지, 그리고 기본값이 정확히 무엇이어야 하는지에 대해서는 의견이 다양합니다. Guido van Rossum은 인터프리터에 전달되는 전역 플래그는 모든 모듈에 적용되므로 받아들일 수 없다고 언급했습니다.
논의
Ka-Ping Yee가 논의와 추가 반대 의견을 요약한 내용은 다음과 같습니다:
- 식별자에 임의의 유니코드 문자를 포함하도록 허용해야 합니까?
비 ASCII 식별자를 전면적으로 허용할 때의 단점은 다음과 같습니다:
- Python은 화면이나 종이 위의 사람이 읽을 수 있는 표시와 신뢰성 있게 왕복 변환하는 능력을 잃게 됩니다.
- Python이 새로운 종류의 보안 공격에 취약해지고, 코드와 제출된 패치를 검토하기가 훨씬 어려워질 것입니다.
- 사람이 더 이상 Python 문법을 검증할 수 없게 됩니다.
- 유니코드는 아직 역사가 짧습니다. 그 문제점은 아직 충분히 이해되거나 해결되지 않았고, 도구 지원도 미흡합니다.
- 비ASCII 식별자를 쓰는 언어들은 저마다 다른 문자 집합과 정규화 방식을 사용합니다. PEP 3131의 선택은 자명하지 않습니다.
- 유니코드 양방향(bidi) 알고리즘은 숫자나 연산자가 가까이 있을 때 RTL 텍스트를 극도로 혼란스러운 순서로 표시합니다.
- 기본 동작은 ASCII 식별자만 허용해야 합니까, 아니면 비ASCII 문자가 포함된 식별자도 허용해야 합니까?
기본적으로 ASCII만 허용해야 한다는 인자:
- 비ASCII 식별자를 기본으로 허용하면 일반적인 관행과 가정이 미묘하게, 그리고 모르는 사이에 틀리게 됩니다. 가끔 틀리는 것은 명백하게 틀리는 것보다 더 나쁩니다.
- 예상하지 못했을 가능성이 높은 상황을 만났을 때는 조용히 실패하기보다 경고를 발생시키는 편이 낫습니다.
- 현재의 사용 사례는 모두 ASCII만 씁니다. 앞으로의 사용 사례도 대다수는 ASCII만 쓸 것입니다.
- 편협한 쪽은 ASCII 옹호자들이 아니라 유니코드를 도입한 일부 집단들입니다.
- Python은 탭과 공백의 일관성을 검사하는 것과 같은 이유로 식별자가 ASCII로만 이루어졌는지도 검사해야 합니다
- 점진적인 변경이 더 안전합니다.
- ASCII 전용을 기본값으로 하면 오픈 소스 개발과 소스 코드 공유에 유리합니다.
- 기존 프로젝트는 유니코드 식별자가 미칠 영향을 걱정하느라 머리를 쓸 필요가 없습니다.
- 비ASCII 식별자를 선택 사항으로 해야 합니까?
플래그를 지지하는 여러 의견이 있습니다(어느 쪽을 기본값으로 할지에 대해서는 논쟁이 있었지만, 끄는 스위치가 없어야 한다고 말하는 사람은 없는 것 같습니다)
- 식별자 문자 집합을 설정할 수 있어야 합니까?
사용자가 혼동하기 쉽거나 익숙하지 않은 문자로 인한 단점 없이 자신의 언어를 사용하는 이점을 모두 누릴 수 있도록, 선택 가능한 문자 집합을 제안하고 지지하는 여러 의견이 있습니다
- 어떤 식별자 문자를 허용해야 합니까?
- 양방향(bidi) 서식 제어 문자는 어떻게 처리해야 합니까?
- 다른 ID_Continue 문자는 어떻게 처리해야 합니까? 문장 부호처럼 보이는 문자는 어떻게 처리해야 합니까? UTS #39의 다른 권고 사항은 어떻게 처리해야 합니까? 여러 문자 체계가 섞인 식별자는 어떻게 처리해야 합니까?
- NFC와 NFKC 중 어떤 정규화 형식을 사용해야 합니까?
- 소스 코드가 정규화된 형식이어야 한다고 요구해야 합니까?
Copyright
This document has been placed in the public domain.