Skip to main content

Building data structures as node trees

Project description

Node

Latest PyPI version Number of PyPI downloads Test node

Overview

Node is a library to create nested data models and structures.

These data models are described as trees of nodes, optionally with attributes and schema definitions.

They utilize:

One purpose of this package is to provide a unified API to different backend storages. Specific storage related implementations are for example:

Another usecase is providing interfaces for specific application domains.

E.g. for user and group management, node.ext.ugm defines the interfaces. Additional it implements a file based default implementation. Then there are specific implementations of those interfaces in node.ext.ldap and cone.sql, to access users and groups in LDAP and SQL databases.

This package is also used to build in-memory models of all sorts.

E.g. yafowil is a HTML form processing and rendering library. It uses node trees for declarative description of the form model.

Another one to mention is cone.app, a Pyramid based development environment for web applications, which uses node trees to describe the application model.

Basic Usage

There are two basic node types. Mapping nodes and sequence nodes. This package provides some basic nodes to start from.

Mapping Nodes

Mapping nodes implement node.interfaces.IMappingNode. A mapping in python is a container object that supports arbitrary key lookups and implements the methods specified in the MutableMapping of pythons abstract base classes respective zope.interface.common.mapping.IFullMapping.

An unordered node. This can be used as base for trees where order of items doesn’t matter:

from node.base import BaseNode

root = BaseNode(name='root')
root['child'] = BaseNode()

An ordered node. The order of items is preserved:

from node.base import OrderedNode

root = OrderedNode(name='orderedroot')
root['foo'] = OrderedNode()
root['bar'] = OrderedNode()

With printtree we can do a quick inspection of our node tree:

>>> root.printtree()
<class 'node.base.OrderedNode'>: orderedroot
  <class 'node.base.OrderedNode'>: foo
  <class 'node.base.OrderedNode'>: bar

Sequence Nodes

Sequence nodes implement node.interfaces.ISequenceNode. In the context of this library, a sequence is an implementation of the methods specified in the MutableSequence of pythons abstract base classes respective zope.interface.common.collections.IMutableSequence.

Using a list node:

from node.base import BaseNode
from node.base import ListNode

root = ListNode(name='listroot')
root.insert(0, BaseNode())
root.insert(1, BaseNode())

Check tree structure with printtree:

>>> root.printtree()
<class 'node.base.ListNode'>: listnode
  <class 'node.base.BaseNode'>: 0
  <class 'node.base.BaseNode'>: 1

Behaviors

node utilizes the plumber package.

The different functionalities of nodes are provided as plumbing behaviors:

from node.behaviors import DefaultInit
from node.behaviors import MappingNode
from node.behaviors import OdictStorage
from plumber import plumbing

@plumbing(
    DefaultInit,
    MappingNode,
    OdictStorage)
class CustomNode:
    pass

When inspecting the CustomNode class, we can see it was plumbed using given behaviors, now representing a complete node implementation:

>>> dir(CustomNode)
['__bool__', '__class__', '__contains__', '__delattr__', '__delitem__',
'__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__gt__', '__hash__', '__implemented__',
'__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__',
'__module__', '__name__', '__ne__', '__new__', '__nonzero__', '__parent__',
'__plumbing__', '__plumbing_stacks__', '__provides__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__',
'__str__', '__subclasshook__', '__weakref__', 'acquire', 'clear', 'copy',
'deepcopy', 'detach', 'filtereditems', 'filtereditervalues', 'filteredvalues',
'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys',
'name', 'noderepr', 'parent', 'path', 'pop', 'popitem', 'printtree', 'root',
'setdefault', 'storage', 'treerepr', 'update', 'values']

Please read the documentation of plumber for detailed information about the plumbing system.

Attributes

While it is not strictly necessary, it’s a good idea to separate the hierarchical structure of a model from the node related attributes to avoid naming conflicts. Attributes are provided via node.behaviors.Attributes plumbing behavior:

