Exemple #1
0
def test_view_random():

    sys.path.insert(
        0, os.path.abspath(os.path.join(__file__, '..', '..', '_tools')))
    import datagen

    excludes = {}
    for e in os.getenv('BSDF_TEST_EXCLUDES', '').split(','):
        excludes[e.strip()] = True

    types = list(datagen.ALL_TYPES)
    if 'ndarray' in excludes:
        types.remove('ndarray')

    # Process a few random dicts
    for iter in range(8):
        random.seed(time.time())
        data1 = datagen.random_dict(6, maxn=100, types=types)
        bsdf.save(tempfilename, data1)
        r, e = run_local('view', tempfilename)
        assert not e
        assert r
        # not much more to assert, except that it does not crash

    # Process a few random lists
    for iter in range(8):
        random.seed(time.time())
        data1 = datagen.random_list(6, maxn=100, types=types)
        bsdf.save(tempfilename, data1)
        r, e = run_local('view', tempfilename)
        assert not e
        assert r
Exemple #2
0
def test_info():
    data1 = [3, 4, 5]
    bsdf.save(tempfilename, data1)

    r, e = run_local('info', tempfilename)
    r = r.replace('    ', ' ').replace('  ', ' ').replace('  ', ' ')
    assert not e
    assert 'file_size' in r
    assert 'valid: true' in r
    assert 'version:' in r

    # Not a file
    r, e = run_local('info', '~/foo_does_not_exist.bsdf')
    assert not r
    assert 'invalid file' in e

    # Not a bsdf file
    with open(tempfilename, 'wb') as f:
        pass
    r, e = run_local('info', tempfilename)
    r = r.replace('    ', ' ').replace('  ', ' ').replace('  ', ' ')
    assert not e
    assert 'file_size' in r
    assert 'valid: false' in r
    assert 'version: ?' in r
Exemple #3
0
def save(fname, data):
    """ Save to json or bsdf, depending on the extension. """
    if fname.endswith('.json'):
        with open(fname, 'wt', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False)
    elif fname.endswith('.bsdf'):
        bsdf.save(fname, data)
    else:
        assert False
Exemple #4
0
def test_streaming_closing123():
    """ Writing a streamed list, closing the stream. """
    for iter in range(4):

        f = io.BytesIO()

        thelist = bsdf.ListStream()
        bsdf.save(f, thelist)

        thelist.append('hi')

        # closing here will write the length of the stream, marking the stream as closed
        if iter in (1, 2):
            thelist.close()

        for i in range(3):
            thelist.append(i)

        if iter == 2:
            thelist.close()
        if iter == 3:
            thelist.close(True)

        assert thelist.count == 4
        assert thelist.index == thelist.count

        bb = f.getvalue()
        b1 = bsdf.decode(bb)
        b2 = bsdf.decode(bb, load_streaming=True)

        if iter in (0, 1, 2):
            assert isinstance(b2, bsdf.ListStream) and not isinstance(b2, list)
        else:
            assert not isinstance(b2, bsdf.ListStream) and isinstance(b2, list)

        if iter == 0:
            # Not closed
            assert b1 == ['hi', 0, 1, 2]
            assert list(b2) == ['hi', 0, 1, 2]
        elif iter == 1:
            # Closed, and elements added later
            assert b1 == ['hi']
            assert list(b2) == ['hi']
        elif iter == 2:
            # Closed twice
            assert b1 == ['hi', 0, 1, 2]
            assert list(b2) == ['hi', 0, 1, 2]
        elif iter == 3:
            # Closed twice
            assert b1 == ['hi', 0, 1, 2]
            assert list(b2) == ['hi', 0, 1, 2]
        else:
            assert False
