레이블이 Python인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Python인 게시물을 표시합니다. 모든 게시물 표시

pip install gcc error

# pip 설치 중 다음과 같은 에러가 발생했다.
pip install cryptography
... 
/opt/homebrew/bin/gcc-13 -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O3 -Wall -I/opt/homebrew/opt/zlib -I/opt/homebrew/opt/zlib -DFFI_BUILDING=1 -DUSE__THREAD -DHAVE_SYNC_SYNCHRONIZE -I/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/usr/include/ffi -I/Users/ysoftman/.pyenv/versions/3.12.0/include/python3.12 -c src/c/_cffi_backend.c -o build/temp.macosx-14.1-arm64-cpython-312/src/c/_cffi_backend.o -iwithsysroot/usr/include/ffi
...
gcc-13: error: unrecognized command-line option '-iwithsysroot/usr/include/ffi'

# 컴파일러를 clang 으로 변경하면 된다.
CC=clang pip install cryptography

# 참고로 python 환경을 보니 CC 가 gcc 로 설정되어 있었다.
# 예전 pyenv 로 python 설치시 clang 에 문제가 있어 gcc 로 변경해서 설치했던게 문제였다.
python -m sysconfig | rg 'CC = '
40:     CC = "/opt/homebrew/bin/gcc-13"
647:    LINKCC = "/opt/homebrew/bin/gcc-13"

old version ansible

# ansible playbook 이 jenkins job 에서 다음과 같은 에러가 발생했다.
Unsupported parameters for (dnf) module: sslverify Supported parameters include: 

# sslverify 는 ansible 2.13 에 추가되었다.
# 그런데 현재 사용하는 버전은 2.14 로 문제가 없어야 한다.
ansible --version
ansible [core 2.14.2]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/ysoftman/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.11/site-packages/ansible
  ansible collection location = /home/ysoftman/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.11.2 (main, Oct  5 2023, 16:06:03) [GCC 8.5.0 20210514 (Red Hat 8.5.0-18)] (/usr/bin/python3.11)
  jinja version = 3.1.2
  libyaml = True

# 확인 결과 jenkins job 의 script 에서 아래와 같이 python 3.8 버전을 우선하게 설정이 되어 있었고
# python-3.8 /bin 에 ansible 바이너리가 있었다.
export PATH="/home/ysoftman/Python-3.8.17/bin:${PATH}"
export PYTHON_PATH="/home/ysoftman/Python-3.8.17"

# 그래서 Python-3.8.17/bin/ansible-playbook 2.9 버전을 사용하게 되는게 문제였다.
ansible-playbook --version
ansible-playbook 2.9.22
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/ysoftman/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/ysoftman/Python-3.8.17/lib/python3.8/site-packages/ansible
  executable location = /home/ysoftman/Python-3.8.17/bin/ansible-playbook
  python version = 3.8.17 (default, Nov  2 2023, 17:16:07) [GCC 8.5.0 20210514 (Red Hat 8.5.0-18)]

# 정리
# 로컬에서는 최신 ansible 버전 기준으로 playbook을 작성했는데
# 배포시에는 python, ansible 을 고정된 버전으로 사용하고 있었음.

make python package

# python 패키지를 만들때 다음과 같이 하면 dist/xxx.tar.gz(os 따른 포맷)압축파일이 생성된다.
# 소스 배포판 패키지 만들기
python setup.py sdist

# 설치를 위해 압축 풀기
cd dist
tar zxvf xxx.tar.gz
cd xxx

# 설치
python setup.py install

# 또는 pip 로 현재 경로를 설치경로로 사용해서 설치
pip install -e .


##########


# egg -> wheel 로 대체돼 더이상 사용하지 않는다 !!!
# dist/xxx.egg(압축파일)로 패키지 만들도 압축 파일상태에서 설치할 수 도 있다.
# egg 패키지 생성
python setup.py bdist_egg

# 설치
cd dist
python -m easy_install xxx.egg


##########


# wheel (2013년 등장, egg 파일을 대체)
# 소스 배포판으로 만들면 설치를 위해 압축을 풀면 소스가 보인다.
# 압축을 풀때 소스대신 wheel(.whl) 파일로만 보이게 할 수 있다.
# 물론 설치하면 설치된 경로에는 소스파일이 있다.