from node.behaviors import Attributes
from node.behaviors import DefaultInit
from node.behaviors import DictStorage
from node.behaviors import MappingNode
from plumber import plumbing

@plumbing(
    Attributes,
    DefaultInit,
    MappingNode,
    DictStorage)
class NodeWithAttributes:
    pass

The node now provides an attrs attribute. Node attributes are itself just a node:

>>> node = NodeWithAttributes()
>>> attrs = node.attrs
>>> attrs
<NodeAttributes object 'None' at ...>

>>> attrs['foo'] = 'foo'

If it’s desired to access attribute members via python attribute access, attribute_access_for_attrs must be set on node:

>>> node.attribute_access_for_attrs = True
>>> attrs = node.attrs
>>> attrs.foo = 'bar'
>>> attrs.foo
'bar'

A custom attributes implementation can be set by defining attributes_factory on the node:

from node.behaviors import NodeAttributes

class CustomAttributes(NodeAttributes):
    pass

class CustomAttributesNode(NodeWithAttributes):
    attributes_factory = CustomAttributes

This factory is then used to instantiate the attributes:

>>> node = CustomAttributesNode()
>>> node.attrs
<CustomAttributes object 'None' at ...>

Schema

To describe the data types of node members, this package provides a mechanism for defining schemata.

This can happen in different ways. One is to define the schema for node members directly. This is useful for nodes representing a leaf in the hierarchy or for node attribute nodes:

from node import schema
from node.base import BaseNode
from node.behaviors import DefaultInit
from node.behaviors import DictStorage
from node.behaviors import MappingNode
from node.behaviors import Schema
from plumber import plumbing

@plumbing(
    DefaultInit,
    MappingNode,
    DictStorage,
    Schema)
class SchemaNode:
    schema = {
        'int': schema.Int(),
        'float': schema.Float(default=1.),
        'str': schema.Str(),
        'bool': schema.Bool(default=False),
        'node': schema.Node(BaseNode)
    }

Children defined in the schema provide a default value. If not explicitely defined, the default value is always node.utils.UNSET:

>>> node = SchemaNode()
>>> node['int']
<UNSET>

>>> node['float']
1.0

>>> node['bool']
False

Children defined in the schema are validated against the defined type when setting it’s value:

>>> node = SchemaNode()
>>> node['int'] = 'A'
Traceback (most recent call last):
  ...
ValueError: A is no <class 'int'> type

For accessing members defined in the schema as node attributes, SchemaAsAttributes plumbing behavior can be used:

from node.behaviors import SchemaAsAttributes

@plumbing(SchemaAsAttributes)
class SchemaAsAttributesNode(BaseNode):
    schema = {
        'int': schema.Int(default=1),
    }

Node attrs now provides access to the schema members:

>>> node = SchemaAsAttributesNode()
>>> node.attrs['int']
1

Schema members can also be defined as class attributes. This is syntactically the most elegant way, but comes with the tradeoff of possible naming conflicts:

from node.behaviors import SchemaProperties

@plumbing(
    DefaultInit,
    MappingNode,
    DictStorage,
    SchemaProperties)
class SchemaPropertiesNode:
    text = schema.Str(default='Text')

Here we access text as class attribute:

>>> node = SchemaPropertiesNode()
>>> node.text
'Text'

>>> node.text = 1
Traceback (most recent call last):
  ...
ValueError: 1 is no <class 'str'> type

Plumbing Behaviors

General Behaviors

node.behaviors.DefaultInit

Plumbing behavior providing default __init__ function on node. This behavior is going to be deprecated in future versions. Use node.behaviors.NodeInit instead. See node.interfaces.IDefaultInit.

node.behaviors.NodeInit

Plumbing behavior for transparent setting of __name__ and __parent__ at object initialization time. See node.interfaces.INodeInit.

node.behaviors.Node

Fill in gaps for full INode API. See node.interfaces.INode.

node.behaviors.ContentishNode