Exemple #5
0
def test_liststreaming_reading1():
    """ Reading a streamed list. """
    f = io.BytesIO()

    thelist = bsdf.ListStream()
    a = [3, 4, thelist]

    bsdf.save(f, a)

    thelist.append('hi')
    for i in range(3):
        thelist.append(i)

    bb = f.getvalue()
    b = bsdf.decode(bb, load_streaming=True)

    x = b[-1]
    assert isinstance(x, bsdf.ListStream)

    assert x.next() == 'hi'
    assert x.next() == 0
    assert x.next() == 1
    assert x.next() == 2
    with raises(StopIteration):
        x.next()

    # Support iteration
    b = bsdf.decode(bb, load_streaming=True)
    x = b[-1]
    xx = [i for i in x]
    assert xx == ['hi', 0, 1, 2]

    # Cannot read after file is closed
    f = io.BytesIO(bb)
    b = bsdf.load(f, load_streaming=True)
    x = b[-1]
    f.close()
    with raises(IOError):
        x.next()

    # Cannot read when in read-mode
    ls = bsdf.ListStream()
    with raises(IOError):
        ls.next()
    with raises(IOError):
        list(ls)

    # mmm, this would never happen, I guess, but need associated file!
    ls = bsdf.ListStream('r')
    with raises(IOError):
        ls.next()
Exemple #6
0
def cmd_create(filename, code):
    """ Create a BSDF file from data obtained by evaluation Python code.

    Usage: bsdf filename code

    examples:
      bsdf foo.bsdf {meaning:42}
      bsdf bar.bsdf [3,4]*100

    """
    try:
        data = eval(code)
    except Exception as err:
        raise Exception('Could not evaluate Python code to generate data:'
                        '\n  ' + str(err))
    bsdf.save(filename, data)
Exemple #7
0
def cmd_convert(filename1, filename2):
    """ Convert one format into another (e.g. JSON to BSDF).

    Formats currently supported are: JSON, BSDF.
    Note that conversion might fail (e.g. JSON does not support binary blobs).

    Usage: bsdf convert filename1 filename2

    File types are derived from the extensions.
    """
    fname1 = filename1.lower()
    fname2 = filename2.lower()

    if fname1.endswith('.json'):
        with open(filename1, 'rt', encoding='utf-8') as f:
            data = json.load(f)
    elif fname1.endswith('.bsdf'):
        with open(filename1, 'rb') as f:
            data = bsdf.load(f)
    else:
        fail('Unknown load format extension for %r' % filename1)

    try:
        if fname2.endswith('.json'):
            okw = dict(mode='wt', encoding='utf-8')
            okw = dict(mode='wb') if sys.version_info < (3, ) else okw
            with open(filename2, **okw) as f:
                json.dump(data, f)
        elif fname2.endswith('.bsdf'):
            with open(filename2, 'wb') as f:
                bsdf.save(f, data)
        else:
            fail('Unknown save format extension for %r' % filename1)
    except Exception:
        try:
            os.remove(filename2)
        except Exception:  # pragma: no cover
            pass
        raise

    _print('Wrote', filename2)
Exemple #8
0
def test_liststreaming1():
    """ Writing a streamed list. """
    f = io.BytesIO()

    thelist = bsdf.ListStream()
    a = [3, 4, thelist]

    bsdf.save(f, a)

    thelist.append('hi')
    for i in range(10):
        thelist.append(i * 101)
    thelist.append((4, 2))

    thelist.close()
    bb = f.getvalue()
    b = bsdf.decode(bb)

    assert b[-1] == [
        'hi', 0, 101, 202, 303, 404, 505, 606, 707, 808, 909, [4, 2]
    ]
Exemple #9
0
def test_loaders_and_savers():

    # load and save is already tested above and in many other places

    s1 = dict(foo=42, bar=[1, 2.1, False, 'spam', b'eggs'])

    # In-memory
    bb = bsdf.encode(s1)
    s2 = bsdf.decode(bb)
    assert s1 == s2

    # Using a filename
    bsdf.save(tempfilename, s1)
    s2 = bsdf.load(tempfilename)
    assert s1 == s2

    # Using a file object
    with open(tempfilename, 'wb') as f:
        bsdf.save(f, s1)
    with open(tempfilename, 'rb') as f:
        s2 = bsdf.load(f)
    assert s1 == s2

    # Using a very strict file object
    with open(tempfilename, 'wb') as f:
        bsdf.save(StrictWriteFile(f), s1)
    with open(tempfilename, 'rb') as f:
        s2 = bsdf.load(StrictReadFile(f))
    assert s1 == s2