# wheel 과 setuptools 패키지를 설치해야 한다.
pip install wheel setuptools

# wheel 패키지로 만들기
python setup.py bdist_wheel

# 설치
cd dist
pip install xxx.whl

python subprocess arg escape

# subprcoess shell=True 로 명령을 실행할때
# 경로 인자로 single quote(')등이 있을때 \'와 같이 별도 이스케이프 하지 않아야 한다.
# 하지만 ' " 동시에 있는경우 이스케이스 \ 자체도 이스케이프 필요
def exec_Command(command, shellopt):
    # shell 인자(기본값은 False)는 셸을 실행할 프로그램으로 사용할지를 지정합니다. shell이 True이면, args를 시퀀스가 아닌 문자열로 전달하는 것이 좋습니다.
    # POSIX에서 shell=True일 때, 셸의 기본값은 /bin/sh입니다. args가 문자열이면, 문자열은 셸을 통해 실행할 명령을 지정합니다. 이것은 문자열이 프롬프트에서 입력할 때와 똑같이 포맷되어야 한다는 것을 의미합니다. 예를 들어, 스페이스가 포함된 파일명을 인용하거나 역 슬래시 이스케이핑 하는 것을 포함합니다. args가 시퀀스이면, 첫 번째 항목이 명령 문자열을 지정하고, 추가 항목은 셸 자체에 대한 추가 인자로 처리됩니다. 즉, Popen은 다음과 동등한 것을 수행합니다:
    output = subprocess.Popen(
        command, shell=shellopt, stdout=subprocess.PIPE, stderr=subprocess.PIPE
    )
    stdout, stderr = output.communicate()
    print("[stdout]\n", stdout)
    print("[stderr]\n", stderr)

# ' " 동시에 있는경우 이스케이스 \ 자체도 이스케이프 필요
# bash -c "touch zzz\'s\ \\\"a.txt"
exec_Command(f"touch zzz\\'s\ \\\"a.txt", True)

# 테스트코드

python profiling tool py-spy

# py-spy 를 사용하면 파이썬 실행을 쉽게 프로파일링 해준다.

# python 실행이 끝아면 프로파일링 결과(.svg)가 브라우저로 열린다.
sudo py-spy record -o profile.svg -- python ysoftman.py

# top 은 function 의 처리시간 비율을 실시간으로 보여준다.
sudo py-spy top -- python ysoftman.py

python package dependency

# pip freeze 는 설치된 패키지를 나열하지만
pip freeze 

# 패키지들간의 의존성을 파악하려면 pipdeptree 를 사용하면 된다.
# python package dependency tree 설치 
pip install pipdeptree

# 패키지 의존성 파악
pipdeptree

# 실제 설치된 버전만 보는 경우
pipdeptree --freeze

# json 으로 표시
pipdeptree --json

# 특정 패키지(-p)의 의존성(-r) 보는 경우
pipdeptree -p setuptools -r

# 최상위 패키지만 보려면
pipdeptree | rg '^w+'

boto3 s3 업로드 후 파일 안보이는 문제

# python boto3 라이브러리를 이용해 s3 파일 업로드를 했는데
# 디렉토리는 생성됐지만 s3 파일이 존재하지 않는다.
# 확인해 보니 / 로 시작하는 path(key) 때문이었다.

...  생략 ...

path = f"/test/{filename}"
# / 로 시작하면 업로드 후 파일이 없는것으로 표시된다.
path = path.lstrip("/")

# upload to s3
client.upload_file(
    Filename=filename,
    Bucket=AWS_BUCKET,
    Key=path,
    Callback=lambda bytes_transferred: pbar.update(bytes_transferred),
)

# 테스트 코드 

python 패키지 이름 모를때 삭제하기

# /usr/local/bin/aaa 파이썬 프로그램을 실행할 수 있는데,
# pip 로 aaa 를 삭제하려고 하면 설치되지 않았다고 나온다.
pip uninstall aaa
WARNING: Skipping aaa as it is not installed.

