@@ -21,8 +21,6 @@ import tempfile
import unittest
import uuid
from contextlib import nested
# The UUID for the namespace representing the path to a file
_NAMESPACE_MEDASHARE_PATH = uuid.UUID('f6f36b62-3770-4a68-bc3d-dc3e31e429e6')
@@ -31,7 +29,7 @@ _validhashes = set([ 'sha256', 'sha512' ])
_hashlengths = { len(getattr(hashlib, x)().hexdigest()): x for x in _validhashes }
def _iterdictlist(obj):
itms = obj.items()
itms = list( obj.items())
itms.sort()
for k, v in itms:
if isinstance(v, list):
@@ -72,7 +70,7 @@ class MDBase(object):
_common_properties = [ 'type', 'created_by_ref' ] # XXX - add lang?
_common_optional = set(('parent_refs', 'sig'))
_common_names = set(_common_properties + _generated_properties.keys())
_common_names = set(_common_properties + list( _generated_properties.keys() ))
def __init__(self, obj={}, **kwargs):
obj = copy.deepcopy(obj)
@@ -84,20 +82,20 @@ class MDBase(object):
if 'type' in obj and obj['type'] != self._type:
raise ValueError(
'trying to create the wrong type of object, got: %s, expected: %s' %
(`obj['type']`, `self._type` ))
(repr(obj['type']), repr(self._type) ))
if 'type' not in obj:
obj['type'] = self._type
for x in self._common_properties:
if x not in obj:
raise ValueError('common property %s not present' % `x` )
raise ValueError('common property %s not present' % repr(x) )
for x, fun in self._instance_properties.iterite ms():
for x, fun in self._instance_properties.items():
if x in obj:
obj[x] = fun(obj[x])
for x, fun in self._generated_properties.iterite ms():
for x, fun in self._generated_properties.items():
if x not in obj:
obj[x] = fun()
@@ -120,7 +118,7 @@ class MDBase(object):
return i(obj)
else:
raise ValueError('Unable to find class for type %s' %
`ty` )
repr(ty) )
def new_version(self, *args):
'''For each k, v pari, add the property k as an additional one
@@ -140,7 +138,7 @@ class MDBase(object):
return self.create_obj(obj)
def __repr__(self): # pragma: no cover
return '%s(%s)' % (self.__class__.__name__, `self._obj` )
return '%s(%s)' % (self.__class__.__name__, repr(self._obj) )
def __getattr__(self, k):
try:
@@ -161,13 +159,13 @@ class MDBase(object):
return self._obj
def __eq__(self, o):
return cmp(self._obj, o) == 0
return self._obj == o
def __contains__(self, k):
return k in self._obj
def items(self, skipcommon=True):
return [ (k, v) for k, v in self._obj.iterite ms() if
return [ (k, v) for k, v in self._obj.items() if
not skipcommon or k not in self._common_names ]
def encode(self):
@@ -188,7 +186,7 @@ class Identity(MDBase):
'created_by_ref' ]
_common_optional = set([ x for x in MDBase._common_optional if x !=
'parent_refs' ] + [ 'name', 'pubkey' ])
_common_names = set(_common_properties + MDBase._generated_properties.keys())
_common_names = set(_common_properties + list( MDBase._generated_properties.keys() ))
def _trytodict(o):
if isinstance(o, uuid.UUID):
@@ -196,13 +194,13 @@ def _trytodict(o):
try:
return 'dict', o.__to_dict__()
except Exception: # pragma: no cover
raise TypeError('unable to find __to_dict__ on %s: %s' % (type(o), `o` ))
raise TypeError('unable to find __to_dict__ on %s: %s' % (type(o), repr(o) ))
class CanonicalCoder(pasn1.ASN1DictCoder):
def enc_dict(self, obj, **kwargs):
class FakeIter:
def iterite ms(self):
itms = obj.items()
def items(self):
itms = list( obj.items())
itms.sort()
return iter(itms)
@@ -245,7 +243,7 @@ class Persona(object):
def __repr__(self): # pragma: no cover
r = '<Persona: has key: %s, has pubkey: %s, identity: %s>' % \
(self._key is not None, self._pubkey is not None,
`self._identity` )
repr(self._identity) )
return r
@@ -284,7 +282,7 @@ class Persona(object):
'''Store the Persona to a file. If there is a private
key associated w/ the Persona, it will be saved as well.'''
with open(fname, 'w') as fp:
with open(fname, 'wb ') as fp:
obj = {
'identity': self._identity,
}
@@ -299,7 +297,7 @@ class Persona(object):
def load(cls, fname):
'''Load the Persona from the provided file.'''
with open(fname) as fp:
with open(fname, 'rb' ) as fp:
objs = _asn1coder.loads(fp.read())
kwargs = {}
@@ -393,7 +391,8 @@ class ObjectStore(object):
hash = _hashlengths[len(hashstr)]
value = hashstr
if strict and len(str(value).translate(None, string.hexdigits.lower())) != 0:
bvalue = value.encode('ascii')
if strict and len(bvalue.translate(None, string.hexdigits.lower().encode('ascii'))) != 0:
raise ValueError('value has invalid hex digits (must be lower case)', value)
if hash in _validhashes:
@@ -408,10 +407,10 @@ class ObjectStore(object):
'''Write out the objects in the store to the file named
fname.'''
with open(fname, 'w') as fp:
with open(fname, 'wb ') as fp:
obj = {
'created_by_ref': self._created_by_ref,
'objects': self._uuids.values(),
'objects': list( self._uuids.values() ),
}
fp.write(_asn1coder.dumps(obj))
@@ -433,7 +432,7 @@ class ObjectStore(object):
The objects will be accessible via other methods.'''
with open(fname) as fp:
with open(fname, 'rb' ) as fp:
objs = _asn1coder.loads(fp.read())
obj = cls(objs['created_by_ref'])
@@ -481,7 +480,7 @@ class ObjectStore(object):
def _hashfile(fname):
hash = getattr(hashlib, _defaulthash)()
with open(fname) as fp:
with open(fname, 'rb' ) as fp:
r = fp.read()
hash.update(r)
@@ -521,8 +520,7 @@ def enumeratedir(_dir, created_by_ref):
Returned is a list of FileObjects.'''
return map(lambda x: FileObject.from_file(os.path.join(_dir, x), created_by_ref),
os.listdir(_dir))
return [FileObject.from_file(os.path.join(_dir, x), created_by_ref) for x in os.listdir(_dir)]
def main():
from optparse import OptionParser
@@ -545,13 +543,13 @@ def main():
options, args = parser.parse_args()
# this is shared between generateident and add
addprops = map(lambda x: x.split('=', 1), options.add)
addprops = [x.split('=', 1) for x in options.add]
if options.generateident or options.updateident or options.printpub:
identfname = os.path.expanduser('~/.medashare_identity.pasn1')
if options.generateident and os.path.exists(identfname):
print >>sys.stderr, 'Error: Identity already created.'
print('Error: Identity already created.', file=sys.stderr)
sys.exit(1)
if options.generateident:
@@ -561,7 +559,7 @@ def main():
persona = Persona.load(identfname)
if options.printpub:
print persona.get_pubkey( )
print(persona.get_pubkey() )
return
persona.new_version(*addprops)
@@ -578,7 +576,7 @@ def main():
for j in objstr.by_file(i):
#print >>sys.stderr, `j._obj`
for k, v in _iterdictlist(j):
print '%s:\t%s' % (k, v )
print('%s:\t%s' % (k, v) )
elif options.add:
for i in args:
for j in objstr.by_file(i):
@@ -607,14 +605,14 @@ if __name__ == '__main__': # pragma: no cover
class _TestCononicalCoder(unittest.TestCase):
def test_con(self):
obja = { 'foo': 23984732, 'a': 5, 'b': 6, 'something': '2398472398723498273dfasdfjlaksdfj' }
objaitems = obja.items()
objaitems = list( obja.items())
objaitems.sort()
objb = dict(objaitems)
self.assertEqual(obja, objb)
# This is to make sure that item order changed
self.assertNotEqual(obja.items(), objb.items())
self.assertNotEqual(list( obja.items() ), list( objb.items() ))
astr = pasn1.dumps(obja)
bstr = pasn1.dumps(objb)
@@ -709,7 +707,7 @@ class _TestCases(unittest.TestCase):
eobj = _asn1coder.loads(coded)
# the uuid property is a str instance
self.assertIsInstance(eobj['uuid'], str )
self.assertIsInstance(eobj['uuid'], bytes )
# and has the length of 16
self.assertEqual(len(eobj['uuid']), 16)
@@ -782,7 +780,7 @@ class _TestCases(unittest.TestCase):
# and that when you get it's properties
oobj = objst.by_id(oid)
odict = dict(oobj.items())
odict = dict(list( oobj.items() ))
# that is has the overlays property
self.assertEqual(odict['parent_refs'], [ bid ])
@@ -811,7 +809,7 @@ class _TestCases(unittest.TestCase):
# that the pubkey property is present
idobj = persona.get_identity()
self.assertIsInstance(idobj['pubkey'], str )
self.assertIsInstance(idobj['pubkey'], bytes )
# that get_pubkey returns the correct thing
pubstr = _asn1coder.dumps([ idobj.uuid, idobj['pubkey'] ])
@@ -819,7 +817,7 @@ class _TestCases(unittest.TestCase):
base58.b58encode_check(pubstr))
# and that there is a signature
self.assertIsInstance(idobj['sig'], str )
self.assertIsInstance(idobj['sig'], bytes )
# and that it can verify itself
persona.verify(idobj)
@@ -917,12 +915,12 @@ class _TestCases(unittest.TestCase):
r = byid
self.assertEqual(r.uuid, uuid.UUID('3e466e06-45de-4ecc-84ba-2d2a3d970e96'))
self.assertEqual(r['dc:creator'], [ u 'John-Mark Gurney' ])
self.assertEqual(r['dc:creator'], [ 'John-Mark Gurney' ])
fname = 'testfile.pasn1'
objst.store(fname)
with open(fname) as fp:
with open(fname, 'rb' ) as fp:
objs = _asn1coder.loads(fp.read())
os.unlink(fname)
@@ -968,15 +966,13 @@ class _TestCases(unittest.TestCase):
testfname = os.path.join(self.tempdir, 'test.txt')
import sys
import StringIO
import io
import itertools
with mock.patch('os.path.expanduser', side_effect=expandusermock) \
as eu:
# that generating a new identity
with nested(mock.patch('sys.stdout',
StringIO.StringIO()), mock.patch('sys.argv',
[ 'progname', '-g', '-a', 'name=A Test User' ])) as (stdout, argv):
with mock.patch('sys.stdout', io.StringIO()) as stdout, mock.patch('sys.argv', [ 'progname', '-g', '-a', 'name=A Test User' ]) as argv:
main()
# does not output anything
@@ -993,15 +989,13 @@ class _TestCases(unittest.TestCase):
self.assertEqual(pident.name, 'A Test User')
# that when generating an identity when one already exists
with nested(mock.patch('sys.stderr',
StringIO.StringIO()), mock.patch('sys.argv',
[ 'progname', '-g', '-a', 'name=A Test User' ])) as (stderr, argv):
with mock.patch('sys.stderr', io.StringIO()) as stderr, mock.patch('sys.argv', [ 'progname', '-g', '-a', 'name=A Test User' ]) as argv:
# that it exits
with self.assertRaises(SystemExit) as cm:
main()
# with error code 1
self.assertEqual(cm.exception[0] , 1)
self.assertEqual(cm.exception.code , 1)
# and outputs an error message
self.assertEqual(stderr.getvalue(),
@@ -1011,9 +1005,7 @@ class _TestCases(unittest.TestCase):
eu.assert_called_with('~/.medashare_identity.pasn1')
# that when updating the identity
with nested(mock.patch('sys.stdout',
StringIO.StringIO()), mock.patch('sys.argv',
[ 'progname', '-i', '-a', 'name=Changed Name' ])) as (stdout, argv):
with mock.patch('sys.stdout', io.StringIO()) as stdout, mock.patch('sys.argv', [ 'progname', '-i', '-a', 'name=Changed Name' ]) as argv:
main()
# it doesn't output anything
@@ -1038,9 +1030,7 @@ class _TestCases(unittest.TestCase):
self.assertTrue(persona.verify(nident))
# that when asked to print the public key
with nested(mock.patch('sys.stdout',
StringIO.StringIO()), mock.patch('sys.argv',
[ 'progname', '-p' ])) as (stdout, argv):
with mock.patch('sys.stdout', io.StringIO()) as stdout, mock.patch('sys.argv', [ 'progname', '-p' ]) as argv:
main()
# the correct key is printed
@@ -1050,58 +1040,40 @@ class _TestCases(unittest.TestCase):
# and looked up the correct file
eu.assert_called_with('~/.medashare_identity.pasn1')
with nested(mock.patch('sys.stdout',
StringIO.StringIO()), mock.patch('sys.argv',
[ 'progname', '-l', testfname ])) as (stdout, argv):
with mock.patch('sys.stdout', io.StringIO()) as stdout, mock.patch('sys.argv', [ 'progname', '-l', testfname ]) as argv:
main()
self.assertEqual(stdout.getvalue(),
'dc:creator:\tJohn-Mark Gurney\nhashes:\tsha256:91751cee0a1ab8414400238a761411daa29643ab4b8243e9a91649e25be53ada\nhashes:\tsha512:7d5768d47b6bc27dc4fa7e9732cfa2de506ca262a2749cb108923e5dddffde842bbfee6cb8d692fb43aca0f12946c521cce2633887914ca1f96898478d10ad3f\nlang:\ten\n')
eu.assert_called_with('~/.medashare_store.pasn1')
with nested(mock.patch('sys.stdout',
StringIO.StringIO()), mock.patch('sys.argv',
[ 'progname', '-a', 'dc:creator=Another user', '-a', 'foo=bar=baz', testfname ])) as (stdout, argv):
with mock.patch('sys.stdout', io.StringIO()) as stdout, mock.patch('sys.argv', [ 'progname', '-a', 'dc:creator=Another user', '-a', 'foo=bar=baz', testfname ]) as argv:
main()
with nested(mock.patch('sys.stdout',
StringIO.StringIO()), mock.patch('sys.argv',
[ 'progname', '-l', testfname ])) as (stdout, argv):
with mock.patch('sys.stdout', io.StringIO()) as stdout, mock.patch('sys.argv', [ 'progname', '-l', testfname ]) as argv:
main()
self.assertEqual(stdout.getvalue(),
'dc:creator:\tAnother user\ndc:creator:\tJohn-Mark Gurney\nfoo:\tbar=baz\nhashes:\tsha256:91751cee0a1ab8414400238a761411daa29643ab4b8243e9a91649e25be53ada\nhashes:\tsha512:7d5768d47b6bc27dc4fa7e9732cfa2de506ca262a2749cb108923e5dddffde842bbfee6cb8d692fb43aca0f12946c521cce2633887914ca1f96898478d10ad3f\nlang:\ten\n')
with nested(mock.patch('sys.stdout',
StringIO.StringIO()), mock.patch('sys.argv',
[ 'progname', '-d', 'dc:creator', testfname ])) as (stdout, argv):
with mock.patch('sys.stdout', io.StringIO()) as stdout, mock.patch('sys.argv', [ 'progname', '-d', 'dc:creator', testfname ]) as argv:
main()
with nested(mock.patch('sys.stdout',
StringIO.StringIO()), mock.patch('sys.argv',
[ 'progname', '-l', testfname ])) as (stdout, argv):
with mock.patch('sys.stdout', io.StringIO()) as stdout, mock.patch('sys.argv', [ 'progname', '-l', testfname ]) as argv:
main()
self.assertEqual(stdout.getvalue(),
'foo:\tbar=baz\nhashes:\tsha256:91751cee0a1ab8414400238a761411daa29643ab4b8243e9a91649e25be53ada\nhashes:\tsha512:7d5768d47b6bc27dc4fa7e9732cfa2de506ca262a2749cb108923e5dddffde842bbfee6cb8d692fb43aca0f12946c521cce2633887914ca1f96898478d10ad3f\nlang:\ten\n')
with nested(mock.patch('sys.stdout',
StringIO.StringIO()), mock.patch('sys.argv',
[ 'progname', '-a', 'foo=bleh', testfname ])) as (stdout, argv):
with mock.patch('sys.stdout', io.StringIO()) as stdout, mock.patch('sys.argv', [ 'progname', '-a', 'foo=bleh', testfname ]) as argv:
main()
with nested(mock.patch('sys.stdout',
StringIO.StringIO()), mock.patch('sys.argv',
[ 'progname', '-l', testfname ])) as (stdout, argv):
with mock.patch('sys.stdout', io.StringIO()) as stdout, mock.patch('sys.argv', [ 'progname', '-l', testfname ]) as argv:
main()
self.assertEqual(stdout.getvalue(),
'foo:\tbar=baz\nfoo:\tbleh\nhashes:\tsha256:91751cee0a1ab8414400238a761411daa29643ab4b8243e9a91649e25be53ada\nhashes:\tsha512:7d5768d47b6bc27dc4fa7e9732cfa2de506ca262a2749cb108923e5dddffde842bbfee6cb8d692fb43aca0f12946c521cce2633887914ca1f96898478d10ad3f\nlang:\ten\n')
with nested(mock.patch('sys.stdout',
StringIO.StringIO()), mock.patch('sys.argv',
[ 'progname', '-d', 'foo=bar=baz', testfname ])) as (stdout, argv):
with mock.patch('sys.stdout', io.StringIO()) as stdout, mock.patch('sys.argv', [ 'progname', '-d', 'foo=bar=baz', testfname ]) as argv:
main()
with nested(mock.patch('sys.stdout',
StringIO.StringIO()), mock.patch('sys.argv',
[ 'progname', '-l', testfname ])) as (stdout, argv):
with mock.patch('sys.stdout', io.StringIO()) as stdout, mock.patch('sys.argv', [ 'progname', '-l', testfname ]) as argv:
main()
self.assertEqual(stdout.getvalue(),
'foo:\tbleh\nhashes:\tsha256:91751cee0a1ab8414400238a761411daa29643ab4b8243e9a91649e25be53ada\nhashes:\tsha512:7d5768d47b6bc27dc4fa7e9732cfa2de506ca262a2749cb108923e5dddffde842bbfee6cb8d692fb43aca0f12946c521cce2633887914ca1f96898478d10ad3f\nlang:\ten\n')