nionutils 4.14.1
Nion utility classes.
License: Apache-2.0
Requires Python: >=3.11

Nion Utilities
==============

The Nion Utils library (used in Nion Swift)
-------------------------------------------
Nion utility classes.

.. start-badges

.. list-table::
    :stub-columns: 1

    * - package
      - |version|

.. |version| image:: https://img.shields.io/pypi/v/nionutils.svg
   :target: https://pypi.org/project/nionutils/
   :alt: Latest PyPI version

.. end-badges

More Information
----------------

- `Changelog <https://github.com/nion-software/nionutils/blob/master/CHANGES.rst>`_

Introduction
------------

A utility library of useful Python objects.

-  Events
-  Observable
-  Bindings, Converters, Models
-  Geometry
-  Persistence
-  Process, Threads
-  Publish and Subscribe
-  Reference Counting
-  Stream
-  Structured Model

These objects are primarily used within the Nion Python libraries, but
may be useful in general usage too.

This project is funded by Nion Co. as part of the `Nion
Swift <http://nion.com/swift/>`__ imaging and analysis platform. The
code is available under the Apache License, Version 2.0.

Requirements
------------

Requires Python 3.11 or later.

Getting Help and Contributing
-----------------------------

If you find a bug, please file an issue on GitHub. You can also contact
us directly at swift@nion.com.

This is primarily a library focused on providing support to higher level
Nion Python libraries. If you are using this in your own project, we
will accept bug fixes and minor feature improvements via pull requests.
For larger features or additions, please contact us to discuss.

This library includes some direct tests, but is also tested via other
Nion Python projects. Any contribution will need to pass the entire
suite of tests. New contributions should be submitted with new tests.

Summary of Features
-------------------

Events
~~~~~~

Events can be used by objects to notify other objects when something of
interest occurs. The source object "fires" the event, optionally passing
parameters, and the "listener" receives a function call. The source
object determines when to fire an event. The event can have multiple
listeners. The listeners are called synchronously in the order in which
they are added, and the source can fire unconditionally, or until a
listener returns True or False.

.. code:: python

    from nion.utils import Event

    class Telescope:
      def __init__(self):
        self.new_planet_detected_event = Event.Event()

      def on_external_event(self, coordinates):
        self.new_planet_detected_event.fire(coordinates)

    def handle_new_planet(coordinates):
      print("New planet coordinates at " + str(coordinates))

    telescope = Telescope()
    listener = telescope.new_planet_detected_event.listen(handle_new_planet)

    listener.close()  # when finished

Observable
~~~~~~~~~~

The Observable based class defines five basic events for watching for
direct changes to an object such as a property changing, an object being
set or cleared, or an item being inserted or removed from a list. The
observable is used along with events to implement bindings.

.. code:: python

    from nion.utils import Observable

    class MyClass(Observable.Observable):
      def __init__(self):
        self.__weight = 1.0

      @property
      def weight(self):
        return self.__weight

      @weight.setter
      def weight(self, new_weight):
        self.__weight = new_weight
        self.notify_property_changed("weight")

    myc = MyClass()

    def property_changed(key):
      if key == "weight":
        print("The weight changed " + str(myc.weight))

    listener = myc.property_changed_event.listen(property_changed)

    listener.close()  # when finished

Bindings, Converters, Models
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Bindings connect a value in a source object to a value in a target
object. Bindings can be one way bindings from source to target, or two
way bindings from source to target and from target to source. Bindings
can bind property values, lists, or an item in a tuple between the
source and target. Bindings work using the Observable events and
subsequently are implemented via Events.

Bindings can optionally make value conversions between the source and
target. For instance, a binding between a float property and a user
interface text field will need to convert from float to string and back.
Converters between value and strings are included for integer, float,
percentage, check state, and UUID to strings.

Geometry
~~~~~~~~

Classes for integer and float based points, sizes, and rectangles are
included. Additional geometry routines are also included, for instance:
line midpoint.

Persistence
~~~~~~~~~~~

The PersistentObject based class defines a basic structure for storing
objects and their relationship to each other into a persistent storage
context. PersistentObjects can store basic properties, single objects
(to-one relationship) and lists of objects (to-many relationship).
Subclasses must strictly notify the PersistentObject of changes to their
persistent data and follow certain guidelines. Doing so allows the
object to be stored persistently and restored from persistent storage.

