diff --git a/pasn1.py b/pasn1.py index c1f6312..69d1b86 100644 --- a/pasn1.py +++ b/pasn1.py @@ -15,7 +15,7 @@ __author__ = 'John-Mark Gurney' __copyright__ = 'Copyright 2016 John-Mark Gurney. All rights reserved.' __license__ = '2-clause BSD license' -# Copyright 2016, John-Mark Gurney +# Copyright 2016-2019, John-Mark Gurney # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -321,12 +321,24 @@ class ASN1Coder(object): return r, end - def dumps(self, obj): - '''Convert obj into an array of bytes.''' + def dumps(self, obj, default=None): + '''Convert obj into an array of bytes. + + ``default(obj)`` is a function that should return a + serializable version of obj or raise TypeError. The + default simply raises TypeError. + ''' + try: tf = self._typemap[type(obj)] except KeyError: + if default is not None: + try: + return self.dumps(default(obj)) + except TypeError: + pass + if self.coerce is None: raise TypeError('unhandled object: %s' % `obj`) @@ -645,3 +657,19 @@ class TestCode(unittest.TestCase): '''Verify that ASN1Coder does not support dict.''' self.assertRaises(KeyError, ASN1Coder().loads, dumps({})) + + def test_dumps_default(self): + '''Test that dumps supports the default method, and that + it works.''' + + class Dummy(object): + def somefun(self): + return 5 + + def deffun(obj): + try: + return obj.somefun() + except Exception: + raise TypeError + + self.assertEqual(dumps(5), dumps(Dummy(), default=deffun))