gavo.base.structure module

Representation of structured data deserializable from XML.

We want all the managed attribute stuff since the main user input comes from resource descriptors, and we want relatively strong input validation here. Also, lots of fancy copying and crazy cross-referencing is going on in our resource definitions, so we want a certain amount of rigorous structure. Finally, a monolithic parser for that stuff becomes really huge and tedious, so I want to keep the XML parsing information in the constructed objects themselves.

class gavo.base.structure.DataContent(default='', description='Undocumented', **kwargs)[source]

Bases: UnicodeAttribute

A magic attribute that allows character content to be added to a structure.

You can configure it with all the arguments available for UnicodeAttribute.

Since parsers may call characters with an empty string for empty elements, the empty string will not be fed (i.e., the default will be preserved). This makes setting an empty string as an element content impossible (you could use DataContent with strip=True, though), but that’s probably not a problem.

feed(ctx, instance, value)[source]
makeUserDoc()[source]
typeDesc_ = 'string'
class gavo.base.structure.ParseableStructure(parent, **kwargs)[source]

Bases: StructureBase, StructCallbacks, Parser

is a base class for Structures parseable from EventProcessors (and thus XML).

This is still abstract in that you need at least a name_ attribute. But it knows how to be fed from a parser, plus you have feed and feedObject methods that look up the attribute names and call the methods on the respective attribute definitions.

attrSeq = [<gavo.base.parsecontext.IdAttribute object>]
completedCallbacks = []
end_(ctx, name, value)[source]
feed(name, literal, ctx=None)[source]

feeds the literal to the attribute name.

If you do not have a proper parse context ctx, so there may be restrictions on what literals can be fed.

feedFrom(other, ctx=None, suppress={})[source]

feeds parsed objects from another structure.

This only works if the other structure is a of the same or a superclass of self.

feedObject(name, ob)[source]

feeds the object ob to the attribute name.

finishElement(ctx)[source]
getAttribute(name)[source]

Returns an attribute instance from name.

This function will raise a StructureError if no matching attribute definition is found.

iterEvents()[source]

yields an event sequence that transfers the copyable information from self to something receiving the events.

If something is not copyable, it is ignored (i.e., keeps its default on the target object).

managedAttrs = {'id': <gavo.base.parsecontext.IdAttribute object>}
start_(ctx, name, value)[source]
value_(ctx, name, value)[source]
class gavo.base.structure.RestrictionMixin[source]

Bases: StructCallbacks

A mixin for structure classes not allowed in untrusted RDs.

completeElement(ctx)[source]
class gavo.base.structure.StructType(name, bases, dict)[source]

Bases: type

A metaclass for the representation of structured data.

StructType classes with this will be called structures within the DC software.

Structures do quite a bit of the managed attribute nonsense to meaningfully catch crazy user input.

Basically, you give a Structure class attributes (preferably with underscores in front) specifying the attributes the instances should have and how they should be handled.

Structures must be constructed with a parent (for the root element, this is None). All other arguments should be keyword arguments. If given, they have to refer to existing attributes, and their values will directly give the the values of the attribute (i.e., parsed values).

Structures should always inherit from StructBase below and arrange for its constructor to be called, since, e.g., default processing happens there.

Structures have a managedAttrs dictionary containing names and attrdef.AttributeDef objects for the defined attributes.

class gavo.base.structure.Structure(parent, **kwargs)[source]

Bases: ParseableStructure

is the base class for user-defined structures.

It will do some basic validation and will call hooks to complete elements and compute computed attributes, based on ParseableStructure’s finishElement hook.

Also, it supports onParentComplete callbacks; this works by checking if any managedAttr has a onParentComplete method and calling it with the current value of that attribute if necessary.

attrSeq = [<gavo.base.parsecontext.IdAttribute object>]
callCompletedCallbacks()[source]
completeElement(ctx)[source]
completedCallbacks = []
finishElement(ctx=None)[source]
managedAttrs = {'id': <gavo.base.parsecontext.IdAttribute object>}
onElementComplete()[source]
validate()[source]
class gavo.base.structure.StructureBase(parent, **kwargs)[source]

Bases: object

is a base class for all structures.

You must arrange for calling its constructor from classes inheriting this.

The constructor receives a parent (another structure, or None) and keyword arguments containing values for actual attributes (which will be set without any intervening consultation of the AttributeDef).

The attribute definitions talking about structures let you set parent to None when constructing default values; they will then insert the actual parent.

adopt(struct)[source]
attrSeq = [<gavo.base.parsecontext.IdAttribute object>]
breakCircles()[source]

removes the parent attributes from all child structures recursively.

The struct will probably be broken after this, but this is sometimes necessary to help the python garbage collector.

In case you’re asking: parent cannot be a weak reference with the current parse architecture, as it usually is the only reference to the embedding object. Yes, we should probably change that.

change(**kwargs)[source]

returns a copy of self with all attributes in kwargs overridden with the passed values.

completedCallbacks = []
copy(parent, ctx=None)[source]

returns a deep copy of self, reparented to parent.

This is a shallow wrapper around change, present for backward compatibility.

classmethod fromStructure(newParent, oldStructure)[source]
getAttributes(attDefsFrom=None)[source]

returns a dict of the current attributes, suitable for making a shallow copy of self.

Struct attributes will not be reparented, so there are limits to what you can do with such shallow copies.

getCopyableAttributes(ignoreKeys={}, ctx=None, newParent=None)[source]

returns a dictionary mapping attribute names to copyable children.

ignoreKeys can be a set or dict of additional attribute names to ignore. The children are orphan deep copies.

getSourcePosition()[source]

returns a string representation of where the struct was parsed from.

iterChildren()[source]

iterates over structure children of self.

To make this work, attributes containing structs must define iterChildren methods (and the others must not).

managedAttrs = {'id': <gavo.base.parsecontext.IdAttribute object>}
name_

alias of Undefined

setParent(parent)[source]

sets the parent of a Structure.

This is a method mainly to let individual elements override the behaviour.

setPosition(fName, lineNumber)[source]

should be called by parsers to what file at what line the serialisation came from.

gavo.base.structure.makeStruct(structClass, **kwargs)[source]

creates a parentless instance of structClass with **kwargs.

You can pass in a parent_ kwarg to force a parent, and a ctx_ if you need a parse context.

This is the preferred way to create struct instances in DaCHS, as it will cause the sequence of completers and validators run. Use it like this:

MS(rscdef.Column, name="ra", type="double precision)
gavo.base.structure.sortAttrs(attrSeq)[source]

evaluates the before attributes on the AttributeDefs in attrsSeq and returns a sequence satisfying them.

It returns a reference to attrSeq for convenience.