TypeError: exceptions must derive from BaseException
Commit 66afc8921e4f5d3a41e407ab6d95ce7e4ec5383a introduces code that generates an type error -- TypeError: exceptions must derive from BaseException.
The problem seems to be that in multiple files the result of value.isInconsistent (boolean) is used to raise an exception (see code below).
inconsistency = value.isInconsistent
if inconsistency:
raise inconsistency
Effected files:
- pyasn1/codec/ber/decoder.py
- pyasn1/codec/ber/encoder.py
- pyasn1/codec/cer/encoder.py
- pyasn1/codec/native/encoder.py
Thank you for raising this problem!
However I do not see so far, how a boolean can end up being raised. Here is the code - if True, it should always be an exception object.
Do you have a reproducer handy?
At the moment I don't have a simple reproducer to hand -- but I will try to create one.
I couldn't find the problem in the code linked to above but after a little searching I found some issues in master. It looks like commit d0b7f2ec8677eec8f9aa31103a66f5cab18e9308 introduced two new isInconsistent() implementations in univ.py that can return either True or False, or raise an Exception:
- https://github.com/etingof/pyasn1/blob/40d5a7f27b8f56e103cdc83d3a294f02c5eb1496/pyasn1/type/univ.py#L2046
- https://github.com/etingof/pyasn1/blob/40d5a7f27b8f56e103cdc83d3a294f02c5eb1496/pyasn1/type/univ.py#L2676
Hope this helps/makes sense?
I'm encountering that issue trying to upgrade to 0.4.7. I get through this line: https://github.com/etingof/pyasn1/blob/6bb6e5b1cc752caf5c08cafca350644c8028dcda/pyasn1/type/univ.py#L2043. Unfortunately know very little about pyasn1, I can only tell it's trigger with pysnmp and SNMPv3.
Hi @etingof, any feedback on that one or the associated PR? Thanks.
I'm able to reliably reproduce this but in a massive codebase which just uses pysnmp for some simple querying. The first hook into pyasn1 code that causes this exception looks like this from pysnmp.proto.secmod.rfc3414.service.
from pyasn1.codec.ber import encoder
...
encoder.encode(msg)
When it blows up, at this point in the stacktrace msg is a pysnmp.proto.mpmod.rfc3412.SNMPv3Message.
From poking around in the debugger it seems like that class has quite a lot going on and isn't trivial to rebuild into a simple reproduction script.
Any advise on what I can do to extract the data in this class out in a form that could be used for debugging? I don't know how any of the pyasn1 code works enough to know what it should be doing to fix this myself. Today is my first foray into pysnmp/pyasn1.
The interesting part of my stacktrace is:
File "/home/jamie/path/to/snmp_manager.py", line 165, in snmp_get
lookupValues=lookup_values)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pysnmp/entity/rfc3413/oneliner/cmdgen.py", line 183, in getCmd
**kwargs):
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pysnmp/hlapi/asyncore/sync/cmdgen.py", line 111, in getCmd
lookupMib=options.get('lookupMib', True)))
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pysnmp/hlapi/asyncore/cmdgen.py", line 131, in getCmd
options.get('cbFun'), options.get('cbCtx'))
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pysnmp/entity/rfc3413/cmdgen.py", line 231, in sendVarBinds
(cbFun, cbCtx))
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pysnmp/entity/rfc3413/cmdgen.py", line 189, in sendPdu
(sendRequestHandle, cbFun, cbCtx)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pysnmp/proto/rfc3412.py", line 153, in sendPdu
pduVersion, PDU, expectResponse, sendPduHandle
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pysnmp/proto/mpmod/rfc3412.py", line 240, in prepareOutgoingMessage
securityEngineId, securityName, securityLevel, scopedPDU
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pysnmp/proto/secmod/rfc3414/service.py", line 525, in generateRequestMsg
None)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pysnmp/proto/secmod/rfc3414/service.py", line 497, in __generateRequestOrResponseMsg
authenticatedWholeMsg = encoder.encode(msg)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 832, in __call__
substrate = concreteEncoder.encode(value, asn1Spec, self, **options)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 102, in encode
value, asn1Spec, encodeFun, **options
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 588, in encodeValue
substrate += encodeFun(component, asn1Spec, **options)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 832, in __call__
substrate = concreteEncoder.encode(value, asn1Spec, self, **options)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 86, in encode
value, asn1Spec, encodeFun, **options
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 696, in encodeValue
return encodeFun(component, asn1Spec, **options), True, True
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 832, in __call__
substrate = concreteEncoder.encode(value, asn1Spec, self, **options)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 102, in encode
value, asn1Spec, encodeFun, **options
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 588, in encodeValue
substrate += encodeFun(component, asn1Spec, **options)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 832, in __call__
substrate = concreteEncoder.encode(value, asn1Spec, self, **options)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 86, in encode
value, asn1Spec, encodeFun, **options
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 696, in encodeValue
return encodeFun(component, asn1Spec, **options), True, True
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 832, in __call__
substrate = concreteEncoder.encode(value, asn1Spec, self, **options)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 102, in encode
value, asn1Spec, encodeFun, **options
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 588, in encodeValue
substrate += encodeFun(component, asn1Spec, **options)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 832, in __call__
substrate = concreteEncoder.encode(value, asn1Spec, self, **options)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 102, in encode
value, asn1Spec, encodeFun, **options
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 676, in encodeValue
value, asn1Spec, encodeFun, **options)
File "/home/jamie/.virtualenvs/venv/lib/python2.7/site-packages/pyasn1/codec/ber/encoder.py", line 650, in _encodeComponents
raise inconsistency
TypeError: exceptions must be old-style classes or derived from BaseException, not bool