A node which can contain children. See node.interfaces.IContentishNode. Concrete implementations are node.behaviors.MappingNode and node.behaviors.SequenceNode.

node.behaviors.Attributes

Provide attributes on node. See node.interfaces.IAttributes. If node.behaviors.Nodespaces is applied on node, the attributes instance gets stored internally in __attrs__ nodespace, otherwise its set on __attrs__ attribute.

node.behaviors.Events

Provide an event registration and dispatching mechanism. See node.interfaces.IEvents.

node.behaviors.BoundContext

Mechanism for scoping objects to interfaces and classes. See node.interfaces.IBoundContext.

node.behaviors.NodeReference

Plumbing behavior holding an index of nodes contained in the tree. See node.interfaces.INodeReference.

node.behaviors.WildcardFactory

Plumbing behavior providing factories by wildcard patterns. See node.interfaces.IWildcardFactory.

Mapping Behaviors

node.behaviors.MappingNode

Turn an object into a mapping node. Extends node.behaviors.Node. See node.interfaces.IMappingNode.

node.behaviors.MappingAdopt

Plumbing behavior that provides __name__ and __parent__ attribute adoption on child nodes of mapping. See node.interfaces.IMappingAdopt.

node.behaviors.MappingConstraints

Plumbing behavior for constraints on mapping nodes. See node.interfaces.IMappingConstraints.

node.behaviors.UnicodeAware

Plumbing behavior to ensure unicode for keys and string values. See node.interfaces.IUnicodeAware.

node.behaviors.Alias

Plumbing behavior that provides aliasing of child keys. See node.interfaces.IAlias.

node.behaviors.AsAttrAccess

Plumbing behavior to get node as IAttributeAccess implementation. See node.interfaces.IAsAttrAccess.

node.behaviors.ChildFactory

Plumbing behavior providing child factories. See node.interfaces.IChildFactory.

node.behaviors.FixedChildren

Plumbing Behavior that initializes a fixed dictionary as children. See node.interfaces.IFixedChildren.

node.behaviors.Nodespaces

Plumbing behavior for providing nodespaces on node. See node.interfaces.INodespaces.

node.behaviors.Lifecycle

Plumbing behavior taking care of lifecycle events. See node.interfaces.ILifecycle.

node.behaviors.AttributesLifecycle

Plumbing behavior for handling lifecycle events on attribute manipulation. See node.interfaces.IAttributesLifecycle.

node.behaviors.Invalidate

Plumbing behavior for node invalidation. See node.interfaces.Invalidate.

node.behaviors.VolatileStorageInvalidate

Plumbing behavior for invalidating nodes using a volatile storage. See node.interfaces.Invalidate.

node.behaviors.Cache

Plumbing behavior for caching. See node.interfaces.ICache.

node.behaviors.MappingOrder

Plumbing behavior for ordering support on mapping nodes. See node.interfaces.IMappingOrder.

node.behaviors.UUIDAware

Plumbing behavior providing a uuid on nodes. See node.interfaces.IUUIDAware.

node.behaviors.MappingReference

Plumbing behavior to provide node.interfaces.INodeReference on mapping nodes. See node.interfaces.IMappingReference.

node.behaviors.MappingStorage

Provide abstract mapping storage access. See node.interfaces.IMappingStorage.

node.behaviors.DictStorage

Provide dictionary storage. Extends node.behaviors.MappingStorage. See node.interfaces.IMappingStorage.

node.behaviors.OdictStorage

Provide ordered dictionary storage. Extends node.behaviors.MappingStorage. See node.interfaces.IMappingStorage.

node.behaviors.Fallback

Provide a way to fall back to values by subpath stored on another node. See node.interfaces.IFallback.

node.behaviors.Schema

Provide schema validation and value serialization on node values. See node.interfaces.ISchema.

node.behaviors.SchemaAsAttributes

Provide schema validation and value serialization on node values via dedicated attributes object. See node.interfaces.ISchemaAsAttributes.

node.behaviors.SchemaProperties