Exemple #10
0
def test_convert():
    tempfilename1 = tempfilename
    tempfilename2 = tempfilename + '.json'

    data1 = [4, 5, 6]
    bsdf.save(tempfilename, data1)

    # Convert to json
    r, e = run_local('convert', tempfilename1, tempfilename2)
    assert not e
    assert tempfilename2 in r

    # Convert back
    r, e = run_local('convert', tempfilename2, tempfilename1)
    assert not e
    assert tempfilename1 in r

    # Check
    assert open(tempfilename2, 'rb').read().decode().strip() == '[4, 5, 6]'
    data2 = bsdf.load(tempfilename)
    assert data1 == data2

    # Fail, unknown extension
    r, e = run_local('convert', tempfilename1 + '.png', tempfilename1)
    assert not r
    assert 'unknown' in e.lower() and 'extension' in e.lower() and 'load' in e
    #
    r, e = run_local('convert', tempfilename1, tempfilename1 + '.png')
    assert not r
    assert 'unknown' in e.lower() and 'extension' in e.lower() and 'save' in e

    if sys.version_info < (3, ):
        return

    # Cannot convert bytes and nan
    bsdf.save(tempfilename, [bsdf.Blob(b'xx'), float('nan')])
    r, e = run_local('convert', tempfilename1, tempfilename2)
    assert not r
    assert 'not JSON serializable' in e
    assert not os.path.isfile(tempfilename2)  # file was deleted/not written
Exemple #11
0
def test_blob_modding3():  # actual files
    bsdf.save(tempfilename, bsdf.Blob(b'xxyyzz', extra_size=2))

    # Can read, but not modify in rb mode
    with open(tempfilename, 'rb') as f:
        blob = bsdf.load(f, lazy_blob=True)

        blob.seek(0)
        assert blob.read(2) == b'xx'
        blob.seek(4)
        with raises(IOError):
            blob.write(b'aa')

    # But we can in a+ mode
    with open(tempfilename, 'r+b') as f:
        blob = bsdf.load(f, lazy_blob=True)

        blob.seek(0)
        assert blob.read(2) == b'xx'
        blob.seek(4)
        blob.write(b'aa')

    assert bsdf.load(tempfilename) == b'xxyyaa'
Exemple #12
0
def test_liststream_modding():

    # Create a file
    ls = bsdf.ListStream()
    with open(tempfilename, 'wb') as f:
        bsdf.save(f, ls)
        ls.append('foo')
        ls.append('bar')

    assert bsdf.load(tempfilename) == ['foo', 'bar']

    # Append items hard-core more
    with open(tempfilename, 'ab') as f:
        f.write(b'v')
        f.write(b'h*\x00')  # ord('*') == 42

    assert bsdf.load(tempfilename) == ['foo', 'bar', None, 42]

    # Append items using the BSDF API
    with open(tempfilename, 'r+b') as f:
        ls = bsdf.load(f, load_streaming=True)
        for i in ls:
            pass
        ls.append(4)
        ls.append(5)
        ls.close()  # also close here

    assert bsdf.load(tempfilename) == ['foo', 'bar', None, 42, 4, 5]

    # Try adding more items
    with open(tempfilename, 'ab') as f:
        f.write(b'v')
        f.write(b'h*\x00')  # ord('*') == 42

    # But no effect
    assert bsdf.load(tempfilename) == ['foo', 'bar', None, 42, 4, 5]
Exemple #13
0
from io import open  # pypy and py27 compat

import bsdf


# Get filenames
fname1 = sys.argv[1]
fname2 = sys.argv[2]
assert os.path.isfile(fname1)
assert not os.path.isfile(fname2)

# Read data
if fname1.endswith('.json'):
    with open(fname1, 'rt', encoding='utf-8') as f:
        data = json.load(f)
elif fname1.endswith('.bsdf'):
    data = bsdf.load(fname1)
else:
    raise NotImplementedError()

# Write data
if fname2.endswith('.json'):
    okw = dict(mode='wt', encoding='utf-8')
    okw = dict(mode='wb') if sys.version_info < (3, ) else okw
    with open(fname2, **okw) as f:
        json.dump(data, f)
elif fname2.endswith('.bsdf'):
    bsdf.save(fname2, data)
else:
    raise NotImplementedError()
