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.