Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (seongtaejeong at gmail.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)

파이썬 - Windows embeddable package 환경에서 외부 패키지 사용하는 방법(ex: UFO² 환경 구성)

개인적으로 설치 버전보다 압축을 풀어 사용하는 Windows embeddable package를 선호합니다.

파이썬 - "Windows embeddable package"로 개발 환경 구성하는 방법
; https://www.sysnet.pe.kr/2/0/12861

그런데, 좀 숨겨 놓은 기능들이 많군요. ^^; 파이썬 초짜인 티가 이런 데서 나오는 것 같은데, ^^ 어떤 시행착오를 거쳤는지 정리해 보았습니다.




예를 들어, Windows embeddable package의 zip 파일을 다음의 경로에 압축을 푼 다음,

C:\python310

지난 글에서 다룬 UFO² 프로젝트를 clone 및 requirements.txt 구성과 yaml 설정을 다음의 디렉터리에 완료했다고 가정해 보겠습니다.

D:\temp\UFO

이 상태에서 ufo 디렉터리를 기준으로 작업을 실행해 보면 이런 에러가 발생합니다.

D:\temp\UFO> C:\python310\python -m ufo --task my_test
C:\python310\python.exe: No module named ufo

이에 대한 문제는 이미 지난 글에 설명했듯이, 현재 UFO 패키지가 설치된 디렉터리를 _pth 파일에 추가하는 것으로 해결할 수 있습니다.

D:\temp\UFO> type C:\python310\python310._pth
python310.zip
.
Lib\site-packages
D:\temp\UFO

# Uncomment to run site.main() automatically
# import site

그런데, 여전히 실행하면 오류가 발생하는데요,

D:\temp\UFO> C:\python310\python -m ufo --task my_test
Traceback (most recent call last):
  File "runpy.py", line 196, in _run_module_as_main
  File "runpy.py", line 86, in _run_code
  File "D:\temp\UFO\ufo\__main__.py", line 3, in <module>
    from ufo import ufo
  File "D:\temp\UFO\ufo\ufo.py", line 8, in <module>
    from ufo.module.client import UFOClientManager
  File "D:\temp\UFO\ufo\module\client.py", line 7, in <module>
    from ufo.module.basic import BaseSession
  File "D:\temp\UFO\ufo\module\basic.py", line 24, in <module>
    from pywinauto.controls.uiawrapper import UIAWrapper
  File "C:\python310\Lib\site-packages\pywinauto\__init__.py", line 59, in <module>
    import win32api  # noqa: E402
ModuleNotFoundError: No module named 'win32api'

단지 이번엔 오류가 바뀌긴 했지만, 상황 자체는 더욱더 이해가 되질 않습니다. 오류 메시지를 잘 보면, _pth 파일의 변경으로 인해 일단 UFO 프로젝트를 clone한 디렉터리를 기준으로 __main__.py까지는 진입도 잘 했고, 다시 "Windows embeddable package"를 기준으로 .\Lib\site-packages 디렉터리 내에 있는 pywinauto까지 로드가 잘 됐습니다.

그런데, pywinauto에서 참조한 또 다른 .\Lib\site-packages 하위에 있는 win32api 모듈은 로드하지 못한 것입니다.




바로 여기서 재미있는 점이 있는데요, 사실 win32api 모듈은 .\Lib\site-packages 하위에 있는 win32 디렉터리 내에 있는 pyd 파일입니다.

"C:\python310\Lib\site-packages\win32\win32api.pyd"

그래서 원래 설치 파일 기준의 파이썬 환경에서는 이게 import가 잘됩니다.

// 설치 파일의 파이썬 환경인 경우

D:\temp\UFO> python
Python 3.10.10 (tags/v3.10.10:aad5f6a, Feb  7 2023, 17:20:36) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import win32api
>>> print(win32api.__file__)
%USERPROFILE%\AppData\Local\Programs\Python\Python310\lib\site-packages\win32\win32api.pyd
>>>

반면 embeddable package로 설치한 파이썬에서는 win32api에 대한 import가 안 됩니다.

// embeddable package의 파이썬 환경인 경우,

C:\python310> python
Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32
>>> import win32api
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'win32api'

// 대신 win32 모듈까지는 import가 됩니다.

>>> import win32
None
>>> 

참 희한하죠? ^^; 이에 대한 해결은, 의외로 이전에 설명했던 site 패키지에 있었습니다.

파이썬 - "Windows embeddable package" REPL 환경에서 "NameError: name 'exit' is not defined"
; https://www.sysnet.pe.kr/2/0/13929

그러니까, "Windows embeddable package"인 경우에도 site.main 함수를 실행하면 정상적으로 win32api 모듈을 로드할 수 있습니다.

>>> import site
>>> site.main()
>>> import win32api
>>> print(win32api.__file__)
C:\python310\lib\site-packages\win32\win32api.pyd
>>>

물론, 저렇게는 번거로우니까 _pth 파일의 "import site" 주석을 해제하는 걸로 간단하게 해결할 수 있습니다.

D:\temp\UFO> type C:\python310\python310._pth
python310.zip
.
Lib\site-packages

# Uncomment to run site.main() automatically
import site

D:\temp\UFO

이후로는 본문에서 예로 든 ufo 패키지가 아주 잘 실행됩니다. ^^

D:\temp\UFO> C:\python310\python -m ufo --task my_test

Welcome to use UFO🛸, A UI-focused Agent for Windows OS Interaction.
 _   _  _____   ___