Provide schema fields as class properties. See node.interfaces.ISchemaProperties.

node.behaviors.MappingFilter

Filter mapping children by class or interface. See node.interfaces.IChildFilter.

Sequence Behaviors

node.behaviors.SequenceNode

Turn an object into a sequence node. Extends node.behaviors.Node. See node.interfaces.IMappingNode.

node.behaviors.SequenceAdopt

Plumbing behavior that provides __name__ and __parent__ attribute adoption on child nodes of sequence. See node.interfaces.ISequenceAdopt.

node.behaviors.SequenceConstraints

Plumbing behavior for constraints on sequence nodes. See node.interfaces.ISequenceConstraints.

node.behaviors.SequenceStorage

Provide abstract sequence storage access. See node.interfaces.ISequenceStorage.

node.behaviors.ListStorage

Provide list storage. See node.interfaces.ISequenceStorage.

node.behaviors.SequenceReference

Plumbing behavior to provide node.interfaces.INodeReference on sequence nodes. See node.interfaces.ISequenceReference.

node.behaviors.SequenceFilter

Filter sequence children by class or interface. See node.interfaces.IChildFilter.

node.behaviors.SequenceOrder

Plumbing behavior for ordering support on sequence nodes. See node.interfaces.ISequenceOrder.

JSON Serialization

Nodes can be serialized to and deserialized from JSON:

>>> from node.serializer import serialize
>>> json_dump = serialize(BaseNode(name='node'))

>>> from node.serializer import deserialize
>>> deserialize(json_dump)
<BaseNode object 'node' at ...>

For details on serialization API please read file in docs/archive/serializer.rst.

Python Versions

  • Python 2.7, 3.7+

  • May work with other versions (untested)

Contributors

  • Robert Niederreiter

  • Florian Friesdorf

  • Jens Klein

Changes

1.2.2 (2024-05-30)

  • Make sure Unset class always returns the same instance in __new__. Fixes problems with pickle. [rnix]

1.2.1 (2023-04-16)

  • Replace deprecated import of Order with MappingOrder in node.base. [rnix]

1.2 (2022-12-05)

  • Do not overwrite uuid in node.behaviors.UUIDAware.__init__ if uuid already set. [rnix]

  • Rename node.interfaces.IOrder to node.interfaces.IMappingOrder and node.behaviors.Order to node.behaviors.MappingOrder. B/C is kept. [rnix]

  • Introduce node.behaviors.ISequenceOrder and node.interfaces.SequenceOrder. [rnix]

  • Introduce node.interfaces.INodeOrder. Used as base for node.interfaces.IMappingOrder and node.interfaces.ISequenceOrder. [rnix]

  • Add rich comparison functions __lt__, __le__, __gt__ and __ge__ to node.utils.Unset. [rnix]

Breaking changes:

  • Importing B/C Order behavior from node.behaviors.order not works any more. Please import from node.behaviors. [rnix]

1.1 (2022-10-06)

  • Add node.schema.DateTime, node.schema.DateTimeSerializer and node.schema.datetime_serializer. [rnix]

  • Subclass threading.local for node.behaviors.lifecycle._lifecycle_context, node.behaviors.events._attribute_subscribers and node.behaviors.schema._schema_property objects in order to safely provide default values. [rnix]

  • Introduce node.interfaces.IChildFilter, node.behaviors.MappingFilter and node.behaviors.SequenceFilter. [rnix]

  • Introduce node.interfaces.IWildcardFactory and node.behaviors.WildcardFactory. [rnix]

  • Introduce node.interfaces.INodeInit and node.behaviors.NodeInit. [rnix]

  • Deprecate IFixedChildren.fixed_children_factories Use IFixedChildren.factories instead. [rnix]

  • Introduce node.interfaces.IContentishNode and node.behaviors.ContentishNode. Use as base for mapping and sequence nodes. [rnix]

  • insertbefore, insertafter and swap in node.behaviors.Order alternatively accept node names as arguments where possible. [rnix]

  • insertbefore, insertafter, and insertfirst and insertlast in node.behaviors.Order internally use movebefore, moveafter, movefirst and movelast of odict to avoid modifying the data structure before __setitem__ gets called. [rnix]

  • Extend node.interfaces.IOrder respective node.behaviors.Order by movebefore, moveafter, movefirst and movelast. [rnix]

  • Reset __parent__ in node.behaviors.Node.detach. Node is no longer contained in tree. [rnix]

  • Introduce IndexViolationError which inherits from ValueError and raise it in reference related behaviors instead of ValueError where appropriate. [rnix]

  • Introduce node.interfaces.INodeReference and node.behaviors.NodeReference. [rnix]

  • Introduce node.interfaces.ISequenceReference and node.behaviors.SequenceReference. [rnix]

  • Rename node.interfaces.IReference to node.interfaces.IMappingReference and node.behaviors.Reference to node.behaviors.MappingReference. B/C is kept. [rnix]