# aaa 패키지를 정보를 보면 찾을 수 없다고 나온다.
pip show aaa
WARNING: Package(s) not found: aaa

# 원인은 실행파일 이름과 실제 패키지명이 달라서다.
# 삭제를 위해선 실제 패키지명을 알아야 하는데 pip 로 파악할 수 없었다.

# [패키지 설치 경로 찾아서 삭제하기]
# 우선 다음 스크립트를 실행해 python 패키지 모듈 경로를 파악한다.
cat << zzz | python | sed -e 's/\[//g' -e 's/\]//g' -e 's/,/\n/g'
import sys
print(sys.path)
zzz

# 보통 /usr/local/lib/python3.9/site-packages/ 같은 곳에서 
# aaa (실행파일명)으로 시작하는 파일을 찾아본다.
fd "^aaa" /usr/local/lib/python3.9/site-packages/
/usr/local/lib/python3.9/site-packages/aaa
/usr/local/lib/python3.9/site-packages/aaa-bbb
... 생략

# aaa-bbb 가 실제 패키지 이름인것을 유추해볼수 있다.
# aaa-bbb 소스 내에서 aaa 를 사용하는지 확인해본다.
# 이제 pip 로 삭제본다.
pip uninstall aaa-bbb

webdav chunked size

# python upload/download 시 tqdm 으로 progressbar 표시한다.
# download 는 resp=requests.get(... stream=True) 와 resp.iter_content 로 스트림으로 받는 있는 데이터 사이즈를 파악할 수 있다.
# upload 는 async 와 async with aiohttp.ClientSession() 를 사용해 표시한다.
# tqdm 참고
# 그런데 upload(aiohttp > seesion > put) 시 http://httpbin.org/put 는 동작되는데
# webdav(http의 확장으로 COPY, MOVE, MKCOL(mkdir), PROPFIND(조회) 등 파일관리 메소드들 제공) 서버(https://github.com/mar10/wsgidav)에서는
# 다음 코드에서 진행되지 않고 CPU 100%를 사용하는 문제가 발생했다.
# 이 상태에서 요청을 계속 하면 서버 행 상태가 된다.
buf = environ["wsgi.input"].readline()

# 관련해서 비슷한 이슈가 오래전에 있어 수정이 되었다.
# chunk 사이즈 명시를 누락하는것 rfc2616(https://datatracker.ietf.org/doc/html/rfc2616#section-3.6.1) 명세를 위한반것으로 예외케이스를 추가한것으로 보인다.

# 클라이언트에서 X_EXPECTED_ENTITY_LENGTH 로 전체보낼 크기를 명시하고
# User-Agent 를 Darwin 으로 명시한다.
headers = {}
# headers["X_EXPECTED_ENTITY_LENGTH"] = repr(os.fstat(fileobj.fileno()).st_size) # fileobject case
headers["X_EXPECTED_ENTITY_LENGTH"] = repr(os.path.getsize(filename))
headers["User-Agent"] = "Darwin"

# 이제 put 을 하면 webdav 의 _stream_data_chunked > Darwin 조건에 다음과 같이 버크 크기를 알수 있어 진행된다.
buf = environ.get("HTTP_X_EXPECTED_ENTITY_LENGTH", "0")

# aiohttp 는 기본 Agent 가 다음과 같았고,
Python/3.9 aiohttp/3.7.4.post0

# 별도 chunk 크기를 명시하는 것이 없다. 
# 암튼 mar10 의 wsgidav chunk put 처리에는 예외 케이스가 있어
# 위처럼 클라이언트를 수정하던 wsgidav 서버 조건을 수정해야 한다.

# 참고로 User-Agent 없이 X_EXPECTED_ENTITY_LENGTH 만 설정하면 좋을것 같아서 문의함

# 이것땜에 한참 고생함ㅠㅠ, 힘들게 원인 파악한 기념으로 개비스콘 짤 생성~ㅋ

fastapi 422 error

# fastapi(web framework for building APIs with Python 3.6+) 서버에 요청시 422 에러 발생 해결하기

# 다음과 같은 요청시
curl 'http://localhost:8000/path/lemon/ysoftman' \
  -H 'Origin: http://localhost:8000' \
  -H 'X-User-Token: abc123' \
  --data-raw '{"name":"ysoftman","desc":"test","spec":{"val1":100,"val2":"asdf"}}'

