--------------------------------------------------------------------------------
/8th_members/고동희/1주차.md:
--------------------------------------------------------------------------------
1 | # 1주차
2 |
3 | ## CPython 소스코드 다운로드 및 환경 구성
4 |
5 |
6 | ## 스터디에서 이루고 싶은 목표, 함께 하게 된 소감
7 | 1. CPython internal 뿌셔뿌셔~!
8 | 2. 운영체제, 자료구조는 덤~!
9 | 3. 열심히 하겠습니다!!
10 |
--------------------------------------------------------------------------------
/8th_members/김진아/5주차.md:
--------------------------------------------------------------------------------
1 | # 4주차
2 |
3 | ## ‘거의 같음’ 연산자 구현
4 |
5 |
--------------------------------------------------------------------------------
/8th_members/김원경/8주차.md:
--------------------------------------------------------------------------------
1 | ### 원하는 라이브러리 import 해보고, 참조 카운트가 어떻게 바뀌는지 출력해보기
2 |
--------------------------------------------------------------------------------
/8th_members/김진아/10주차.md:
--------------------------------------------------------------------------------
1 | # 10주차
2 |
3 | ## Port Scanner: Multi Threading
4 |
5 |
--------------------------------------------------------------------------------
/8th_members/김필모/8주차.md:
--------------------------------------------------------------------------------
1 | # 원하는 라이브러리 import 해보고, 참조 카운트가 어떻게 바뀌는지 출력해보기
2 |
3 |
4 |
--------------------------------------------------------------------------------
/8th_members/김진아/8주차.md:
--------------------------------------------------------------------------------
1 | # 8주차
2 |
3 | ## 원하는 라이브러리 import 해보고, 참조 카운트가 어떻게 바뀌는지 출력해보기
4 |
5 |
--------------------------------------------------------------------------------
/8th_members/고동희/10주차.md:
--------------------------------------------------------------------------------
1 | # 10주차
2 |
3 | ## 싱글 프로세스 + 싱글 스레드
4 | 
5 |
6 | ## 싱글 프로세스 + 멀티 스레딩
7 | 
8 |
9 | ## 싱글 프로세스 + 멀티 스레딩 (개수 제한)
10 | 
--------------------------------------------------------------------------------
/8th_members/이성범/1주차.md:
--------------------------------------------------------------------------------
1 | # 1주차
2 |
3 | ## CPython 소스코드 다운로드 및 환경 구성
4 |
5 |
6 | ## 스터디에서 이루고 싶은 목표, 함께 하게 된 소감
7 | - 이번 스터디를 통해서 Python 동작 원리를 조금 더 깊게 이해해서, 사용하고 있는 코드들의 성능을 최적화 하고 싶습니다.
8 | - CPython을 공부하려는 사람들을 위한 좋은 가이드북을 만들면 좋겠습니다.
--------------------------------------------------------------------------------
/8th_members/이성범/4주차.md:
--------------------------------------------------------------------------------
1 | # 4주차
2 |
3 | ## instaviz로 AST 시각화 해보기
4 |
9 |
--------------------------------------------------------------------------------
/8th_members/이용준/9주차.md:
--------------------------------------------------------------------------------
1 | ## 10.3.8 애플리케이션 예제의 두 코드를 실행
2 |
3 | 
4 |
5 | 
6 |
--------------------------------------------------------------------------------
/8th_members/이용준/4주차.md:
--------------------------------------------------------------------------------
1 | # instaviz로 AST 시각화 해보기
2 |
3 | 
4 |
5 | # ‘거의 같음’ 연산자를 문법에 추가하고 AlE타입의 객체를 출력 해보기
6 |
7 | 
8 |
--------------------------------------------------------------------------------
/8th_members/이용준/2주차.md:
--------------------------------------------------------------------------------
1 | # 컴파일 완료된 화면 캡쳐 (./python.exe 실행 화면)
2 |
3 | 
4 |
5 | # 문법 다시 생성하기 (pass 키워드 변경해보기) (결과 화면 캡쳐)
6 |
7 | 
8 |
--------------------------------------------------------------------------------
/8th_members/전희선/1주차.md:
--------------------------------------------------------------------------------
1 | - CPython 소스코드 다운로드 및 환경 구성 (화면 캡쳐)
2 |
3 | - 스터디에서 이루고 싶은 목표, 함께 하게 된 소감 등
4 | - CPython 튜토리얼 페이지를 팀원 분들과 함께 완성해나가는 것이 목표입니다!
5 | - 함께 Python 내부 구조를 깊이 있게 알아가서 고급 Python 개발자가 되었으면 좋겠습니다 :)
6 |
--------------------------------------------------------------------------------
/8th_members/이용준/3주차.md:
--------------------------------------------------------------------------------
1 | # 파이썬 세션에서 runtime flag 확인하기
2 |
3 | 
4 |
5 | # importlib.util.find_spec 함수를 사용해서 원하는 모듈의 위치를 찾아보기 (결과 화면 캡쳐)
6 |
7 | 
8 |
--------------------------------------------------------------------------------
/8th_members/김원경/4주차.md:
--------------------------------------------------------------------------------
1 | # 1. instaviz로 AST 시각화
2 |
3 |
4 |
5 | # 2. ‘거의 같음’ 연산자를 문법에 추가하고 AlE타입의 객체를 출력
6 |
--------------------------------------------------------------------------------
/8th_members/하상천/1주차.md:
--------------------------------------------------------------------------------
1 | - CPython 소스코드 다운로드 및 환경 구성
2 |
3 | - 스터디에서 이루고 싶은 목표, 함께 하게 된 소감
4 | - Python의 내부 구조를 깊이 있게 이해하고, CPython 소스코드를 분석해보고 싶습니다.
5 | - CPython 소스코드를 분석하면서, Python의 내부 동작 원리를 이해하고, 이를 통해 Python의 성능을 최적화하는 방법을 배우고 싶습니다.
6 |
--------------------------------------------------------------------------------
/8th_members/김원경/3주차.md:
--------------------------------------------------------------------------------
1 | ## 파이썬 세션에서 runtime flag 확인하기
2 |
3 |
4 | ## importlib.util.find_spec 함수를 사용해서 원하는 모듈의 위치를 찾아보기
5 |
--------------------------------------------------------------------------------
/8th_members/이성범/3주차.md:
--------------------------------------------------------------------------------
1 | # 3주차
2 |
3 | ## CPython 인터프리터 실행 과정 코드 레벨로 이해하기
4 |
5 |
6 | ## 파이썬 세션에서 runtime flag 확인하기
7 |
8 |
9 | ## importlib.util.find_spec 함수를 사용해서 원하는 모듈의 위치를 찾아보기
10 |
--------------------------------------------------------------------------------
/8th_members/김필모/1주차.md:
--------------------------------------------------------------------------------
1 | # 1주차
2 |
3 | ## CPython 소스코드 다운로드 및 환경 구성
4 |
5 |
6 |
7 | ## 스터디에서 이루고 싶은 목표, 함께 하게 된 소감
8 |
9 | - 한국어로 된 문서 중 가장 좋은 Cpython 문서 만들기!!
10 | - 이제 백준 문제 풀이 시간 순위 1등은 내꺼!
11 | - 어디가서 파이썬 좀 안다 자신있게 말하기
12 |
--------------------------------------------------------------------------------
/8th_members/김원경/2주차.md:
--------------------------------------------------------------------------------
1 | # 2주차
2 |
3 | ## 컴파일 완료된 화면 캡쳐 (./python.exe 실행 화면)
4 |
5 |
6 |
7 | ## 문법 다시 생성하기 (pass 키워드 변경해보기) 부분 원하는 키워드 다른걸로 바꿔보기
8 |
--------------------------------------------------------------------------------
/8th_members/김진아/9주차.md:
--------------------------------------------------------------------------------
1 | # 9주차
2 |
3 | ## Port Scanner: Queue
4 |
5 |
6 | ## Port Scanner: multiprocessing.Queue
7 |
8 |
--------------------------------------------------------------------------------
/book/c_extension_sample/setup.py:
--------------------------------------------------------------------------------
1 | from distutils.core import setup, Extension
2 |
3 | def main():
4 | setup(name="fputs",
5 | version="1.0.0",
6 | description="Python interface for the fputs C library funtion",
7 | author="kwang1",
8 | author_email="4roring@naver.com",
9 | ext_modules=[Extension("fputs", ["fputsmodule.c"])])
10 |
11 |
12 | if __name__ == "__main__":
13 | main()
14 |
--------------------------------------------------------------------------------
/8th_members/김원경/9주차.md:
--------------------------------------------------------------------------------
1 | ### 10.3.8 애플리케이션 예제 두 코드 실행해보기
2 | 1개 이상의 port가 출력되도록 만들기 위해 검사하는 port 번호 range를 0~99로 변경했습니다.
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/8th_members/김필모/3주차.md:
--------------------------------------------------------------------------------
1 | # 3주차
2 |
3 | ## 파이썬 세션에서 runtime flag 확인하기
4 |
5 |
6 |
7 | ## importlib.util.find_spec 함수를 사용해서 원하는 모듈의 위치를 찾아보기
8 |
9 |
--------------------------------------------------------------------------------
/8th_members/김진아/2주차.md:
--------------------------------------------------------------------------------
1 | # 2주차
2 |
3 | ## 컴파일 완료된 화면 캡쳐 (./python.exe 실행 화면)
4 |
5 |
6 | ## 문법 다시 생성하기 (pass 키워드 변경해보기) 부분 원하는 키워드 다른걸로 바꿔보기 (결과 화면 캡쳐)
7 |
8 |
--------------------------------------------------------------------------------
/8th_members/김진아/1주차.md:
--------------------------------------------------------------------------------
1 | # 1주차
2 |
3 | ## CPython 소스코드 다운로드 및 환경 구성 (화면 캡쳐)
4 |
5 |
6 | ## 스터디에서 이루고 싶은 목표, 함께 하게 된 소감 등
7 | - Python을 깊이 이해하여 Python을 잘 활용하는 개발자가 되고 싶습니다.
8 | - Python의 내부 구조와 코드를 파악하며 Python의 철학을 이해하고 좋은 코드에 대해서도 배워가고 싶습니다.
9 | - 같이 스터디하면서 많이 배우겠습니다! 재밌고 보람찬 시간이 될 수 있도록 열심히 참여하겠습니다.
10 |
--------------------------------------------------------------------------------
/8th_members/하상천/4주차.md:
--------------------------------------------------------------------------------
1 | - instaviz로 AST 시각화 해보기
2 |
3 |
4 |
5 |
6 |
7 | - ‘거의 같음’ 연산자를 문법에 추가하고 AlE타입의 객체를 출력 해보기
8 |
9 | 
10 |
--------------------------------------------------------------------------------
/8th_members/전희선/2주차.md:
--------------------------------------------------------------------------------
1 | - 컴파일 진행
2 |
3 |
4 | - Grammar/python.gram 에서 'break'문 키워드에 'end_this_loop' 추가
5 |
6 |
--------------------------------------------------------------------------------
/book/intro.md:
--------------------------------------------------------------------------------
1 | # CPython Guide for PseudoLab
2 |
3 | 가짜연구소 CPython 파헤치기 스터디팀에서 작성하는 CPython Guide 페이지 입니다.
4 |
5 | ### [CPython Github](https://github.com/python/cpython)
6 | 스터디에 활용되는 CPython Github 저장소 입니다.
7 |
8 | ### CPython 파헤치기 Notion 페이지
9 | 스터디 진행 기록을 저장하는 Notion 페이지 입니다.
10 | - [6기 (2023.03~2023.07)](https://www.notion.so/chanrankim/CPython-868604c8879341808b85d4321bb07501?pvs=4)
11 | - [8기 (2024.03~2024.06)](https://www.notion.so/chanrankim/Python-CPython-eb832e65c4b1443ba3b9be8d5fc5883a?pvs=4)
12 |
--------------------------------------------------------------------------------
/8th_members/김원경/7주차.md:
--------------------------------------------------------------------------------
1 | - tracemalloc 통해 직접 메모리 확인해보기
2 |
3 | 아래 레포지토리의 코드(프로그램)를 통해 메모리를 확인해보았습니다.
4 | https://github.com/secureWKkim/web-crawling-on-container
5 |
6 |
7 | 실행 결과는 아래와 같습니다.
8 |
9 |
--------------------------------------------------------------------------------
/8th_members/김원경/1주차.md:
--------------------------------------------------------------------------------
1 | ## CPython 소스코드 다운로드 및 환경 구성 (화면 캡쳐)
2 | 
3 |
4 |
5 | ### 특이 사항
6 | 스터디 노션 환경 구성에 나온 정보대로
7 | git clone --branch 3.9 https://github.com/python/cpython
8 |
9 | 명령어만 사용하면 사이즈가 커서 RPC fail 에러 발생.
10 | 그래서 뒤에 "--depth 1" 을 추가로 붙여 얕은 클론만 해둔 상태.
11 | 필요한 경우 "git fetch --unshallow"로 다른 레포들도 갖고 와야 한다.
12 | *참고: https://eunjinii.tistory.com/128
13 |
14 |
15 |
16 | ## 스터디에서 이루고 싶은 목표, 함께 하게 된 소감 등
17 | 그동안 파이썬을 사용하면서 궁금했던 점들을 알아 가며 호기심을 해소할 수 있는 기회가 됐음 합니다!
--------------------------------------------------------------------------------
/8th_members/김원경/13주차.md:
--------------------------------------------------------------------------------
1 | # pdb 실행 해보기
2 |
3 |
4 |
5 | # CProfile 예제 파일 직접 생성해서 실행해보기
6 | 12주차 미션으로 제출한 python game.py 코드를 그대로 사용했습니다. 실행 결과는 아래와 같습니다.
7 |
8 |
--------------------------------------------------------------------------------
/8th_members/김진아/4주차.md:
--------------------------------------------------------------------------------
1 | # 4주차
2 |
3 | ## instaviz로 AST 시각화 해보기
4 | ```python
5 | def pow(x, y):
6 | result = 1
7 | for i in range(0, y):
8 | result *= x
9 | return result
10 |
11 | import instaviz
12 | instaviz.show(pow)
13 | ```
14 | 
15 |
16 | ## ‘거의 같음’ 연산자를 문법에 추가하고 AlE타입의 객체를 출력 해보기
17 |
18 |
--------------------------------------------------------------------------------
/8th_members/이용준/1주차.md:
--------------------------------------------------------------------------------
1 | # CPython 소스코드 다운로드 및 환경 구성 (화면 캡쳐)
2 |
3 | 
4 |
5 | # 스터디에서 이루고 싶은 목표, 함께 하게 된 소감 등
6 | - 목표
7 | - Python 동작 원리 맛보기
8 | - 스터디 참여자분들과 소통하며 다른 분들의 생각 본받기
9 | - 회사 일이 습격하더라도, 중간에 내용 이해가 어렵더라도 끝까지 완주하기
10 | - 소감
11 | - 개인적으로 진지한 스터디 참여(?)는 처음이고 Cpython을 공부해볼 수 있다니 기대가 됩니다. 하지만 내 실력에 너무 난이도 높은 주제를 선택한 게 아닐까 하는 두려움이 있습니다. 그리고 당장 도움이 안 될 것 같은 내용 가지고 씨름하며 동기부여를 잃어버릴까 걱정도 앞섭니다. 그래서 스터디원분들과 소통하며 서로의 학습과 동기부여의 도우미가 된다면 좋겠습니다.
--------------------------------------------------------------------------------
/8th_members/고동희/3주차.md:
--------------------------------------------------------------------------------
1 | # 3주차
2 |
3 | ## [1] CPython 인터프리터 실행 과정 코드 레벨로 이해하기
4 |
5 |
6 |
7 |
8 |
9 | ## [2] 파이썬 세션에서 runtime flag 확인하기
10 |
11 |
12 |
13 |
14 |
15 | ## [3] `importlib.util.find_spec` 함수를 사용해서 원하는 모듈의 위치를 찾아보기
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/8th_members/전희선/8주차.md:
--------------------------------------------------------------------------------
1 | - 라이브러리(requests) import 후 참조 카운트 변화 확인
2 | ```python
3 | >>> import sys
4 | >>> for i in range(1, 4):
5 | ... print(f"{i}: {sys.getrefcount(i)}")
6 | ...
7 | 1: 146
8 | 2: 110
9 | 3: 50
10 | >>> import requests
11 | >>> for i in range(1, 4):
12 | ... print(f"{i}: {sys.getrefcount(i)}")
13 | ...
14 | 1: 1063
15 | 2: 444
16 | 3: 244
17 | ```
18 |
19 |
--------------------------------------------------------------------------------
/8th_members/김원경/10주차.md:
--------------------------------------------------------------------------------
1 | # Port Scanner: Multi Threading 코드 실행해보기
2 | ## 싱글 프로세스 + 싱글 스레드
3 |
4 |
5 |
6 | ## 멀티 스레드
7 |
8 |
9 |
10 | ## 멀티스레딩 + 스레드 개수 제한
11 |
12 | 근소하게 개선됐다.
--------------------------------------------------------------------------------
/8th_members/하상천/3주차.md:
--------------------------------------------------------------------------------
1 |
2 | 1. CPython 인터프리터 실행 과정 코드 레벨로 이해하기
3 |
4 |
5 |
6 | 2. 파이썬 세션에서 runtime flag 확인하기
7 |
8 |
9 |
10 | 3. importlib.util.find_spec 함수를 사용해서 원하는 모듈의 위치를 찾아보기
11 |
12 |
13 |
--------------------------------------------------------------------------------
/8th_members/김진아/3주차.md:
--------------------------------------------------------------------------------
1 | # 3주차
2 |
3 | ## CPython 인터프리터 실행 과정 코드 레벨로 이해하기
4 |
5 |
6 | ## 파이썬 세션에서 runtime flag 확인하기
7 |
8 |
9 |
10 | ## importlib.util.find_spec 함수를 사용해서 원하는 모듈의 위치를 찾아보기
11 |
12 |
13 |
--------------------------------------------------------------------------------
/8th_members/이용우/5주차.md:
--------------------------------------------------------------------------------
1 | ### 요약
2 | 이번 챕터에서는 Parsing된 파이썬 모듈을
3 | 심볼 테이블과 컴파일러 상태로 변환하고
4 | 마지막으로 일련의 바이트코드 명령으로 변환하는 과정에 대해 알아보았다.
5 |
6 |
7 |
8 |
9 | 바이트코드 명령으로 변환된 모듈을 실행하는 것이
10 | CPython 인터프리터의 코어 평가 루프가 하는 역할이다.
11 |
12 |
13 |
14 | ### 5주차 미션
15 | 이번 장에서는 컴파일러, 바이트코드 명령, 어셈블러를 다뤘다.
16 | 여기서 06. 렉싱과 파싱에서 문법에 추가한 '거의 같음' 연산자를 지원하도록 CPython을 수정해보자.
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/8th_members/김필모/2주차.md:
--------------------------------------------------------------------------------
1 | ## 문법 다시 생성하기 (pass 키워드 변경해보기) 부분 원하는 키워드 다른걸로 바꿔보기 (결과 화면 캡쳐)
2 | ### 1. pass -> do_nothing
3 |
4 |
5 | ### 2. break -> stop
6 |
7 |
8 | ### lzma.h 을 찾을 수 없다는 에러
9 |
10 |
11 | - 맥 기준 brew install xz 하면 해결된다는데 저는 안되네요.. ㅠㅠ
12 |
--------------------------------------------------------------------------------
/book/docs/0_1_directory_structure.md:
--------------------------------------------------------------------------------
1 | # CPython 디렉터리 구조
2 | CPython 프로젝트의 디렉터리 구조입니다.
3 | ```yaml
4 | CPython-Guide
5 | ├── Doc # 문서 소스 파일
6 | ├── Grammar # 컴퓨터가 읽을 수 있는 언어 정의
7 | ├── Include # C 헤더 파일
8 | ├── Lib # 파이썬으로 작성된 표준 라이브러리 모듈
9 | ├── Mac # macOS를 위한 파일
10 | ├── Misc # 기타 파일
11 | ├── Modules # C로 작성된 표준 라이브러리 모듈
12 | ├── Objects # 코어 타입과 객체 모델
13 | ├── Parser # 파이썬 파서 소스 코드
14 | ├── PC # 이전 버전 윈도우를 위한 윈도우 빌드 지원 파일
15 | ├── PCbuild # 윈도우 빌드 지원 파일
16 | ├── Python # CPython 인터프리터 소스 코드
17 | ├── Tools # CPython을 빌드하거나 확장하는 데 유용한 독립 실행형 도구
18 | └── m4 # makefile 구성을 자동화하는 사용자화 스크립트
19 | ```
20 |
21 |
--------------------------------------------------------------------------------
/8th_members/이용우/13주차.md:
--------------------------------------------------------------------------------
1 | ### 1. pdb 실행
2 |
3 | |shortcut|설명|
4 | |---|---|
5 | |`l`|주변 소스코드를 출력하며 현재 라인이 화살표로 나옴|
6 | |`n`|다음 문장으로 이동|
7 | |`s`|Step Into|
8 | |`w`|함수의 call stack 출력|
9 | |`s`|현재 함수의 argument들을 출력|
10 |
11 |
12 |
13 |
12 |
13 | ``` python
14 | import tracemalloc
15 |
16 |
17 | tracemalloc.start()
18 | value = "1"
19 | string_value = [value for _ in range(1000)]
20 | float_value = [float(value) for _ in range(1000)]
21 | int_value = [int(value) for _ in range(1000)]
22 |
23 | # 스냅샷 시작
24 | snapshot1 = tracemalloc.take_snapshot()
25 | snapshot1 = snapshot1.filter_traces([tracemalloc.Filter(True, "**/stat_*.py")])
26 | stats = snapshot1.statistics("lineno")
27 |
28 | for stat in stats:
29 | print(stat)
30 | print(stat.traceback.format(), end='\n\n')
31 |
32 | # 스냅샷 종료
33 | tracemalloc.stop()
34 | ```
35 |
36 |
--------------------------------------------------------------------------------
/8th_members/김필모/13주차.md:
--------------------------------------------------------------------------------
1 | # pdb 실행 해보기
2 |
3 |
4 |
5 |
6 |
7 | # CProfile 예제 직접 실행해보기
8 |
9 | ```python3
10 | # example.py
11 |
12 | import cProfile
13 | import pstats
14 | import io
15 |
16 | def slow_function():
17 | total = 0
18 | for i in range(10000):
19 | for j in range(10000):
20 | total += i * j
21 | return total
22 |
23 | def fast_function():
24 | return sum(i * j for i in range(1000) for j in range(1000))
25 |
26 | def main():
27 | slow_function()
28 | fast_function()
29 |
30 | if __name__ == '__main__':
31 | pr = cProfile.Profile()
32 | pr.enable()
33 | main()
34 | pr.disable()
35 |
36 | s = io.StringIO()
37 | sortby = 'cumulative'
38 | ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
39 | ps.print_stats()
40 | print(s.getvalue())
41 |
42 | ```
43 |
44 |
--------------------------------------------------------------------------------
/8th_members/김필모/9주차.md:
--------------------------------------------------------------------------------
1 | ```python3
2 | import time
3 | from multiprocessing import Pool
4 |
5 | # Define the CPU-bound task
6 |
7 |
8 | def cpu_bound_task(n):
9 | result = 1
10 | for i in range(1, n + 1):
11 | result *= i
12 | return result
13 |
14 | # Single-process version
15 |
16 |
17 | def single_process(tasks):
18 | results = []
19 | for task in tasks:
20 | results.append(cpu_bound_task(task))
21 | return results
22 |
23 | # Multiprocessing version
24 |
25 |
26 | def multi_process(tasks):
27 | with Pool() as pool:
28 | results = pool.map(cpu_bound_task, tasks)
29 | return results
30 |
31 |
32 | if __name__ == "__main__":
33 | tasks = [100000 + i for i in range(20)] # Define tasks
34 |
35 | start = time.time()
36 | single_process(tasks)
37 | print("Single-process time:", time.time() - start)
38 |
39 | start = time.time()
40 | multi_process(tasks)
41 | print("Multiprocessing time:", time.time() - start)
42 | ```
43 |
44 |
45 |
--------------------------------------------------------------------------------
/8th_members/김필모/4주차.md:
--------------------------------------------------------------------------------
1 | - instaviz로 AST 시각화 해보기
2 |
3 | ```python3
4 | def scramble_word(word):
5 | word_list = list(word)
6 | random.shuffle(word_list)
7 | return ''.join(word_list)
8 | ```
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | - ‘거의 같음’ 연산자를 문법에 추가하고 ALE 타입의 객체를 출력 해보기
17 |
18 |
19 |
20 | ```shell
21 | make regen-token regen-pegen
22 | make regen-ast
23 | make -j2 -s
24 | ```
25 |
26 |
--------------------------------------------------------------------------------
/book/docs/10_0_parallel_and_concurrent.md:
--------------------------------------------------------------------------------
1 | # 10. 병렬성과 동시성
2 |
3 | ## 개요
4 |
5 | 모든 운영체제의 핵심 기능은 실행 중인 프로세스를 관리하는 것이다.
6 | 모든 프로세스는 메모리와 CPU 같은 자원을 요청할 수 있다.
7 |
8 | **프로세스는 작업 단위로 실행**되기 때문에 CPU에 자신이 사용할 시간을 요청한다.
9 | 이 요쳥을 받은 운영체제는 시간을 프로세스에 할당해주고 우선순위에 따라 스케줄링하며
10 | 어떤 프로세스가 CPU를 사용할지를 컨트롤한다.
11 |
12 | 
13 |
14 | 동시성은 멀티태스킹 구현에 알맞은 해결책이긴 하지만
15 | CPU를 나눠쓰기 때문에 한계가 있다.
16 |
17 | 
18 |
19 | 때문에 여러 개의 코어 또는 CPU를 사용해 작업을 분산하는 방식으로
20 | 멀티태스킹을 수행하는 방법도 OS가 제공해준다.
21 |
22 | 즉, 컴퓨터는 병렬성과 동시성을 활용해 멀티태스킹을 처리한다.
23 |
24 | - 병렬성 → CPU와 같은 연산 유닛들이 여러 개 필요
25 | - 동시성 → 유휴 상태의 프로세스가 하나의 자원을 계속해서 차지하지 않도록 스케줄링 필요
26 |
27 | ## 병렬성과 동시성 모델
28 |
29 | CPython은 병렬성과 동시성에 대해 다양한 접근 방식을 제공한다.
30 | 기본적으로 아래의 4가지 모델을 제공한다.
31 |
32 | | 접근 방식 | 모델명 | 동시 실행 | 병렬 실행 |
33 | | -------------- | --------------- | --------- | --------- |
34 | | 쓰레딩 | threading | O | X |
35 | | 멀티프로세싱 | multiprocessing | O | O |
36 | | 비동기 | asyncio | O | X |
37 | | 서브인터프리터 | subinterpreters | O | O |
38 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: deploy-book
2 |
3 | # Only run this when the master branch changes
4 | on:
5 | push:
6 | branches:
7 | - master
8 | # If your git repository has the Jupyter Book within some-subfolder next to
9 | # unrelated files, you can make this run only if a file within that specific
10 | # folder has been modified.
11 | #
12 | # paths:
13 | # - some-subfolder/**
14 |
15 | # This job installs dependencies, builds the book, and pushes it to `gh-pages`
16 | jobs:
17 | deploy-book:
18 | runs-on: ubuntu-latest
19 | steps:
20 | - uses: actions/checkout@v2
21 |
22 | # Install dependencies
23 | - name: Set up Python 3.8
24 | uses: actions/setup-python@v2
25 | with:
26 | python-version: 3.8
27 |
28 | - name: Install dependencies
29 | run: |
30 | pip install -r requirements.txt
31 |
32 | # Build the book
33 | - name: Build the book
34 | run: |
35 | jupyter-book build ./book
36 |
37 | # Push the book's HTML to github-pages
38 | - name: GitHub Pages action
39 | uses: peaceiris/actions-gh-pages@v3.6.1
40 | with:
41 | github_token: ${{ secrets.GITHUB_TOKEN }}
42 | publish_dir: ./book/_build/html
43 |
--------------------------------------------------------------------------------
/8th_members/이성범/10주차.md:
--------------------------------------------------------------------------------
1 | # 10주차
2 |
3 | ## Port Scanner: Multi Threading - 멀티스레딩 + 스레드 개수 제한
4 | ```python
5 | import time
6 | import socket
7 | from concurrent.futures import ThreadPoolExecutor, as_completed
8 |
9 | timeout = 1.0
10 |
11 | def check_port(host: str, port: int) -> int:
12 | with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
13 | sock.settimeout(timeout)
14 | result = sock.connect_ex((host, port))
15 | if result == 0:
16 | return port
17 | return None
18 |
19 | def main():
20 | start = time.time()
21 | host = "localhost" # Replace with a host you own
22 | open_ports = []
23 |
24 | with ThreadPoolExecutor(max_workers=10) as executor:
25 | futures = [executor.submit(check_port, host, port) for port in range(100, 200)]
26 |
27 | for future in as_completed(futures):
28 | port = future.result()
29 | if port is not None:
30 | open_ports.append(port)
31 |
32 | for port in open_ports:
33 | print(f"Port {port} is open")
34 | print(f"Completed scan in {time.time() - start:.2f} seconds")
35 |
36 | if __name__ == '__main__':
37 | main()
38 | ```
39 |
--------------------------------------------------------------------------------
/8th_members/김원경/6주차.md:
--------------------------------------------------------------------------------
1 | ## 1. 사용한 코드
2 | ```python
3 | import inspect
4 |
5 | def minBitFlips3(start: int, goal: int) -> int:
6 | flips, xor = 0, start ^ goal
7 | while xor != 0:
8 | flips += 1
9 | xor &= (xor - 1)
10 | print_frame_info()
11 | return flips
12 |
13 |
14 |
15 | def minBitFlips4(start: int, goal: int) -> int:
16 | x = start ^ goal
17 | count = 0
18 | while x:
19 | x = x & (x - 1)
20 | count += 1
21 | print_frame_info()
22 | return count
23 |
24 |
25 | def print_frame_info():
26 | frame = inspect.currentframe().f_back # 현재 함수의 호출자 프레임
27 | try:
28 | print("Function Name:", frame.f_code.co_name)
29 | print("File Name:", frame.f_code.co_filename)
30 | print("Line No:", frame.f_back.f_lineno)
31 | print("Local Variables:", list(frame.f_locals.keys()))
32 | print("Global Variables:", list(frame.f_globals.keys()))
33 | # dis.dis(frame.f_code) # 역 디스어셈블러
34 | print("\\n\\n")
35 | finally:
36 | del frame
37 |
38 |
39 | minBitFlips3(1, 10)
40 | minBitFlips4(1, 10)
41 | ```
42 |
43 |
44 | ## 2. 실행 결과
45 |
--------------------------------------------------------------------------------
/8th_members/이용우/10주차.md:
--------------------------------------------------------------------------------
1 | ### 멀티 쓰레드 요약
2 | 1. 각 쓰레드는 각자의 Program Counter와 Stack을 갖기 때문에
3 | 동시에 다른 작업을 처리할 수 있다.
4 | 2. **Thread Safety**를 위해서 CPython에서는 GIL을 사용한다.
5 | 3. GIL로 인해서 CPU-Bound 작업에서는 멀티 쓰레드의 이점을 얻지 못하지만,
6 | I/O-Bound 작업에서는 멀티 쓰레딩을 적극적으로 활용할 수 있다.
7 | 4. 이를 위해서 `Py_BEGIN_ALLOW_THREADS`와 `Py_END_ALLOW_THREADS`
8 | 매크로가 실제 구현에 사용된다. 내장 패키지 구석구석에서 해당 구현을 확인할 수 있다.
9 | 5. Thread는 프로세스와 메모리를 공유하기 때문에
10 | 프로세스를 새로 생성하는 것 보다는 오버헤드가 적다.
11 |
12 |
13 |
14 |
15 | #### 코루틴
16 | → 실행을 중단하고 재개할 수 있는 함수, 특정 시점에서 작업을 중단하고 다른 작업을 수행할 수 있다.
17 | → 호출자와 호출된 함수 사이의 제어 흐름이 상호작용
18 | → 비동기 프로그래밍에서 사용
19 |
20 |
21 |
22 | #### 네이티브 코루틴
23 | - 함수 앞에 `async` 키워드를 명시하여 코루틴을 반환함을 명시
24 | - `asyncio.run()`을 통해 코루틴 객체 생성
25 | - 실행 순서
26 | - 1) 새 이벤트 루프를 시작
27 | - 2) 코루틴 객체를 Task로 감싸기
28 | - 3) Task가 완료될 때 까지 실행할 CallBack을 설정
29 | - 4) Task가 완료될 때 까지 루프를 반복
30 | - 5) 결과 반환
31 |
32 | 장점
33 | - 여러 코루틴 동시 실행 가능
34 | - 코루틴 객체를 다른 함수의 인자로 사용 가능
35 | - 코루틴 객체를 서로 연결하여 연쇄적으로 처리하거나 순차적으로 생성 가능
36 |
37 | ※ 이벤트 루프
38 | - 비동기 코드를 연결하는 접착제 역할
39 |
40 |
41 |
42 |
43 | ### Port Scanner 예제 실행
44 |
45 | 좌: 멀티 쓰레드, 우: 멀티 쓰레드(쓰레드 수 제한)
46 |
47 |
--------------------------------------------------------------------------------
/8th_members/김필모/12주차.md:
--------------------------------------------------------------------------------
1 |
2 | # 나만의 Test Case 만들기
3 |
4 | ```python3
5 | def is_prime(n):
6 | """
7 | Check if a number is a prime number.
8 |
9 | Parameters:
10 | n (int): The number to check.
11 |
12 | Returns:
13 | bool: True if n is a prime number, False otherwise.
14 | """
15 | if n <= 1:
16 | return False
17 | if n <= 3:
18 | return True
19 | if n % 2 == 0 or n % 3 == 0:
20 | return False
21 | i = 5
22 | while i * i <= n:
23 | if n % i == 0 or n % (i + 2) == 0:
24 | return False
25 | i += 6
26 | return True
27 |
28 |
29 | # Example usage:
30 | if __name__ == "__main__":
31 | print(is_prime(29)) # Expected output: True
32 | print(is_prime(15)) # Expected output: False
33 | ```
34 |
35 |
36 | ```
37 | import unittest
38 |
39 | from src import example
40 |
41 |
42 | class TestIsPrime(unittest.TestCase):
43 | def test_is_prime(self):
44 | self.assertEqual(example.is_prime(2), True)
45 | self.assertEqual(example.is_prime(3), True)
46 | self.assertEqual(example.is_prime(4), False)
47 | self.assertEqual(example.is_prime(5), True)
48 | self.assertEqual(example.is_prime(7), True)
49 |
50 | ```
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/8th_members/김필모/7주차.md:
--------------------------------------------------------------------------------
1 |
2 | ## 코드
3 | ```python
4 | import tracemalloc
5 | import linecache
6 | import random
7 | import numpy as np
8 |
9 | def memory_intensive_function(size):
10 | data = [random.randint(1, 1000000) for _ in range(size)]
11 | sorted_data = sorted(data)
12 | mid_index = len(sorted_data) // 2
13 | return sorted_data[mid_index]
14 |
15 |
16 | def matrix_multiply(size):
17 | # size x size 크기의 무작위 행렬 두 개 생성
18 | matrix1 = np.random.rand(size, size)
19 | matrix2 = np.random.rand(size, size)
20 | # 두 행렬의 곱 계산
21 | product = np.dot(matrix1, matrix2)
22 | return product
23 |
24 |
25 | def main():
26 | tracemalloc.start()
27 | x = memory_intensive_function(100000)
28 | y = matrix_multiply(100)
29 | snapshot = tracemalloc.take_snapshot()
30 | snapshot = snapshot.filter_traces((
31 | tracemalloc.Filter(True, "**/tracedemo.py"),
32 | ))
33 | stats = snapshot.statistics("lineno")
34 |
35 | for stat in stats:
36 | frame = stat.traceback[0]
37 | print(stat)
38 | print(linecache.getline(frame.filename, frame.lineno).strip())
39 |
40 | tracemalloc.stop()
41 |
42 |
43 | if __name__ == "__main__":
44 | main()
45 | ```
46 |
47 |
48 | ## 결과 스크린샷
49 |
50 |
51 |
--------------------------------------------------------------------------------
/8th_members/김진아/13주차.md:
--------------------------------------------------------------------------------
1 | # 13주차
2 |
3 | ## pbd 실행해보기
4 |
5 | ```python
6 | def calculate_performance_improvement_rate(before, after):
7 | return (before - after) / after * 100
8 |
9 |
10 | if __name__ == "__main__":
11 | breakpoint()
12 |
13 | before_performance = 150
14 | after_performance = 57
15 |
16 | performance_improvement_rate = calculate_performance_improvement_rate(before_performance, after_performance)
17 |
18 | print(f"{performance_improvement_rate:.2f}%")
19 |
20 | ```
21 |
22 |
23 |
24 |
25 | ## CProfile 예제 파일 직접 생성해서 실행해보기
26 |
27 | ```python
28 | def calculate_performance_improvement_rate(before, after):
29 | return (before - after) / after * 100
30 |
31 |
32 | if __name__ == "__main__":
33 | before_performance = 150
34 | after_performance = 57
35 |
36 | performance_improvement_rate = calculate_performance_improvement_rate(before_performance, after_performance)
37 |
38 | print(f"{performance_improvement_rate:.2f}%")
39 | ```
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/8th_members/하상천/9주차.md:
--------------------------------------------------------------------------------
1 | ## 9주차 미션
2 |
3 | ### Queue 사용
4 |
5 |
6 |
7 | ### multiprocessing.Queue 사용
8 |
9 | ```python
10 | import multiprocessing as mp
11 | import socket
12 | import time
13 |
14 | timeout = 1.0
15 |
16 |
17 | def check_port(host: str, port: int, results: mp.Queue):
18 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
19 | sock.settimeout(timeout)
20 | result = sock.connect_ex((host, port))
21 | if result == 0:
22 | results.put(port)
23 | sock.close()
24 |
25 |
26 | if __name__ == '__main__':
27 | start = time.time()
28 | processes = []
29 | scan_range = range(80, 100)
30 | host = "localhost"
31 | mp.set_start_method('spawn')
32 | pool_manager = mp.Manager()
33 | with mp.Pool(len(scan_range)) as pool:
34 | outputs = pool_manager.Queue()
35 | for port in scan_range:
36 | processes.append(pool.apply_async(check_port, (host, port, outputs)))
37 | for process in processes:
38 | process.get()
39 | while not outputs.empty():
40 | print("Port {0} is open.".format(outputs.get()))
41 | print("Completed scan in {0} seconds".format(time.time() - start))
42 | ```
43 |
44 |
45 |
--------------------------------------------------------------------------------
/book/_config.yml:
--------------------------------------------------------------------------------
1 | #######################################################################################
2 | # Book settings
3 | title : PseudoLab [CPython 파헤치기]
4 | author: PseudoLab
5 | logo: 'PseudoLab_logo.png'
6 |
7 | # Short description about the book
8 | description: >-
9 | CPython Guide for PseudoLab studies
10 |
11 | #######################################################################################
12 | # Execution settings
13 | execute:
14 | execute_notebooks : off
15 |
16 | #######################################################################################
17 | # HTML-specific settings
18 | html:
19 | home_page_in_navbar : false
20 |
21 | # #######################################################################################
22 | # Interact link settings
23 | notebook_interface : "notebook"
24 |
25 | #######################################################################################
26 | # Launch button settings
27 | repository:
28 | url : https://github.com/pseudo-lab/CPython-Guide
29 | path_to_book : "book"
30 |
31 | latex:
32 | latex_engine : "xelatex"
33 | latex_documents:
34 | targetname: book.tex
35 |
36 | html:
37 | favicon: 'PseudoLab_logo.png'
38 | use_issues_button: true
39 | use_repository_button: true
40 |
41 | sphinx:
42 | config:
43 | html_js_files:
44 | - https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js
45 |
--------------------------------------------------------------------------------
/8th_members/전희선/9주차.md:
--------------------------------------------------------------------------------
1 | 간단한 CPU-Bound Job을 만들고 멀티프로세싱을 적용한 코드와 아닌 코드를 작성해보기
2 |
3 | ```python
4 | from math import sqrt
5 | import time
6 | import multiprocessing as mp
7 | import sys
8 |
9 | NUMBERS_LIMIT = 100000000
10 |
11 | def compute_sqrt(numbers):
12 | return [sqrt(n) for n in numbers]
13 |
14 | def multiprocessing_compute():
15 | numbers = range(1, NUMBERS_LIMIT)
16 | process_count = mp.cpu_count() # 사용 가능한 CPU 코어 수
17 | pool = mp.Pool(process_count)
18 |
19 | # 데이터 분할
20 | size = len(numbers) // process_count
21 | numbers_split = [numbers[i * size:(i + 1) * size] for i in range(process_count)]
22 |
23 | start_time = time.time()
24 | results = pool.map(compute_sqrt, numbers_split)
25 | end_time = time.time()
26 | pool.close()
27 | pool.join()
28 | print(f"Duration with multiprocessing: {end_time - start_time} seconds")
29 |
30 |
31 | def no_multiprocessing():
32 | numbers = range(1, NUMBERS_LIMIT)
33 | start_time = time.time()
34 | results = compute_sqrt(numbers)
35 | end_time = time.time()
36 | print(f"Duration without multiprocessing: {end_time - start_time} seconds")
37 |
38 |
39 | if __name__ == '__main__':
40 | option = sys.argv[1]
41 | if option == "multiprocessing":
42 | multiprocessing_compute()
43 | else:
44 | no_multiprocessing()
45 | ```
46 |
47 |
48 |
--------------------------------------------------------------------------------
/8th_members/김필모/6주차.md:
--------------------------------------------------------------------------------
1 | ```python3
2 | import inspect
3 | import re
4 |
5 |
6 | def print_frame_info():
7 | frame = inspect.currentframe().f_back # 현재 함수의 호출자 프레임
8 | try:
9 | print("Function Name:", frame.f_code.co_name)
10 | print("File Name:", frame.f_code.co_filename)
11 | print("Line No:", frame.f_back.f_lineno)
12 | print("Local Variables:", list(frame.f_locals.keys()))
13 | print("Global Variables:", list(frame.f_globals.keys()))
14 | # dis.dis(frame.f_code) # 역 디스어셈블러
15 | print("\\n\\n")
16 | finally:
17 | del frame
18 |
19 |
20 | def validate_email(email):
21 | pattern = r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"
22 | if re.match(pattern, email):
23 | print_frame_info()
24 |
25 | return True
26 | else:
27 | print_frame_info()
28 |
29 | return False
30 |
31 |
32 | def check_password_complexity(password):
33 | if (len(password) >= 8 and
34 | any(c.isupper() for c in password) and
35 | any(c.islower() for c in password) and
36 | any(c.isdigit() for c in password) and
37 | any(c in '!@#$%^&*()-_=+[]{}|;:",.<>?`~' for c in password)):
38 | print_frame_info()
39 | return True
40 | else:
41 | print_frame_info()
42 | return False
43 |
44 | validate_email("pilmokim99@gmail.com")
45 | check_password_complexity("1234")
46 | ```
47 |
48 |
--------------------------------------------------------------------------------
/8th_members/김원경/11주차.md:
--------------------------------------------------------------------------------
1 | # 원하는 Type 분석해보기: List 타입
2 | ### 1. data structure of python list
3 | 
4 | 
5 | ### Python list data structure
6 | 
7 | - PyListObject: python list의 C 구현체.
8 | - PyObject_VAR_HEAD: 인스턴스마다 길이가 변하는 객체를 선언할 때 사용되는 macro.
9 | - **ob_item: 이중 포인터 (리스트 원소들의 포인터 배열에 대한 포인터). 객체 주소들을 저장한다.
10 | - allocated: 리스트에 할당된 크기
11 | - **Py__Object: 모든 클래스들의 조상인 PyObject를 상속받은 뒤 __에 type명(ex: int, var, list, array etc.)을 붙여 각 타입에 대한 파이썬 클래스를 구현.
12 |
13 | 이에 의해 파생되는 특징들?
14 | #### 1) 동적 타입 지원
15 | 
16 | 한 연산 수행 중간중간에 type checking이 많아 정적 배열보다 동작 느림
17 |
18 | #### 2) 크기가 가변적(동적)
19 | 처음에 크기를 작게 잡아뒀다 꽉 차면 list_resize 메서드를 작동시켜 크기를 늘려준다. (용어: 더블링)
20 | → 해당 작업 발생 시 정적 배열보다 동작 속도 느려짐
21 |
22 | #### 3) 포인터를 이중으로 거침
23 | ob_items**의 특징에 의해 value를 바로 얻을 수 없어 속도 느림
24 |
25 | #### 4) 캐시의 메모리 지역성 문제
26 | 
27 | 
28 | 
29 | list의 0, 1번 객체 즉 PyObject를 가리키는 포인터 주소는 메모리 상에서 인접하지만 value는 인접하지 않음
30 | → nparray와 비교하면, 캐싱 시 메모리 지역성 문제로 cache hit rate가 더 낮음
31 |
--------------------------------------------------------------------------------
/8th_members/이용우/6주차.md:
--------------------------------------------------------------------------------
1 | ### 요약
2 |
3 | 코드 객체는 프레임 객체에 삽입된다.
4 | 파이썬 타입인 프레임 객체는 C와 파이썬 코드 양쪽에서 참조할 수 있다.
5 |
6 |
7 | 프레임 객체는 코드 객체의 명령을 실행하는 데 필요한 런타임 데이터를 포함한다.
8 | 런타임 데이터에는 지역, 전역 변수 및 내장 모듈 등이 포함된다.
9 |
10 |
11 |
12 |
13 |
14 | 코드 객체에서 PyEval_EvalCode → _PyFrame_New_NoTrack를 거쳐서
15 | 프레임 객체를 반환받게 된다. 그리고 프레임 객체는 다음과 같이 구성된다.
16 |
17 |
18 |
19 |
20 |
21 |
22 | ### TODO: 파이썬에서 프레임 객체 접근해보기
23 | 프레임 객체는 함수가 호출될 때마다 만들어집니다.
24 | 이를 파이썬의 inspect.currentframe() 메소드를 사용하여 접근할 수 있습니다.
25 |
26 | 다음은 현재 함수의 프레임 객체 상태를 확인할 수 있는 예제 코드이다.
27 |
28 |
29 |
30 | ``` python
31 | import dis
32 | import inspect
33 |
34 | global_variable01 = 'gvalue01'
35 |
36 | def print_frame_info():
37 | frame = inspect.currentframe().f_back # 현재 함수의 호출자 프레임
38 | try:
39 | print("Function Name:", frame.f_code.co_name)
40 | print("File Name:", frame.f_code.co_filename)
41 | print("Line No:", frame.f_back.f_lineno)
42 | print("Local Variables:", list(frame.f_locals.keys()))
43 | print("Global Variables:", list(frame.f_globals.keys()))
44 | # dis.dis(frame.f_code) # 역 디스어셈블러
45 | print("\n\n")
46 | finally:
47 | del frame
48 |
49 | def sample01():
50 | sample01_variable = 1
51 | print_frame_info()
52 |
53 | def sample02():
54 | sample02_variable = 2
55 | print_frame_info()
56 |
57 | sample01()
58 | sample02()
59 | ```
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/8th_members/전희선/10주차.md:
--------------------------------------------------------------------------------
1 | ### 멀티스레딩 + 스레드 개수 제한 통한 port scanner 실행
2 |
3 | - 실행 코드
4 | ```python
5 | import socket
6 | import time
7 | from concurrent.futures import ThreadPoolExecutor, as_completed
8 | from queue import Queue
9 | import sys
10 |
11 | timeout = 1.0
12 |
13 | def check_port(host: str, port: int) -> int:
14 | with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
15 | sock.settimeout(timeout)
16 | result = sock.connect_ex((host, port))
17 | if result == 0:
18 | return port
19 | return None
20 |
21 | def main():
22 | MAX_WORKERS = int(sys.argv[1]) # worker 수 입력으로 받아 다르게 테스트
23 |
24 | start = time.time()
25 | host = "localhost" # Replace with a host you own
26 | open_ports = []
27 |
28 | with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
29 | futures = [executor.submit(check_port, host, port) for port in range(10000, 65536)] # port 범위 확장
30 |
31 | for future in as_completed(futures):
32 | port = future.result()
33 | if port is not None:
34 | open_ports.append(port)
35 |
36 | for port in open_ports:
37 | print(f"Port {port} is open")
38 | print(f"Completed scan in {time.time() - start:.2f} seconds")
39 |
40 | if __name__ == '__main__':
41 | main()
42 | ```
43 | - 결과: worker 수를 30으로 했을 때 가장 적게 걸리는 점을 통해, 멀티스레딩도 오버헤드가 존재하며 (멀티프로세스에 비해 상대적으로 적을 뿐) worker 개수가 많다고 항상 좋은 것은 아니라는 점을 확인할 수 있었습니다 :)
44 |
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CPython-Guide jupyter-book 작업 가이드
2 |
3 | jupyter-book github page 접속 주소: https://pseudo-lab.github.io/CPython-Guide
4 |
5 | 1. 저장소를 fork 합니다.
6 |
7 | ```
8 | Pseudo-Lab/CPython-Guide
9 | ```
10 |
11 | 2. 저장소 및 python 패키지를 받습니다.
12 |
13 | ```bash
14 | git clone https://github.com/[작업자의 Github아이디]/CPython-Guide.git
15 | cd [CPython-Guide 폴더] # 윈도우즈 command line의 /d 옵션도 같이
16 | pip install -r requirements.txt # jupyter-book 패키지 설치, ghp-import는 꼭 설치안해도됨. (git action용)
17 | ```
18 |
19 | 3. 담당 페이지 작업을 진행합니다.
20 | 그 후 빌드를 돌린 후 _build/html/index.html을 열어서 결과를 확인합니다.
21 |
22 | ```bash
23 | # 작업 root 경로 (working directory)가 CPython-Guide 최상위 경로인 경우.
24 | jupyter-book build ./book
25 | ```
26 |
27 | 4. 정상적으로 완료되었다면 pull request를 날립니다.
28 |
29 | ```bash
30 | # TODO: pull request 하는 방법 첨부 예정.
31 | ```
32 |
33 | 5. pull request 승인 후 push가 완료되면 자동으로 사이트가 빌드됩니다.
34 |
35 |
36 |
37 | # jupyter-book 작업 구조
38 | ```yaml
39 | CPython-Guide
40 | ├── .github # git action workflow가 있습니다.
41 | ├── book # 문서 메인 폴더 입니다.
42 | │ ├── docs # 문서가 모여있는 폴더입니다.
43 | │ ├── images # 문서에 들어가는 이미지 폴더입니다.
44 | │ ├── _config.yml # github page config 입니다.
45 | │ ├── _toc.yml # 문서 레이아웃 구성 파일 입니다.
46 | │ ├── intro.md # 문서의 시작 페이지 파일 입니다.
47 | ├── README.md
48 | ├── requirements.txt
49 | └── .gitignore
50 | ```
51 | 문서는 book/docs 폴더에 추가하고 작성합니다.
52 | _toc.yml에 문서를 등록해야 페이지에 보입니다.
53 |
54 | # 파일명 규칙
55 | 1. docs: 챕터번호_섹션번호_문서제목
56 | (0_0_dev_env_setup.md, 0_1_directory_structure.md, 챕터 최상단은 0번 섹션으로 처리)
57 | 2. images: 챕터폴더/사진순서(두자리)_사진내용
58 | (0_dev_env_setup/00_vscode_plugin.png, 0_dev_env_setup/01_tasks_explorer_result.png)
59 |
60 |
61 | # 로컬에서 빌드한 페이지가 조금 이상할 때
62 | _build 폴더를 삭제 후 다시 빌드합니다. 이전 빌드 결과물에 대한 잔여물이 남는 케이스입니다.
--------------------------------------------------------------------------------
/8th_members/이용우/4주차.md:
--------------------------------------------------------------------------------
1 | # 4주차
2 | ### 목차
3 | 1. [Lexer](#lexer)
4 | 2. [중요한 용어들](#중요한-용어들)
5 | 3. [미션](#미션)
6 | - [instaviz로 AST 시각화 해보기](#instaviz로-ast-시각화-해보기)
7 | - ["거의 같음" 연산자를 문법에 추가하고 AlE 타입의 객체를 출력해보기](#거의-같음-연산자를-문법에-추가하고-ale타입의-객체를-출력-해보기)
8 |
9 |
10 |
11 |
12 |
13 | ### Lexer
14 | Lexer는 Tokenizer로 쪼개진 토큰들의 의미를 분석하는 역할을 한다.
15 | Tokenizer를 거치며 의미있는 단위로 쪼개지고,
16 | Lexer를 거치며 그 의미를 분석하는 과정을 통틀어서 Lexical Analyze라고 한다.
17 |
18 | > 예를 들어 return 명령어를 분석해보자.
19 | > - return이라는 단어에서 r, e, t, u, r, n은 각각 따로 놓고 보면 아무 의미도 가지지 않는다.
20 | > - Tokenizer를 거치며 return이 의미 있는 단어가 된다. (Tokenizing)
21 | > - Lexer를 거치며 이 토큰은 무언가를 반환하는 명령어임을 인지하게 된다.
22 | >
23 | > 위 과정을 거치며 생성된 오브젝트 {type: 명령어, value: "return", child: []}가 Parser에 전달된다.
24 |
25 |
26 |
27 | - Tokenizer : 구문에서 의미 있는 요소들을 토큰으로 쪼깸
28 | - Lexer : 토큰의 의미를 분석
29 | - Parser : Lexical analyze된 후의 리턴값인 CST를 AST로 바꿔줌
30 |
31 |
32 |
33 |
34 | ### 중요한 용어들
35 |
36 | | 용어 | 설명 |
37 | |----------| -------------------------------------------------|
38 | |AST | 파이썬 문법과 문장들에 대한 문맥(Context) 있는 트리 표현 |
39 | |CST | 토큰과 심볼에 대한 문맥(Context)이 없는 트리 표현 |
40 | |Parse Tree | CST의 다른 이름 |
41 | |Token | 심볼의 종류 중 하나 |
42 | |Tokenizing | 텍스트를 토큰들로 변환하는 과정 |
43 | |Parsing | 텍스트를 CST나 AST로 변환하는 과정 |
44 |
45 |
54 |
55 | #### ‘거의 같음’ 연산자를 문법에 추가하고 AlE타입의 객체를 출력 해보기
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/8th_members/전희선/3주차.md:
--------------------------------------------------------------------------------
1 | 1. CPython 인터프리터 실행 과정 코드 레벨로 이해하기
2 |
3 |
4 |
5 |
6 |
7 |
8 | 2. 파이썬 세션에서 runtime flag 확인하기
9 | - 플래그 미사용
10 |
11 | - `-X dev` 플래그 사용 (`dev_mode=True`)
12 |
13 | - `-X dev -X utf8` 플래그 사용 (`dev_mode=True, utf8_mode=1`)
14 |
15 | - `-X dev -q` 플래그 사용 (`dev_mode=True, quiet=1` + python version 미출력)
16 |
17 | 3. importlib.util.find_spec 함수를 사용해서 원하는 모듈의 위치를 찾아보기
18 |
19 |
--------------------------------------------------------------------------------
/book/docs/0_0_dev_env_setup.md:
--------------------------------------------------------------------------------
1 | # CPython 개발 환경 세팅
2 | CPython-Guide는 CPython 파헤치기 책과 동일한 python3.9 버전을 기반으로 진행됩니다.
3 |
4 | ## CPython git 저장소 받기
5 | ```bash
6 | git clone --branch 3.9 https://github.com/python/cpython.git
7 | ```
8 | 저장소를 받은 후 Visual Studio Code로 해당 폴더를 열어줍니다.
9 |
10 | ## Visual Studio Code 개발 환경 세팅
11 | 
12 | 위 플러그인들을 설치합니다.
13 |
14 | ## task.json 작성
15 | ```json
16 | {
17 | "version": "2.0.0",
18 | "tasks": [
19 | {
20 | "label": "build",
21 | "type": "shell",
22 | "group": {
23 | "kind": "build",
24 | "isDefault": true
25 | },
26 | "windows": {
27 | "command": "PCBuild/build.bat",
28 | "args": ["-p", "x64", "-c", "Debug"]
29 | },
30 | "linux": {
31 | "command": "make -j2 -s"
32 | },
33 | "osx": {
34 | "command": "make -j2 -s"
35 | }
36 | }
37 | ]
38 | }
39 | ```
40 | .vscode/task.json 파일을 생성하고 위 내용을 작성합니다.
41 |
42 | 
43 | task.json 작성을 완료하면 TASK EXPLORER의 vscode 하위에 작성한 build task가 추가된 것을 볼 수 있습니다.
44 |
45 | ## launch.json 작성
46 | ```json
47 | {
48 | "version": "0.2.0",
49 | "configurations": [
50 | {
51 | "name": "msvc cl.exe debug cpython",
52 | "type": "cppvsdbg",
53 | "request": "launch",
54 | "program": "PCBuild/amd64/python_d.exe",
55 | "args": [],
56 | "stopAtEntry": false,
57 | "cwd": "${workspaceFolder}",
58 | "environment": [],
59 | "externalConsole": true,
60 | "preLaunchTask": "build"
61 | }
62 | ]
63 | }
64 | ```
65 | .vscode/launch.json 파일을 생성하고 위 내용을 작성합니다.
66 |
67 | 이제 F5를 누르면 CPython 빌드 진행 및 디버깅을 할 수 있습니다.
68 | CPython의 진입점이 되는 Programs/python.c의 9번 라인에 디버그 브레이크를 걸고 실행해봅니다.
69 | 
70 | 위와 같이 디버깅 잡힌 것을 볼 수 있습니다.
71 |
72 | 개발환경 세팅은 여기까지입니다.
73 |
74 |
--------------------------------------------------------------------------------
/8th_members/김진아/12주차.md:
--------------------------------------------------------------------------------
1 | # 12주차
2 |
3 | ## 나만의 Test Case 만들기
4 |
5 | ### 구조
6 |
7 | ```
8 | .
9 | ├── tests
10 | │ └── test_normalize.py
11 | └── text_processing.py
12 | ```
13 |
14 | ### `text_processing.py`
15 |
16 | ```python
17 | def normalize(input_str):
18 | out = input_str.lower()
19 | out = out.strip()
20 | while ' ' in out:
21 | out = out.replace(' ', ' ')
22 | return out
23 | ```
24 |
25 | ### `test_normalize.py`
26 |
27 | ```python
28 | import unittest
29 | from text_processing import normalize
30 |
31 |
32 | class TestTextNormalize(unittest.TestCase):
33 | def test_normalize(self):
34 | test_str = "This is an example."
35 | pred = normalize(test_str)
36 | self.assertEqual(pred, "this is an example.")
37 |
38 | test_str = " EXTRA SPACE "
39 | pred = normalize(test_str)
40 | self.assertEqual(pred, "extra space")
41 |
42 | test_str = "THIS IS ALL CAPS!!"
43 | pred = normalize(test_str)
44 | self.assertEqual(pred, "this is all caps!!")
45 |
46 | test_str = " "
47 | pred = normalize(test_str)
48 | self.assertEqual(pred, "")
49 |
50 | test_str = "this is all lower space..."
51 | pred = normalize(test_str)
52 | self.assertEqual(pred, "this is all lower space...")
53 |
54 | test_str = " H e L l O !"
55 | pred = normalize(test_str)
56 | self.assertEqual(pred, "h e l l o !")
57 |
58 | test_str = ""
59 | pred = normalize(test_str)
60 | self.assertEqual(pred, "")
61 |
62 | test_str = "........"
63 | pred = normalize(test_str)
64 | self.assertEqual(pred, "........")
65 |
66 | test_str = "EX A M P LE"
67 | pred = normalize(test_str)
68 | self.assertEqual(pred, "ex a m p le")
69 |
70 | test_str = "AbCd EfGh IjKl MnOp"
71 | pred = normalize(test_str)
72 | self.assertEqual(pred, "abcd efgh ijkl mnop")
73 | ```
74 |
75 | ### 결과
76 |
77 |
78 |
--------------------------------------------------------------------------------
/8th_members/이용우/1주차.md:
--------------------------------------------------------------------------------
1 | # 1주차
2 | ### 목차
3 | 1. [CPython 소스코드 다운로드 및 환경 구성](#cpython-소스코드-다운로드-및-환경-구성)
4 | 1-1. [VSCode 코드 구성하기](#vscode-코드-구성하기)
5 | 1-2. [작업과 실행 파일 설정](#작업과-실행-파일-설정)
6 | 1-3. [환경 구성 켑처](#환경-구성-결과)
7 | 2. [스터디에서 이루고 싶은 목표 & 함께 하게 된 소감](#스터디에서-이루고-싶은-목표--함께-하게-된-소감)
8 |
9 |
10 |
11 | ## CPython 소스코드 다운로드 및 환경 구성
12 | ### VSCode 코드 구성하기
13 | VSCode는 온라인 플러그인 마켓 플레이스를 제공하는 확장 가능한 코드 편집기이다.
14 | 통합 git 인터페이스를 제공하며, C와 파이썬 모두를 지원하기 때문에 CPython을 위한 좋은 선택이 될 수 있다.
15 |
16 | Extensions 패널에 접근하여 `ms-vscode.cpptools`와 같은 고유 식별자로 확장을 검색할 수 있다.
17 | C/C++ for Visual Studio Code를 클릭하여 다운로드하도록 하자.
18 |
19 |
20 | 또한 권장되는 확장은 아래와 같다.
21 | |Extension|Description|
22 | |--|--|
23 | |C/C++ (`ms-vscode.cpptools`)|인텔리센스, 디버깅, 코드 강조 등의 C/C++ 지원을 제공|
24 | |Python (`ms-python.python`)|파이썬 코드 편집, 디버깅, 탐색 등의 파이썬 지원을 제공|
25 | |reStructuredText (`lextudio.restructuredtext`)|CPython 문서에 사용되는 reStructuredtext에 대한 지원을 제공|
26 | |Task Explorer (`spmeesseman.vscode-taskexplorer`)|make 작업을 편리하게 실행할 수 있는 Task Explorer 패널을 Explorer 탭 안에 추가|
27 |
28 |
29 |
30 |
31 | ### 작업과 실행 파일 설정
32 | VSCode는 작업 디렉터리 내부의 `.vscode` 폴더를 작업 공간 설정에 사용한다.
33 | 폴더가 없으면 새로 만들고 다음 파일들을 추가해서 작업 공간을 설정할 수 있다.
34 |
35 | - 프로젝트 실행 명령에 대한 `tasks.json`
36 | - 디버거를 위한 `launch.json`
37 | - 기타 플러그인을 위한 파일
38 |
39 | `tasks.json` 파일에 작업을 등록할 수 있다.
40 |
41 | ```json
42 | {
43 | "version": "2.0.0",
44 | "tasks": [
45 | {
46 | "label": "build",
47 | "type": "shell",
48 | "group": {
49 | "kind": "build",
50 | "isDefault": true
51 | },
52 | "windows": {
53 | "command": "PCBuild/build.bat",
54 | "args": ["-p", "x64", "-c", "Debug"]
55 | },
56 | "linux": {
57 | "command": "make -j2 -s"
58 | },
59 | "osx": {
60 | "command": "make -j2 -s"
61 | }
62 | }
63 | ]
64 | }
65 | ```
66 |
67 |
68 |
69 | ### 환경 구성 결과
70 |
71 |
72 |
73 |
74 |
75 |
76 | ## 스터디에서 이루고 싶은 목표 & 함께 하게 된 소감
77 | 이번 스터디를 통해 Python 언어를 더 깊이 있게 이해하고,
78 | 이 스터디를 마친 후에는 Python을 원하는 기능 및 스펙에 맞게
79 | 입맛대로 커스텀 할 수 있는 엔지니어로 성장하기 위한 초석을 다지고 싶습니다.
80 |
81 | 이번 CPython 스터디에 참여하여 관심사가 비슷한 분들과 함께 할 수 있게 되어 기쁘게 생각하고 있습니다.
82 | 모든 분들이 이번 스터디를 통해 각자 성취, 혹은 원하는 바를 이룰 수 있었으면 좋겠습니다.
83 | 앞으로 스터디 기간 동안 잘 부탁드립니다. 감사합니다🙂
--------------------------------------------------------------------------------
/8th_members/이용우/9주차.md:
--------------------------------------------------------------------------------
1 | ### 멀티 프로세싱 요약
2 | **장점**
3 | `multiprocessing`은 확장 가능한 파이썬용 병렬 실행 API를 제공한다.
4 | 프로세스 간 데이터 공유가 가능하며, CPU 집약적인 작업을 병렬로 쪼개서
5 | 멀티코어 또는 멀티 CPU 컴퓨터의 장점을 활용할 수도 있다.
6 |
7 | **단점**
8 | 단, I/O 집약적인 작업의 경우에는 멀티 프로세싱이 적합하지 않다.
9 | 예를 들어 Worker 프로세스 4개를 Spawn 하고 같은 파일을 읽고 쓰는 경우,
10 | 한 프로세스가 작업하는 동안 나머지 프로세스 3개는 Lock 해제될 때 까지 기다려야 한다.
11 |
12 | 멀티프로세싱은 새로운 파이썬 인터프리터를 시작하는 데 필요한 시간과 처리 오버헤드로 인해
13 | 시간 소요가 얼마 되지 않는 작업에는 적합하지 않다.
14 |
15 |
16 |
17 | → I/O 작업과 시간 소요가 얼마되지 않는 작업에 대해서는 멀티 쓰레딩 방식이 더 적합하다.
18 |
19 |
20 |
21 |
22 | ### CPU Bound, Unbound 예제 실행
23 | #### CPU Bound
24 |
25 | ``` python
26 | import time
27 | from typing import List
28 |
29 | def compute_squares(numbers: List[int]) -> List[int]:
30 | return [x**2 for x in numbers]
31 |
32 |
33 | def no_multiprocessing():
34 | numbers = range(1, 10000000)
35 | start_time = time.time()
36 | results = compute_squares(numbers)
37 | end_time = time.time()
38 |
39 | print(f"Duration without multiprocessing: {end_time - start_time} seconds")
40 |
41 | if __name__ == '__main__':
42 | no_multiprocessing()
43 | ```
44 |
45 |
46 |
47 |
48 |
49 |
50 | #### CPU Unbound
51 |
52 | ``` python
53 | import time
54 | import multiprocessing as mp
55 | from typing import List
56 |
57 | def compute_squares(numbers: List[int]) -> List[int]:
58 | return [x**2 for x in numbers]
59 |
60 |
61 | def multiprocessing_compute():
62 | numbers = range(1, 10000000)
63 | process_cnt = mp.cpu_count()
64 | print(f"cpu count: {process_cnt}")
65 |
66 | pool = mp.Pool(process_cnt)
67 |
68 | # 데이터 분할
69 | size = len(numbers) // process_cnt
70 | numbers_split = [
71 | numbers[i * size:(i + 1) * size]
72 | for i in range(process_cnt)
73 | ]
74 |
75 | start_time = time.time()
76 | results = pool.map(compute_squares, numbers_split)
77 | end_time = time.time()
78 |
79 | pool.close()
80 | pool.join()
81 | print(f"Duration with multiprocessing: {end_time - start_time} seconds")
82 |
83 |
84 | if __name__ == '__main__':
85 | multiprocessing_compute()
86 | ```
87 |
88 |
--------------------------------------------------------------------------------
/8th_members/전희선/12주차.md:
--------------------------------------------------------------------------------
1 | ```
2 | ✗ tree tests
3 | tests
4 | ├── __init__.py
5 | ├── test_normalize.py
6 | └── text_processing.py
7 | ```
8 | - text_processing.py
9 | ```python
10 | def normalize(input_str):
11 | """
12 | 인풋으로 받는 스트링에서 아래의 규칙으로 정규화된 스트링을 반환하는 함수입니다.
13 | * 모든 단어들은 소문자로 변환됨
14 | * 띄어쓰기는 한칸으로 되도록 함
15 | * 앞뒤 필요없는 띄어쓰기는 제거함
16 | Parameters:
17 | input_str (string): 영어로 된 대문자, 소문자, 띄어쓰기, 문장부호, 숫자로 이루어진 string
18 | ex - " EXTRA SPACE "
19 | Returns:
20 | normalized_string (string): 정규회된 string
21 | ex - 'extra space'
22 | Examples:
23 | >>> import text_processing as tp
24 | >>> example = " EXTRA SPACE "
25 | >>> tp.normalize(example)
26 | 'extra space'
27 | """
28 | out = input_str.lower()
29 | out = out.strip()
30 | while ' ' in out:
31 | out = out.replace(' ', ' ')
32 | return out
33 | ```
34 | - test_normalize.py
35 | ```python
36 | import unittest
37 | from text_processing import normalize
38 |
39 |
40 | class TestTextNormalize(unittest.TestCase):
41 | def test_normalize(self):
42 | test_str = "This is an example."
43 | pred = normalize(test_str)
44 | self.assertEqual(pred, "this is an example.")
45 |
46 | def test_extra_space(self):
47 | test_str = " EXTRA SPACE "
48 | pred = normalize(test_str)
49 | self.assertEqual(pred, "extra space")
50 |
51 | def test_uppercase(self):
52 | test_str = "THIS IS ALL UPPERCASE!!"
53 | pred = normalize(test_str)
54 | self.assertEqual(pred, "this is all uppercase!!")
55 |
56 | def test_lowercase(self):
57 | test_str = "this is all lowercase..."
58 | pred = normalize(test_str)
59 | self.assertEqual(pred, "this is all lowercase...")
60 |
61 | def test_whitespace(self):
62 | test_str = " "
63 | pred = normalize(test_str)
64 | self.assertEqual(pred, "")
65 | ```
66 | ### Result
67 |
68 |
--------------------------------------------------------------------------------
/8th_members/이성범/12주차.md:
--------------------------------------------------------------------------------
1 | # 12주차
2 |
3 | ## unittest 사용해보기
4 | ```python
5 | import unittest
6 |
7 | def normalize(input_str):
8 | """
9 | 인풋으로 받는 스트링에서 아래의 규칙으로 정규화된 스트링을 반환하는 함수입니다.
10 | * 모든 단어들은 소문자로 변환됨
11 | * 띄어쓰기는 한칸으로 되도록 함
12 | * 앞뒤 필요없는 띄어쓰기는 제거함
13 | Parameters:
14 | input_str (string): 영어로 된 대문자, 소문자, 띄어쓰기, 문장부호, 숫자로 이루어진 string
15 | ex - " EXTRA SPACE "
16 | Returns:
17 | normalized_string (string): 정규회된 string
18 | ex - 'extra space'
19 | Examples:
20 | >>> import text_processing as tp
21 | >>> example = " EXTRA SPACE "
22 | >>> tp.normalize(example)
23 | 'extra space'
24 | """
25 | out = input_str.lower()
26 | out = out.strip()
27 | while ' ' in out:
28 | out = out.replace(' ', ' ')
29 | return out
30 |
31 | class TestTextNormalize(unittest.TestCase):
32 | def test_normalize(self):
33 | test_str = "This is an example."
34 | pred = normalize(test_str)
35 | self.assertEqual(pred, "this is an example.")
36 |
37 | test_str = " EXTRA SPACE "
38 | pred = normalize(test_str)
39 | self.assertEqual(pred, "extra space")
40 |
41 | test_str = "THIS IS ALL CAPS!!"
42 | pred = normalize(test_str)
43 | self.assertEqual(pred, "this is all caps!!")
44 |
45 | test_str = " "
46 | pred = normalize(test_str)
47 | self.assertEqual(pred, "")
48 |
49 | test_str = "this is all lower space..."
50 | pred = normalize(test_str)
51 | self.assertEqual(pred, "this is all lower space...")
52 |
53 | test_str = " H e L l O !"
54 | pred = normalize(test_str)
55 | self.assertEqual(pred, "h e l l o !")
56 |
57 | test_str = ""
58 | pred = normalize(test_str)
59 | self.assertEqual(pred, "")
60 |
61 | test_str = "........"
62 | pred = normalize(test_str)
63 | self.assertEqual(pred, "........")
64 |
65 | test_str = "EX A M P LE"
66 | pred = normalize(test_str)
67 | self.assertEqual(pred, "ex a m p le")
68 |
69 | test_str = "AbCd EfGh IjKl MnOp"
70 | pred = normalize(test_str)
71 | self.assertEqual(pred, "abcd efgh ijkl mnop")
72 | ```
73 |
--------------------------------------------------------------------------------
/8th_members/이용우/2주차.md:
--------------------------------------------------------------------------------
1 | # 2주차
2 | ### 목차
3 | 1. [macOS에서 CPython 컴파일하기](#macos에서-cpython-컴파일하기)
4 | 2. [문법 다시 생성하기 (pass 키워드 변경해보기) 부분 원하는 키워드 다른걸로 바꿔보기 (결과 화면 캡쳐)](#문법-다시-생성하기-pass-키워드-변경해보기-부분-원하는-키워드-다른걸로-바꿔보기-결과-화면-캡쳐)
5 |
6 |
7 |
8 | ### macOS에서 CPython 컴파일하기
9 | macOS에서 CPython을 컴파일하려면 어플리케이션과 라이브러리가 추가로 필요하다.
10 | 그 중 Command Line Tools는 필수적인 C 컴파일러 툴킷으로
11 | 터미널로 설치하고 앱스토어에서 업데이트 할 수 있다.
12 |
13 | 다음 명령을 실행해 C 컴파일러 툴킷을 설치하면
14 | git, make, GNU C 컴파일러 등의 도구들이 설치된다.
15 |
16 | ```
17 | $ xcode-select --install
18 | ```
19 |
20 |
21 |
22 |
23 |
24 | PyPI에서 패키지를 받아 설치하려면 OpenSSL도 필요하다.
25 | HomeBrew로 macOS에 간단하게 OpenSSL을 설치할 수 있다.
26 |
27 | brew install 명령으로 CPython에 필요한 의존성을 설치하자.
28 |
29 | ```
30 | $ brew install openssl xz zlib gdbm sqlite
31 | ```
32 |
33 |
34 |
35 | zlib이 설치된 위치를 지정하고 구성 작업을 실행하자.
36 | 이 작업은 한 번만 실행하면 된다.
37 |
38 | ```
39 | # cd ~/your/cpython/path
40 |
41 | $ CPPFLAGS="-I$(brew --prefix zlib)/include" \
42 | LDFLAGS="-L$(brew --prefix zlib)/lib" \
43 | ./configure --with-openssl=$(brew --prefix openssl) \
44 | --with-pydebug
45 | ```
46 |
47 |
48 |
49 | ./configure가 저장소 최상단에 위치한 Makefile이 빌드 과정을 자동화한다.
50 | 다음 명령어로 CPython 바이너리를 빌드하자.
51 |
52 | ```
53 | $ make -j2 -s
54 | ```
55 |
56 |
57 |
58 | ### 문법 다시 생성하기 (pass 키워드 변경해보기) 부분 원하는 키워드 다른걸로 바꿔보기 (결과 화면 캡쳐)
59 | CPython3.9 부터 도입된 새로운 PEG 생성기인 pegen을 테스트해 보기 위해 문법 일부를 변경해보자.
60 | Grammar → python.gram에서 간단한 정의인 small_stmt를 찾아 수정해보자.
61 | ※ small_stmt: 단일 독립 실행 가능한 구성요소
62 |
63 | ```
64 | small_stmt[stmt_ty] (memo):
65 | | assignment
66 | | e=star_expressions { _Py_Expr(e, EXTRA) }
67 | | &'return' return_stmt
68 | | &('import' | 'from') import_stmt
69 | | &'raise' raise_stmt
70 | | 'pass' { _Py_Pass(EXTRA) }
71 | | &'del' del_stmt
72 | | &'yield' yield_stmt
73 | | &'assert' assert_stmt
74 | | ('break' | 'heartbreaker') { _Py_Break(EXTRA) }
75 | | 'continue' { _Py_Continue(EXTRA) }
76 | | &'global' global_stmt
77 | | &'nonlocal' nonlocal_stmt
78 | ```
79 |
80 |
81 |
82 | CPython의 자동 문법 재생성 스크립트를 사용해 문법 파일을 다시 빌드하자.
83 | ```
84 | $ make regen-pegen
85 | ```
86 |
87 |
88 |
89 | CPython을 새 파서 테이블과 같이 컴파일하면 새 문법이 추가된다.
90 | 이전 장에서 소개한 운영 체제 별 컴파일 방법을 그대로 실행하면 된다.
91 |
92 | ```
93 | $ make -j2 -s
94 | ```
95 |
96 |
204 |
205 | 실행 결과는 아래와 같습니다.
206 |
--------------------------------------------------------------------------------
/8th_members/이용우/3주차.md:
--------------------------------------------------------------------------------
1 | # 3주차
2 | ### 목차
3 | 1. [구성 상태](#구성-상태)
4 | - [딕셔너리 초기화 구성](#딕셔너리-초기화-구성)
5 | - [연관된 소스 파일 목록](#연관된-소스-파일-목록)
6 | - [런타임 구성 구조체](#런타임-구성-구조체)
7 | - [명령줄로 런타임 구성 설정하기](#명령줄로-런타임-구성-설정하기)
8 | 2. [빌드 구성](#빌드-구성)
9 | 3. [입력에서 모듈 만들기](#입력에서-모듈-만들기)
10 | - [연관된 소스 파일 목록](#연관된-소스-파일-목록)
11 | 4. [3주차 미션](#3주차-미션)
12 | - [CPython 인터프리터 실행 과정 코드 레벨로 이해하기](#cpython-인터프리터-실행-과정-코드-레벨로-이해하기)
13 | - [파이썬 세션에서 Runtime Flag 확인하기](#파이썬-세션에서-runtime-flag-확인하기)
14 | - [importlib.util.find_spec 함수를 사용해서 원하는 모듈의 위치를 찾아보기](#importlibutilfind_spec-함수를-사용해서-원하는-모듈의-위치를-찾아보기)
15 |
16 |
17 |
18 |
19 | ### 구성 상태
20 | CPython 런타임은 사용자 옵션과 구성(Configuration)을 설정한다.
21 | 특히 **Configuration**은 세 부분으로 나뉘어 있다.
22 |
23 | - `PyPreConfig` 딕셔너리 초기화 Configuration
24 | - `PyConfig` 런타임 Configuration
25 | - CPython 인터프리터에 같이 컴파일된 Configuration
26 |
27 | 여기서 `PyPreconfig`, `PyConfig` 구조체는
28 | `Include/cpython/initconfig.h`에서 정의한다.
29 |
30 |
31 |
32 | #### 딕셔너리 초기화 구성
33 | **딕셔너리 초기화 Configuration**은 사용자 환경 또는 운영체제와 관련된 Configuration이기에
34 | 런타임 Configuration과는 구분된다.
35 |
36 | 다음은 `PyPreConfig`의 세 가지 주요 기능이다.
37 | 1. 파이썬 메모리 할당자 설정하기
38 | 2. `LC_CTYPE` 로켈(locale)을 시스템 또는 사용자 선호 로켈로 구성
39 | 3. UTF-8 모드로 설정
40 |
41 | > Locale : 특정 지역, 국가, 또는 문화권에서 사용하는 언어 등과 같은 지역설정을 의미함. (ex. `ko-KR`)
42 |
43 |
44 | `PyPreConfig` 구조체는 다음과 같은 `int` 타입 필드들을 포함한다.
45 |
46 | | 필드 | 설명 |
47 | | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
48 | | `allocator` | `PYMEM_ALLOCATOR_MALLOC`와 같은 값을 사용해서 메모리 할당자를 선택한다. `./configure --help`를 실행해 메모리 할당자에 대한 추가 정보를 얻을 수 있다. |
49 | | `configure_locate` | `LC_CTYPE` 로켈을 사용자 선호 로캘로 설정한다. `0`으로 설정하면 `coerce_c_locale`과 `coerce_c_locale_warn`을 `0`으로 설정한다. |
50 | | `coerce_c_locale` | `2`로 설정하면 C 로켈을 강제로 적용한다. `1`로 설정하면 `LC_CTYPE`을 읽은 후 강제로 적용할지 결정한다. |
51 | | `coerce_c_locale_warn` | `0`이 아니면 C 로켈이 강제로 적용될 때 경고가 발생한다. |
52 | | `dev_mode` | 개발 모드를 활성화한다. |
53 | | `isolated` | 격리 모드를 활성화한다. `sys.path`에 스크립트 디렉터리와 사용자의 사이트 패키지 디렉터리가 포함되지 않는다. |
54 | | `legacy_windows_fs_encoding` | `0`이 아니면 UTF-8 모드를 비활성화하고 파이썬 파일 시스템 인코딩을 `mbcs`로 설정한다. |
55 | | `parse_argv` | `0`이 아니면 명령줄 인자를 사용한다. |
56 | | `use_environment` | `0`보다 큰 값이면 환경 변수를 사용한다. |
57 | | `utf8_mode` | `0`이 아니면 UTF-8 모드를 활성화한다. |
58 |
59 |
60 |
61 | `Include/cpython/initconfig.h`에서 `PyPreConfig` 구조체를 찾아볼 수 있다.
62 |
63 |
64 |
65 | #### 연관된 소스 파일 목록
66 | 다음은 `PyPreConfig`와 연관된 소스 파일 목록이다.
67 |
68 | | 파일 | 용도 |
69 | | ---------------------- | ------------------------------------------------------- |
70 | |`Python/initconfig.c` | 시스템 환경에서 불러온 구성을 명령줄 플래그와 결합한다. |
71 | |`Include/cpython/initconfig.h` | 초기화 구성 구조체를 정의한다. |
72 |
73 |
74 |
75 | #### 런타임 구성 구조체
76 | `PyConfig`이라 불리는 런타임 Configuration 구조체는 다음과 같은 값들을 포함한다.
77 | - '디버그'나 '최적화'와 같은 실행 모드 플래그
78 | - 스크립트 파일이나 `stdin`, 모듈 등 실행 모드
79 | - `-X