AFM-analysis / igor2

Python3 Igor Pro pxp and ibw file reader
GNU Lesser General Public License v3.0
8 stars 7 forks source link

Tests fail under Python 3.12 #9

Closed ns-rse closed 6 months ago

ns-rse commented 9 months ago

Hi,

Thanks for continuing the development of igor, really useful to our project (TopoStats).

We're in the process of ensuring we can support Python 3.12 and I've found that igor2 doesn't play ball with Python 3.12. To investigate I've tried running the tests under Python 3.11.6 (all pass)...

❱ python --version
Python 3.11.6

❱ pytest          
=============================================================================== test session starts ================================================================================
platform linux -- Python 3.11.6, pytest-7.4.2, pluggy-1.3.0
Matplotlib: 3.8.0
Freetype: 2.6.1
rootdir: /home/neil/work/git/hub/ns-rse/igor2
plugins: mock-3.11.1, mpl-0.16.1, github-actions-annotate-failures-0.2.0, xdist-3.3.1, napari-plugin-engine-0.2.0, regtest-1.5.1, cov-4.1.0, hypothesis-6.87.1, lazy-fixture-0.6.3, anyio-4.0.0, typeguard-4.1.5
collected 12 items                                                                                                                                                                 

tests/test_ibw.py ...........                                                                                                                                                [ 91%]
tests/test_pxp.py .                                                                                                                                                          [100%]

================================================================================ 12 passed in 0.95s ================================================================================

...and Python 3.12.0 (none start due to noted error)...

❱ python --version
Python 3.12.0
 12:44:36 pm GMT  •100  neil  ~/work/git/hub/ns-rse/igor2  G  master  @  + + ⭑ ⭑ - - ?  
❱ pytest          
=============================================================================== test session starts ================================================================================
platform linux -- Python 3.12.0, pytest-7.4.3, pluggy-1.3.0
Matplotlib: 3.8.2
Freetype: 2.6.1
rootdir: /home/neil/work/git/hub/ns-rse/igor2
plugins: mpl-0.16.1, github-actions-annotate-failures-0.2.0, regtest-1.5.1, cov-4.1.0, lazy-fixture-0.6.3
collected 0 items / 2 errors                                                                                                                                                       

====================================================================================== ERRORS ======================================================================================
________________________________________________________________________ ERROR collecting tests/test_ibw.py ________________________________________________________________________
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/python.py:531: in collect
    self._inject_setup_module_fixture()
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/python.py:545: in _inject_setup_module_fixture
    self.obj, ("setUpModule", "setup_module")
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/python.py:310: in obj
    self._obj = obj = self._getobj()
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/python.py:528: in _getobj
    return self._importtestmodule()
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/python.py:617: in _importtestmodule
    mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/pathlib.py:567: in import_path
    importlib.import_module(module_name)
/home/neil/miniconda3/envs/topo312/lib/python3.12/importlib/__init__.py:90: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1381: in _gcd_import
    ???
<frozen importlib._bootstrap>:1354: in _find_and_load
    ???
<frozen importlib._bootstrap>:1325: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:929: in _load_unlocked
    ???
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/assertion/rewrite.py:186: in exec_module
    exec(co, module.__dict__)
tests/test_ibw.py:1: in <module>
    from helper import assert_equal_dump_no_whitespace_no_byte, dumpibw
tests/helper.py:4: in <module>
    from igor2.binarywave import load as loadibw
igor2/__init__.py:5: in <module>
    from . import binarywave
igor2/binarywave.py:114: in <module>
    BinHeader1 = _Structure(
E   TypeError: Struct() takes at most 1 keyword argument (2 given)
________________________________________________________________________ ERROR collecting tests/test_pxp.py ________________________________________________________________________
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/python.py:531: in collect
    self._inject_setup_module_fixture()
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/python.py:545: in _inject_setup_module_fixture
    self.obj, ("setUpModule", "setup_module")
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/python.py:310: in obj
    self._obj = obj = self._getobj()
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/python.py:528: in _getobj
    return self._importtestmodule()
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/python.py:617: in _importtestmodule
    mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/pathlib.py:567: in import_path
    importlib.import_module(module_name)
/home/neil/miniconda3/envs/topo312/lib/python3.12/importlib/__init__.py:90: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1381: in _gcd_import
    ???
<frozen importlib._bootstrap>:1354: in _find_and_load
    ???
<frozen importlib._bootstrap>:1325: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:929: in _load_unlocked
    ???
/home/neil/miniconda3/envs/topo312/lib/python3.12/site-packages/_pytest/assertion/rewrite.py:186: in exec_module
    exec(co, module.__dict__)
tests/test_pxp.py:3: in <module>
    from igor2.packed import load as loadpxp
igor2/__init__.py:5: in <module>
    from . import binarywave
igor2/binarywave.py:114: in <module>
    BinHeader1 = _Structure(
E   TypeError: Struct() takes at most 1 keyword argument (2 given)
============================================================================= short test summary info ==============================================================================
ERROR tests/test_ibw.py - TypeError: Struct() takes at most 1 keyword argument (2 given)
ERROR tests/test_pxp.py - TypeError: Struct() takes at most 1 keyword argument (2 given)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 2 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
================================================================================ 2 errors in 0.41s =================================================================================

I'm confused, I can see the igor2.struct.Structure class inherits struct.Struct but don't understand how or why the error is thrown because the __init__() for igor2.struct.Structure defines three arguments (two required, one with default).

It almost looks like the from .struct import Structure as _Structure is actually importing the struct.Struct class by mistake. :shrug:

kmnhan commented 6 months ago

This seems to be due to a regression in cpython that was fixed in 3.12.2: https://github.com/python/cpython/issues/112358

ns-rse commented 6 months ago

I noticed the other day that TopoStats now ran under Python 3.12.