sbmlteam / libsbml

LibSBML is a native library for reading, writing and manipulating files and data streams containing the Systems Biology Markup Language (SBML). It offers language bindings for C, C++, C#, Java, JavaScript, MATLAB, Perl, PHP, Python, R and Ruby.

Home Page:https://sbml.org/software/libsbml

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Python crash with idlist.at()

luciansmith opened this issue · comments

The following Python program crashes Python entirely:

import libsbml

doc = libsbml.readSBMLFromFile("BIOMD0000000001_url.xml")
model = doc.getModel()
metaIdList = model.getAllElementMetaIdList()
print(metaIdList.size())
metaIdList.at(0)

Same with the similar:

import libsbml

doc = libsbml.readSBMLFromFile("BIOMD0000000001_url.xml")
model = doc.getModel()
idList = model.getAllElementIdList()
print(idList.size())
idList.at(0)

The particular model doesn't matter, but it does have many elements with both IDs and with metaids. The lists claim to be of size zero, however, so there's a couple issues:

  • Those functions should presumably return a list of all the metaids/ids in the model.
  • The 'at' function shouldn't crash Python when called with an invalid argument.

(Alternatively, the functions could just be scrapped, but if so, it would be nice if 'getAllElements' was added to the Python interface. Or if there was some way of getting all the elements of a document and/or model.)

accessing an idlist past its end, does throw an STL exception, that we can catch. As for why you dont get elements returned. Thats the way it is implemented, since those operations are expensive, these lists have to be populated before being accessed. that way people can decide when to populate / clear / get them.

 /**
   * Clears the internal list of the identifiers of all elements within this Model object.
   *
   * @see populateAllElementIdList()
   * @see isPopulatedAllElementIdList()
   */
  void clearAllElementIdList();


  /**
   * Populates the internal list of the metaids of all elements within this Model object.
   *
   * This method tells libSBML to retrieve the identifiers of all elements
   * of the enclosing Model object.  The result is stored in an internal list
   * of metaids.  Users can access the resulting data by calling the method
   * getAllElementMetaIdList().
   *
   * @warning Retrieving all elements within a model is a time-consuming operation.
   * Callers may want to call isPopulatedAllElementMetaIdList() to determine
   * whether the metaid list may already have been populated.
   *
   * @see isPopulatedAllElementMetaIdList()
   */
  void populateAllElementMetaIdList();


  /**
   * Predicate returning @c true if libSBML has a list of the metaids of all 
   * components of this model.
   *
   * @return @c true if the metaid list has already been populated, @c false
   * otherwise.
   */
  bool isPopulatedAllElementMetaIdList() const;


  /**
   * Returns the internal list of the metaids of all elements within this Model object.
   *
   * @return an IdList of all the metaids in the model.
   *
   * @see populateAllElementMetaIdList()
   * @see isPopulatedAllElementMetaIdList()
   */
  IdList getAllElementMetaIdList() const;


  /**
   * Clears the internal list of the metaids of all elements within this Model object.
   *
   * @see populateAllElementMetaIdList()
   * @see isPopulatedAllElementMetaIdList()
   */
  void clearAllElementMetaIdList();

it does describe that in python as well:

In [3]: ? m.getAllElementIdList
Signature:  m.getAllElementIdList()
Docstring:
getAllElementIdList(Model self) -> IdList

Returns the internal list of the identifiers of all elements within
this Model object.

Returns an IdList of all the identifiers in the model.

See also populateAllElementIdList(), isPopulatedAllElementIdList().

Is there any use case for someone calling 'getAllElementMetaIdList' and not wanting to populate it?