X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/54ee272dfb207d6d20cd3217f7f100751496772d..71574cbaff3942fd35ceb2754cbfc36449856644:/catacomb/__init__.py diff --git a/catacomb/__init__.py b/catacomb/__init__.py index 508f1f8..26463b4 100644 --- a/catacomb/__init__.py +++ b/catacomb/__init__.py @@ -55,7 +55,8 @@ if _dlflags >= 0: else: pass # can't do this. _sys.setdlopenflags(_dlflags) -import _base +if _sys.version_info >= (3,): from . import _base +else: import _base if _odlflags >= 0: _sys.setdlopenflags(_odlflags) @@ -78,11 +79,23 @@ def default_lostexchook(why, ty, val, tb): lostexchook = default_lostexchook ## Text/binary conversions. -def _bin(s): return s +if _sys.version_info >= (3,): + def _bin(s): return s.encode('iso8859-1') +else: + def _bin(s): return s ## Iterating over dictionaries. -def _iteritems(dict): return dict.iteritems() -def _itervalues(dict): return dict.itervalues() +if _sys.version_info >= (3,): + def _iteritems(dict): return dict.items() + def _itervalues(dict): return dict.values() +else: + def _iteritems(dict): return dict.iteritems() + def _itervalues(dict): return dict.itervalues() + +## The built-in bignum type. +try: long +except NameError: _long = int +else: _long = long ## How to fix a name back into the right identifier. Alas, the rules are not ## consistent. @@ -174,14 +187,32 @@ def _pp_dict(pp, items): _pp_commas(pp, p, items) ###-------------------------------------------------------------------------- +### Mappings. + +if _sys.version_info >= (3,): + class _tmp: + def __str__(me): return '%s(%r)' % (type(me).__name__, list(me)) + __repr__ = __str__ + def _repr_pretty_(me, pp, cyclep): + ind = _pp_bgroup_tyname(pp, me, '([') + _pp_commas(pp, pp.pretty, me) + pp.end_group(ind, '])') + _augment(_base._KeyView, _tmp) + _augment(_base._ValueView, _tmp) + _augment(_base._ItemView, _tmp) + +###-------------------------------------------------------------------------- ### Bytestrings. class _tmp: def fromhex(x): return ByteString(_unhexify(x)) fromhex = staticmethod(fromhex) - def hex(me): return _hexify(me) - __hex__ = hex + if _sys.version_info >= (3,): + def hex(me): return _hexify(me).decode() + else: + def hex(me): return _hexify(me) + __hex__ = hex def __repr__(me): return 'bytes(%r)' % me.hex() _augment(ByteString, _tmp) @@ -385,8 +416,9 @@ class BaseRat (object): def __rtruediv__(me, you): n, d = _split_rat(you) return type(me)(me._d*n, me._n*d) - __div__ = __truediv__ - __rdiv__ = __rtruediv__ + if _sys.version_info < (3,): + __div__ = __truediv__ + __rdiv__ = __rtruediv__ def _order(me, you, op): n, d = _split_rat(you) return op(me._n*d, n*me._d) @@ -399,6 +431,10 @@ class BaseRat (object): class IntRat (BaseRat): RING = MP + def __new__(cls, a, b): + if isinstance(a, float) or isinstance(b, float): return a/b + return super(IntRat, cls).__new__(cls, a, b) + def __float__(me): return float(me._n)/float(me._d) class GFRat (BaseRat): RING = GF @@ -412,10 +448,15 @@ class _tmp: def mont(x): return MPMont(x) def barrett(x): return MPBarrett(x) def reduce(x): return MPReduce(x) - def __truediv__(me, you): return IntRat(me, you) - def __rtruediv__(me, you): return IntRat(you, me) - __div__ = __truediv__ - __rdiv__ = __rtruediv__ + def __truediv__(me, you): + if isinstance(you, float): return _long(me)/you + else: return IntRat(me, you) + def __rtruediv__(me, you): + if isinstance(you, float): return you/_long(me) + else: return IntRat(you, me) + if _sys.version_info < (3,): + __div__ = __truediv__ + __rdiv__ = __rtruediv__ _repr_pretty_ = _pp_str _augment(MP, _tmp) @@ -428,8 +469,9 @@ class _tmp: def quadsolve(x, y): return x.reduce().quadsolve(y) def __truediv__(me, you): return GFRat(me, you) def __rtruediv__(me, you): return GFRat(you, me) - __div__ = __truediv__ - __rdiv__ = __rtruediv__ + if _sys.version_info < (3,): + __div__ = __truediv__ + __rdiv__ = __rtruediv__ _repr_pretty_ = _pp_str _augment(GF, _tmp) @@ -449,7 +491,7 @@ class _tmp: _augment(Field, _tmp) class _tmp: - def __repr__(me): return '%s(%sL)' % (_clsname(me), me.p) + def __repr__(me): return '%s(%s)' % (_clsname(me), me.p) def __hash__(me): return 0x114401de ^ hash(me.p) def _repr_pretty_(me, pp, cyclep): ind = _pp_bgroup_tyname(pp, me) @@ -460,7 +502,7 @@ class _tmp: _augment(PrimeField, _tmp) class _tmp: - def __repr__(me): return '%s(%#xL)' % (_clsname(me), me.p) + def __repr__(me): return '%s(%#x)' % (_clsname(me), me.p) def ec(me, a, b): return ECBinProjCurve(me, a, b) def _repr_pretty_(me, pp, cyclep): ind = _pp_bgroup_tyname(pp, me) @@ -616,10 +658,10 @@ class _tmp: def check(me, sz): return me.min <= sz <= me.max and sz%me.mod == 0 def best(me, sz): if sz < me.min: raise ValueError('key too small') - elif sz > me.max: return me.max + elif me.max is not None and sz > me.max: return me.max else: return sz - sz%me.mod def pad(me, sz): - if sz > me.max: raise ValueError('key too large') + if me.max is not None and sz > me.max: raise ValueError('key too large') elif sz < me.min: return me.min else: sz += me.mod - 1; return sz - sz%me.mod _augment(KeySZRange, _tmp) @@ -655,10 +697,23 @@ _augment(KeySZSet, _tmp) ### Key data objects. class _tmp: + def merge(me, file, report = None): + """KF.merge(FILE, [report = ])""" + name = file.name + lno = 1 + for line in file: + me.mergeline(name, lno, line, report) + lno += 1 + return me def __repr__(me): return '%s(%r)' % (_clsname(me), me.name) _augment(KeyFile, _tmp) class _tmp: + def extract(me, file, filter = ''): + """KEY.extract(FILE, [filter = ])""" + line = me.extractline(filter) + file.write(line) + return me def __repr__(me): return '%s(%r)' % (_clsname(me), me.fulltag) _augment(Key, _tmp) @@ -688,27 +743,41 @@ class _tmp: pp.text(','); pp.breakable() pp.pretty(me.writeflags(me.flags)) pp.end_group(ind, ')') + def __hash__(me): return me._HASHBASE ^ hash(me._guts()) + def __eq__(me, kd): + return type(me) == type(kd) and \ + me._guts() == kd._guts() and \ + me.flags == kd.flags + def __ne__(me, kd): + return not me == kd _augment(KeyData, _tmp) class _tmp: def _guts(me): return me.bin + def __eq__(me, kd): + return isinstance(kd, KeyDataBinary) and me.bin == kd.bin _augment(KeyDataBinary, _tmp) +KeyDataBinary._HASHBASE = 0x961755c3 class _tmp: def _guts(me): return me.ct _augment(KeyDataEncrypted, _tmp) +KeyDataEncrypted._HASHBASE = 0xffe000d4 class _tmp: def _guts(me): return me.mp _augment(KeyDataMP, _tmp) +KeyDataMP._HASHBASE = 0x1cb64d69 class _tmp: def _guts(me): return me.str _augment(KeyDataString, _tmp) +KeyDataString._HASHBASE = 0x349c33ea class _tmp: def _guts(me): return me.ecpt _augment(KeyDataECPt, _tmp) +KeyDataECPt._HASHBASE = 0x2509718b class _tmp: def __repr__(me): @@ -719,7 +788,21 @@ class _tmp: if cyclep: pp.text('...') else: _pp_dict(pp, _iteritems(me)) pp.end_group(ind, ' })') + def __hash__(me): + h = me._HASHBASE + for k, v in _iteritems(me): + h = ((h << 1) ^ 3*hash(k) ^ 5*hash(v))&0xffffffff + return h + def __eq__(me, kd): + if type(me) != type(kd) or me.flags != kd.flags or len(me) != len(kd): + return False + for k, v in _iteritems(me): + try: vv = kd[k] + except KeyError: return False + if v != vv: return False + return True _augment(KeyDataStructured, _tmp) +KeyDataStructured._HASHBASE = 0x85851b21 ###-------------------------------------------------------------------------- ### Abstract groups.