# 응답으로 422(Unprocessable Entity)가 발생하며 다음과 같은 응답 메시지를 받는 경우가 있다.
{"detail":[{"loc":["query","data"],"msg":"field required","type":"value_error.missing"}]}%

# fastapi route 함수에서 파라메터 타입이 잘못된거나 빠지면 발생한다.
# BaseModel 을 이용해 파라메터 타입을 명시하면 된다.
class SpecObject(BaseModel):
    val1: int
    val2: str

class YsoftmanData(BaseModel):
    name: str
    desc: str
    spec: SpecObject

@router.post("/path/{val1}/ysoftman")
def post_ysoftman(val1: str, data: YsoftmanData, x_user_token: str = Header(default=None)):

# 참고

python unused import

# python 작업시 오타등으로 의도하지 않은 패키지가 자동 import 되는 경우가 있다.
# 존재하지 않거나 사용하지 않는 패키지가 import 된 경우 찾기

# autoflake 사용
# pip3 install autoflake
# --remove-all-unused-imports 사용 안하는 import 부분 화면 출력
# --in-place 를 사용하면 화면 출력 대신 파일에 바로 적용
fd .py ./aaa | xargs autoflake --remove-all-unused-imports --in-place 

# pylint 사용
# pip3 install pylint
# W0611 (unused-import)
fd .py ./aaa | xargs pylint --disable="all" --enable="W0611"

# 추가로 vscode pylint 설정시
"python.linting.pylintEnabled": true,
"python.linting.pylintArgs": [
  "--disable=all",
  "--enable=W0611",
],

vscode python no definition found

# vscode python 사용시 로컬 특정 경로의 패키지를 찾지 못해
# 모듈, 함수등에 'go to definition'(F12) 수행시 다음과 같이 찾을 수 없다고 나온다.

No Definition found for 'xxxxx'

# File > Save Workspace As... 로 워크스페이스 파일을 다음과 같이 생성하자. 
# ysoftman.code-workspace 내용
{
"folders": [
{
"path": "."
},
],
"settings": {
"python.envFile": "${workspaceFolder}/local.env",
}
}

# 그리고 local.env 파일에 생성하고 PYTHONPATH 에 찾지 못하는 패키지 경로를 설정한다.
PYTHONPATH=../my_custom_pkg1:../my_custom_pkg2:

# 이제 workspace file 로 열면 go to definition 이 동작한다.
code ./ysoftman.code-workspace

# 참고

pip config comment

# git+http 로 pip 패키지 설치시 dependencies 단계에서 진행이 되지 않는다.
pip install git+https://github.com/psf/black
Looking in indexes: https://pypi.org/simple, http://사설(extra-index-url),

... 생략 ...
  Installing build dependencies ... 

# 원인은 pip.conf 사설 extra-index-url 설정 때문이었다.
# pip install requests 와 같이 git+https 가 아닌 경우 
# --isolated (사용자 환경변수나 구성 무시)옵션을 사용하면 설치된다.
# pip install requests --isolated

# 해결방법1
# extra-index-url 주석처리하면 설치된다.
# 주석처리는 # 로 할 수 있다.
# pip config 파일 수정
pip config edit

# 해결방법2(삭제해도 되는 경우)
pip config unset global.extra-index-url

# 참고로 pip install 시 extra-index-url 은 추가만 되고 삭제나 무시돼는 옵션이 없다.
# 관련해서 이슈화되었지만 진행은 안되고 있다.

# 기타 config 관련 정보
# config 설정 리스트
pip config list

# config 파일 수정
pip config edit

# global > user > site 우선순위로 설정된다. 

ansible docker sdk for python 에러

# 다음과 같이 ansible 로 docker 처리를 하는 경우 
- name: ysoftman docker build
  docker_image:
    path: "/home/ysoftman/testdocker"
    name: "/ysofmtan/testdocker"
    tag: "test"
    state: build
    force: yes

# python 용 docker sdk 를 찾을 수 없다는 에러가 발생한다.
MSG:

