# Python 3.10 신규 문법 : Parenthesized context managers와 PEG Parser

## Python 3.10 추가 기능 - 괄호로 둘러싸인 Context Manager

Python 3.10부터 아래와 같이 Context Manager사용 시 괄호 안에서 여러 줄을 사용하는 것이 가능해졌다.

```javascript
with (CtxManager() as example):
    ...

with (
    CtxManager1(),
    CtxManager2()
):
    ...

with (CtxManager1() as example,
      CtxManager2()):
    ...

with (CtxManager1(),
      CtxManager2() as example):
    ...

with (
    CtxManager1() as example1,
    CtxManager2() as example2
):
    ...
```

## Python 3.10에 반영된 이유

아래 사진과 같이 [Github Issue](https://github.com/python/cpython/issues/56991)에서 귀도 반 로섬은 **PEG-based parser**가 도입(Python 3.9)된 이후인 3.10에서 해당 기능을 구현하는 것을 제안하다.

- `Python 3.10`은 20.5.18에 개발이 시작되서 21.10.4 `final` 버전이 배포된다.

- `Python 3.9`는 19.6.4에 개발이 시작되서 20.10.5에 `final` 버전이 배포된다.

![Image](https://upload.cafenono.com/image/slashpagePost/20250314/145539_pzY7jNyCg3fob8iV0l?q=80&s=1280x180&t=outside&f=webp)

### Parser변경 Migration 계획

1. `3.9 alpha 6` 버전에서 PEG 기반의 parser를 command-line flag와 환경 변수와 같이 포함한다. 이는 이전 Parser로 전환하는 것이 가능하다. 모든 Python API(`ast.parse`와 `compile`)은 설정된 flag와 환경변수를 사용할 것이고 deafult parser는 신규 PEG기반의 Parser로 지정된다.

2. `3.10` 이 배포될 때까지 이전 parser와 그와 관련된 코드들은 유지될 것이다. 이전 Parser가 제거될 때까지 PEG Parser를 요구하는 새로운 문법이 추가되지 않을 것이다.

3. `3.10` 에서 이전 Parser와 commnad-line flag, 환경변수, parser모듈 및 그와 관련된 코드는 삭제 될 것이다.

## Parser가 변경된 이유(LL(1) → PEG)?

LL(1) Parser와 PEG Parser에 대해서 간략히 살펴보고, LL(1) Parser가 갖는 문제점을 통해서 CPython의 Parser가 LL(1) Parser에서 PEG Parser로 변경된 이유에 대해서 확인해본다.

### Parser의 종류

![Image](https://upload.cafenono.com/image/slashpagePost/20250314/145015_vYR8MFCZcK0IHJvIFj?q=80&s=1280x180&t=outside&f=webp)

| **이름** | **LL(1)** | **PEG** |
| --- | --- | --- |
| **설명** | `L`eft to Right  `L`eft Most Derivation Tree `1` symbol is used to make a decision | `PEG` = Parsing Expression Grammar |
| **Python 도입** | 3.9 이전에 사용 | 3.9부터 도입 |
| **Parser 유형** | **Non-recursive descent parser** 비재귀적인 하향식 분석기 | **Recursive descent parser** 재귀적인 하향식 분석기 |

### LL(1) Parser가 갖는 문제점

1. 몇 가지 규칙은 LL(1) 규칙에 맞지 않는다.

    1. CST → AST로 변환하는 과정에서 규칙이 추가되었다.

    2. grammar 파일이 실제 grammar를 반영하지 못한다

    3. 추가된 규칙에 대한 유지보수 비용 증가

2. AST 파싱이 복잡하다. (위의 이유와 연관)

3. 좌향-재귀가 불가능하다.

4. 중간에 사용되지 않는 CST가 생성된다.

## 참조 문서

- [https://github.com/python/cpython/issues/56991](https://github.com/python/cpython/issues/56991) : Multiple context expressions do not support parentheses for continuation across lines

- [https://github.com/we-like-parsers/pegen_experiments/issues/229](https://github.com/we-like-parsers/pegen_experiments/issues/229) : pegen_experiments Repo - Integration: Parenthesized with statements are currently allowed

- Python Docs : [What’s New In Python 3.10](https://docs.python.org/3/whatsnew/3.10.html#parenthesized-context-managers)

- [PEP 617 - New PEG parser for CPython](https://peps.python.org/pep-0617/)

- GeeksforGeeks Parsing - Introduction to Parsers - GeeksforGeeks

For the site tree, see the [root Markdown](https://slashpage.com/kpmg-lighthouse.md).
