Skip to content
BETSE 0.9.2 (Luckiest Levin) released.

Significant changes include:

* Downstream data dirname issues resolved. Previously, downstream
  consumers (e.g., the BETSEE GUI) were erroneously required to recreate
  rather than share the default simulation configuration provided by the
  BETSE codebase. This has now been resolved, reducing unseemly Don't
  Repeat Yourself (DRY).
* Gene regulatory network (GRN) pathname issues resolved. Specifically,
  the "gene regulatory network settings/gene regulatory network config"
  setting in YAML-formatted simulation configuration files has now been
  generalized to be relative to the directory containing those files.
* Resource consumption reduced. Matplotlib-based figures, graphs, plots,
  and animations are now properly destroyed on completion, substantially
  reducing memory usage during long-running simulation exports.
* Deprecation warnings eliminated. The codebase now complies with all
  upstream deprecations, including breaking NumPy, py.test, and Python
  changes. Notably, NumPy >= 1.16 has deprecated the passing of
  arbitrary iterables to the np.column_stack() function, which now
  requires strict sequences:
      FutureWarning: arrays to stack must be passed as a "sequence" type
      such as list or tuple. Support for non-sequence iterables such as
      generators is deprecated as of NumPy 1.16 and will raise an error
      in the future.
  Since converting non-sequence iterables to sequences is trivial
  (ignoring the obvious edge case of infinite generators, which much
  like the legendary Pokemon of yore appear not to exist in the wild),
  NumPy developers chose poorly when they chose to explicitly break
  rather than implicitly resolve this non-issue. Thanks for generating
  more meaningless boilerplate, NumPy.
* Significant continuous integration (CI) improvements, including:
  * Conda-forge-centric testing. All CI host environments (i.e.,
    GitLab-CI, AppVeyor) now install all mandatory and optional
    application dependencies from the open-source volunteer
    "conda-forge" channel rather than the closed-source proprietary
    "anaconda" channel. Doing so better mimics real-world installation
    environments and enables us to begin exercising optional
    dependencies (e.g., FFmpeg, NetworkX, PyDot).
  * Early-time logging verbosity increased. To simplify testing
    maintenance, Early-time logging verbosity increased has now been
    increased during tests.
  * CI-specific decorators added. The new
    betse.util.test.pytest.mark.pytskip.skip_if_ci_gitlab() decorator
    skips the decorated test or fixture if GitLab-CI is currently
    hosting these tests.
  * The following previously failing tests have been corrected:
    * The test_packages_init() unit test, which is now conditionally
      skipped under GitLab-CI by the aforementioned decorator. GitLab-CI
      no longer clones this repository correctly, erroneously preserving
      empty subdirectories no longer tracked by git. While usually
      innocuous, empty subdirectories trigger false negatives from this
      unit test. Since this test succeeds both locally and under
      AppVeyor, GitLab-CI's misconfigured git checkout policy
      inexplicably remains the culprit.
    * The test_c_* pair of unit tests, which erupted into incoherent
      flames due to inappropriate assumptions about the internal
      structure of NumPy. NumPy
      1.16.0 unified the prior public "numpy.core.multiarray" and
      "numpy.core.umath" C extensions into a new private
      "numpy.core._multiarray_umath" C extension.
    * The pivotal test_cli_sim_compat() functional test, which has now
      been reenabled in a manner seemingly incompatible with recent
      py.test changes. Since this test safeguards backward compatibility
      with respect to our YAML-based simulation configuration format,
      enabling this test is critical to long-term joy.
* Installation-time improvements, including:
  * Substantial "setup.py" streamlining. The contents of our topmost
    setuptools-based installation script now reflect those of their
    counterpart in the BETSEE GUI -- which is to say, this script has
    been compacted into a fairly minimal line length.
  * "betse.metadata.PYTHON_VERSION_MINOR_MAX" addition. This integer
    global specifies the maximum minor stable version of the Python 3.x
    mainline, as required by this "setup.py" streamlining.
  * "betse_setup.buputil" streamlining. This submodule collects
    miscellaneous utility functions required only at BETSE installation.
    This submodule has now been reduced in length, reducing our
    maintenance burden.