Breaking changes:

  • Remove _notify_suppress flag from Lifecycle behavior. Introduce suppress_lifecycle_events contextmanager as substitute. [rnix]

  • Importing ChildFactory and FixedChildren from node.behaviors.common not works any more. Please import from node.behaviors. [rnix]

  • Importing B/C Reference behavior from node.behaviors.reference not works any more. Please import from node.behaviors. [rnix]

1.0 (2022-03-17)

  • Implement __copy__ and __deepcopy__ on node.utils.UNSET. [rnix]

  • Introduce node.interfaces.ISequenceConstraints and node.behaviors.SequenceConstraints. [rnix]

  • Rename node.interfaces.INodeChildValidate to node.interfaces.IMappingConstraints and node.behaviors.NodeChildValidate to node.behaviors.MappingConstraints. MappingConstraints implementation moved from node.behaviors.common to node.behaviors.constraints. B/C is kept. [rnix]

  • Introduce node.interfaces.ISequenceAdopt and node.behaviors.SequenceAdopt. [rnix]

  • MappingAdopt now catches all exceptions instead of only AttributeError, KeyError and ValueError. [rnix]

  • Rename node.interfaces.IAdopt to node.interfaces.IMappingAdopt and node.behaviors.Adopt to node.behaviors.MappingAdopt. MappingAdopt implementation moved from node.behaviors.common to node.behaviors.adopt. B/C is kept. [rnix]

  • node.behaviors.Attributes now also works if node.behaviors.Nodespaces is not applied. [rnix]

  • Introduce node.behaviors.Node which implements only node.interfaces.INode contract. It is used as base for node.behaviors.MappingNode and node.behaviors.SequcneNode. [rnix]

  • Do not inherit node.interfaces.INode from zope.interfaces.common.mapping.IFullMapping any more. Data model specific interfaces are added now via node.interfaces.IMappingNode and node.interfaces.ISequenceNode. [rnix]

  • Introduce sequence nodes. Sequence nodes are implemented via node.behaviors.SequcneNode and node.behaviors.ListStorage. [rnix]

  • Rename node.interfaces.INodify to node.interfaces.IMappingNode and node.behaviors.Nodify to node.behaviors.MappingNode. MappingNode implementation moved from node.behaviors.nodify to node.behaviors.mapping. B/C is kept. [rnix]

  • Rename node.interfaces.IStorage to node.interfaces.IMappingStorage and node.behaviors.Storage to node.behaviors.Storage. B/C is kept. [rnix]

  • Add key and value type validation to schema fields where appropriate. [rnix]

  • Introduce serializer support to schema fields. Add a couple of concrete field serializer implementations to node.schema.serializer. [rnix]

  • Add ODict and Node schema fields to node.schema.fields. [rnix]

  • Add node.schema.fields.IterableField and use as base class for List, Tuple and Set schema fields.

  • Introduce node.behaviors.schema.SchemaProperties plumbing behavior. [rnix]

  • Split up node.schema module into a package. [rnix]

  • Introduce node.behaviors.context.BoundContext plumbing behavior. [rnix]