Failed to import the required Python library (Docker SDK for Python: docker (Python >= 2.7) or docker-py (Python 2.6)) on xxxxx's Python /usr/bin/python. Please read module documentation and install in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter, for example via `pip install docker` or `pip install docker-py` (Python 2.6). The error was: No module named parse

# python 2.7.5 이라
ansible --version | command grep python
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  python version = 2.7.5 (default, Nov 16 2020, 22:23:17) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]

# docker 패키지를 설치했다.
sudo pip install docker

# 설치 확인
pip list | grep docker
10:docker (5.0.0)

# 설치해도 똑같은 에러가 발생한다.
# 혹시나 해서 docker-py 를 설치하면
sudo pip install docker-py

# 2개를(docker, docker-py)를 설치하면 안된다는 에러가 발생한다.
Cannot have both the docker-py and docker python modules (old and new version of Docker SDK for Python) installed together as they use the same namespace and cause a corrupt installation. Please uninstall both packages, and re-install only the docker-py or docker python module (for xxxxx's Python /usr/bin/python). It is recommended to install the docker module if no support for Python 2.6 is required. Please note that simply uninstalling one of the modules can leave the other module in a broken state.

# 둘다 지워 보자.
sudo pip uninstall docker docker-py

# 역시 위 첫번째 에러가 발생한다.
# 혹시나 해서 docker-py 만 설치해봤다.
sudo pip install docker-py

# 설치 확인
pip list | grep docker
10:docker-py (1.10.6)

# 에러가 발생 안한다. 뭐지? python 2.7 은 docker 패키지를 설치,
# python 2.6 은 docker-py 를 설치해야만 되는줄 알았는데,흠.

centos 최신 repo 반영하기

# docker등 CentOS 기본 버전에서는 최신 패키지 내용이 반영되어 있지 않다.
# CentOS:7 도커 이미지를 기반에서 nodejs(npm 사용하기 위해) 패키지를 설치할때
yum install -y nodejs

# 다음과 같이 사용 불가능한 패키지로 표시된다.
No package nodejs available

# 이 경우 https://ius.io/ 에서 제공하는 최신 패키지 리스트를 사용하면 된다.
# RHEL(Red Hat Enterprise Linux) 나 CentOS 에 최신 패키지 리스트 적용
# /etc/yum.repos.d/ius.repo 등이 생성된다.
yum install -y https://centos7.iuscommunity.org/ius-release.rpm

# ius 를 추가하면 centos 7 에서 yum 으로 python3 설치할 수 있다.
yum install -y python36u python36u-libs python36u-devel python36u-setuptools

matplotlib on wsl

# wsl(windows subsystem for linux) 에서 matplotlib 사용시
# 다음과 같이 그래프를 출력하는데
import matplotlib.pyplot as plt
plt.show()

# 다음과 같은 에러가 발생한다.
UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.

# 해결방법
# python3-tk 설치
sudo apt-get install python3-tk

# DISPLAY 환경변수 설정(.bashrc 에 추가하자)
export DISPLAY=localhost:0.0

# 윈도우용 xserver 설치 후
# xlaunch 앱 실행 -> multiple windows 선택 실행한다.
https://sourceforge.net/projects/vcxsrv/

# 이제 다시 실행하면 그래프 창을 볼 수 있다.

ansible jinja template list 유니코드 에러

# 문제
# ansible jinja template 파일에서 다음과 같이 리스트를 사용하는 경우
# default/main.yml
ysoftman_servers:
  service:
    - ysoftman1:9001
    - ysoftman2:9001

# templates/ysoftman.yml.j2
hosts : {{ ysoftman_servers[env] }}

# ansible 수행하면 다음과 같이 u(유니코드)문자가 붙어 설정 에러가 발생한다.
hosts: [u'ysoftman1:9001', u'ysoftman2:9001']

# 원인
# ansible 버전을 확인해 보면 python2 를 사용하고 있다.
# python2 에서는 유니코드를 표현하기 위해 u'글자' 형식으로 표현되는게 문제다.
ansible --version
ansible 2.8.5
  ... 생략 ...
  python version = 2.7.10 .. 생략

# 해결방법
# python3 기반의 ansible 을 새롭게 설치하자.
pip3 install ansible

# 또는 brew 삭제하고 재설지 설치
# 최근 brew 는 python3 이 기본이 되어 그냥 python 으로 표기된다.
# python2 는 python@2 로 표기해야 한다.
brew uninstall ansible
brew install ansible

# ansible with python3 으로 실행하면 u(유니코드) 표기를 사용하지 않는다.
ansible 2.8.5
  python version = 3.7.4

# 만약 python2 를 쓸수 밖에 없는 상황이라면 다음처럼 u를 제거할 수도 있다.
hosts: ["{{ ysoftman_servers[env].stdout_lines | list | join("\", \"") }}"]

