Source code for apptools.naming.py_context
# (C) Copyright 2005-2024 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
""" A naming context for a Python namespace. """
# Enthought library imports.
from traits.api import Any, Dict, Instance, Property
# Local imports.
from .address import Address
from .binding import Binding
from .context import Context
from .naming_manager import naming_manager
from .py_object_factory import PyObjectFactory
from .reference import Reference
from .referenceable import Referenceable
from .referenceable_state_factory import ReferenceableStateFactory
# The default environment.
ENVIRONMENT = {
# 'Context' properties.
Context.OBJECT_FACTORIES: [PyObjectFactory()],
Context.STATE_FACTORIES: [ReferenceableStateFactory()],
}
[docs]class PyContext(Context, Referenceable):
""" A naming context for a Python namespace. """
#### 'Context' interface ##################################################
# The naming environment in effect for this context.
environment = Dict(ENVIRONMENT)
#### 'PyContext' interface ################################################
# The Python namespace that we represent.
namespace = Any
# If the namespace is actual a Python object that has a '__dict__'
# attribute, then this will be that object (the namespace will be the
# object's '__dict__'.
obj = Any
#### 'Referenceable' interface ############################################
# The object's reference suitable for binding in a naming context.
reference = Property(Instance(Reference))
###########################################################################
# 'object' interface.
###########################################################################
def __init__(self, **traits):
""" Creates a new context. """
# Base class constructor.
super(PyContext, self).__init__(**traits)
if type(self.namespace) is not dict:
if hasattr(self.namespace, "__dict__"):
self.obj = self.namespace
self.namespace = self.namespace.__dict__
else:
raise ValueError("Need a dictionary or a __dict__ attribute")
###########################################################################
# 'Referenceable' interface.
###########################################################################
#### Properties ###########################################################
def _get_reference(self):
""" Returns a reference to this object suitable for binding. """
reference = Reference(
class_name=self.__class__.__name__,
addresses=[Address(type="py_context", content=self.namespace)],
)
return reference
###########################################################################
# Protected 'Context' interface.
###########################################################################
def _is_bound(self, name):
""" Is a name bound in this context? """
return name in self.namespace
def _lookup(self, name):
""" Looks up a name in this context. """
obj = self.namespace[name]
return naming_manager.get_object_instance(obj, name, self)
def _bind(self, name, obj):
""" Binds a name to an object in this context. """
state = naming_manager.get_state_to_bind(obj, name, self)
self.namespace[name] = state
def _rebind(self, name, obj):
""" Rebinds a name to a object in this context. """
self._bind(name, obj)
def _unbind(self, name):
""" Unbinds a name from this context. """
del self.namespace[name]
# Trait event notification.
self.trait_property_changed("context_changed", None, None)
def _rename(self, old_name, new_name):
""" Renames an object in this context. """
state = self.namespace[old_name]
# Bind the new name.
self.namespace[new_name] = state
# Unbind the old one.
del self.namespace[old_name]
# Trait event notification.
self.context_changed = True
def _create_subcontext(self, name):
""" Creates a sub-context of this context. """
sub = self._context_factory(name, {})
self.namespace[name] = sub
# Trait event notification.
self.trait_property_changed("context_changed", None, None)
return sub
def _destroy_subcontext(self, name):
""" Destroys a sub-context of this context. """
del self.namespace[name]
# Trait event notification.
self.trait_property_changed("context_changed", None, None)
def _list_bindings(self):
""" Lists the bindings in this context. """
bindings = []
for name, value in self.namespace.items():
bindings.append(
Binding(name=name, obj=self._lookup(name), context=self)
)
return bindings
def _list_names(self):
""" Lists the names bound in this context. """
return list(self.namespace.keys())
###########################################################################
# Private interface.
###########################################################################
def _context_factory(self, name, namespace):
""" Create a sub-context. """
return self.__class__(namespace=namespace)