Exemple #14
0
def test_bsdf_to_bsdf_extensions(**excludes):

    # Test extension using complex number
    fname1, fname2 = get_filenames('.bsdf', '.bsdf')
    data1 = 3 + 4j
    try:
        bsdf.save(fname1, data1)
        invoke_runner(fname1, fname2)
        data2 = bsdf.load(fname2)
    except Exception:
        print(data1)
        raise
    finally:
        remove(fname1, fname2)
    assert isinstance(data2, complex)
    assert data1 == data2
    print_dot()

    # Test extension using nd arrays
    if 'ndarray' not in excludes:
        import numpy as np

        for dtype in ['uint8', 'int16', 'int32', 'float32']:
            for shape in [(24, ), (24, 1), (1, 24), (4, 6), (2, 3, 4)]:
                # uint8 is tricky since it may represent bytes in e.g. Matlab
                if 'uint8_1d' in excludes:
                    if dtype == 'uint8' and len(shape) == 1 or min(shape) == 1:
                        continue
                data1 = np.arange(24, dtype=dtype)
                data1.shape = shape
                try:
                    bsdf.save(fname1, data1)
                    invoke_runner(fname1, fname2)
                    data2 = bsdf.load(fname2)
                except Exception:
                    print(data1)
                    raise
                finally:
                    remove(fname1, fname2)
                assert isinstance(data2, np.ndarray)
                if shape == (24, ):  # Matlab ...
                    assert data2.shape == (24, ) or data2.shape == (
                        24, 1) or data2.shape == (1, 24)
                else:
                    assert data2.shape == shape
                assert data2.dtype == dtype
                assert np.all(data1 == data2)
                print_dot()

    # Deal with unknown extensions by leaving data through
    class MyExtension(bsdf.Extension):
        name = 'test.foo'
        cls = threading.Thread

        def encode(self, s, v):
            return [7, 42]

        def decode(self, s, v):
            return None

    fname1, fname2 = get_filenames('.bsdf', '.bsdf')
    data1 = ['hi', threading.Thread(), 'there']
    try:
        bsdf.save(fname1, data1, [MyExtension])
        invoke_runner(fname1, fname2)
        data2 = bsdf.load(fname2)
    except Exception:
        print(data1)
        raise
    finally:
        remove(fname1, fname2)
    assert data2 == ['hi', [7, 42], 'there']
    print_dot()
