2to3 --- Automated Python 2 to 3 code translation
*************************************************

2to3는 파이썬 2.x 소스 코드를 유효한 파이썬 3.x 코드로 변환하기 위해
일련의 *변환자(fixers)*를 적용하는 프로그램입니다. 표준 라이브러리는
많은 양의 변환자를 제공하고 있어 코드 대부분을 처리할 수 있을 것입니다
. 2to3에서 사용하는 모듈인 "lib2to3" 는 유연하고 제네릭합니다. 따라서
2to3 프로그램을 위해 당신만의 변환자를 작성할 수 있습니다.


2to3 사용법
===========

파이썬 인터프리터가 설치될 때, 보통 2to3 스크립트도 같이 설치됩니다.
2to3 스크립트 파일은 파이썬 루트 디렉터리의 하위 디렉터리인
"Tools/scripts" 에서 찾을 수 있습니다.

2to3의 기본 인자는 변환하고자 하는 파일이나 디렉터리 리스트입니다. 디
렉터리의 경우 하위 폴더의 파이썬 소스까지 적용됩니다.

샘플 파이썬 2.x 코드가 여기 있습니다. "example.py":

   def greet(name):
       print "Hello, {0}!".format(name)
   print "What's your name?"
   name = raw_input()
   greet(name)

명령줄에서 2to3를 실행하면 이 코드를 파이썬 3.x 코드로 바꿀 수 있습니
다:

   $ 2to3 example.py

원본 파일과 변환 결과를 비교한 차이점(diff)이 출력됩니다. 2to3은 원본
소스 파일에 필요한 수정사항을 바로 적용할 수도 있습니다. ("-n" 옵션이
적용되지 않았다면 원본 파일에 대한 백업이 생성될 것입니다.) "-w" 옵션
을 사용하면 바로 원본 파일이 수정됩니다.

   $ 2to3 -w example.py

"example.py" 를 변환한 결과는 다음과 같습니다.

   def greet(name):
       print("Hello, {0}!".format(name))
   print("What's your name?")
   name = input()
   greet(name)

변환 과정에서 들여쓰기와 주석은 그대로 보존됩니다.

기본적으로 2to3는 미리 정의된 변환자 를 사용하여 실행됩니다. "-l" 옵션
을 사용하면 사용 가능한 모든 변환자를 볼 수 있습니다. 특정 변환자만 명
시적으로 설정하고 싶으시면 "-f" 를 사용하시면 됩니다. 마찬가지로 "-x"
옵션으로 특정 변환자를 비활성화할 수도 있습니다. 다음 예는 "imports"
와 "has_key" 변환자만 사용한 것입니다.

   $ 2to3 -f imports -f has_key example.py

다음은 "apply" 변환자만 빼고 모든 변환자를 실행하는 명령어입니다.

   $ 2to3 -x apply example.py

몇몇 변환자는 기본적으로 실행되지 않기 때문에 명시적으로 명령줄에서 설
정해야 합니다. 기본 변환자에 "idioms" 변환자를 추가한 예시가 여기 있습
니다.

   $ 2to3 -f all -f idioms example.py

모든 기본 변환자를 활성화하기 위해 "all" 값을 사용한 것을 주목해주세요
.

때때로 2to3는 자동 변환을 하지 못하고 당신의 코드에서 수정이 필요한 부
분을 찾을 수도 있습니다. 이러면 파일의 비교 결과 아래에 경고 문구를 출
력할 것입니다. 당신은 이 소스코드를 3.x 버전에 맞도록 경고 사항을 수정
해야 합니다.

2to3는 doctest도 수정할 수 있습니다. 이것을 활성화하기 위해서는 "-d"
옵션을 사용하세요. 이것은 *오직* doctest만 수정한다는 것을 명심하세요.
이것을 사용하기 위해서 꼭 적합한 파이썬 모듈이 필요한 것은 아닙니다.
예를 들어 reST 문서에 있는 예와 같은 doctest도 이 옵션과 함께 수정할
수 있습니다.

"-v" 옵션은 변환 과정 동안 더 자세한 정보를 출력하게 해줍니다.

어떤 print 문장의 경우는 문장 또는 함수 호출로 파싱될 수 있기 때문에
2to3이 print 함수를 포함한 파일을 항상 처리할 수 있는 것은 아닙니다.
2to3이 "from __future__ import print_function" 이란 컴파일러 지시어를
찾았다면 2to3는 "print()" 를 함수로 처리하도록 내부 처리 문법을 변경할
것입니다. 이러한 변경은 "-p" 옵션을 가지고 직접 활성화할 수도 있습니다
. 출력 문장이 이미 변경된 코드에 변환자를 실행하기 위해 "-p" 옵션을 사
용하세요. 또한 "-e"를 사용하여 "exec()"를 함수로 만들 수 있습니다.