Breaking changes:

  • Remove node.behaviors.GetattrChildren. See node.utils.AttributeAccess instead if you need to access node children via __getattr__. [rnix]

  • Importing B/C Adopt behavior from node.behaviors.common not works any more. Please import from node.behaviors. [rnix]

  • Importing B/C NodeChildValidate behavior from node.behaviors.common not works any more. Please import from node.behaviors. [rnix]

  • Importing B/C Nodify behavior from node.behaviors.nodify not works any more. Please import from node.behaviors. [rnix]

  • Remove deprecated B/C import location node.parts. [rnix]

  • node.behaviors.schema.Schema no longer considers wildcard fields. [rnix]

  • node.behaviors.schema.Schema.__setitem__ deletes value from related storage for field if value is node.utils.UNSET. [rnix]

  • node.behaviors.schema.Schema.__getitem__ always returns default value for field instead of raising KeyError if no default is set. [rnix]

  • Default value of node.schema.fields.Field.default is node.utils.UNSET now. [rnix]

  • node.schema.fields.Field.validate raises exception if validation fails instead of returning boolean. [rnix]

0.9.28 (2021-11-08)

  • Add missing node.interfaces.INodeAttributes interface. [rnix]

  • Add missing attribute_access_for_attrs attribute to IAttributes interface. [rnix]

  • Rename node.behaviors.common.NodeChildValidate.allow_non_node_childs to allow_non_node_children. A Deprecation warning is printed if the old attribute is used. [rnix]

  • Introduce node.behaviors.schema.Schema, node.behaviors.schema.SchemaAsAttributes and related schema definitions in node.schema. [rnix]

0.9.27 (2021-10-21)

  • Expose first_key, last_key, next_key and prev_key from odict storage on Order behavior. [rnix, 2021-10-21]

  • Add basic serializer settings mechanism. [rnix, 2021-07-20]

0.9.26 (2021-05-10)

  • Use node.utils.safe_decode in node.behaviors.nodify.Nodify.treerepr. [rnix, 2021-05-04]

  • Add node.utils.safe_encode and node.utils.safe_decode. [rnix, 2021-05-04]

0.9.25 (2020-03-30)

  • Introduce uuid_factory function on node.interfaces.IUUIDAware and implement default function in node.behaviors.common.UUIDAware. [rnix, 2020-03-01]

  • Rename NodeTestCase.expect_error to NodeTestCase.expectError. [rnix, 2019-09-04]

  • Rename NodeTestCase.check_output to NodeTestCase.checkOutput. [rnix, 2019-09-04]

  • Introduce prefix keyword argument in Nodify.treerepr. [rnix, 2019-09-04]

0.9.24 (2019-07-10)

  • Overhaul node.behaviors.Order. Use related functions from odict where appropriate. [rnix, 2019-07-10]

  • Remove superfluous extra_require from setup.py. [rnix, 2019-04-25]

  • Drop Support for python < 2.7 and < 3.3. [rnix, 2019-04-25]

0.9.23 (2018-11-07)

  • Use property decorators for node.behaviors.reference.Reference.uuid. [rnix, 2017-12-15]

0.9.22 (2017-07-18)

  • Add always_dispatch keyword argument to node.behaviors.events.EventAttribute constructor which defines whether events are always dispatched on __set__, not only if attribute value changes. [rnix, 2017-06-20]

  • Use node.utils.UNSET as default default value in node.behaviors.events.EventAttribute.__init__. [rnix, 2017-06-19]

  • Introduce node.behaviors.events.EventAttribute.subscriber decorator which can be used to register attribute subscribers. [rnix, 2017-06-19]

  • Move event dispatching related classes and functions from node.events to node.behaviors.events and import it from there in node.events. [rnix, 2017-06-16]

  • Introduce node.interfaces.IEvents and implement node.behaviors.events.Events behavior. Contains business logic from node.events.EventDispatcher. Use new behavior on EventDispatcher. [rnix, 2017-06-16]

  • Create suppress_events context manager which can be used to suppress event notification in conjunction with node.behaviors.Events behavior. [rnix, 2017-06-15]

  • Create node.behaviors.fallback.fallback_processing context manager and and use it in node.behaviors.fallback.Fallback.__getitem__ to check whether fallback processing is active. [rnix, 2017-06-15]

