diff options
Diffstat (limited to 'python/qpid/spec.py')
| -rw-r--r-- | python/qpid/spec.py | 88 |
1 files changed, 51 insertions, 37 deletions
diff --git a/python/qpid/spec.py b/python/qpid/spec.py index 3e8b9e37bd..ffd7b5a454 100644 --- a/python/qpid/spec.py +++ b/python/qpid/spec.py @@ -79,11 +79,12 @@ class Spec(Metadata): PRINT=["major", "minor", "file"] - def __init__(self, major, minor, file): + def __init__(self, major, minor, file, errata): Metadata.__init__(self) self.major = major self.minor = minor self.file = file + self.errata = errata self.constants = SpecContainer() self.classes = SpecContainer() # methods indexed by classname_methname @@ -267,43 +268,56 @@ def load_fields(nd, l, domains): type = domains[type] l.add(Field(pythonize(f_nd["@name"]), f_nd.index(), type, get_docs(f_nd))) -def load(specfile): +def load(specfile, *errata): doc = xmlutil.parse(specfile) - root = doc["amqp"][0] - spec = Spec(int(root["@major"]), int(root["@minor"]), specfile) - - # constants - for nd in root["constant"]: - const = Constant(spec, pythonize(nd["@name"]), int(nd["@value"]), - nd.get("@class"), get_docs(nd)) - spec.constants.add(const) - - # domains are typedefs - domains = {} - for nd in root["domain"]: - domains[nd["@name"]] = nd["@type"] - - # classes - for c_nd in root["class"]: - klass = Class(spec, pythonize(c_nd["@name"]), int(c_nd["@index"]), - c_nd["@handler"], get_docs(c_nd)) - load_fields(c_nd, klass.fields, domains) - for m_nd in c_nd["method"]: - meth = Method(klass, pythonize(m_nd["@name"]), - int(m_nd["@index"]), - m_nd.get_bool("@content", False), - [pythonize(nd["@name"]) for nd in m_nd["response"]], - m_nd.get_bool("@synchronous", False), - m_nd.text, - get_docs(m_nd)) - load_fields(m_nd, meth.fields, domains) - klass.methods.add(meth) - # resolve the responses - for m in klass.methods: - m.responses = [klass.methods.byname[r] for r in m.responses] - for resp in m.responses: - resp.response = True - spec.classes.add(klass) + spec_root = doc["amqp"][0] + spec = Spec(int(spec_root["@major"]), int(spec_root["@minor"]), specfile, errata) + + for root in [spec_root] + map(lambda x: xmlutil.parse(x)["amqp"][0], errata): + # constants + for nd in root["constant"]: + const = Constant(spec, pythonize(nd["@name"]), int(nd["@value"]), + nd.get("@class"), get_docs(nd)) + spec.constants.add(const) + + # domains are typedefs + domains = {} + for nd in root["domain"]: + domains[nd["@name"]] = nd["@type"] + + # classes + for c_nd in root["class"]: + cname = pythonize(c_nd["@name"]) + if root == spec_root: + klass = Class(spec, cname, int(c_nd["@index"]), c_nd["@handler"], + get_docs(c_nd)) + spec.classes.add(klass) + else: + klass = spec.classes.byname[cname] + + added_methods = [] + load_fields(c_nd, klass.fields, domains) + for m_nd in c_nd["method"]: + mname = pythonize(m_nd["@name"]) + if root == spec_root: + meth = Method(klass, mname, + int(m_nd["@index"]), + m_nd.get_bool("@content", False), + [pythonize(nd["@name"]) for nd in m_nd["response"]], + m_nd.get_bool("@synchronous", False), + m_nd.text, + get_docs(m_nd)) + klass.methods.add(meth) + added_methods.append(meth) + else: + meth = klass.methods.byname[mname] + load_fields(m_nd, meth.fields, domains) + # resolve the responses + for m in added_methods: + m.responses = [klass.methods.byname[r] for r in m.responses] + for resp in m.responses: + resp.response = True + spec.post_load() return spec |