"-o" 또는 "--output-dir" 옵션을 사용하면 출력 파일이 쓰일 디렉터리를
설정할 수 있습니다. "-n" 옵션은 입력 파일을 덮어쓰지 않아 백업 파일이
필요 없을 때 사용할 수 있습니다.

버전 3.2.3에 추가: "-o" 옵션이 추가되었습니다.

"-W" 또는 "--write-unchanged-files" 옵션은 변경 사항이 없더라도 항상
출력 파일을 쓰도록 합니다. 이것을 "-o" 옵션과 함께 쓰면 한 디렉터리에
있는 전체 파이썬 소스 트리를 파이썬 3.x로 변환해서 다른 디렉터리로 복
사할 때 유용하게 사용할 수 있습니다. 이치에 맞게 하기 위해 이 옵션은
"-w" 옵션을 포함하고 있습니다.

버전 3.2.3에 추가: "-W" 옵션이 추가되었습니다.

"--add-suffix" 옵션은 모든 출력 파일 이름 뒤에 추가할 문자열을 지정합
니다. 다른 파일 이름으로 저장할 때 백업 파일이 필요하지 않다면 "-n" 옵
션을 같이 사용해야 합니다. 예시:

   $ 2to3 -n -W --add-suffix=3 example.py

이 명령어는 출력 파일의 이름을 "example.py3" 로 만들어 줍니다.

버전 3.2.3에 추가: "--add-suffix" 옵션이 추가되었습니다.

한 디렉터리에서 다른 디렉터리로 전체 프로젝트를 변환하고 싶을 때는 다
음과 같이 하면 됩니다.

   $ 2to3 --output-dir=python3-version/mycode -W -n python2-version/mycode


변환자 목록
===========

변환되는 코드의 각각 단계는 변환자 안에 캡슐화되어 있습니다. "2to3 -l"
명령어를 실행하면 변환자 목록을 보실 수 있습니다. 위에 적어놓은 것 과
같이, 각 변환자는 개별적으로 활성화/비활성화를 할 수 있습니다. 변환자
들에 대한 자세한 설명이 아래에 있습니다.

apply

   "apply()" 사용을 제거합니다. 예를 들어 "apply(function, *args,
   **kwargs)" 를 "function(*args, **kwargs)" 로 변경합니다.

asserts

   폐지된 "unittest" 메서드 이름을 올바른 것으로 변경합니다.

   +----------------------------------+--------------------------------------------+
   | 변경 전                          | 변경 후                                    |
   |==================================|============================================|
   | "failUnlessEqual(a, b)"          | "assertEqual(a, b)"                        |
   +----------------------------------+--------------------------------------------+
   | "assertEquals(a, b)"             | "assertEqual(a, b)"                        |
   +----------------------------------+--------------------------------------------+
   | "failIfEqual(a, b)"              | "assertNotEqual(a, b)"                     |
   +----------------------------------+--------------------------------------------+
   | "assertNotEquals(a, b)"          | "assertNotEqual(a, b)"                     |
   +----------------------------------+--------------------------------------------+
   | "failUnless(a)"                  | "assertTrue(a)"                            |
   +----------------------------------+--------------------------------------------+
   | "assert_(a)"                     | "assertTrue(a)"                            |
   +----------------------------------+--------------------------------------------+
   | "failIf(a)"                      | "assertFalse(a)"                           |
   +----------------------------------+--------------------------------------------+
   | "failUnlessRaises(exc, cal)"     | "assertRaises(exc, cal)"                   |
   +----------------------------------+--------------------------------------------+
   | "failUnlessAlmostEqual(a, b)"    | "assertAlmostEqual(a, b)"                  |
   +----------------------------------+--------------------------------------------+
   | "assertAlmostEquals(a, b)"       | "assertAlmostEqual(a, b)"                  |
   +----------------------------------+--------------------------------------------+
   | "failIfAlmostEqual(a, b)"        | "assertNotAlmostEqual(a, b)"               |
   +----------------------------------+--------------------------------------------+
   | "assertNotAlmostEquals(a, b)"    | "assertNotAlmostEqual(a, b)"               |
   +----------------------------------+--------------------------------------------+

basestring

   "basestring" 을 "str" 로 변환합니다.

buffer

   "buffer" 를 "memoryview" 로 변환합니다. "memoryview" API가 "buffer"
   API와 비슷하긴 하지만 완전히 같진 않아서 이 변환자는 선택적으로 실
   행됩니다.

