2011-11-06 11 views
3

pyobjc 응용 프로그램이 gevent 라이브러리를 사용하는 32 비트 전용 파이썬 빌드에서 실행되고 있습니다. 모든 것은 py2app'ed 별칭 모드에서 훌륭하게 작동하지만, 일단 앱 번들을 빌드하면 gevent 모듈은 site-packages 디렉토리에 번들 된 경우에도 httplib 라이브러리를 찾을 수 없습니다.py2app'ed 응용 프로그램이 별칭 모드에서 제대로 실행되지만 번들로 제공되지 않을 경우

File "gevent/monkey.pyo", line 182, in patch_httplib 
File "gevent/httplib.pyo", line 8, in <module> 
ImportError: No module named httplib 

제안 된대로 잘못된 가져 오기를 시도했지만 (모듈이 패키지로되어 있어도 마찬가지 임) 유용하지는 않습니다. 그것은 gevent.httplib 모듈을 찾을 수 있지만 원숭이 패치를하기로되어있는 모듈은 찾을 수 없습니다. 이것은 원숭이 패치 기능에 문제가 될 수 있습니까?

EDIT : find_module이 내 py2app 번들과 제대로 작동하지 않는 것 같습니다. 이 문제를 해결할 수 있습니까? httplib가 점선으로되어 있지 않기 때문에 점이 찍힌 모듈에 문제가 있다고 생각하지 않습니다. (코어 파이썬 라이브러리의 일부입니다)

EDIT 2 : 정말 imp.find_module입니다. 을 사용하여 load_module 대신 ('httplib')을 사용하면이 문제가 해결되지만 sys.modules에서 'httplib'에 대한 참조를 삭제해야합니다. 이미로드 된 경우 원숭이 패치를 적용 할 수 없기 때문입니다. 나는 이것이 올바른 방법이라고 생각하지 않는다. 비록 빌드 된 애플리케이션 번들이 제대로 작동하지만 (httplib는 이제 원숭이 패치이며 HTTPSConnection과 함께 init을 허용한다). 이 py2app 문제에 대한 해결 방법/수정 사항이 있습니까?

답변

2

이 조금 까다 롭습니다 더욱 패치를 포함하지만, 확실히 풀 수 :

def main(): 

    # Patch the imp standard library module to fix an incompatibility between 
    # py2app and gevent.httplib while running a py2app build on Mac OS-X. 
    # This patch must be executed before applying gevent's monkey patching. 
    if getattr(sys, 'frozen', None) == 'macosx_app': 

     import imp, httplib 

     original_load_module = imp.load_module 
     original_find_module = imp.find_module 

     def custom_load_module(name, file, pathname, description): 
      if name == '__httplib__': 
       return httplib 
      return original_load_module(name, file, pathname, description) 

     def custom_find_module(name, path=None): 
      if name == 'httplib': 
       return (None, None, None) 
      return original_find_module(name, path) 

     imp.load_module = custom_load_module 
     imp.find_module = custom_find_module 

     # Verify that the patch is working properly (you can remove these lines safely) 
     __httplib__ = imp.load_module('__httplib__', *imp.find_module('httplib')) 
     assert __httplib__ is httplib 

     # Your application here 

if __name__ == '__main__': 
    main() 

이 솔루션은 단순히 gevent.httplib을 수정하는 것보다 더 복잡하지만, 적어도 주가는 0.13 분포를 gevent와 함께 작동합니다. 나는 최근에 공개 된 gevent 1.0 alpha 버전으로 아직 시도하지 않았다.

+0

내 솔루션에 대한 한 가지 더 의견 :이 경우 imp.find_module이 작동하지 않는 이유를 파악하는 것이 훨씬 더 쉬울 것입니다. 나는 py2app가 새로운 조리법을 필요로한다고 생각하지만 그것은 단지 추측 일뿐입니다. 이것에 대한 아이디어가 있습니까? – fviktor

+1

위의 해킹은 적어도 gevent 0.13.7, Python 2.6에서는 Windows에서도 필요합니다. – fviktor