gavo.base.parsecontext module

ParseContexts for parsing into structures.

A Context is a scratchpad for struct parsing. It always provides an idmap, but you’re free to insert additional attributes.

Based on this, we provide some attribute definitions.

class gavo.base.parsecontext.IdAttribute(name, **kwargs)[source]

Bases: UnicodeAttribute

is an attribute that registers its parent in the context’s id map in addition to setting its id attribute.

feed(ctx, parent, literal)[source]
getCopy(parent, newParent, ctx)[source]
makeUserDoc()[source]
class gavo.base.parsecontext.OriginalAttribute(name='original', description='An id of an element to base the current one on.  This provides a simple inheritance method.  The general rules for advanced referencing in RDs apply.', forceType=None, **kwargs)[source]

Bases: AtomicAttribute

is an attribute that resolves an item copies over the managed attributes from the referenced item.

The references may be anything resolveId can cope with.

You can pass a forceType argument to make sure only references to specific types are allowable. In general, this will be the class itself of a base class. If you don’t do this, you’ll probably get weird AttributeErrors for certain inputs.

To work reliably, these attributes have to be known to the XML parser so it makes sure they are processed first. This currently works by name, and “original” is reserved for this purpose. Other names will raise an AssertionError right now.

As a safety mechanism, OriginalAttribute checks if it is replacing a “pristine” object, i.e. one that has not had events fed to it.

computed_ = True
feed(ctx, instance, literal)[source]
feedObject(instance, original, ctx=None)[source]
typeDesc_ = 'id reference'
class gavo.base.parsecontext.ParseContext(restricted=False, forRD=None)[source]

Bases: object

A scratchpad for any kind of data parsers want to pass to feed methods.

These objects are available to the feed methods as their first objects.

If restricted is True, embedded code must raise an error.

You should set an eventSource using the setter provided. This is the iterparse instance the events are coming from (or something else that has a pos attribute returning the current position).

You can register exit functions to do some “global” cleanup. Parsers should call runExitFuncs right before they return the results; this arranges for these functions to be called. The signature of an exit function is exitfunc(rootStruct, parseContext) -> whatever.

Then there’s injected info. This is used to read “dynamic” metadata for RDs from the database up front and then fill the respective data where appropriate. Use inject to fill this (for RDs, do things like that in the rscdef.rdinj module) and getInjected to get data out again.

addExitFunc(callable)[source]
getById(id, forceType=None)[source]

returns the object last registered for id.

You probably want to use resolveId; getById does no namePath or resource descriptor resolution.

getInjected(key, default=<Not given/empty>)[source]

get injected data for key.

This will raise a KeyError if no data for key has been injected (or default, if given).

For keys available here while parsing RDs, see rscdef.rdinj, look for ctx.inject.

getQualifiedId(id)[source]

returns an id including the current RD’s id, if known, otherwise id itself.

inject(key, data)[source]

sets injected data for key.

This will silently overwrite any pre-existing data.

property pos

returns a token stringifying into a position guess.

registerId(elId, value, silentOverwrite=False)[source]

enters a value in the id map.

We allow overriding in id. That should not happen while parsing an XML document because of their uniqueness requirement, but might come in handy for programmatic manipulations.

We’ll still emit an Info in that case (and may need to find a way to suppress it).

replaying()[source]

is called by active tags to indicate they’re replaying events.

The main effect right now is to suppress diagnostics for overwritten ids. But let’s see what else we might want to use it for.

The API to see if we’re replaying: replayLevel>0.

resolveId(id, instance=None, forceType=None)[source]

returns the object referred to by the complex id.

See the resolveId function.

runExitFuncs(root)[source]
setEventSource(evSource)[source]
setPositionOn(struct)[source]

calls a struct’s setPosition method to tell it where it came from.

class gavo.base.parsecontext.ReferenceAttribute(name='ref', default=<Undefined>, description='Uncodumented', forceType=None, **kwargs)[source]

Bases: AtomicAttribute

An attribute keeping a reference to some other structure

This is a bit messy since the value referred to keeps its original parent, so self.attr.parent!=self for these attributes. This is ok for many applications, but it will certainly not work for, e.g. tables (roughly, it’s always trouble when an attribute value’s implementation refers to self.parent; this is particularly true for structures having an RDAttribute).

So, before adding a reference attribute, think first whether it wouldn’t be wiser to have the real thing and rather use active tags.

create(structure, ctx, name)[source]
feed(ctx, instance, literal)[source]
typeDesc_ = 'id reference'
unparse(value)[source]

returns a typed python value for the string representation value.

value can be expected to be a unicode string.

class gavo.base.parsecontext.ReferenceListAttribute(name, **kwargs)[source]

Bases: ReferenceAttribute

A list of references.

These can come as distinct elements – <ref>a</ref><ref>b</ref> – or as a comma-joined string with ignored whitespace – ref=”a, //services#b, x.y”, or in a mixture between the two.

property default_
feed(ctx, instance, literal)[source]
feedObject(instance, value)[source]
typeDesc_ = 'list of id references (comma separated or in distinct elements)'
unparse(value)[source]

returns a typed python value for the string representation value.

value can be expected to be a unicode string.

gavo.base.parsecontext.assertType(id, ob, forceType)[source]

raises a StructureError if forceType is not None and ob is not of type forceType, returns ob otherwise.

gavo.base.parsecontext.getTableDefForTable(connection, tableName)[source]

returns a TableDef object for a SQL table name.

connection needs to be TableConnection or something with higher privileges.

This really has little to do with resolving identifiers, but this module already has getRDs and similar, so it seemed the least unnatural place.

gavo.base.parsecontext.resolveComplexId(ctx, id, forceType=None)[source]

resolves a dotted id.

See resolveId.

gavo.base.parsecontext.resolveCrossId(id, forceType=None, **kwargs)[source]

resolves id, where id is of the form rdId#id.

forceType, if non-None must be a DaCHS struct type (e.g., rscdef.Table); a StructureError will be raised if the reference resolves to something else than an instance of that type.

id can also be a simple rd id.

kwargs lets you pass additional keyword arguments to the getRD calls that may be triggered by this.

gavo.base.parsecontext.resolveId(ctx, id, instance=None, forceType=None)[source]

tries to resolve id in context.

ctx is some object having a getById method; this could be an RD or a parse context.

The rules for id are as follows:

(#) if id has a # in it, split it and take the first part to be an RD id, the second and id built according to the rest of this spec.

(#) if id has a dot in it, split at the first dot to get a pair of id and name. Iterate over the element with id, and look for something with a “name” attribute valued name. If this fails, raise a NotFoundError.

(#) if instance is not None and has a resolveName method or has a parent, and that parent has a resolveName method, pass id to it. If it does not raise a NotFoundError, return the result. This is for parents with a rscdef.NamePathAttribute.

(#) ask the ParseContext ctx’s getById method to resolve id, not catching the NotFoundError this will raise if the id is not known.

gavo.base.parsecontext.resolveNameBased(container, id, forceType=None)[source]

Tries to find a thing with name id within container.

If container defines a method getElementForName, it will be called; it must either return some element with this name or raise a NotFoundError.

If no such method exists, the function iterates over container until it finds an element with el.name==id. If no such element exists, it again raises a NotFoundError.

The function raises a NotFoundError when no such thing exists.