dict

   딕셔너리 이터레이션 메서드를 변환합니다. "dict.iteritems()" 를
   "dict.items()" 로, "dict.iterkeys()" 를 "dict.keys()" 로,
   "dict.itervalues()" 를 "dict.values()" 로 변경합니다. 마찬가지로
   "dict.viewitems()", "dict.viewkeys()", "dict.viewvalues()" 를 각각
   "dict.items()", "dict.keys()", "dict.values()" 로 변경합니다. 기존
   의 "dict.items()", "dict.keys()", "dict.values()" 의 사용을 "list"
   로 감싸도록 바꿉니다.

except

   "except X, T" 를 "except X as T" 로 변환합니다.

exec

   "exec" 문장을 "exec()" 함수로 변환합니다.

execfile

   "execfile()" 사용을 제거합니다. "execfile()" 에 사용되는 인자는
   "open()", "compile()", "exec()" 을 사용하도록 바뀝니다.

exitfunc

   "sys.exitfunc" 대입이 "atexit" 모듈을 사용하도록 바뀝니다.

filter

   "filter()" 함수 사용을 "list" 로 감싸도록 바꿉니다.

funcattrs

   이름이 변경된 함수 어트리뷰트를 변환합니다. 예를 들어
   "my_function.func_closure" 를 "my_function.__closure__" 로 변경합니
   다.

future

   "from __future__ import new_feature" 구문을 제거합니다.

getcwdu

   "os.getcwdu()" 를 "os.getcwd()" 로 변경합니다.

has_key

   "dict.has_key(key)" 를 "key in dict" 로 바꿉니다.

idioms

   이 선택적인 변환자는 이디엄을 더 사용하도록 파이썬 코드를 변환해줍
   니다. "type(x) is SomeClass" 나 "type(x) == SomeClass" 같은 형 비교
   는 "isinstance(x, SomeClass)" 로 변환합니다. "while 1" 는 "while
   True" 로 변환합니다. 또한 이 변환자는 "sorted()" 가 올바른 위치에
   사용될 수 있도록 수정합니다. 예를 들어 다음 코드는

      L = list(some_iterable)
      L.sort()

   아래와 같이 변경됩니다.

      L = sorted(some_iterable)

import

   같은 단계 경로의 임포트를 찾아 상대 경로 임포트로 변경합니다.

imports

   표준 라이브러리에 있는 모듈의 이름 변경 사항을 처리합니다.

imports2

   표준 라이브러리에 있는 또 다른 모듈의 이름 변경 사항을 처리합니다.
   기술적인 제한 사항 때문에 "imports" 변환자와 분리했습니다.

input

   "input(prompt)" 를 "eval(input(prompt))" 로 변경합니다.

intern

   "intern()" 를 "sys.intern()" 로 변경합니다.

isinstance

   "isinstance()" 의 두 번째 인자에서 중복된 형을 수정합니다. 예를 들
   어 "isinstance(x, (int, int))" 를 "isinstance(x, int)" 로,
   "isinstance(x, (int, float, int))" 를 "isinstance(x, (int, float))"
   로 변경합니다.

itertools_imports

   "itertools.ifilter()",  "itertools.izip()", "itertools.imap()" 임포
   트를 제거합니다. "itertools.ifilterfalse()" 임포트를
   "itertools.filterfalse()" 로 바꿉니다.

itertools

   "itertools.ifilter()", "itertools.izip()", "itertools.imap()" 를 각
   각 그것에 맞는 내장 함수로 변경합니다. "itertools.ifilterfalse()"
   를 "itertools.filterfalse()" 로 변경합니다.

long

   "long" 을 "int" 로 바꿉니다.

map

   "map()" 을 "list" 로 감싸도록 바꿉니다. "map(None, x)" 를 "list(x)"
   로 바꿉니다. "from future_builtins import map" 를 사용하면 이 변환
   자가 비활성화됩니다.

metaclass

   구식의 메타 클래스 문법(클래스 바디에 "__metaclass__ = Meta" 를 사
   용)을 새로운 문법("class X(metaclass=Meta)")으로 변경합니다.

methodattrs

   구식의 메서드 어트리뷰트 이름을 수정합니다. 예를 들어
   "meth.im_func" 를 "meth.__func__" 로 변경합니다.

ne

   구식의 부등호 문법인 "<>" 을 "!=" 로 변경합니다.

next

   이터레이터의 "next()" 메서드 사용을 "next()" 함수로 변경합니다. 또
   한 "next()" 메서드를 "__next__()" 로 바꿉니다.

nonzero

   Renames definitions of methods called "__nonzero__()" to
   "__bool__()".

numliterals

   8진수 리터럴을 새 문법으로 변경합니다.

