X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/7f5c0c27f85afa10f7a123e4bde03534602b6619..f05b013bba23c63a664053c91e5107a25b67b933:/catacomb/pwsafe.py diff --git a/catacomb/pwsafe.py b/catacomb/pwsafe.py index 7951e0a..944cfa7 100644 --- a/catacomb/pwsafe.py +++ b/catacomb/pwsafe.py @@ -28,26 +28,40 @@ from __future__ import with_statement +import binascii as _B import errno as _E import os as _OS -from cStringIO import StringIO as _StringIO +import sys as _SYS + +if _SYS.version_info >= (3,): from io import StringIO as _StringIO +else: from cStringIO import StringIO as _StringIO import catacomb as _C ###-------------------------------------------------------------------------- ### Python version portability. -def _iterkeys(dict): return dict.iterkeys() -def _itervalues(dict): return dict.itervalues() -def _iteritems(dict): return dict.iteritems() - -def _bin(text): return text -def _text(bin): return bin +if _SYS.version_info >= (3,): + def _iterkeys(dict): return dict.keys() + def _itervalues(dict): return dict.values() + def _iteritems(dict): return dict.items() + def _bin(text): return text.encode(errors = "surrogateescape") + def _text(bin): return bin.decode(errors = "surrogateescape") +else: + def _iterkeys(dict): return dict.iterkeys() + def _itervalues(dict): return dict.itervalues() + def _iteritems(dict): return dict.iteritems() + def _bin(text): return text + def _text(bin): return bin _NUL = _bin('\0') _CIPHER = _bin('cipher:') _MAC = _bin('mac:') +def _with_metaclass(meta, *supers): + return meta("#" % meta.__name__, + supers or (object,), dict()) + def _excval(): return SYS.exc_info()[1] _M600 = int("600", 8) @@ -99,10 +113,10 @@ def _dec_metaname(name): def _b64(s): """Encode S as base64, without newlines, and trimming `=' padding.""" - return s.encode('base64').replace('\n', '').rstrip('=') + return _text(_B.b2a_base64(s)).replace('\n', '').rstrip('=') def _unb64(s): """Decode S as base64 with trimmed `=' padding.""" - return (s + '='*((4 - len(s))%4)).decode('base64') + return _B.a2b_base64(s + '='*((4 - len(s))%4)) def _enc_metaval(val): """Encode VAL as a metadata item value, returning the result.""" @@ -235,7 +249,7 @@ class StorageBackendClass (type): except AttributeError: pass else: StorageBackend.register_concrete_subclass(me) -class StorageBackend (object): +class StorageBackend (_with_metaclass(StorageBackendClass)): """ I provide basic protocol for password storage backends. @@ -303,7 +317,6 @@ class StorageBackend (object): priority order when opening an existing database. """ - __metaclass__ = StorageBackendClass PRIO = 10 ## The registry of subclasses.