openff-toolkit
openff-toolkit copied to clipboard
Strange behavior when applying `.index()` to list of molecules read from sdf
Describe the bug
When I tried read a list of molecules form an sdf file and try to apply the .index
method (list
method) I get an unexpected behavior.
It might be a minor issue but it was unexpected.
To Reproduce The code to reproduce the issue is the following:
from openff.toolkit.topology import Molecule
molecules = Molecule.from_file("ligands.sdf")
molecules.index("some_name")
The ligands.sdf
file to reproduce the issue is attached.
Output
The ipython traceback is as follows:
traceback
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In [15], line 1
----> 1 molecules.index("some_name")
File ~/miniconda3/envs/openff-0.11/lib/python3.10/site-packages/openff/toolkit/topology/molecule.py:1300, in FrozenMolecule.__eq__(self, other)
1287 """
1288 Test two molecules for equality to see if they are the chemical species, but do not check other
1289 annotated properties.
(...)
1296
1297 """
1298 # updated to use the new isomorphic checking method, with full matching
1299 # TODO the doc string did not match the previous function what matching should this method do?
-> 1300 return Molecule.are_isomorphic(self, other, return_atom_map=False)[0]
File ~/miniconda3/envs/openff-0.11/lib/python3.10/site-packages/openff/toolkit/topology/molecule.py:1917, in FrozenMolecule.are_isomorphic(mol1, mol2, return_atom_map, aromatic_matching, formal_charge_matching, bond_order_matching, atom_stereochemistry_matching, bond_stereochemistry_matching, strip_pyrimidal_n_atom_stereo, toolkit_registry)
1911 raise TypeError(
1912 "are_isomorphic accepts a NetworkX Graph or OpenFF "
1913 + f"(Frozen)Molecule, not {type(obj)}"
1914 )
1916 # Quick number of atoms check. Important for large molecules
-> 1917 if _object_to_n_atoms(mol1) != _object_to_n_atoms(mol2):
1918 return False, None
1920 # If the number of atoms match, check the Hill formula
File ~/miniconda3/envs/openff-0.11/lib/python3.10/site-packages/openff/toolkit/topology/molecule.py:1911, in FrozenMolecule.are_isomorphic.<locals>._object_to_n_atoms(obj)
1909 return obj.number_of_nodes()
1910 else:
-> 1911 raise TypeError(
1912 "are_isomorphic accepts a NetworkX Graph or OpenFF "
1913 + f"(Frozen)Molecule, not {type(obj)}"
1914 )
TypeError: are_isomorphic accepts a NetworkX Graph or OpenFF (Frozen)Molecule, not <class 'str'>
I was expecting a ValueError: 'some_name' is not in list
as the error output.
Computing environment (please complete the following information):
- Operating system: Linux 64 bits
Output of running `conda list`
# Name Version Build Channel
_libgcc_mutex 0.1 conda_forge conda-forge
_openmp_mutex 4.5 2_gnu conda-forge
amberlite 22.0 pypi_0 pypi
ambertools 22.0 py310h206695f_3 conda-forge
amberutils 21.0 pypi_0 pypi
anyio 3.6.1 pyhd8ed1ab_1 conda-forge
argon2-cffi 21.3.0 pyhd8ed1ab_0 conda-forge
argon2-cffi-bindings 21.2.0 py310h5764c6d_2 conda-forge
arpack 3.7.0 hdefa2d7_2 conda-forge
asttokens 2.0.8 pyhd8ed1ab_0 conda-forge
astunparse 1.6.3 pyhd8ed1ab_0 conda-forge
attrs 22.1.0 pyh71513ae_1 conda-forge
babel 2.10.3 pyhd8ed1ab_0 conda-forge
backcall 0.2.0 pyh9f0ad1d_0 conda-forge
backports 1.0 py_2 conda-forge
backports.functools_lru_cache 1.6.4 pyhd8ed1ab_0 conda-forge
beautifulsoup4 4.11.1 pyha770c72_0 conda-forge
bleach 5.0.1 pyhd8ed1ab_0 conda-forge
blosc 1.21.1 h83bc5f7_3 conda-forge
boost 1.74.0 py310h7c3ba0c_5 conda-forge
boost-cpp 1.74.0 h75c5d50_8 conda-forge
brotli 1.0.9 h166bdaf_7 conda-forge
brotli-bin 1.0.9 h166bdaf_7 conda-forge
brotlipy 0.7.0 py310h5764c6d_1004 conda-forge
bzip2 1.0.8 h7f98852_4 conda-forge
c-ares 1.18.1 h7f98852_0 conda-forge
ca-certificates 2022.9.24 ha878542_0 conda-forge
cached-property 1.5.2 hd8ed1ab_1 conda-forge
cached_property 1.5.2 pyha770c72_1 conda-forge
cachetools 5.2.0 pyhd8ed1ab_0 conda-forge
cairo 1.16.0 ha61ee94_1014 conda-forge
certifi 2022.9.24 pyhd8ed1ab_0 conda-forge
cffi 1.15.1 py310h255011f_0 conda-forge
charset-normalizer 2.1.1 pyhd8ed1ab_0 conda-forge
contourpy 1.0.5 py310hbf28c38_0 conda-forge
cryptography 37.0.1 py310h9ce1e76_0
cudatoolkit 11.7.0 hd8887f6_10 conda-forge
curl 7.83.1 h2283fc2_0 conda-forge
cycler 0.11.0 pyhd8ed1ab_0 conda-forge
cython 0.29.32 py310hd8f1fbe_0 conda-forge
debugpy 1.6.3 py310hd8f1fbe_0 conda-forge
decorator 5.1.1 pyhd8ed1ab_0 conda-forge
defusedxml 0.7.1 pyhd8ed1ab_0 conda-forge
entrypoints 0.4 pyhd8ed1ab_0 conda-forge
executing 1.1.0 pyhd8ed1ab_0 conda-forge
expat 2.4.9 h27087fc_0 conda-forge
fftw 3.3.10 nompi_hf0379b8_105 conda-forge
flit-core 3.7.1 pyhd8ed1ab_0 conda-forge
font-ttf-dejavu-sans-mono 2.37 hab24e00_0 conda-forge
font-ttf-inconsolata 3.000 h77eed37_0 conda-forge
font-ttf-source-code-pro 2.038 h77eed37_0 conda-forge
font-ttf-ubuntu 0.83 hab24e00_0 conda-forge
fontconfig 2.14.0 hc2a2eb6_1 conda-forge
fonts-conda-ecosystem 1 0 conda-forge
fonts-conda-forge 1 0 conda-forge
fonttools 4.37.3 py310h5764c6d_0 conda-forge
freetype 2.12.1 hca18f0e_0 conda-forge
gettext 0.19.8.1 h27087fc_1009 conda-forge
greenlet 1.1.3 py310hd8f1fbe_0 conda-forge
hdf4 4.2.15 h9772cbc_4 conda-forge
hdf5 1.12.2 nompi_h4df4325_100 conda-forge
icu 70.1 h27087fc_0 conda-forge
idna 3.4 pyhd8ed1ab_0 conda-forge
importlib-metadata 4.11.4 py310hff52083_0 conda-forge
importlib_metadata 4.11.4 hd8ed1ab_0 conda-forge
importlib_resources 5.9.0 pyhd8ed1ab_0 conda-forge
iniconfig 1.1.1 pyh9f0ad1d_0 conda-forge
ipykernel 6.15.3 pyh210e3f2_0 conda-forge
ipython 8.5.0 pyh41d4057_1 conda-forge
ipython_genutils 0.2.0 py_1 conda-forge
jedi 0.18.1 pyhd8ed1ab_2 conda-forge
jinja2 3.1.2 pyhd8ed1ab_1 conda-forge
jpeg 9e h166bdaf_2 conda-forge
json5 0.9.5 pyh9f0ad1d_0 conda-forge
jsonschema 4.16.0 pyhd8ed1ab_0 conda-forge
jupyter_client 7.3.5 pyhd8ed1ab_0 conda-forge
jupyter_core 4.11.1 py310hff52083_0 conda-forge
jupyter_server 1.18.1 pyhd8ed1ab_0 conda-forge
jupyterlab 3.4.7 pyhd8ed1ab_0 conda-forge
jupyterlab_pygments 0.2.2 pyhd8ed1ab_0 conda-forge
jupyterlab_server 2.15.1 pyhd8ed1ab_0 conda-forge
keyutils 1.6.1 h166bdaf_0 conda-forge
kiwisolver 1.4.4 py310hbf28c38_0 conda-forge
krb5 1.19.3 h08a2579_0 conda-forge
lcms2 2.12 hddcbb42_0 conda-forge
ld_impl_linux-64 2.36.1 hea4e1c9_2 conda-forge
lerc 4.0.0 h27087fc_0 conda-forge
libblas 3.9.0 16_linux64_openblas conda-forge
libbrotlicommon 1.0.9 h166bdaf_7 conda-forge
libbrotlidec 1.0.9 h166bdaf_7 conda-forge
libbrotlienc 1.0.9 h166bdaf_7 conda-forge
libcblas 3.9.0 16_linux64_openblas conda-forge
libcurl 7.83.1 h2283fc2_0 conda-forge
libdeflate 1.14 h166bdaf_0 conda-forge
libedit 3.1.20191231 he28a2e2_2 conda-forge
libev 4.33 h516909a_1 conda-forge
libffi 3.4.2 h7f98852_5 conda-forge
libgcc-ng 12.1.0 h8d9b700_16 conda-forge
libgfortran-ng 12.1.0 h69a702a_16 conda-forge
libgfortran5 12.1.0 hdcd56e2_16 conda-forge
libglib 2.74.0 h7a41b64_0 conda-forge
libgomp 12.1.0 h8d9b700_16 conda-forge
libiconv 1.17 h166bdaf_0 conda-forge
liblapack 3.9.0 16_linux64_openblas conda-forge
libnetcdf 4.8.1 nompi_h21705cb_104 conda-forge
libnghttp2 1.47.0 hff17c54_1 conda-forge
libnsl 2.0.0 h7f98852_0 conda-forge
libopenblas 0.3.21 pthreads_h78a6416_3 conda-forge
libpng 1.6.38 h753d276_0 conda-forge
libsodium 1.0.18 h36c2ea0_1 conda-forge
libsqlite 3.39.3 h753d276_0 conda-forge
libssh2 1.10.0 hf14f497_3 conda-forge
libstdcxx-ng 12.1.0 ha89aaad_16 conda-forge
libtiff 4.4.0 h55922b4_4 conda-forge
libuuid 2.32.1 h7f98852_1000 conda-forge
libwebp-base 1.2.4 h166bdaf_0 conda-forge
libxcb 1.13 h7f98852_1004 conda-forge
libxml2 2.10.2 h4c7fe37_1 conda-forge
libxslt 1.1.35 h8affb1d_0 conda-forge
libzip 1.9.2 hc929e4a_1 conda-forge
libzlib 1.2.12 h166bdaf_3 conda-forge
lxml 4.9.1 py310h5764c6d_0 conda-forge
lz4-c 1.9.3 h9c3ff4c_1 conda-forge
lzo 2.10 h516909a_1000 conda-forge
markupsafe 2.1.1 py310h5764c6d_1 conda-forge
matplotlib-base 3.6.0 py310h8d5ebf3_0 conda-forge
matplotlib-inline 0.1.6 pyhd8ed1ab_0 conda-forge
mdtraj 1.9.7 py310h902c554_2 conda-forge
mistune 2.0.4 pyhd8ed1ab_0 conda-forge
mmpbsa-py 16.0 pypi_0 pypi
munkres 1.1.4 pyh9f0ad1d_0 conda-forge
nbclassic 0.4.3 pyhd8ed1ab_0 conda-forge
nbclient 0.6.8 pyhd8ed1ab_0 conda-forge
nbconvert 7.0.0 pyhd8ed1ab_0 conda-forge
nbconvert-core 7.0.0 pyhd8ed1ab_0 conda-forge
nbconvert-pandoc 7.0.0 pyhd8ed1ab_0 conda-forge
nbformat 5.6.1 pyhd8ed1ab_0 conda-forge
ncurses 6.3 h27087fc_1 conda-forge
nest-asyncio 1.5.5 pyhd8ed1ab_0 conda-forge
netcdf-fortran 4.6.0 nompi_hc402ea5_100 conda-forge
networkx 2.8.6 pyhd8ed1ab_0 conda-forge
nomkl 1.0 h5ca1d4c_0 conda-forge
notebook 6.4.12 pyha770c72_0 conda-forge
notebook-shim 0.1.0 pyhd8ed1ab_0 conda-forge
numexpr 2.8.3 py310hf05e7a9_100 conda-forge
numpy 1.23.3 py310h53a5b5f_0 conda-forge
ocl-icd 2.3.1 h7f98852_0 conda-forge
ocl-icd-system 1.0.0 1 conda-forge
openeye-toolkits 2022.1.1 py310_0 openeye
openff-amber-ff-ports 0.0.3 pyh6c4a22f_0 conda-forge
openff-forcefields 2.0.0 pyh6c4a22f_0 conda-forge
openff-interchange 0.2.1 pyhd8ed1ab_0 conda-forge
openff-interchange-base 0.2.1 pyhd8ed1ab_0 conda-forge
openff-toolkit 0.11.1 pyhd8ed1ab_0 conda-forge
openff-toolkit-base 0.11.1 pyhd8ed1ab_0 conda-forge
openff-units 0.1.8 pyh1a96a4e_0 conda-forge
openff-utilities 0.1.6 pyh1a96a4e_0 conda-forge
openjpeg 2.5.0 h7d73246_1 conda-forge
openmm 7.7.0 py310hccf1d78_1 conda-forge
openssl 3.0.5 h166bdaf_2 conda-forge
packaging 21.3 pyhd8ed1ab_0 conda-forge
packmol 20.010 h86c2bf4_0 conda-forge
packmol-memgen 1.2.3rc0 pypi_0 pypi
pandas 1.5.0 py310h769672d_0 conda-forge
pandoc 2.19.2 ha770c72_0 conda-forge
pandocfilters 1.5.0 pyhd8ed1ab_0 conda-forge
panedr 0.5.2 py_0 conda-forge
parmed 3.4.3 py310hd8f1fbe_2 conda-forge
parso 0.8.3 pyhd8ed1ab_0 conda-forge
pbr 5.10.0 pyhd8ed1ab_0 conda-forge
pcre2 10.37 hc3806b6_1 conda-forge
pdb4amber 22.0 pypi_0 pypi
perl 5.32.1 2_h7f98852_perl5 conda-forge
pexpect 4.8.0 pyh9f0ad1d_2 conda-forge
pickleshare 0.7.5 py_1003 conda-forge
pillow 9.2.0 py310hbd86126_2 conda-forge
pint 0.19.2 pyhd8ed1ab_0 conda-forge
pip 22.2.2 pyhd8ed1ab_0 conda-forge
pixman 0.40.0 h36c2ea0_0 conda-forge
pkgutil-resolve-name 1.3.10 pyhd8ed1ab_0 conda-forge
pluggy 1.0.0 py310hff52083_3 conda-forge
prometheus_client 0.14.1 pyhd8ed1ab_0 conda-forge
prompt-toolkit 3.0.31 pyha770c72_0 conda-forge
psutil 5.9.2 py310h5764c6d_0 conda-forge
pthread-stubs 0.4 h36c2ea0_1001 conda-forge
ptyprocess 0.7.0 pyhd3deb0d_0 conda-forge
pure_eval 0.2.2 pyhd8ed1ab_0 conda-forge
py 1.11.0 pyh6c4a22f_0 conda-forge
pycairo 1.21.0 py310h96fc21a_1 conda-forge
pycparser 2.21 pyhd8ed1ab_0 conda-forge
pydantic 1.10.2 py310h5764c6d_0 conda-forge
pygments 2.13.0 pyhd8ed1ab_0 conda-forge
pyopenssl 22.0.0 pyhd8ed1ab_1 conda-forge
pyparsing 3.0.9 pyhd8ed1ab_0 conda-forge
pyrsistent 0.18.1 py310h5764c6d_1 conda-forge
pysocks 1.7.1 pyha2e5f31_6 conda-forge
pytables 3.7.0 py310hb60b9b2_2 conda-forge
pytest 7.1.3 py310hff52083_0 conda-forge
python 3.10.6 ha86cf86_0_cpython conda-forge
python-constraint 1.4.0 py_0 conda-forge
python-dateutil 2.8.2 pyhd8ed1ab_0 conda-forge
python-fastjsonschema 2.16.2 pyhd8ed1ab_0 conda-forge
python_abi 3.10 2_cp310 conda-forge
pytraj 2.0.6 pypi_0 pypi
pytz 2022.2.1 pyhd8ed1ab_0 conda-forge
pyzmq 24.0.1 py310h330234f_0 conda-forge
rdkit 2022.03.5 py310h1c297d8_0 conda-forge
readline 8.1.2 h0f457ee_0 conda-forge
reportlab 3.5.68 py310h94fcab3_1 conda-forge
requests 2.28.1 pyhd8ed1ab_1 conda-forge
sander 22.0 pypi_0 pypi
scipy 1.9.1 py310hdfbd76f_0 conda-forge
send2trash 1.8.0 pyhd8ed1ab_0 conda-forge
setuptools 65.4.0 pyhd8ed1ab_0 conda-forge
six 1.16.0 pyh6c4a22f_0 conda-forge
smirnoff99frosst 1.1.0 pyh44b312d_0 conda-forge
snappy 1.1.9 hbd366e4_1 conda-forge
sniffio 1.3.0 pyhd8ed1ab_0 conda-forge
soupsieve 2.3.2.post1 pyhd8ed1ab_0 conda-forge
sqlalchemy 1.4.41 py310h5764c6d_0 conda-forge
stack_data 0.5.1 pyhd8ed1ab_0 conda-forge
terminado 0.15.0 py310hff52083_0 conda-forge
tinycss2 1.1.1 pyhd8ed1ab_0 conda-forge
tk 8.6.12 h27826a3_0 conda-forge
tomli 2.0.1 pyhd8ed1ab_0 conda-forge
tornado 6.2 py310h5764c6d_0 conda-forge
traitlets 5.4.0 pyhd8ed1ab_0 conda-forge
typing-extensions 4.3.0 hd8ed1ab_0 conda-forge
typing_extensions 4.3.0 pyha770c72_0 conda-forge
tzdata 2022d h191b570_0 conda-forge
unicodedata2 14.0.0 py310h5764c6d_1 conda-forge
urllib3 1.26.11 pyhd8ed1ab_0 conda-forge
wcwidth 0.2.5 pyh9f0ad1d_2 conda-forge
webencodings 0.5.1 py_1 conda-forge
websocket-client 1.4.1 pyhd8ed1ab_0 conda-forge
wheel 0.37.1 pyhd8ed1ab_0 conda-forge
xmltodict 0.13.0 pyhd8ed1ab_0 conda-forge
xorg-kbproto 1.0.7 h7f98852_1002 conda-forge
xorg-libice 1.0.10 h7f98852_0 conda-forge
xorg-libsm 1.2.3 hd9c2040_1000 conda-forge
xorg-libx11 1.7.2 h7f98852_0 conda-forge
xorg-libxau 1.0.9 h7f98852_0 conda-forge
xorg-libxdmcp 1.1.3 h7f98852_0 conda-forge
xorg-libxext 1.3.4 h7f98852_1 conda-forge
xorg-libxrender 0.9.10 h7f98852_1003 conda-forge
xorg-libxt 1.2.1 h7f98852_2 conda-forge
xorg-renderproto 0.11.1 h7f98852_1002 conda-forge
xorg-xextproto 7.3.0 h7f98852_1002 conda-forge
xorg-xproto 7.0.31 h7f98852_1007 conda-forge
xz 5.2.6 h166bdaf_0 conda-forge
zeromq 4.3.4 h9c3ff4c_1 conda-forge
zipp 3.8.1 pyhd8ed1ab_0 conda-forge
zlib 1.2.12 h166bdaf_3 conda-forge
zstd 1.5.2 h6239696_4 conda-forge
Woah, that's weird and I can reproduce this. Molecule.from_file
returns a List[Molecule]
when given a multi-molecule SDF file. It looks like list.index
is choking on equality checking, which makes sense given that we override it.
~~There's probably a way to make some sort of class MoleculeList(list)
that overrides~~
The docs suggest that list.index
is supposed to raise a ValueError
when the item is not found in the list (which would be the case here - "some_item"
is not going to be found in a list of Molecule
objects). Switching that exception would be a marginal API break. Raising a new exception that inherits from both would be either not a behavior change or a marginal one, depending on one's perspective of things. TypeError
does seem like the right one to use here according to the official docs, if using built-in exception types.