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