Exemple #15
0
def test_bsdf_to_bsdf(**excludes):

    # Just repeat these
    for data1 in JSON_ABLE_OBJECTS[:-1]:
        fname1, fname2 = get_filenames('.bsdf', '.bsdf')
        data2 = convert_data(fname1, fname2, data1)
        compare_data(data1, data2)
        print_dot()

    # Singletons, some JSON implementations choke on these
    for data1 in [None, False, True, 3.4, '', 'hello', [], {}, b'', b'xx']:
        fname1, fname2 = get_filenames('.bsdf', '.bsdf')
        data2 = convert_data(fname1, fname2, data1)
        compare_data(data1, data2)
        assert str(data1) == str(data2), str(
            (data1, data2))  # because False != 0
        print_dot()

    for data1 in [0, 1, 0.0, 1.0, 4]:
        fname1, fname2 = get_filenames('.bsdf', '.bsdf')
        data2 = convert_data(fname1, fname2, data1)
        compare_data(data1, data2)
        if 'roundfloatisnotint' not in excludes:
            assert str(data1) == str(data2), str(
                (data1, data2))  # because 0.0 != 0
        print_dot()

    # Special values
    for data1 in [float('nan'), float('inf'), float('-inf')]:
        fname1, fname2 = get_filenames('.bsdf', '.bsdf')
        data2 = convert_data(fname1, fname2, data1)
        #compare_data(data1, data2)
        assert str(data1) == str(data2)  # because nan != nan
        print_dot()

    # Use float32 for encoding floats
    fname1, fname2 = get_filenames('.bsdf', '.bsdf')
    data1 = [1, 2, 3, 4.2, 5.6, 6.001]
    try:
        bsdf.save(fname1, data1, float64=False)
        invoke_runner(fname1, fname2)
        data2 = bsdf.load(fname2)
    except Exception:
        print(data1)
        raise
    finally:
        remove(fname1, fname2)
    assert data1 != data2
    assert all([(abs(d1 - d2) < 0.001) for d1, d2 in zip(data1, data2)])
    print_dot()

    # Test bytes / blobs
    # We do not test compression in shared tests, since its not a strict requirement
    for data1 in [
        [3, 4, b'', b'x', b'yyy', 5],
        [
            5, 6,
            bsdf.Blob(b'foo', compression=0, extra_size=20,
                      use_checksum=False), 7
        ],
        [
            5, 6,
            bsdf.Blob(b'foo', compression=0, extra_size=10, use_checksum=True),
            7
        ],
    ]:
        fname1, fname2 = get_filenames('.bsdf', '.bsdf')
        data2 = convert_data(fname1, fname2, data1)
        # Compare, but turn blobs into bytes
        data1 = [
            x.get_bytes() if isinstance(x, bsdf.Blob) else x for x in data1
        ]
        compare_data(data1, data2)
        print_dot()

    # Test alignment
    for i in range(9):
        data1 = ['x' * i, b'd']  # ord('d') == 100
        fname1, fname2 = get_filenames('.bsdf', '.bsdf')
        try:
            save(fname1, data1)
            invoke_runner(fname1, fname2)
            raw2 = open(fname2, 'rb').read()
        except Exception:
            print(data1)
            raise
        finally:
            remove(fname1, fname2)
        index = raw2.find(100)
        assert index % 8 == 0

    # Test stream 1 (unclosed)
    s = bsdf.ListStream()
    data1 = [3, 4, 5, s]
    #
    fname1, fname2 = get_filenames('.bsdf', '.bsdf')
    with open(fname1, 'wb') as f:
        bsdf.save(f, data1)
        s.append(6)
        s.append(7)
        s.append(8)
        s.append(9)
    invoke_runner(fname1, fname2)
    data2 = bsdf.load(fname2)
    assert data2 == [3, 4, 5, [6, 7, 8, 9]]
    print_dot()

    # Test stream 2 (closed early)
    s = bsdf.ListStream()
    data1 = [3, 4, 5, s]
    #
    fname1, fname2 = get_filenames('.bsdf', '.bsdf')
    with open(fname1, 'wb') as f:
        bsdf.save(f, data1)
        s.append(6)
        s.append(7)
        s.close()
        s.append(8)
        s.append(9)
    invoke_runner(fname1, fname2)
    data2 = bsdf.load(fname2)
    assert data2 == [3, 4, 5, [6, 7]]
    print_dot()

    # Test stream 3 (closed twice)
    s = bsdf.ListStream()
    data1 = [3, 4, 5, s]
    #
    fname1, fname2 = get_filenames('.bsdf', '.bsdf')
    with open(fname1, 'wb') as f:
        bsdf.save(f, data1)
        s.append(6)
        s.append(7)
        s.close()
        s.append(8)
        s.append(9)
        s.close()
    invoke_runner(fname1, fname2)
    data2 = bsdf.load(fname2)
    assert data2 == [3, 4, 5, [6, 7, 8, 9]]
    print_dot()

    # Test stream 4 (close hard)
    s = bsdf.ListStream()
    data1 = [3, 4, 5, s]
    #
    fname1, fname2 = get_filenames('.bsdf', '.bsdf')
    with open(fname1, 'wb') as f:
        bsdf.save(f, data1)
        s.append(6)
        s.append(7)
        s.close(True)
    invoke_runner(fname1, fname2)
    data2 = bsdf.load(fname2)
    assert data2 == [3, 4, 5, [6, 7]]
    print_dot()
