uym2 / TreeShrink

Implementation of the TreeShrink problem
https://uym2.github.io/TreeShrink/
GNU General Public License v3.0
36 stars 11 forks source link

run_treeshrink.py fails with python 3.10 #33

Closed nylander closed 1 month ago

nylander commented 2 years ago

FYK,

After a recent local upgrade of my Ubuntu Linux OS --- which brought python to version 3.10.4 --- run_treeshrink.py no longer works.

The reason seems to be an outdated version of dendropy's file utility/container.py in the TreeShrink repo. Apparently, there was a change between python 3.9 and 3.10 involving the library collections (see, e.g., https://www.datasciencelearner.com/attributeerror-module-collections-has-no-attribute-mutablemapping/, and https://github.com/jeetsukumaran/DendroPy/blob/main/src/dendropy/utility/container.py).

Some details:

$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.1 LTS"
$ python -V
Python 3.10.4
$ git clone https://github.com/uym2/TreeShrink.git
$ cd TreeShrink
$ python setup.py install --user
$  python run_treeshrink.py 
Traceback (most recent call last):
  File "/home/nylander/tmp/TreeShrink/run_treeshrink.py", line 5, in <module>
    from treeshrink.optimal_filter_lib import TreeFilter
  File "/home/nylander/tmp/TreeShrink/treeshrink/optimal_filter_lib.py", line 2, in <module>
    from dendropy.datamodel.treemodel import Tree
  File "/home/nylander/tmp/TreeShrink/dendropy/__init__.py", line 24, in <module>
    from dendropy.dataio.nexusprocessing import get_rooting_argument
  File "/home/nylander/tmp/TreeShrink/dendropy/dataio/__init__.py", line 20, in <module>
    from dendropy.dataio import newickreader
  File "/home/nylander/tmp/TreeShrink/dendropy/dataio/newickreader.py", line 29, in <module>
    from dendropy.dataio import nexusprocessing
  File "/home/nylander/tmp/TreeShrink/dendropy/dataio/nexusprocessing.py", line 30, in <module>
    from dendropy.utility import container
  File "/home/nylander/tmp/TreeShrink/dendropy/utility/container.py", line 356, in <module>
    class CaseInsensitiveDict(collections.MutableMapping):
AttributeError: module 'collections' has no attribute 'MutableMapping'
V-Z commented 1 year ago

I can confirm, Python 3.9 seems to be the last Python version working with TreeShrink.

With Python 3.10 I get:

$ run_treeshrink.py -h
Traceback (most recent call last):
  File "/home/vojta/.local/bin/run_treeshrink.py", line 4, in <module>
    __import__('pkg_resources').run_script('TREESHRINK==1.3.9', 'run_treeshrink.py')
  File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 720, in run_script
    self.require(requires)[0].run_script(script_name, ns)
  File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 1559, in run_script
    exec(code, namespace, namespace)
  File "/home/vojta/.local/lib/python3.10/site-packages/TREESHRINK-1.3.9-py3.10.egg/EGG-INFO/scripts/run_treeshrink.py", line 5, in <module>
    from treeshrink.optimal_filter_lib import TreeFilter
  File "/home/vojta/.local/lib/python3.10/site-packages/TREESHRINK-1.3.9-py3.10.egg/treeshrink/optimal_filter_lib.py", line 2, in <module>
    from dendropy.datamodel.treemodel import Tree
  File "/home/vojta/.local/lib/python3.10/site-packages/TREESHRINK-1.3.9-py3.10.egg/dendropy/__init__.py", line 24, in <module>
    from dendropy.dataio.nexusprocessing import get_rooting_argument
  File "/home/vojta/.local/lib/python3.10/site-packages/TREESHRINK-1.3.9-py3.10.egg/dendropy/dataio/__init__.py", line 20, in <module>
    from dendropy.dataio import newickreader
  File "/home/vojta/.local/lib/python3.10/site-packages/TREESHRINK-1.3.9-py3.10.egg/dendropy/dataio/newickreader.py", line 29, in <module>
    from dendropy.dataio import nexusprocessing
  File "/home/vojta/.local/lib/python3.10/site-packages/TREESHRINK-1.3.9-py3.10.egg/dendropy/dataio/nexusprocessing.py", line 30, in <module>
    from dendropy.utility import container
  File "/home/vojta/.local/lib/python3.10/site-packages/TREESHRINK-1.3.9-py3.10.egg/dendropy/utility/container.py", line 356, in <module>
    class CaseInsensitiveDict(collections.MutableMapping):
AttributeError: module 'collections' has no attribute 'MutableMapping'

So for now I stay with Python 3.9.

V-Z commented 1 year ago

My easy PR https://github.com/uym2/TreeShrink/pull/40 should fix it. You can try it.

uym2 commented 1 year ago

Thank you very much for pointing out the error snf fixing it. I will do some tests and will merge.

On Thu, Apr 27, 2023 at 5:42 AM V-Z @.***> wrote:

My easy PR #40 https://github.com/uym2/TreeShrink/pull/40 should fix it. You can try it.

— Reply to this email directly, view it on GitHub https://github.com/uym2/TreeShrink/issues/33#issuecomment-1525290417, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB6MKWQO6RX46Q3GVPM6OI3XDI5RJANCNFSM56ZU6EXQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

smirarab commented 1 year ago

ping!

chrisjackson-pellicle commented 1 year ago

Hi - won't this PR break compatibility with Python <= 3.9, though?

In the link provided in the opening post (https://www.datasciencelearner.com/attributeerror-module-collections-has-no-attribute-mutablemapping/), solution 2 suggests a dynamic approach i.e.:

import collections 
if sys.version_info.major == 3 and sys.version_info.minor >= 10

    from collections.abc import MutableMapping
else 
    from collections import MutableMapping

Then, CaseInsensitiveDict(collections.MutableMapping) can be changed to CaseInsensitiveDict(MutableMapping). It should then work with e.g. either Python 3.9 or 3.10.

Cheers,

Chris

nylander commented 9 months ago

Hi, for the dendropy code shipped with TreeShrink, the code suggested by @chrisjackson-pellicle will work given that sys is imported before checking for version and after adding the missing colons for the pythonic if: else: :-) I would have liked to see the whole dendropy folder updated though. Most probably more work... Cheers Johan

import sys
import collections 
if sys.version_info.major == 3 and sys.version_info.minor >= 10:
    from collections.abc import MutableMapping
else: 
    from collections import MutableMapping

Then, CaseInsensitiveDict(collections.MutableMapping) can be changed to CaseInsensitiveDict(MutableMapping). It should then work with e.g. either Python 3.9 or 3.10.