Source code for nti.externalization._base_interfaces

# cython: auto_pickle=False,embedsignature=True,always_allow_keywords=False
# -*- coding: utf-8 -*-
"""
Code that is compiled by cython for speed and then exported from
interfaces.py.

This should have no dependencies on things in this package.

This module is **PRIVATE** to this package.

"""
import decimal


__all__ = [
    'NotGiven',
    'LocatedExternalDict',
    'ExternalizationPolicy',
]

class _NotGiven(object):
    """
    A special object you must never pass to any API.
    Used as a marker object for keyword arguments that cannot have the
    builtin None (because that might be a valid value).

    This object is used as-is, it is not instantiated.
    """
    __slots__ = ()

    def __repr__(self): # pragma: no cover
        return '<default value>'

NotGiven = _NotGiven()

dict_init = dict.__init__
dict_update = dict.update

[docs] class LocatedExternalDict(dict): """ A dictionary that implements :class:`~nti.externalization.interfaces.ILocatedExternalMapping`. Returned by :func:`~nti.externalization.externalization.to_standard_external_dictionary`. This class is not :class:`.IContentTypeAware`, and it indicates so explicitly by declaring a `mime_type` value of None. """ # interfaces are applied in interfaces.py def __init__(self, *args, **kwargs): # pylint:disable=super-init-not-called dict_init(self, *args, **kwargs) self.__name__ = '' self.__parent__ = None self.__acl__ = () self.mimeType = None def update_from_other(self, other): return dict_update(self, other)
def make_external_dict() -> LocatedExternalDict: # This layer of indirection is for cython; it can't cimport # types when the extension name doesn't match the # pxd name. But it can cimport functions that are cpdef to return # a type, and then it correctly infers that type for the variable. return LocatedExternalDict()
[docs] class StandardExternalFields(object): """ Namespace object defining constants whose values are the keys used in external mappings. These are text (unicode). Not all external objects will have all possible keys. Two special values are collections of metadata, not strings: `ALL` and `EXTERNAL_KEYS`. """ # We're a namespace object, meant to have instance attributes. # pylint:disable=too-many-instance-attributes __slots__ = ( 'CLASS', 'CONTAINER_ID', 'CREATED_TIME', 'CREATOR', 'HREF', 'ID', 'INTID', 'ITEMS', 'ITEM_COUNT', 'LAST_MODIFIED', 'LINKS', 'MIMETYPE', 'NTIID', 'OID', 'TOTAL', '_ALL_ATTR_NAMES', '_ALL_EXTERNAL_KEYS', ) def __init__(self): #: An id self.ID = 'ID' #: An identifier specific to this exact object instance self.OID = 'OID' #: A hyperlink to reach this object self.HREF = 'href' #: An integer uniquely identifying the object in some scope self.INTID = 'INTID' #: A structured identifier similar to a hyperlink self.NTIID = 'NTIID' #: The name of the creator of the object self.CREATOR = 'Creator' #: The name of the container holding the object self.CONTAINER_ID = 'ContainerId' #: The floating point value giving the Unix epoch time #: of the object's creation self.CREATED_TIME = 'CreatedTime' #: The floating point value giving the Unix epoch time #: of the last modification of the object self.LAST_MODIFIED = 'Last Modified' #: 'Class': The class of the object. If the object provides #: ``__external_class_name__`` it will be used to populate this. self.CLASS = 'Class' #: A dictionary mapping "rel" to more hrefs. self.LINKS = 'Links' #: The MIME type of this object self.MIMETYPE = 'MimeType' #: A list or dictionary of external objects contained within #: this object self.ITEMS = 'Items' #: A counter self.TOTAL = 'Total' #: The total number of items contained in this object self.ITEM_COUNT = 'ItemCount' self._ALL_ATTR_NAMES = frozenset((s for s in StandardExternalFields.__slots__ if not s.startswith('_'))) self._ALL_EXTERNAL_KEYS = frozenset((getattr(self, s) for s in self._ALL_ATTR_NAMES)) @property def ALL(self): """ A collection of all *names* of all the attributes of this class. That is, the contents of this collection are the attribute names that give standard external fields. You can iterate this and use :func:`getattr` to get the corresponding values. """ return self._ALL_ATTR_NAMES @property def EXTERNAL_KEYS(self): """ A collection of all *values* of all attributes of this class. That is, the contents of this collection are the keys that a standard external object would be expected to have. """ return self._ALL_EXTERNAL_KEYS
_standard_external_fields = StandardExternalFields() def get_standard_external_fields(): return _standard_external_fields #: A set of the external keys (fields) used in #: minimal external dictionaries. In general, #: you should prefer StandardExternalFields.EXTERNAL_KEYS MINIMAL_SYNTHETIC_EXTERNAL_KEYS = frozenset(( 'OID', 'ID', 'Last Modified', 'Creator', 'ContainerId', 'Class', )) def isSyntheticKey(k:str) -> bool: """ Deprecated. Prefer to test against StandardExternalFields.EXTERNAL_KEYS """ # pylint:disable=protected-access return k in _standard_external_fields._ALL_EXTERNAL_KEYS
[docs] class StandardInternalFields(object): """ Namespace object defining constants whose values are the property/attribute names looked for on internal objects. These must be native strings. """ __slots__ = ( 'ID', 'NTIID', 'CREATOR', 'CREATED_TIME', 'CONTAINER_ID', 'LAST_MODIFIED', 'LAST_MODIFIEDU', ) def __init__(self): #: 'id': An object ID self.ID = 'id' #: 'ntiid': An object's structured ID. self.NTIID = 'ntiid' #: 'creator': An object that created this object. This will be converted #: to a text string to fill in `.StandardExternalFields.CREATOR`. self.CREATOR = 'creator' #: 'createdTime': The Unix timestamp of the creation of this object. #: If no value can be found, we will attempt to adapt to #: `zope.dublincore.interfaces.IDCTimes` #: and use its 'created' attribute. Fills `StandardExternalFields.CREATED_TIME` self.CREATED_TIME = 'createdTime' #: 'containerId': The ID of the container of this object. #: Fills `StandardExternalFields.CONTAINER_ID`. self.CONTAINER_ID = 'containerId' #: 'lastModified': The Unix timestamp of the last modification of this object. #: If no value can be found, we will attempt to adapt to #: zope.dublincore.interfaces.IDCTimes` #: and use its 'modified' attribute. Fills `.StandardExternalFields.LAST_MODIFIED` self.LAST_MODIFIED = 'lastModified' self.LAST_MODIFIEDU = 'LastModified'
_standard_internal_fields = StandardInternalFields() def get_standard_internal_fields() -> StandardInternalFields: return _standard_internal_fields # Note that we DO NOT include ``numbers.Number`` # as a primitive type. That's because ``numbers.Number`` # is an ABC and arbitrary types can register as it; but # arbitrary types are not necessarily understood as proper # external objects by all representers. In particular, # ``fractions.Fraction`` cannot be handled by default and # needs to go through the adaptation process, as does ``complex``. # simplejson can handle ``decimal.Decimal``, but YAML cannot; # neither can orjson. _PRIMITIVE_NUMBER_TYPES = ( int, # bool is a subclass of int. float, decimal.Decimal, ) PRIMITIVES = ( str, type(None), ) + _PRIMITIVE_NUMBER_TYPES
[docs] class ExternalizationPolicy(object): """ Adjustment knobs for making tweaks across an entire externalization. These knobs will tweak low-level details of the externalization format, details that are often in a hot code path where overhead should be kept to a minimum. Instances of this class are used by registering them as named components in the global site manager. Certain low-level functions accept an optional *policy* argument that must be an instance of this class; higher level functions accept a *policy_name* argument that is used to find the registered component. If either argument is not given, then `DEFAULT_EXTERNALIZATION_POLICY` is used instead. Instances are immutable. This class must not be subclassed; as such, there is no interface for it, merely the class itself. """ __slots__ = ( 'use_iso8601_for_unix_timestamp', ) def __init__(self, use_iso8601_for_unix_timestamp=False): #: Should unix timestamp fields be output as their numeric value, #: or be converted into an ISO 8601 timestamp string? By default, #: the numeric value is output. This is known to specifically apply #: to "Created Time" and "Last Modified." self.use_iso8601_for_unix_timestamp = use_iso8601_for_unix_timestamp def __repr__(self): # pragma: no cover return "ExternalizationPolicy(use_iso8601_for_unix_timestamp=%s)" % ( self.use_iso8601_for_unix_timestamp )
#: The default externalization policy. DEFAULT_EXTERNALIZATION_POLICY = ExternalizationPolicy() def get_default_externalization_policy() -> ExternalizationPolicy: return DEFAULT_EXTERNALIZATION_POLICY from nti.externalization._compat import import_c_accel # pylint:disable=wrong-import-position import_c_accel(globals(), 'nti.externalization.__base_interfaces')