【问题标题】:PyInstaller does NOT work when including PysnmpPyInstaller 在包含 Pysnmp 时不起作用
【发布时间】:2018-03-09 21:05:03
【问题描述】:

只是尝试官方文档站点示例之一:

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)[user@machine testSNMP]$ python testSNMP.py 
 SNMPv2-MIB::sysDescr."0" = 48-port 10/100/1000 Gigabit Switch

但是,如果我尝试使用 PyInstaller (PyInstaller --onefile) “冻结”它,我会在执行后收到以下错误:

  (Compiler)[user@machine 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 中的强制文件未明确导入以供使用。这就是为什么我将构建过程分成几个阶段。拳头,创建spec文件。

(Compiler)[user@machine 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)[user@machine 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

我还能做什么?提前致谢!

【问题讨论】:

  • 尝试添加以下内容以获得更好的调试输出。 '从 pysnmp 导入调试 debug.setLogger(debug.Debug('mibbuild'))'

标签: python-2.7 pyinstaller pysnmp


【解决方案1】:

为了使 Jeremy 的答案可移植,您可以像这样修改您的规范文件:

+ 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'),
      ...

编辑: 原来将这些添加到 hiddenimports 解决了我的问题:

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

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,并设法通过将 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,
    
    ...
    

    虽然这有效,但我实际上通过使用不依赖 pysmi 的旧版本 pysnmp v4.2.5 以另一种方式解决了它

    【讨论】:

      【解决方案3】:

      遇到同样的错误“无法获取源代码”。 Pyinstaller github页面上创建的有一个问题: https://github.com/pyinstaller/pyinstaller/issues/1945 解决方案是将 ply 包含到规范文件中,如您提到的链接中所述: Can't get pysnmp to work with pyinstaller 通过将“PyInstaller.utils.hooks.collect_submodules('ply')”添加到 hiddenimports

      并确保 ply 版本 >= 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)
      

      【讨论】:

        猜你喜欢
        • 2014-03-17
        • 2020-11-09
        • 1970-01-01
        • 1970-01-01
        • 2016-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多