* Significant internal API improvements, including:
  * Application API creation. The new "betse.util.app" subpackage now
    provides:
    * The prior "betse.util.meta" subpackage, which has been subsumed
      under "betse.util.app.meta" for maintainability.
    * Application pathname API creation. The new
      "betse.util.app.apppath" submodule enables callers to query the
      absolute pathnames of application-relative paths regardless of
      application installation specifics (e.g., setuptools-based egg,
      frozen application).
    * Application initialization API centralized. The existing
      "betse.util.app.meta.metaappabc.MetaAppABC" superclass now
      centralizes all application initialization logic into a single
      coherent object-oriented API previously distributed throughout the
      codebase as a cacophony of incoherent procedural APIs not reusable
      by downstream consumers. This includes:
      * The "MetaAppABC" constructor, which now guarantees the current
        application to be completely initialized excluding third-party
        dependencies (e.g., NumPy, SciPy), whose initialization must
        necessarily be deferred until later in the application startup
        process. This constructor now entirely obsoletes the prior
        "betse.ignition" API.
      * The MetaAppABC.init_libs() method, which now initializes
        third-party dependencies (e.g., NumPy, SciPy) in a
        user-configurable manner late in the application startup
        process. This method now obsoletes a significant portion of the
        existing "betse.lib.libs" API.
      * The MetaAppABC.init_libs_if_needed() method, which efficiently
        simplifies the aforementioned process on behalf of low-level
        automation (e.g., dark voodoo in the "betse.science.__init__"
        module).
    * Application metadata singleton API creation. The new
      "betse.util.app.meta.metaappton" submodule centralizes all logic
      concerning the application metadata singleton previously residing
      in the "betse.metaapp" submodule.
  * Bitwise API creation. The new "betse.util.type.numeric.bits"
    submodule now provides general-purpose bit and bit field
    functionality, including an is_bit_on() function implementing a
    standard bit field testing routine.
  * Matplotlib Figure API creation. The new
    "betse.lib.matplotlib.mplfigure" submodule defines critical
    functionality for reliably closing matplotlib figures, a prevalent
    "pain point" in most matplotlib-based applications.
  * Testing API creation. The new "betse.util.test" subpackage now
    defines testing-specific APIs, including:
    * The new "betse.util.test.tests" submodule, defining
      general-purpose test suite functionality. This includes the
      is_testing() tester, enabling the codebase itself to query whether
      or not it is currently being tested.
    * The new "betse.util.test.tstci" submodule, defining CI-specific
      functionality. This includes one tester for each well-known CI
      host (e.g., is_ci_gitlab() for GitLab-CI), returning true only
      when the active Python interpreter is exercising tests on that
      host.
    * The new py.test API. The BETSE-specific and hence non-reusable
      "betse_test.util" subpackage has been moved to the BETSE-agnostic
      and hence reusable "betse.util.test.pytest" subpackage, enabling
      reuse by downstream consumers (e.g., BETSEE).
  * Class API generalizations. The "betse.util.type.cls.classes"
    submodule now defines a host of new general-purpose getter
    functions, including:
    * get_name_qualified(), obtaining the fully-qualified name of the
      passed class. The implementation proved highly non-trivial, due to
      common edge cases (e.g., classes with no or poorly defined
      modules).
    * get_module_name_qualified_or_none(), obtaining the fully-qualified
      name of the module defining the passed class if any or "None"
      otherwise.
  * Module API generalizations. A new "betse.util.py.module" subpackage
    has been created, replacing the prior "betse.util.py.pymodule"
    submodule. This subpackage provides the following new submodules:
    * "betse.util.py.module.pymodname", providing lookup facilities both
      to and from fully-qualified module names and their corresponding
      module objects.
    * "betse.util.py.module.pymodule", providing generic module
      handling.
    * "betse.util.py.module.pypackage", providing generic package
      handling -- notably, the get_object_type_package_root() function
      returning the root package transitively defining any arbitrary
      object's class.
  * String API generalizations. The existing "betse.util.type.text.strs"
    submodule now defines a holy trifecta of
    "get_prefix_preceding_char"-prefixed functions, enabling callers to
    obtain the prefix preceding any character in arbitrary strings.
* Obsolete subdirectories removed, including:
  * The long-broken "doc/examples" subdirectory, whose code snippets
    have all non-working for at least several major application
    revisions. While documentation in and of itself is commendable, bad
    documentation is readily worse than no documentation.
  * The long-unused "betse/data/yamale" subdirectory.