From 5c64b499c2cf6f168970aa7ae51fe4997cdd89fc Mon Sep 17 00:00:00 2001 From: Ilya Etingof Date: Sun, 10 Feb 2019 18:30:59 +0100 Subject: Officially remove Python < 2.6 support (#239) Perhaps previous commits have already broken older Python support. This commit mostly declares Python 2.6+ support. --- README.md | 2 +- docs/source/contents.rst | 11 +- docs/source/development.rst | 2 +- pysnmp/carrier/sockmsg.py | 1 - pysnmp/hlapi/v1arch/asyncore/sync/cmdgen.py | 8 - pysnmp/hlapi/v1arch/asyncore/sync/ntforg.py | 8 - pysnmp/hlapi/v3arch/asyncore/sync/__init__.py | 8 +- pysnmp/hlapi/v3arch/asyncore/sync/cmdgen.py | 8 - .../hlapi/v3arch/asyncore/sync/compat/__init__.py | 1 - pysnmp/hlapi/v3arch/asyncore/sync/compat/cmdgen.py | 251 --------------------- pysnmp/hlapi/v3arch/asyncore/sync/compat/ntforg.py | 51 ----- pysnmp/hlapi/v3arch/asyncore/sync/ntforg.py | 8 - pysnmp/proto/rfc1902.py | 1 - pysnmp/proto/secmod/rfc3414/priv/des.py | 7 +- setup.py | 7 +- 15 files changed, 13 insertions(+), 361 deletions(-) delete mode 100644 pysnmp/hlapi/v3arch/asyncore/sync/compat/__init__.py delete mode 100644 pysnmp/hlapi/v3arch/asyncore/sync/compat/cmdgen.py delete mode 100644 pysnmp/hlapi/v3arch/asyncore/sync/compat/ntforg.py diff --git a/README.md b/README.md index 0301aecc..7a2d8a11 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Features * [PySMI](http://snmplabs.com/pysmi/) integration for dynamic MIB compilation * Built-in instrumentation exposing protocol engine operations * Python eggs and py2exe friendly -* 100% Python, works with Python 2.4 though 3.7 +* 100% Python, works with Python 2.6 though 3.7 * MT-safe (if SnmpEngine is thread-local) Features, specific to SNMPv3 model include: diff --git a/docs/source/contents.rst b/docs/source/contents.rst index 4419c0de..38f87c0a 100644 --- a/docs/source/contents.rst +++ b/docs/source/contents.rst @@ -17,11 +17,12 @@ multilingual capabilities, remote configuration and other features. PySNMP implementation closely follows intricate system details and features bringing most possible power and flexibility to its users. -Current PySNMP stable version is 4.4. It runs with Python 2.4 through 3.7 -and is recommended for new applications as well as for migration from -older, now obsolete, PySNMP releases. All site documentation and -examples are written for the 4.4 and later versions in mind. -Older materials are still available under the obsolete section. +Current PySNMP stable version is 4.4 and 5.0 is being in development. +It runs with Python 2.6 through 3.7 and is recommended for new applications +as well as for migration from older, now obsolete, PySNMP releases. +All documentation and examples are written for the 4.4 and later +versions in mind. Older materials are still available under the +obsolete section. Besides the libraries, a set of pure-Python `command-line tools `_ diff --git a/docs/source/development.rst b/docs/source/development.rst index 0050f943..3be7f1e1 100644 --- a/docs/source/development.rst +++ b/docs/source/development.rst @@ -92,7 +92,7 @@ You could greater speed up the development of particular feature by sponsoring it. Please get back to us to discuss details. Contributions to the PySNMP source code is greatly appreciated as well. -We require contributed code to run with Python 2.4 through the latest +We require contributed code to run with Python 2.6 through the latest Python version (which is 3.7 at the time of this writing). Contributed code will be redistributed under the terms of the same `license `_ as PySNMP is. diff --git a/pysnmp/carrier/sockmsg.py b/pysnmp/carrier/sockmsg.py index deab4b6d..e36bc85a 100644 --- a/pysnmp/carrier/sockmsg.py +++ b/pysnmp/carrier/sockmsg.py @@ -20,7 +20,6 @@ import sys from pysnmp import debug if sys.version_info[:2] < (3, 3): - # noinspection PyUnusedLocal def getRecvFrom(addressType): raise error.CarrierError('sendmsg()/recvmsg() interface is not supported by this OS and/or Python version') diff --git a/pysnmp/hlapi/v1arch/asyncore/sync/cmdgen.py b/pysnmp/hlapi/v1arch/asyncore/sync/cmdgen.py index bb7b9ad5..4ca7c66c 100644 --- a/pysnmp/hlapi/v1arch/asyncore/sync/cmdgen.py +++ b/pysnmp/hlapi/v1arch/asyncore/sync/cmdgen.py @@ -4,7 +4,6 @@ # Copyright (c) 2005-2019, Ilya Etingof # License: http://snmplabs.com/pysnmp/license.html # -from sys import version_info from pysnmp.hlapi.v1arch.asyncore import cmdgen from pysnmp.hlapi.varbinds import * from pysnmp.proto.rfc1905 import endOfMibView @@ -13,13 +12,6 @@ from pyasn1.type.univ import Null __all__ = ['getCmd', 'nextCmd', 'setCmd', 'bulkCmd'] -if version_info[:2] < (2, 6): - __all__.append('next') - - # noinspection PyShadowingBuiltins - def next(iter): - return iter.next() - VB_PROCESSOR = CommandGeneratorVarBinds() diff --git a/pysnmp/hlapi/v1arch/asyncore/sync/ntforg.py b/pysnmp/hlapi/v1arch/asyncore/sync/ntforg.py index 4732b460..d3e3ee03 100644 --- a/pysnmp/hlapi/v1arch/asyncore/sync/ntforg.py +++ b/pysnmp/hlapi/v1arch/asyncore/sync/ntforg.py @@ -4,7 +4,6 @@ # Copyright (c) 2005-2019, Ilya Etingof # License: http://snmplabs.com/pysnmp/license.html # -from sys import version_info from pysnmp.hlapi.v1arch.asyncore import ntforg from pysnmp.hlapi.varbinds import * from pysnmp.proto import errind @@ -12,13 +11,6 @@ from pyasn1.type.univ import Null __all__ = ['sendNotification'] -if version_info[:2] < (2, 6): - __all__.append('next') - - # noinspection PyShadowingBuiltins - def next(iter): - return iter.next() - def sendNotification(snmpDispatcher, authData, transportTarget, notifyType, *varBinds, **options): diff --git a/pysnmp/hlapi/v3arch/asyncore/sync/__init__.py b/pysnmp/hlapi/v3arch/asyncore/sync/__init__.py index b537bc28..9ff7d84d 100644 --- a/pysnmp/hlapi/v3arch/asyncore/sync/__init__.py +++ b/pysnmp/hlapi/v3arch/asyncore/sync/__init__.py @@ -11,9 +11,5 @@ from pysnmp.hlapi.v3arch.context import * from pysnmp.hlapi.v3arch.asyncore.transport import * from pysnmp.entity.engine import * -try: - from pysnmp.hlapi.v3arch.asyncore.sync.cmdgen import * - from pysnmp.hlapi.v3arch.asyncore.sync.ntforg import * -except SyntaxError: - from pysnmp.hlapi.v3arch.asyncore.sync.compat.cmdgen import * - from pysnmp.hlapi.v3arch.asyncore.sync.compat.ntforg import * +from pysnmp.hlapi.v3arch.asyncore.sync.cmdgen import * +from pysnmp.hlapi.v3arch.asyncore.sync.ntforg import * diff --git a/pysnmp/hlapi/v3arch/asyncore/sync/cmdgen.py b/pysnmp/hlapi/v3arch/asyncore/sync/cmdgen.py index d8bb8e34..7caa05ba 100644 --- a/pysnmp/hlapi/v3arch/asyncore/sync/cmdgen.py +++ b/pysnmp/hlapi/v3arch/asyncore/sync/cmdgen.py @@ -4,7 +4,6 @@ # Copyright (c) 2005-2019, Ilya Etingof # License: http://snmplabs.com/pysnmp/license.html # -from sys import version_info from pysnmp.hlapi.v3arch.asyncore import cmdgen from pysnmp.hlapi.varbinds import * from pysnmp.proto.rfc1905 import endOfMibView @@ -13,13 +12,6 @@ from pyasn1.type.univ import Null __all__ = ['getCmd', 'nextCmd', 'setCmd', 'bulkCmd'] -if version_info[:2] < (2, 6): - __all__.append('next') - - # noinspection PyShadowingBuiltins - def next(iter): - return iter.next() - def getCmd(snmpEngine, authData, transportTarget, contextData, *varBinds, **options): diff --git a/pysnmp/hlapi/v3arch/asyncore/sync/compat/__init__.py b/pysnmp/hlapi/v3arch/asyncore/sync/compat/__init__.py deleted file mode 100644 index 8c3066b2..00000000 --- a/pysnmp/hlapi/v3arch/asyncore/sync/compat/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# This file is necessary to make this directory a package. diff --git a/pysnmp/hlapi/v3arch/asyncore/sync/compat/cmdgen.py b/pysnmp/hlapi/v3arch/asyncore/sync/compat/cmdgen.py deleted file mode 100644 index bb9703f4..00000000 --- a/pysnmp/hlapi/v3arch/asyncore/sync/compat/cmdgen.py +++ /dev/null @@ -1,251 +0,0 @@ -# -# This file is part of pysnmp software. -# -# Copyright (c) 2005-2019, Ilya Etingof -# License: http://snmplabs.com/pysnmp/license.html -# -# This is a Python 2.6- version of the same file at level up -# -from pysnmp.hlapi.v3arch.asyncore import cmdgen -from pysnmp.hlapi.varbinds import * -from pysnmp.proto.rfc1905 import endOfMibView -from pysnmp.proto import errind -from pyasn1.type.univ import Null - -__all__ = ['getCmd', 'nextCmd', 'setCmd', 'bulkCmd', 'next'] - - -# noinspection PyShadowingBuiltins -def next(iter): - return iter.next() - - -def getCmd(snmpEngine, authData, transportTarget, contextData, - *varBinds, **options): - # noinspection PyShadowingNames - def cbFun(snmpEngine, sendRequestHandle, - errorIndication, errorStatus, errorIndex, - varBinds, cbCtx): - cbCtx['errorIndication'] = errorIndication - cbCtx['errorStatus'] = errorStatus - cbCtx['errorIndex'] = errorIndex - cbCtx['varBinds'] = varBinds - - cbCtx = {} - - if varBinds: - cmdgen.getCmd(snmpEngine, authData, transportTarget, - contextData, *varBinds, - cbFun=cbFun, cbCtx=cbCtx, - lookupMib=options.get('lookupMib', True)) - - snmpEngine.transportDispatcher.runDispatcher() - - errorIndication = cbCtx['errorIndication'] - errorStatus = cbCtx['errorStatus'] - errorIndex = cbCtx['errorIndex'] - varBinds = cbCtx['varBinds'] - else: - errorIndication = errorStatus = errorIndex = None - varBinds = [] - - yield errorIndication, errorStatus, errorIndex, varBinds - - -def setCmd(snmpEngine, authData, transportTarget, contextData, - *varBinds, **options): - # noinspection PyShadowingNames - def cbFun(snmpEngine, sendRequestHandle, - errorIndication, errorStatus, errorIndex, - varBinds, cbCtx): - cbCtx['errorIndication'] = errorIndication - cbCtx['errorStatus'] = errorStatus - cbCtx['errorIndex'] = errorIndex - cbCtx['varBinds'] = varBinds - - cbCtx = {} - - while True: - cmdgen.setCmd(snmpEngine, authData, transportTarget, - contextData, *varBinds, - cbFun=cbFun, cbCtx=cbCtx, - lookupMib=options.get('lookupMib', True)) - - snmpEngine.transportDispatcher.runDispatcher() - - yield (cbCtx['errorIndication'], - cbCtx['errorStatus'], cbCtx['errorIndex'], - cbCtx['varBinds']) - - if cbCtx['errorIndication'] != errind.requestTimedOut: - break - - -def nextCmd(snmpEngine, authData, transportTarget, contextData, - *varBinds, **options): - # noinspection PyShadowingNames - def cbFun(snmpEngine, sendRequestHandle, - errorIndication, errorStatus, errorIndex, - varBindTable, cbCtx): - cbCtx['errorIndication'] = errorIndication - cbCtx['errorStatus'] = errorStatus - cbCtx['errorIndex'] = errorIndex - cbCtx['varBindTable'] = varBindTable - - lexicographicMode = options.get('lexicographicMode', True) - ignoreNonIncreasingOid = options.get('ignoreNonIncreasingOid', False) - maxRows = options.get('maxRows', 0) - maxCalls = options.get('maxCalls', 0) - - cbCtx = {} - - vbProcessor = CommandGeneratorVarBinds() - - initialVars = [x[0] for x in vbProcessor.makeVarBinds(snmpEngine.cache, varBinds)] - - totalRows = totalCalls = 0 - - while True: - cmdgen.nextCmd(snmpEngine, authData, transportTarget, contextData, - *[(x[0], Null('')) for x in varBinds], - cbFun=cbFun, cbCtx=cbCtx, - lookupMib=options.get('lookupMib', True)) - - snmpEngine.transportDispatcher.runDispatcher() - - errorIndication = cbCtx['errorIndication'] - errorStatus = cbCtx['errorStatus'] - errorIndex = cbCtx['errorIndex'] - - if ignoreNonIncreasingOid and errorIndication and \ - isinstance(errorIndication, errind.OidNotIncreasing): - errorIndication = None - - if errorIndication: - yield errorIndication, errorStatus, errorIndex, varBinds - if errorIndication != errind.requestTimedOut: - return - elif errorStatus: - if errorStatus == 2: - # Hide SNMPv1 noSuchName error which leaks in here - # from SNMPv1 Agent through internal pysnmp proxy. - errorStatus = errorStatus.clone(0) - errorIndex = errorIndex.clone(0) - yield errorIndication, errorStatus, errorIndex, varBinds - return - else: - varBinds = cbCtx['varBindTable'] and cbCtx['varBindTable'][0] - for idx, varBind in enumerate(varBinds): - name, val = varBind - if not isinstance(val, Null): - if lexicographicMode or initialVars[idx].isPrefixOf(name): - break - else: - return - - totalRows += 1 - totalCalls += 1 - - yield errorIndication, errorStatus, errorIndex, varBinds - - if maxRows and totalRows >= maxRows or \ - maxCalls and totalCalls >= maxCalls: - return - - -def bulkCmd(snmpEngine, authData, transportTarget, contextData, - nonRepeaters, maxRepetitions, *varBinds, **options): - # noinspection PyShadowingNames - def cbFun(snmpEngine, sendRequestHandle, - errorIndication, errorStatus, errorIndex, - varBindTable, cbCtx): - cbCtx['errorIndication'] = errorIndication - cbCtx['errorStatus'] = errorStatus - cbCtx['errorIndex'] = errorIndex - cbCtx['varBindTable'] = varBindTable - - lexicographicMode = options.get('lexicographicMode', True) - ignoreNonIncreasingOid = options.get('ignoreNonIncreasingOid', False) - maxRows = options.get('maxRows', 0) - maxCalls = options.get('maxCalls', 0) - - cbCtx = {} - - vbProcessor = CommandGeneratorVarBinds() - - initialVars = [x[0] for x in vbProcessor.makeVarBinds(snmpEngine.cache, varBinds)] - nullVarBinds = [False] * len(initialVars) - - totalRows = totalCalls = 0 - stopFlag = False - - while not stopFlag: - if maxRows and totalRows < maxRows: - maxRepetitions = min(maxRepetitions, maxRows - totalRows) - - cmdgen.bulkCmd(snmpEngine, authData, transportTarget, contextData, - nonRepeaters, maxRepetitions, - *[(x[0], Null('')) for x in varBinds], - cbFun=cbFun, cbCtx=cbCtx, - lookupMib=options.get('lookupMib', True)) - - snmpEngine.transportDispatcher.runDispatcher() - - errorIndication = cbCtx['errorIndication'] - errorStatus = cbCtx['errorStatus'] - errorIndex = cbCtx['errorIndex'] - varBindTable = cbCtx['varBindTable'] - - if ignoreNonIncreasingOid and errorIndication and \ - isinstance(errorIndication, errind.OidNotIncreasing): - errorIndication = None - - if errorIndication: - yield (errorIndication, errorStatus, errorIndex, - varBindTable and varBindTable[0] or []) - if errorIndication != errind.requestTimedOut: - return - elif errorStatus: - if errorStatus == 2: - # Hide SNMPv1 noSuchName error which leaks in here - # from SNMPv1 Agent through internal pysnmp proxy. - errorStatus = errorStatus.clone(0) - errorIndex = errorIndex.clone(0) - yield (errorIndication, errorStatus, errorIndex, - varBindTable and varBindTable[0] or []) - return - else: - for i in range(len(varBindTable)): - stopFlag = True - if len(varBindTable[i]) != len(initialVars): - varBindTable = i and varBindTable[:i - 1] or [] - break - for j in range(len(varBindTable[i])): - name, val = varBindTable[i][j] - if nullVarBinds[j]: - varBindTable[i][j] = name, endOfMibView - continue - stopFlag = False - if isinstance(val, Null): - nullVarBinds[j] = True - elif not lexicographicMode and \ - not initialVars[j].isPrefixOf(name): - varBindTable[i][j] = name, endOfMibView - nullVarBinds[j] = True - if stopFlag: - varBindTable = i and varBindTable[:i - 1] or [] - break - - totalRows += len(varBindTable) - totalCalls += 1 - - if maxRows and totalRows >= maxRows: - if totalRows > maxRows: - varBindTable = varBindTable[:-(totalRows - maxRows)] - stopFlag = True - - if maxCalls and totalCalls >= maxCalls: - stopFlag = True - - for varBinds in varBindTable: - yield errorIndication, errorStatus, errorIndex, varBinds diff --git a/pysnmp/hlapi/v3arch/asyncore/sync/compat/ntforg.py b/pysnmp/hlapi/v3arch/asyncore/sync/compat/ntforg.py deleted file mode 100644 index 5b10cd0e..00000000 --- a/pysnmp/hlapi/v3arch/asyncore/sync/compat/ntforg.py +++ /dev/null @@ -1,51 +0,0 @@ -# -# This file is part of pysnmp software. -# -# Copyright (c) 2005-2019, Ilya Etingof -# License: http://snmplabs.com/pysnmp/license.html -# -# This is a Python 2.6- version of the same file at level up -# -from pysnmp.hlapi.v3arch.asyncore import ntforg - -__all__ = ['sendNotification', 'next'] - - -# noinspection PyShadowingBuiltins -def next(iter): - return iter.next() - - -# -# Synchronous one-liner SNMP Notification Originator application -# - -def sendNotification(snmpEngine, authData, transportTarget, contextData, - notifyType, varBinds, **options): - # noinspection PyShadowingNames - def cbFun(snmpEngine, sendRequestHandle, - errorIndication, errorStatus, errorIndex, - varBinds, cbCtx): - cbCtx['errorIndication'] = errorIndication - cbCtx['errorStatus'] = errorStatus - cbCtx['errorIndex'] = errorIndex - cbCtx['varBinds'] = varBinds - - cbCtx = {} - - if varBinds: - ntforg.sendNotification(snmpEngine, authData, transportTarget, - contextData, notifyType, varBinds, - cbFun, cbCtx, options.get('lookupMib', True)) - - snmpEngine.transportDispatcher.runDispatcher() - - errorIndication = cbCtx.get('errorIndication') - errorStatus = cbCtx.get('errorStatus') - errorIndex = cbCtx.get('errorIndex') - varBinds = cbCtx.get('varBinds', []) - else: - errorIndication = errorStatus = errorIndex = None - varBinds = [] - - yield errorIndication, errorStatus, errorIndex, varBinds diff --git a/pysnmp/hlapi/v3arch/asyncore/sync/ntforg.py b/pysnmp/hlapi/v3arch/asyncore/sync/ntforg.py index c466c869..e334eefd 100644 --- a/pysnmp/hlapi/v3arch/asyncore/sync/ntforg.py +++ b/pysnmp/hlapi/v3arch/asyncore/sync/ntforg.py @@ -4,18 +4,10 @@ # Copyright (c) 2005-2019, Ilya Etingof # License: http://snmplabs.com/pysnmp/license.html # -from sys import version_info from pysnmp.hlapi.v3arch.asyncore import ntforg __all__ = ['sendNotification'] -if version_info[:2] < (2, 6): - __all__.append('next') - - # noinspection PyShadowingBuiltins - def next(iter): - return iter.next() - def sendNotification(snmpEngine, authData, transportTarget, contextData, notifyType, *varBinds, **options): diff --git a/pysnmp/proto/rfc1902.py b/pysnmp/proto/rfc1902.py index 6c569a12..14900ce7 100644 --- a/pysnmp/proto/rfc1902.py +++ b/pysnmp/proto/rfc1902.py @@ -4,7 +4,6 @@ # Copyright (c) 2005-2019, Ilya Etingof # License: http://snmplabs.com/pysnmp/license.html # -from sys import version_info from pyasn1.type import univ, tag, constraint, namedtype, namedval from pysnmp.proto import rfc1155, error diff --git a/pysnmp/proto/secmod/rfc3414/priv/des.py b/pysnmp/proto/secmod/rfc3414/priv/des.py index c9b483a2..a9a1137c 100644 --- a/pysnmp/proto/secmod/rfc3414/priv/des.py +++ b/pysnmp/proto/secmod/rfc3414/priv/des.py @@ -16,8 +16,6 @@ except ImportError: md5 = md5.new sha1 = sha.new -from sys import version_info - try: from pysnmpcrypto import des, PysnmpCryptoError @@ -41,10 +39,7 @@ class Des(base.AbstractEncryptionService): SERVICE_ID = (1, 3, 6, 1, 6, 3, 10, 1, 2, 2) # usmDESPrivProtocol KEY_SIZE = 16 - if version_info < (2, 3): - local_int = int(random.random() * 0xffffffff) - else: - local_int = random.randrange(0, 0xffffffff) + local_int = random.randrange(0, 0xffffffff) def hashPassphrase(self, authProtocol, privKey): if authProtocol == hmacmd5.HmacMd5.SERVICE_ID: diff --git a/setup.py b/setup.py index 0ccc2376..317487d4 100644 --- a/setup.py +++ b/setup.py @@ -21,8 +21,6 @@ License :: OSI Approved :: BSD License Natural Language :: English Operating System :: OS Independent Programming Language :: Python :: 2 -Programming Language :: Python :: 2.4 -Programming Language :: Python :: 2.5 Programming Language :: Python :: 2.6 Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 @@ -53,8 +51,8 @@ def howto_install_setuptools(): py_version = sys.version_info[:2] -if py_version < (2, 4): - print("ERROR: this package requires Python 2.4 or later!") +if py_version < (2, 6): + print("ERROR: this package requires Python 2.6 or later!") sys.exit(1) requires = [ln.strip() for ln in open('requirements.txt').readlines()] @@ -159,7 +157,6 @@ params.update({ 'pysnmp.hlapi.v3arch.asyncio', 'pysnmp.hlapi.v3arch.asyncore', 'pysnmp.hlapi.v3arch.asyncore.sync', - 'pysnmp.hlapi.v3arch.asyncore.sync.compat', 'pysnmp.hlapi.v3arch.twisted', 'pysnmp.proto', 'pysnmp.proto.mpmod', -- cgit v1.2.1