operator

   "operator" 모듈에 있는 다양한 함수 호출을 그것에 대응하는 다른 함수
   호출로 변경합니다. "import collections.abc" 와 같이 필요하다면
   "import" 구문도 추가됩니다. 다음과 같이 변경합니다.

   +------------------------------------+-----------------------------------------------+
   | 변경 전                            | 변경 후                                       |
   |====================================|===============================================|
   | "operator.isCallable(obj)"         | "callable(obj)"                               |
   +------------------------------------+-----------------------------------------------+
   | "operator.sequenceIncludes(obj)"   | "operator.contains(obj)"                      |
   +------------------------------------+-----------------------------------------------+
   | "operator.isSequenceType(obj)"     | "isinstance(obj, collections.abc.Sequence)"   |
   +------------------------------------+-----------------------------------------------+
   | "operator.isMappingType(obj)"      | "isinstance(obj, collections.abc.Mapping)"    |
   +------------------------------------+-----------------------------------------------+
   | "operator.isNumberType(obj)"       | "isinstance(obj, numbers.Number)"             |
   +------------------------------------+-----------------------------------------------+
   | "operator.repeat(obj, n)"          | "operator.mul(obj, n)"                        |
   +------------------------------------+-----------------------------------------------+
   | "operator.irepeat(obj, n)"         | "operator.imul(obj, n)"                       |
   +------------------------------------+-----------------------------------------------+

paren

   리스트 컴프리헨션 안에 괄호가 필요한 경우 추가합니다. 예를 들어 "[x
   for x in 1, 2]" 를 "[x for x in (1, 2)]" 로 변경합니다.

print

   "print" 구문을 "print()" 함수로 변경합니다.

raise

   "raise E, V" 를 "raise E(V)" 로, "raise E, V, T" 를 "raise
   E(V).with_traceback(T)" 로 변경합니다. 만약 "E" 가 튜플인 경우, 변
   환된 결과물은 동작하지 않을 것입니다. 왜냐하면 튜플이 예외를 대체하
   는 것은 3.0부터 사라졌기 때문입니다.

raw_input

   "raw_input()" 를 "input()" 로 변경합니다.

reduce

   "reduce()" 를 "functools.reduce()" 로 변경합니다.

reload

   "reload()" 를 "importlib.reload()" 로 변경합니다.

renames

   "sys.maxint" 를 "sys.maxsize" 로 변경합니다.

repr

   백틱 repr을 "repr()" 함수로 바꿉니다.

set_literal

   "set" 생성자를 집합 리터럴로 바꿉니다. 이 변환자는 선택적입니다.

standarderror

   "StandardError" 를 "Exception" 로 바꿉니다.

sys_exc

   더 사용되지 않을 "sys.exc_value", "sys.exc_type",
   "sys.exc_traceback" 를 "sys.exc_info()" 로 변경합니다.

throw

   제너레이터 "throw()" 메서드의 API 변경 사항을 반영합니다.

tuple_params

   묵시적으로 튜플 매개 변수를 언 패킹하는 것을 제거합니다. 이로 인해
   이 변환자는 임시 변수를 추가합니다.

types

   "types" 모듈에서 몇몇 멤버가 삭제되어 코드가 동작하지 않던 것을 수
   정합니다.

unicode

   "unicode" 를 "str" 로 변경합니다.

urllib

   "urllib" 와 "urllib2" 를 "urllib" 패키지로 변경합니다.

ws_comma

   쉼표로 구분뒨 아이템 목록에서 필요 이상의 공백을 제거합니다. 이 변
   경자는 선택적입니다.

xrange

   "xrange()" 를 "range()" 로 바꿉니다. 기존 "range()" 를 "list" 로 감
   쌉니다.

xreadlines

   "for x in file.xreadlines()" 를 "for x in file" 로 변경합니다.

zip

   "zip()" 를 "list" 로 감쌉니다. 이 변환자는 "from future_builtins
   import zip" 가 있을 때는 비활성화됩니다.


"lib2to3" --- 2to3's library
============================

**소스 코드:** Lib/lib2to3/

======================================================================

버전 3.11에서 폐지되었습니다, 버전 3.13에서 제거됩니다.: Python 3.9
switched to a PEG parser (see **PEP 617**) while lib2to3 is using a
less flexible LL(1) parser.  Python 3.10 includes new language syntax
that is not parsable by lib2to3's LL(1) parser (see **PEP 634**). The
"lib2to3" module was marked pending for deprecation in Python 3.9
(raising "PendingDeprecationWarning" on import) and fully deprecated
in Python 3.11 (raising "DeprecationWarning"). It will be removed from
the standard library in Python 3.13. Consider third-party alternatives
such as LibCST or parso.

참고:

  "lib2to3" API는 미래에 크게 바뀔 수 있기 때문에 안정적이지 않다고 생
  각해야 합니다.