Properties in the PersistentObject can have validators, converters,
change notifications, and more. Items and relationships have change
notifications and more.

The PersistentStorageContext defines an interfaces which manages a
collection of PersistentObjects. It must be able to store a simple dict
structure for properties, items, and lists.

Process, Threads
~~~~~~~~~~~~~~~~

Process defines classes to facilitate a threaded queue, which executes
its items serially, and thread set which executes the most recent item
in the set.

ThreadPool defines a threaded dispatcher with the ability to limit
dispatch frequency and a thread pool with the ability to execute
explicitly without threads for testing.

Publish and Subscribe
~~~~~~~~~~~~~~~~~~~~~

Publish and subscribe implements a basic publish and subscribe
mechanism. It is should be considered experimental and is not
recommended for use.

Reference Counting
~~~~~~~~~~~~~~~~~~

The ReferenceCounted base class provides an explicitly reference counted
object that is unique from regular Python reference counting in that it
provides precise control of when the reference is acquired and released.
The about\_to\_delete method is called when reference count reaches
zero.

Stream
~~~~~~

The Stream classes provide a async-based stream of values that can be
controlled using standard reactive operators such as sample, debounce,
and combine. The stream source is an Event named value\_stream and the
source object must provide both the value\_stream and a value property.

Structured Model
~~~~~~~~~~~~~~~~

The Structured Model classes provide a way to describe a data structure
which can produce a modifiable and observable object to be used as a
model for other utility classes such as binding and events.

Changelog (nionutils)
=====================

4.14.1 (2025-04-09)
-------------------
- Maintenance release.

4.14.0 (2025-02-11)
-------------------
- Add Platform utility classes.

4.13.0 (2024-12-05)
-------------------
- Performance improvements to filtered list model.
- Add pop_item to ListModel and item_count to FilteredListModel.

4.12.0 (2024-10-26)
-------------------
- Add BoolToStringConverter.
- Allow override of get/set property value in PropertyChangedPropertyModel for more flexibility.
- Change binding to hold reference to source.
- Make point/size/rect classes hashable.
- Add equality operator to color; make it hashable.
- Clean up ticker class, make it immutable and hashable.
- Add ObservedListModel to create a list model from a collection on an observable.
- Drop Python 3.9, 3.10. Add Python 3.13.

4.11.0 (2024-06-12)
-------------------
- Add ability to filter audit reports by top-level audit id.
- Add replace_stream method and stream_list property to CombineLatestStream.
- Add FollowStream utility class.

0.4.10 (2023-12-17)
-------------------
- OptionalStream now returns the proper value.
- Improvements to ValueChangeStreamReactor (still experimental).

0.4.9 (2023-10-23)
------------------
- Minor updates for Python 3.12 compatibility.
- Avoid using utcnow and utcfromtimestamp (both deprecated).

0.4.8 (2023-08-10)
------------------
- Add support for custom ValueStream compare operator.

0.4.7 (2023-06-19)
------------------
- Add explicit support for Python 3.11; drop support for Python 3.8.
- Add an auditing capability for performance auditing.
- Add ability to add/remove streams from CombineLatestStream.
- Add ability to display datetime in local time and with format in DateTime converter.
- Add ValuesToIndexConverter.

0.4.6 (2022-11-04)
------------------
- Minor maintenance.

0.4.5 (2022-09-13)
------------------
- Add minor Color method to get RGB values.
- Add DateTime utilities (utcnow for Windows, strictly increasing).

0.4.4 (2022-07-25)
------------------
- Add a Color utility class.
- Fix issues with FloatToScaledIntegerConverter when min/max are invalid.
- Fix possible race condition in thread pool.

0.4.3 (2022-05-28)
------------------
- Improve convert_back method of IntegerToStringConverter for fuzzy conversion.

0.4.2 (2022-02-18)
------------------
- Ensure component prioritization works.
- Fix top level namespace.

0.4.1 (2021-12-13)
------------------
- Minor typing and return type issues.

