2015-10-05 150 views
1

當不工作只是嘗試的官方文檔站點的例子之一:PyInstaller不包括Pysnmp

from pysnmp.hlapi import * 

errorIndication, errorStatus, errorIndex, varBinds = next(
    getCmd(SnmpEngine(), 
      CommunityData('public'), 
      UdpTransportTarget(('192.168.1.14', 161)), 
      ContextData(), 
      ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0'))) 
) 

if errorIndication: 
    print(errorIndication) 
elif errorStatus: 
    print('%s at %s' % (
      errorStatus.prettyPrint(), 
      errorIndex and varBinds[int(errorIndex)-1][0] or '?' 
     ) 
    ) 
else: 
    for varBind in varBinds: 
     print(' = '.join([ x.prettyPrint() for x in varBind ])) 

,我們可以看到,如果通過Python解釋其執行它的工作:

(Compiler)[[email protected] testSNMP]$ python testSNMP.py 
SNMPv2-MIB::sysDescr."0" = 48-port 10/100/1000 Gigabit Switch 

然而,如果我嘗試用PyInstaller(PyInstaller --onefile)「凍結」它,我會在執行它時收到以下錯誤:

(Compiler)[[email protected] testSNMP]$ /lab/testSNMP/dist/testSNMP 
Traceback (most recent call last): 
    File "<string>", line 4, in <module> 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/pysnmp.entity.engine", line 83, in __init__ 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/pysnmp.smi.builder", line 359, in importSymbols 
pysnmp.smi.error.MibNotFoundError: No module __SNMP-FRAMEWORK-MIB loaded at <pysnmp.smi.builder.MibBuilder instance at 0x179f518> 

似乎pysnmp/smi/mibs中的必需文件沒有明確導入才能使用。這就是爲什麼我分階段拆分構建過程。拳頭,創建規格文件。

(Compiler)[[email protected] testSNMP]$ pyi-makespec --onefile getInterfaces.py 
wrote /lab/testSNMP/getInterfaces.spec 
now run pyinstaller.py to build the executable 

然後,我已經編輯以導入所需文件以下從這個其他的疊後(Can't get pysnmp to work with pyinstaller)建議:

# -*- mode: python -*- 
import PyInstaller.hooks.hookutils 
hiddenimports = ['pysnmp.smi.exval','pysnmp.cache'] + PyInstaller.hooks.hookutils.collect_submodules('pysnmp.smi.mibs') + PyInstaller.hooks.hookutils.collect_submodules('pysnmp.smi.mibs.instances') 
a = Analysis(['testSNMP.py'], 
      pathex=['/lab/testSNMP'], 
      hiddenimports=hiddenimports, 
      hookspath=None, 
      runtime_hooks=None) 
x = Tree('/virtualenvs/Compiler/lib/python2.7/site-packages/pysnmp/smi/mibs',prefix='pysnmp/smi/mibs',excludes='.py') 
pyz = PYZ(a.pure) 
exe = EXE(pyz, 
     a.scripts, 
     a.binaries, 
     a.zipfiles, 
     a.datas, 
     x, 
     name='testSNMP', 
     debug=False, 
     strip=None, 
     upx=True, 
     console=True) 

不過,一旦它的建成和運行,我得到這個其他錯誤:

(Compiler)[[email protected] testSNMP]$ /lab/testSNMP/dist/testSNMP 
Traceback (most recent call last): 
    File "<string>", line 15, in <module> 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/pysnmp.hlapi.asyncore.sync.cmdgen", line 98, in getCmd 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/pysnmp.hlapi.asyncore.cmdgen", line 135, in getCmd 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/pysnmp.hlapi.varbinds", line 30, in makeVarBinds 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/pysnmp.smi.rfc1902", line 689, in resolveWithMib 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/pysnmp.smi.rfc1902", line 299, in resolveWithMib 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/pysnmp.smi.compiler", line 44, in addMibCompiler 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/pysmi.parser.smi", line 21, in __init__ 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/pysmi.lexer.smi", line 83, in __init__ 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/pysmi.lexer.smi", line 100, in reset 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/ply.lex", line 915, in lex 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/ply.lex", line 577, in validate_all 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/ply.lex", line 819, in validate_rules 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/ply.lex", line 830, in validate_module 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/inspect", line 690, in getsourcelines 
    File "/lab/testSNMP/build/testSNMP/out00-PYZ.pyz/inspect", line 538, in findsource 
IOError: could not get source code 

我還能做什麼?提前致謝!

+0

嘗試添加以下內容得到更好的調試輸出。 'from pysnmp import debug debug.setLogger(debug.Debug('mibbuild'))' –

回答

0

我有同樣的問題,並設法通過將pysmi文件包括在樹中,就像pysnmp mibs一樣工作。

我pyinstaller規範文件弄成:

... 

x = Tree(os.getcwd()+'/.pyenv/Lib/site-packages/pysnmp/smi/mibs',prefix='pysnmp/smi/mibs') 
y = Tree(os.getcwd()+'/.pyenv/Lib/site-packages/pysmi',prefix='pysmi') 

... 

exe = EXE(pyz, 
     a.scripts, 
     a.binaries, 
     a.zipfiles, 
     a.datas, 
     x,y, 

... 

雖然這工作,我其實用pysnmp V4.2.5的舊版本不依賴於pysmi解決它以另一種方式

0

得到了同樣的錯誤「無法獲得源代碼」。有關於Pyinstaller GitHub的頁面上創建一個問題: https://github.com/pyinstaller/pyinstaller/issues/1945 解決辦法是包括簾布層規格文件,因爲它是在你提到的鏈接描述: Can't get pysnmp to work with pyinstaller 加入「PyInstaller.utils.hooks.collect_submodules(‘層’) 「以隱藏進口

並確保鋪層版本是> = 3.9!

我的規格文件看起來非常相同,除了分析部分:

a = Analysis(['main.py'], 
     binaries=None, 
     datas=PyInstaller.utils.hooks.collect_data_files('pysnmp') + \ 
     hiddenimports=PyInstaller.utils.hooks.collect_submodules('pysmi')+\ 
     PyInstaller.utils.hooks.collect_submodules('ply') + \ 
     PyInstaller.utils.hooks.collect_submodules('pyasn1') + \ 
     PyInstaller.utils.hooks.collect_submodules('pysnmp'), 
     hookspath=None, 
     runtime_hooks=None, 
     excludes=None, 
     win_no_prefer_redirects=None, 
     win_private_assemblies=None, 
     cipher=block_cipher) 
0

爲了讓傑里米的答案便攜,您可以修改您的spec文件這樣的差異:

+ import os.path 
+ import pysmi 
+ import pysnmp.smi.mibs 

+ def module_base(module): 
+ return os.path.abspath(os.path.join(module.__file__, os.pardir)) 

    coll = COLLECT(
     exe, 
     a.binaries, 
     a.zipfiles, 
     a.datas, 
+  Tree(module_base(pysmi), prefix='pysmi'), 
+  Tree(module_base(pysnmp.smi.mibs), prefix='pysnmp/smi/mibs'), 
     ... 

編輯: 轉出加這些隱藏進口解決了我的問題:

'pysnmp.smi.mibs', 'pysnmp.smi.mibs.instances', 'pysnmp.smi.exval', 'pysnmp.cache'