Exemple #16
0
def test_view():

    # Create file
    data1 = [1, 2, 3, [4, 4, 4, 4, 4], 8, 9]
    bsdf.save(tempfilename, data1)

    # Test content, plain
    r, e = run_local('view', tempfilename)
    assert not e
    assert tempfilename not in r
    assert r.count('4') == 5
    assert '5' in r  # number of elements in inner list
    assert '6' in r  # number of elements in outer list

    # Test content, plus info
    r, e = run_local('view', tempfilename, '--info')
    assert not e
    assert tempfilename in r
    assert 'file_size:' in r
    assert r.count('4') >= 5  # can also occur in meta info
    assert '5' in r  # number of elements in inner list
    assert '6' in r  # number of elements in outer list

    # Test content, max depth 1
    r, e = run_local('view', tempfilename, '--depth=1')
    assert not e
    assert r.count('4') == 0  # collapsed
    assert '5' in r  # number of elements in inner list
    assert '6' in r  # number of elements in outer list

    # Test content, max depth 0
    r, e = run_local('view', tempfilename, '--depth=0')
    assert not e
    assert r.count('\n') == 1  # all collapsed
    assert '5' not in r  # number of elements in inner list
    assert '6' in r  # number of elements in outer list

    # Fail - not a file
    r, e = run_local('view', '~/foo_does_not_exist.bsdf')
    assert not r
    assert 'invalid file' in e

    # Fail - not a bsdf file
    with open(tempfilename, 'wb') as f:
        pass
    r, e = run_local('view', tempfilename)
    assert not r
    assert 'does not look like a BSDF file' in e

    # Fail - major version is off
    bb = bsdf.encode(data1)
    with open(tempfilename, 'wb') as f:
        f.write(bb[:4] + b'\x00' + bb[5:])
    r, e = run_local('view', tempfilename)
    assert r == '' and 'different major version' in e

    # Warn - minor version is lower than file
    bb = bsdf.encode(data1)
    with open(tempfilename, 'wb') as f:
        f.write(bb[:5] + b'\xff' + bb[6:])
    r, e = run_local('view', tempfilename)
    assert not e
    assert 'higher minor version' in r
    assert r.count('4') >= 5

    # Test string truncation
    too_long = u'x' * 200
    just_right = u'x' + '_' * 38 + 'x'
    data1 = [too_long, just_right]
    bsdf.save(tempfilename, data1)
    r, e = run_local('view', tempfilename)
    assert not e
    assert too_long not in r and ('x' * 39 + u'\u2026') in r.replace(
        '\\u2026', u'\u2026')
    assert just_right in r

    # Test float32 for cov
    data1 = [3.14159, 42.0]
    bsdf.save(tempfilename, data1, float64=False)
    r, e = run_local('view', tempfilename)
    assert not e
    assert '3.14159' in r and '42.0' in r

    # Test unclosed stream
    s = bsdf.ListStream()
    data1 = [3, 4, 5, s]
    #
    with open(tempfilename, 'wb') as f:
        bsdf.save(f, data1)
        s.append(6)
        s.append(7)
    #
    r, e = run_local('view', tempfilename)
    assert not e
    assert '6' in r and '7' in r
    assert 'stream' in r and not '2' in r
Exemple #17
0
def save_bsdf(filename, object, encode=True):
    ''' save object to a BSDF file. optionally BSDF-encoded to bytes. '''
    if encode:
        object = bsdf.encode(object)  # type: bytes
    bsdf.save(filename, object)
Exemple #18
0
def test_liststreaming_write_fails():

    # Only write mode
    f = io.BytesIO()
    ls = bsdf.ListStream('r')
    with raises(ValueError):
        bsdf.save(f, ls)
    with raises(IOError):
        ls.append(3)
    with raises(IOError):
        ls.close()

    # Dont append (or close) before use
    ls = bsdf.ListStream()
    with raises(IOError):
        ls.append(3)
    with raises(IOError):
        ls.close()

    # Only use once!
    f = io.BytesIO()
    ls = bsdf.ListStream()
    bsdf.save(f, ls)
    with raises(IOError):
        bsdf.save(f, ls)

    # Do not write when closed!
    f = io.BytesIO()
    ls = bsdf.ListStream()
    bsdf.save(f, ls)
    f.close()
    with raises(IOError):
        ls.append(3)
    with raises(IOError):
        ls.close()

    # Only ListStream
    class MyStream(bsdf.BaseStream):
        pass

    f = io.BytesIO()
    a = [3, 4, MyStream()]
    with raises(TypeError):
        bsdf.save(f, a)

    # Only one!
    f = io.BytesIO()
    a = [3, 4, bsdf.ListStream(), bsdf.ListStream()]
    with raises(ValueError):
        bsdf.save(f, a)

    # Stream must be at the end
    f = io.BytesIO()
    a = [3, 4, bsdf.ListStream(), 5]
    with raises(ValueError):
        bsdf.save(f, a)