| | | ||  ___| / _ \
| | | || |_   | | | |
| |_| ||  _|  | |_| |
 \___/ |_|     \___/


Please enter your request to be completed🛸:




참고로, _pth 파일의 본연의 임무는 모듈 검색 경로를 설정하는 것인데요, 코드의 경우 예외적으로 "import site"만 허용하고 있습니다. 실제로 다른 모듈을 자동으로 import하기 위해 추가하면, (예를 들어 "import sys") python 실행 시 이런 예외가 발생합니다.

C:\python310> python
Fatal Python error: read_pth_file: only 'import site' is supported in ._pth file
Python runtime state: core initialized

Current thread 0x0000e2f4 (most recent call first):
  <no Python frame>

마지막으로, 이렇게 뭔가 숨겨진 게 많은 듯한 _pth 파일과의 연동이 귀찮다면 그냥 삭제하는 것도 좋은 선택입니다. 그런 경우, "embeddable package"는 설치 버전의 파이썬과 동일하게 실행됩니다. 즉, 본문에서 예로 든 ufo 패키지를 아무런 추가 설정 없이도 잘 실행합니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 5/17/2025]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 121  122  123  124  125  126  127  128  129  130  131  132  [133]  134  135  ...
NoWriterDateCnt.TitleFile(s)
1739정성태8/24/201426821.NET Framework: 457. 교착상태(Dead-lock) 해결 방법 - Lock Leveling [2]파일 다운로드1
1738정성태8/23/201422292.NET Framework: 456. C# - CAS를 이용한 Lock 래퍼 클래스파일 다운로드1
1737정성태8/20/201420046VS.NET IDE: 93. Visual Studio 2013 동기화 문제
1736정성태8/19/201425862VC++: 79. [부연] CAS Lock 알고리즘은 과연 빠른가? [2]파일 다운로드1
1735정성태8/19/201418523.NET Framework: 455. 닷넷 사용자 정의 예외 클래스의 최소 구현 코드 - 두 번째 이야기
1734정성태8/13/201420256오류 유형: 237. Windows Media Player cannot access the file. The file might be in use, you might not have access to the computer where the file is stored, or your proxy settings might not be correct.
1733정성태8/13/201426596.NET Framework: 454. EmptyWorkingSet Win32 API를 사용하는 C# 예제파일 다운로드1
1732정성태8/13/201434779Windows: 99. INetCache 폴더가 다르게 보이는 이유
1731정성태8/11/201427322개발 환경 구성: 235. 점(.)으로 시작하는 파일명을 탐색기에서 만드는 방법
1730정성태8/11/201422468개발 환경 구성: 234. Royal TS의 터미널(Terminal) 연결에서 한글이 깨지는 현상 해결 방법
1729정성태8/11/201418511오류 유형: 236. SqlConnection - The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly.
1728정성태8/8/201430571.NET Framework: 453. C# - 오피스 파워포인트(Powerpoint) 파일을 WinForm에서 보는 방법파일 다운로드1
1727정성태8/6/201420845오류 유형: 235. SignalR 오류 메시지 - Counter 'Messages Bus Messages Published Total' does not exist in the specified Category. [2]
1726정성태8/6/201419753오류 유형: 234. IIS Express에서 COM+ 사용 시 SecurityException - "Requested registry access is not allowed" 발생
1725정성태8/6/201421641오류 유형: 233. Visual Studio 2013 Update3 적용 후 Microsoft.VisualStudio.Web.PageInspector.Runtime 모듈에 대한 FileNotFoundException 예외 발생
1724정성태8/5/201426399.NET Framework: 452. .NET System.Threading.Thread 개체에서 Native Thread Id를 구하는 방법 - 두 번째 이야기 [1]파일 다운로드1
1723정성태7/29/201458694개발 환경 구성: 233. DirectX 9 예제 프로젝트 빌드하는 방법 [3]파일 다운로드1
1722정성태7/25/201421348오류 유형: 232. IIS 500 Internal Server Error - NTFS 암호화된 폴더에 웹 애플리케이션이 위치한 경우
1721정성태7/24/201424377.NET Framework: 451. 함수형 프로그래밍 개념 - 리스트 해석(List Comprehension)과 순수 함수 [2]
1720정성태7/23/201422339개발 환경 구성: 232. C:\WINDOWS\system32\LogFiles\HTTPERR 폴더에 로그 파일을 남기지 않는 설정
1719정성태7/22/201426328Math: 13. 동전을 여러 더미로 나누는 경우의 수 세기(Partition Number) - 두 번째 이야기파일 다운로드1
1718정성태7/19/201435623Math: 12. HTML에서 수학 관련 기호/수식을 표현하기 위한 방법 - MathJax.js [4]
1716정성태7/17/201435379개발 환경 구성: 231. PC 용 무료 안드로이드 에뮬레이터 - genymotion
1715정성태7/13/201430819기타: 47. 운영체제 종료 후에도 USB 외장 하드의 전원이 꺼지지 않는 경우 [3]
1714정성태7/11/201421009VS.NET IDE: 92. Visual Studio 2013을 지원하는 IL Support 확장 도구
1713정성태7/11/201444789Windows: 98. 윈도우 시스템 디스크 용량 확보를 위한 "Package Cache" 폴더 이동 [1]
... 121  122  123  124  125  126  127  128  129  130  131  132  [133]  134  135  ...