0.9.21 (2017-06-15)

  • Introduce node.events.EventDispatcher and node.events.EventAttribute. [rnix, 2017-06-15]

  • Use setattr in instance_property decorator instead of object.__setattr__ in order to avoid errors with custom low level __setattr__ implementations. [rnix, 2017-06-14]

0.9.20 (2017-06-07)

  • Type cast sort key to node.compat.UNICODE_TYPE in node.behaviors.Nodify.treerepr to avoid unicode decode errors. [rnix, 2017-06-07]

0.9.19 (2017-06-07)

  • Python 3 and pypy compatibility. [rnix, 2017-06-02]

  • Drop support for Python < 2.7. [rnix, 2017-06-02]

  • Add __bool__ to node.behaviors.Nodify. [rnix, 2017-06-02]

  • Add __bool__ to node.utils.UNSET. [rnix, 2017-06-02]

  • Add treerepr in node.behaviors.nodify.Nodify and move code from printtree to it. Returs tree representation as string instead of printing it. printtree uses treerepr now. As enhancement treerepr sorts children of node if it does not implement IOrdered in order to ensure consistend output which can be used to write tests against. [rnix, 2017-06-02]

  • Use object.__getattribute__ explicitely in node.utils.instance_property to check whether property value already has been computed in order to avoid problems when oberwriting __getattr__ on classes using instance_property decorator. [rnix, 2017-06-02]

0.9.18.1 (2017-02-23)

  • Fix permissions. [rnix, 2017-02-23]

0.9.18 (2017-02-14)

  • Add node.utils.node_by_path. [rnix, 2017-02-07]

  • Do not depend on unittest2 since its is not used. [jensens, 2017-01-17]

  • Add node.behaviors.Fallback behavior. [jensens, 2017-01-17]

0.9.17 (2017-01-17)

  • Add basic JSON serializer and deserializer. [rnix, 2016-12-03]

0.9.16 (2015-10-08)

  • Only encode name in node.behaviors.nodify.Nodify.__repr__ and node.behaviors.nodify.Nodify.noderepr if name is unicode instance. [rnix, 2015-10-03]

  • Improve node.behaviors.nodify.Nodify.printtree. None node children are printed with key. [rnix, 2015-10-03]

0.9.15 (2014-12-17)

  • Fix dependency declaration to odict in order to make setuptools 8.x+ happy; using >= instead of > now. [jensens, 2014-12-17]

0.9.14

  • use plumbing decorator instead of plumber metaclass. [rnix, 2014-07-31]

0.9.13

  • Introduce node.behaviors.cache.VolatileStorageInvalidate. [rnix, 2014-01-15]

0.9.12

  • Add zope.component to install dependencies. [rnix, 2013-12-09]

0.9.11

  • Use node.utils.UNSET instance in node.behaviors.mapping.ExtendedWriteMapping.pop. [rnix, 2013-02-10]

  • Improve node.utils.Unset. Add Unset instance at node.utils.UNSET. [rnix, 2013-02-10]

0.9.10

  • Fix node.utils.StrCodec.encode to return value as is if str and decoding failed. [rnix, 2012-11-07]

0.9.9

  • Python 2.7 compatibility. [rnix, 2012-10-15]

  • Remove zope.component.event B/C. [rnix, 2012-10-15]

  • Remove zope.location B/C. [rnix, 2012-10-15]

  • Remove zope.lifecycleevent B/C. [rnix, 2012-10-15]

  • Pep8. [rnix, 2012-10-15]

