def test_mupdfcpp_swig( out, log):
    '''
    Test the python API.
    '''
    
    # It looks like import doesn't pick local files if this file is a softlink, so
    # force things here.
    sys.path.append( os.getcwd())
    
    import mupdf
    
    log( 'have imported mupdfcpp_swig')

    if 1:
        # Test operations using functions:
        #
        log( 'Testing functions.')
        filename = 'mupdf/thirdparty/zlib/zlib.3.pdf'
        log( '    Opening {filename}')
        if rename == RenameSnake:
            document = mupdf.open_document('mupdf/thirdparty/zlib/zlib.3.pdf')
        else:
            document = mupdf.open_document('mupdf/thirdparty/zlib/zlib.3.pdf')
        log( '    {mupdf.needs_password( document)=}')
        log( '    {mupdf.needs_password( document)=}')
        log( '    {mupdf.count_pages( document)=}')
        log( '    {mupdf.document_output_intent( document)=}')

    # Test operations using classes:
    #
    log( 'Testing classes')
    
    filename = '/home/jules/artifex/testfiles/pdf_reference17.pdf'
    document = mupdf.Document( filename)
    log( 'Have create document for {filename}')
    log( '{document.needs_password()=}')
    log( '{document.count_pages()=}')

    zoom = 10
    scale = mupdf.Matrix.scale( zoom/100., zoom/100.)
    page_number = 0
    log( 'Have created scale: a={scale.a} b={scale.b} c={scale.c} d={scale.d} e={scale.e} f={scale.f}')

    colorspace = mupdf.Colorspace( mupdf.Colorspace.Fixed_RGB)
    log( '{colorspace.m_internal.key_storable.storable.refs=}')
    pixmap = mupdf.Pixmap( document, page_number, scale, colorspace, 0)
    log( 'Have created pixmap: {pixmap.m_internal.w=} {pixmap.m_internal.h=} {pixmap.m_internal.stride=} {pixmap.m_internal.n=}')
    
    filename = 'mupdf_test/out.png'
    pixmap.save_pixmap_as_png( filename)
    log( 'Have created {filename=} using pixmap.save_pixmap_as_png().')
    

    # Print image data in ascii PPM format. Copied from
    # mupdf/docs/examples/example.c.
    #
    samples = pixmap.m_internal.samples
    stride = pixmap.m_internal.stride
    n = pixmap.m_internal.n
    filename = 'mupdf_test/out.ppm'
    with open( filename, 'w') as f:
        f.write( 'P3\n')
        f.write( '%s %s\n' % (pixmap.m_internal.w, pixmap.m_internal.h))
        f.write( '255\n')
        for y in range( 0, pixmap.m_internal.h):
            for x in range( pixmap.m_internal.w):
                if x:
                    f.write( '  ')
                offset = y * stride + x * n
                f.write( '%3d %3d %3d' % (
                        mupdf.bytes_getitem( samples, offset + 0),
                        mupdf.bytes_getitem( samples, offset + 1),
                        mupdf.bytes_getitem( samples, offset + 2),
                        ))
            f.write( '\n')
    log( 'Have created {filename=} by scanning pixmap.')

    # Generate .png and but create Pixmap from Page instead of from Document.
    #
    page = mupdf.Page(document, 0)
    separations = page.page_separations()
    log( 'page_separations() returned {"true" if separations else "false"}')
    pixmap = mupdf.Pixmap( page, scale, colorspace, 0, mupdf.Pixmap.From_PAGE)
    filename = 'mupdf_test/out2.png'
    pixmap.save_pixmap_as_png( filename)
    log( 'Have created {filename=} using pixmap.save_pixmap_as_png()')

    # Show links
    log( 'Links.')
    page = mupdf.Page(document, 0)
    link = mupdf.load_links( page.m_internal);
    log( '{link=}')
    if link:
        for i in link:
            log( '{i=}')

    # Check we can iterate over Link's, by creating one manually.
    #
    link = mupdf.Link( mupdf.Rect(0, 0, 1, 1), None, "hello")
    log( 'items in  are:')
    for i in link:
        log( '    {i.m_internal.refs=} {i.m_internal.uri=}')

    # Check iteration over Outlines.
    #
    log( 'Outlines.')
    outline = mupdf.Outline( document)
    log( '{outline.uri()=} {outline.page()=} {outline.x()=} {outline.y()=} {outline.is_open()=} {outline.title()=}')
    log( 'items in outline tree are:')
    for o in outline:
        log( '    {o.uri()=} {o.page()=} {o.x()=} {o.y()=} {o.is_open()=} {o.title()=}')

    # Check iteration over StextPage.
    #
    log( 'StextPage.')
    stext_options = mupdf.StextOptions(0)
    stext_page = mupdf.StextPage( document, 40, stext_options)
    device_stext = mupdf.Device( stext_page, stext_options)
    matrix = mupdf.Matrix()
    page = mupdf.Page( document, 0)
    cookie = mupdf.Cookie()
    page.run( device_stext, matrix, cookie)
    log( '    stext_page is:')
    for block in stext_page:
        log( '        block:')
        for line in block:
            line_text = ''
            for char in line:
                line_text += chr( char.m_internal.c)
            log( '            {line_text=}')

    device_stext.close_device()

    # Check copy-constructor.
    log( 'Checking copy-constructor')
    document2 = mupdf.Document( document)
    del document
    page = mupdf.Page(document2, 0)
    scale = mupdf.Matrix()
    pixmap = mupdf.Pixmap( page, scale, colorspace, 0, mupdf.Pixmap.From_PAGE)
    pixmap.save_pixmap_as_png( 'mupdf_test/out3.png')
    
    stdout = mupdf.Output(mupdf.Output.Fixed_STDOUT)
    log( '{type(stdout)=} {stdout.m_internal.state=}')
    
    mediabox = page.bound_page()
    out = mupdf.DocumentWriter( filename, None, '')
    dev = out.begin_page( mediabox)
    page.run( dev, mupdf.Matrix(mupdf.fz_identity), mupdf.Cookie())
    out.end_page()
    
    # Check out-params are converted into python return value.
    bitmap = mupdf.Bitmap( 10, 20, 8, 72, 72)
    bitmap_details = bitmap.bitmap_details()
    log( '{bitmap_details=}')
    assert bitmap_details == [10, 20, 8, 12]
    
    log( 'finished')