good bye, python2

# pip 사용중에 다음과 같은 메시지가 나온다.
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.

# 찾아보니 python 2 은퇴 카운트다운 사이트가 있다.
# 2020년 새해부터는 python2 지원이 중단된다.
https://pythonclock.org/


# 대부분 python2.x 를 많이 사용중이라 문제가 많이 발생할것 같지만
# 패키지 대부분이 2,3 두버전을 모두 지원하고 있으니 크게 걱정하지 않아도 될것 같다.
# 암튼 갠적으로 매번 python2,3 스위칭하느라 짜증났는데 확실히 3으로 정리되서 차라리 좋다.

# python2 코드를 python3 로 변경해주는 2to3 툴도 있다.
https://docs.python.org/ko/3/library/2to3.html

# 2to3 설치
pip3 install 2to3

# python2 -> python3 로 변환
# -w 옵션을 주면 대상 파일에 3번으로 기록되고, 원본은 .bak 파일로 백업된다.
2to3 -w ysoftman.py

# 2to3 로 변경안되는 내용
# python3 에서는 기본 인코딩이 utf-8이라서
# sys.setdefaultencoding('utf-8') 는 삭제해주면 된다.
# 그외 utf-8 인코딩해주는 코드도 삭제해야 한다.

간단한 http server 프로그램

# 테스트를 위해 http 요청을 처리할 수 있는 간단한 http server 프로그램들
# node.js 기반 http-server
# 설치
npm install http-server -g

# 현재 디렉토리의 파일을 서빙하는 http server 실행
# http://127.0.0.1:8080 로 접속
http-server ./

# python 기반 simple-http
# 현재 디렉토리의 파일을 서빙하는 http server 실행
# http://127.0.0.1:9999 로 접속
python -m SimpleHTTPServer 9999

# python3 에선 http.server 를 사용한다.
python3 -m http.server 9999

ycmd server SHUT DOWN 에러 해결하기

# youcompleteme(ycm) 플러그인을 설치 후 vim 시작시 다음과 같은 에러가 발생한다.
# 참고로 ycm 은 클라이언트이고 third_party/ycmd 에 서버 소스가 있다.
The ycmd server SHUT DOWN (restart with ':YcmRestartServer')

# 다음과 같이 인스톨을 다시 해줘야 한다.
cd ~/.vim/plugged/youcompleteme
git submodule update --init --recursive
./install.py --all --verbose

# 만약 ./install.py 수행시 c++11 지원 안된다는 에러가 발생하는 경우
CMake Error at CMakeLists.txt:247 (message):
  Your C++ compiler does NOT fully support C++11.

# gcc 는 있지만 g++ 이 설치되어 있지 않아서다.
# 다음과 같이 g++ 를 설치 후 ./install.py
sudo yum install gcc-c++

# 만약 다음과 같은 에러가 발생하는 경우
fatal error: pyconfig.h:

# python-devel 을 설치 후 ./install.py
sudo yum install python-devel

#####

# M1(arm64) 맥북 환경에서 다음과 같이 빌드시 clang 에러가 발생했다.
./install.py --all --verbose

# 원인은 pyenv 로 설치한 python3.12(~/.pyenv/shims/python)가
# 설치시 다음과 같이 gcc 로 빌드해서였다.
CC=/opt/homebrew/bin/gcc-13 pyenv install -v 3.12

# clang 으로 다시 빌드해 설치 후
pyenv install -v 3.12

# ycmd 를 다시 빌드하면 된다.
./install.py --all --verbose