0.4.0 (2021-11-10)
------------------
- Eliminate need to call close methods on models, streams, listeners, etc.
- Drop support for Python 3.7, add support for Python 3.10.
- Enable strict typing.
- Remove unused ConcatStream.
- Make ReferenceCounted work with Python references, not explicit ref count.
- Add useful Geometry functions: empty_rect, int_rect, as_tuple.
- Remove unused/deprecated PersistentObject.
- Add property changed property model for monitoring observables.
- Change Recorder to allow customer logger.
- Change ThreadPool to be no-close.
- Fix issue in single SingleItemDispatcher so it actually delays.
- Change SingleItemDispatcher to be no-close.
- Extend sync processes function to cancel outstanding async functions.
- Add experimental stream, value change, and reactor functions.
- Add method to sync but not close event loop.
- Add a single item dispatcher to thread pool.
- Deprecate ListBinding class.

0.3.26 (2021-03-12)
-------------------
- Add select forward/backward methods to IndexedSelection.

0.3.25 (2021-02-02)
-------------------
- Add None and fuzzy options to int converter.

0.3.24 (2020-12-07)
-------------------
- Fix issue updating selection on master instead of filtered items.
- Add ListPropertyModel to treat a list like a single property.

0.3.23 (2020-11-06)
-------------------
- Change list model to more efficiently send change events.
- Change selection to (optionally) fire changed messages when adjusting indexes.

0.3.22 (2020-10-06)
-------------------
- Fix property binding inconsistency.

0.3.21 (2020-08-31)
-------------------
- Fix issue with stream calling stale function.
- Filtered lists no longer access their container's master items when closing.
- Add rotate methods to FloatPoint and FloatSize.
- Improve LogTicker. Add support for major and minor ticks.
- Fix case of extending selection with no anchor.
- Add separate LogTicker class. Renamed old Ticker to LinearTicker. Add base Ticker class.
- Add date time to string converter.
- Extend PropertyChangedEventStream to optionally take an input stream rather than direct object.
- Add added/discarded notifications to Observable for set-like behavior.
- Add a pathlib.Path converter.
- Improve performance of filtered list models.
- Add Registry function to send registry events to existing components. Useful for initialization.
- Add geometry rectangle functions for intersect and union.
- Add geometry functions to convert from int to float versions.

0.3.20 (2020-01-28)
-------------------
- Add various geometry functions; facilitate geometry objects conversions to tuples.
- Add Process.close_event_loop for standardized way of closing event loops.
- Improve geometry comparisons so handle other being None.

0.3.19 (2019-06-27)
-------------------
- Add method to clear TaskQueue.
- Make event listeners context manager aware.
- Improve stack traceback during events (fire, listen, handler).
- Add auto-close (based on weak refs) and tracing (debugging) to Event objects.

0.3.18 (2019-03-11)
-------------------
- Ensure FuncStreamValueModel handles threading properly.

0.3.17 (2019-02-27)
-------------------
- Add ConcatStream and PropertyChangedEventStream.
- Add standardized [notify] item_content_changed event to Observable.
- Make item_changed_event optional for items within FilteredListModel.
- Add floordiv operator to IntSize.

0.3.16 (2018-12-11)
-------------------
- Change list model text filter to use straight text rather than regular expressions.

0.3.15 (2018-11-13)
-------------------
- Allow recorder object to be closed.
- Improve release of objects when closing MappedListModel.
- Add close method to ListModel for consistency.
- Allow persistent objects to delay writes and handle external data.
- Allow persistent relationships to define storage key.
- Extend Registry to allow registering same component with additional component types.

0.3.14 (2018-09-13)
-------------------
- Allow default values in persistent factory callback.

0.3.13 (2018-09-11)
-------------------
- Allow persistent items to be hidden (like properties).
- Allow persistent interface to use get_properties instead of properties attribute when saving.
- Allow FilteredListModel to have separate master/item property names.

0.3.12 (2018-07-23)
-------------------
- Fix bug where unregistered objects were not reported correctly.
- Add model changed event to structured model to monitor deep changes.

0.3.11 (2018-06-25)
-------------------
- Improve str conversion in Geometry classes (include x/y).
- Add a get_component method to Registry for easier lookup.
- Treat '.' in float numbers as decimal point independent of locale when parsing, leave locale decimal point valid too.

0.3.10 (2018-05-10)
-------------------
- Initial version online.