Source code for schrodinger.infra.mmlist
"""
A wrapper for the mmlist mmlib.
Copyright Schrodinger, LLC. All rights reserved.
"""
from schrodinger.infra import mm
from schrodinger.infra import mmobject
[docs]class mmlist(mmobject.MmObject):
"""
Wrap an anderlying mmlist "instance" and provides access to its members
through the python sequence syntax.
"""
[docs] def __init__(self, handle_or_list, manage_handle=True):
"""
Initialize an object with an existing mmlist handle or python list
of ints.
"""
try: # FIXME: which of these 2 statements needs to be in try?
mm.mmlist_initialize(mm.error_handler)
handle = _mmlist_from_pylist(handle_or_list)
except:
handle = int(handle_or_list)
# mmlist_in_use currently isn't wrapped in mmlist.i, so check to see
# if it's there before trying to call it.
# FIXME: Wrap mmlist_in_use() and remove hasattr section:
if hasattr(mm, 'mmlist_in_use') and not mm.mmlist_in_use(handle):
raise Exception("There is no active MMlist for the handle %d." %
handle)
super().__init__(handle, manage_handle)
mm.mmlist_terminate()
def _delete(self):
"""
A function to terminate this object. Required for MmObject
interface.
"""
mm.mmlist_delete(self.handle)
[docs] def initialize(error_handler=None):
"""
Initialize mmlist.
"""
if error_handler is None:
error_handler = mm.error_handler
mm.mmlist_initialize(mm.error_handler)
initialize = staticmethod(initialize)
[docs] def terminate():
"""
Terminate mmlist.
"""
mm.mmlist_terminate()
terminate = staticmethod(terminate)
def __repr__(self):
"""
Programmer-readable representation, prints the mmlist handle
"""
return "mmlist(%d)" % self.handle
[docs] def __len__(self):
"""
Return the number of elements in the mmlist.
"""
return mm.mmlist_get_size(self.handle)
def __getitem__(self, index):
"""
Return an item from the underlying mmlist library.
"""
size = mm.mmlist_get_size(self.handle)
if index >= size or index < 0:
raise IndexError
return mm.mmlist_get(self.handle, index)
def __setitem__(self, index, value):
"""
Set an item in the underlying mmlist library.
"""
size = mm.mmlist_get_size(self.handle)
if index >= size or index < 0:
raise IndexError
return mm.mmlist_set(self.handle, index, value)
def __delitem__(self, index):
raise Exception("mmlist objects cannot delete items.")
def __iter__(self):
"""
Provide an iterator over the list. This also allows one to create a
python list by invoking list() on an instantiated mmlist object.
"""
# As with all iterators, changing the underlying object while
# iterating is not going to be safe.
return map(self.__getitem__, range(len(self)))
# FIXME: Would it be simpler to do the following:
#
# for i in range(len(self)):
# yield self[i]
#
# This will also remove the need to import the intertools module.
# Is there a reason not to do this?
[docs] def __contains__(self, value):
"""
Returns True if the list contains the specified value, False otherwise
"""
return bool(mm.mmlist_in_list(self, value))
def _mmlist_from_pylist(pylist):
"""
Create an mmlist from a python list, and return the integer handle of
that mmlist. Note that the mmlist will now accept a python sequence as
the first argument to the constructor.
"""
handle = mm.mmlist_new(len(pylist))
for i, val in enumerate(pylist):
mm.mmlist_set(handle, i, 0 if val is None else int(val))
return handle
def _mmlist_to_pylist(mmlist_handle):
"""
Create a standard python list from the provided mmlist handle.
If mmlist_handle is an mmlist object, it's easier to just invoke
list(mmlist_handle).
"""
size = mm.mmlist_get_size(mmlist_handle)
pylist = []
for i in range(size):
pylist.append(mm.mmlist_get(mmlist_handle, i))
return pylist