#3 Python 3 support

Unstable (example)
closed
nobody
None
5
2015-02-16
2014-02-18
Jonathan Niehof
No

The attached patch adds Python 3 support to ffnet. To maintain Python 2.5 compatibility, most of the heavy lifting is done by using 2to3 in setup.py.

Other changes:
1) Pickles are read/written with the file opened in binary mode, which should be fine in Python 2 and is mandatory in Python 3.
2) _mmprop.py uses explicit floor division, introduced in Python 2.2, to chunk the data.
3) fortran/init.py uses an explicit relative import, introduced in Python 2.5.
4) One test in _test.py has an explicit cast from single-element numpy array to float. This is what round() was doing in assertNotAlmostEqual in Python 2.x, but this fallback behavior was eliminated in Python 3.

Tested with "python -m ffnet._tests" and by running the code in the examples directory, under both Python 3.3 and 2.7. Note that, due to the way setup.py is written, the examples will not be run through 2to3 on installation, but they do work fine after a manual 2to3 run. I chose not to mess with this for the sake of minimizing changes.

1 Attachments

Discussion

  • I jumped the gun a bit on the previous patch in terms of getting the pickling to work across versions. Updated patch attached (as with the previous, it's against r360).

    I tried to get backward compatibility working, but numpy arrays pickled in Python 3 aren't openable in Python 2, regardless of format. (Fortunately the other direction is okay.) So I put in a warning for that. Interoperability I tested, using xor.py and opening with a simple "ffnet.loadnet":

    1) Networks created in Python 3 with the patched code open in Python 3 with the patched code.
    2) Networks created in Python 2 with the patched code open in Python 3 with the patched code.
    3) Networks created in Python 2 with the patched code open in Python 2 with the patched code.
    4) Networks created in Python 2 with the patched code open in Python 2 with the unpatched code (r360).
    5) Networks created in Python 2 with the unpatched code (r360) open in Python 2 with the patched code.
    6) Networks created in Python 2 with the unpatched code (r360) open in Python 3 with the patched code.

    Not tested:
    7) Networks created in Python 2 with the unpatched code (r360) are assumed to open in Python 2 with the unpatched code (r360).
    8, 9) Networks created in Python 3 with the patched code will not open in Python 2 with either the patched or unpatched code due to the incompatibility of numpy arrays.

    I've also done some limited regression testing of a network trained locally on Python 2, ffnet 0.7.1 and it passes the tests on both Python 2 and Python 3 with the patched code.

    In addition, I've also rerun the unit tests and the examples under both Python 2 and Python 3 with the latest patched code.

     
  • Marek
    Marek
    2014-02-19

    Hi!

    Many thanks for the patch and testing. Patch is now committed to the trunk.

    I think, examples should be processed by 2to3 in setup.py, this is to be done. Regarding pickling from 3 to 2 don't know what could be done. Maybe arrays should be dumped to lists before save and then recreated after read...

     
  • Thanks for applying. Looks like the first version of the patch was applied--that was far less robust even for reading Python 2 networks into Python 3. So attached is:
    1) a patch that just has those changes, against current trunk.
    2) a patch to process the examples through 2to3, against current trunk. This basically turns examples into a package so .pyc files and such come out, but it's a relatively clean way to handle it.

     
  • Marek
    Marek
    2014-02-20

    Thanks for patching setup.py for examples. Setup is warning now for lacking __init__.py in examples, but i think this is not big deal...

    Everything is now properly applied in r364. Thanks again!

     
  • Fantastic, thanks.

    I noticed the warning about init, but figured, eh, it works :) An empty init would fix that. I guess it would be nice to be able to run the examples with:
    python -m ffnet.examples.ocr
    and I think there needs to be an init for that.

     
  • Marek
    Marek
    2015-02-16

    • status: open --> closed