0.9.8

  • Deprecate the use of node.parts. Use node.behaviors instead. [rnix, 2012-07-28]

  • Adopt to plumber 1.2 [rnix, 2012-07-28]

0.9.7

  • Introduce node.interfaces.IOrdered Marker interface. Set this interface on node.parts.storage.OdictStorage. [rnix, 2012-05-21]

  • node.parts.mapping.ClonableMapping now supports deepcopy. [rnix, 2012-05-18]

  • Use zope.interface.implementer instead of zope.interface.implements all over the place. [rnix, 2012-05-18]

  • Remove superfluos interfaces. [rnix, 2012-05-18]

  • Remove Zodict from node.utils. [rnix, 2012-05-18]

  • Remove AliasedNodespace, use Alias part instead. [rnix, 2012-05-18]

  • Move aliaser objects from node.aliasing to node.parts.alias. [rnix, 2012-05-18]

  • Remove composition module. [rnix, 2012-05-18]

  • Remove bbb module. [rnix, 2012-05-18]

0.9.6

  • Do not inherit node.parts.Reference from node.parts.UUIDAware. [rnix, 2012-01-30]

  • Set uuid in node.parts.Reference.__init__ plumb. [rnix, 2012-01-30]

0.9.5

  • add node.parts.nodify.Nodify.acquire function. [rnix, 2011-12-05]

  • add node.parts.ChildFactory plumbing part. [rnix, 2011-12-04]

  • add node.parts.UUIDAware plumbing part. [rnix, 2011-12-02]

  • fix node.parts.Order.swap in order to work with pickled nodes. [rnix, 2011-11-28]

  • use node.name instead of node.__name__ in node.parts.nodify.Nodify.path. [rnix, 2011-11-17]

  • add swap to node.parts.Order. [rnix, 2011-10-05]

  • add insertfirst and insertlast to node.parts.Order. [rnix, 2011-10-02]

0.9.4

  • add node.utils.debug decorator. [rnix, 2011-07-23]

  • remove non storage contract specific properties from node.aliasing.AliasedNodespace [rnix, 2011-07-18]

  • node.aliasing test completion [rnix, 2011-07-18]

  • Add non strict functionality to node.aliasing.DictAliaser for accessing non aliased keys as is as fallback [rnix, 2011-07-18]

  • Consider INode implementing objects in node.utils.StrCodec [rnix, 2011-07-16]

  • Remove duplicate implements in storage parts [rnix, 2011-05-16]

0.9.3

  • Increase test coverage [rnix, 2011-05-09]

  • Add interfaces IFixedChildren and IGetattrChildren for related parts. [rnix, 2011-05-09]

  • Rename Unicode part to UnicodeAware. [rnix, 2011-05-09]

  • Add node.utils.StrCodec. [rnix, 2011-05-09]

  • Inherit INodify interface from INode. [rnix, 2011-05-08]

  • Locking tests. Add time.sleep after thread start. [rnix, 2011-05-08]

  • Cleanup BaseTester, remove sorted_output flag (always sort), also search class bases for detection in wherefrom. [rnix, 2011-05-08]

  • Remove useless try/except in utils.AttributeAccess. [rnix, 2011-05-08]

  • Add instance_property decorator to utils. [rnix, 2011-05-06]

  • Add FixedChildren and GetattrChildren parts. [chaoflow, 2011-04-22]

0.9.2

  • Add __nonzero__ on Nodifiy part always return True. [rnix, 2011-03-15]

0.9.1

  • Provide node.base.Node with same behavior like zodict.Node for migration purposes. [rnix, 2011-02-08]

0.9

  • Make it work [rnix, chaoflow, et al]

License

Copyright (c) 2009-2021, BlueDynamics Alliance, Austria Copyright (c) 2021-2024, Node Contributors All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

node-1.2.2.tar.gz (100.4 kB view hashes)

Uploaded Source

Built Distribution

node-1.2.2-py3-none-any.whl (102.8 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page