* find a better way to do the decoding.

* break it all in the process
* misc. cleanups
This commit is contained in:
Eray Özkural
2005-09-22 15:10:06 +00:00
parent 2058459ec8
commit 43fc66d6a4
4 changed files with 78 additions and 51 deletions
+1 -2
View File
@@ -22,7 +22,6 @@
files are specification files for PISI source packages. This module files are specification files for PISI source packages. This module
provides read and write access to PSPEC files.""" provides read and write access to PSPEC files."""
# standard python modules # standard python modules
from os.path import basename from os.path import basename
@@ -33,7 +32,6 @@ from pisi.xmlfile import XmlFile
from pisi.dependency import DepInfo from pisi.dependency import DepInfo
from pisi.util import Checks from pisi.util import Checks
#class Packager: #class Packager:
# __metaclass__ = xmlfile.autoxml # __metaclass__ = xmlfile.autoxml
@@ -285,6 +283,7 @@ class SourceInfo:
return err.list return err.list
class PackageInfo: class PackageInfo:
"""A structure to hold package information. Package information is """A structure to hold package information. Package information is
located under <Package> tag in PSPEC file. Opposite to Source each located under <Package> tag in PSPEC file. Opposite to Source each
+74 -43
View File
@@ -208,14 +208,16 @@ class autoxml(type):
cls.decoders = decoders cls.decoders = decoders
def decode(self, node): def decode(self, node):
for decoder in self.__class__.decoders: for decode_member in self.__class__.decoders:
decoder(self, node) decode_member(self, node)
cls.decode = decode cls.decode = decode
cls.encoders = encoders cls.encoders = encoders
def encode(self, xml): def encode(self, xml):
for encoder in self.__class__.encoders: node = xml.newNode(cls.tag)
encoder(self, xml) for encode_member in self.__class__.encoders:
encode_member(self, xml, node)
return node
cls.encode = encode cls.encode = encode
cls.formatters = formatters cls.formatters = formatters
@@ -236,22 +238,33 @@ class autoxml(type):
assert type(tag_type) == type(type) assert type(tag_type) == type(type)
def readtext(node, attr): def readtext(node, attr):
return getNodeAttribute(node, attr) return getNodeAttribute(node, attr)
def writetext(xml, node, attr, value): def createnode(xml, attr):
node.setAttribute(attr, value) return xml.newAttribute(attr)
anonfuns = cls.gen_anon_basic(attr, spec, readtext, writetext) def writetext(node, attr, text):
return cls.gen_named_comp(attr, spec, anonfuns) attr.value = text
node.setAttributeNode(attr)
anonfuns = cls.gen_anon_basic(attr, spec, readtext, createnode, writetext)
def mergetext(node, attr):
pass
return cls.gen_named_comp(attr, spec, anonfuns, mergetext)
def gen_tag_member(cls, tag): def gen_tag_member(cls, tag):
"""generate helper funs for tag member of class""" """generate helper funs for tag member of class"""
spec = getattr(cls, 't_' + tag) spec = getattr(cls, 't_' + tag)
def readtext(node, tag): def readtext(node, tagpath):
return getNodeText(getNode(node, tag)) return getNodeText(getNode(node, tagpath))
def writetext(xml, node, tag, value): def createnode(xml, tag):
xml.addTextNodeUnder(node, tag, value) return xml.newNode(tag)
anonfuns = cls.gen_tag(tag, spec, readtext, writetext) def writetext(node, text):
return cls.gen_named_comp(tag, spec, anonfuns) node.addText(node, text)
anonfuns = cls.gen_tag(tag, spec, createnode, readtext, writetext)
def mergetext(xml, node, tagpath):
pass
head, tail = cls.tagpath_head_last(tagpath)
subnode = xml.newNode(tail)
return cls.gen_named_comp(tag, spec, anonfuns, mergetext)
def gen_named_comp(cls, token, spec, anonfuns): def gen_named_comp(cls, token, spec, anonfuns, createnode):
"""generate a named component tag/attr. a decoration of """generate a named component tag/attr. a decoration of
anonymous functions that do not bind to variable names""" anonymous functions that do not bind to variable names"""
name = cls.mixed_case(token) name = cls.mixed_case(token)
@@ -260,17 +273,20 @@ class autoxml(type):
(init_a, decode_a, encode_a, format_a) = anonfuns (init_a, decode_a, encode_a, format_a) = anonfuns
def init(self): def init(self):
"""initialize component"""
setattr(self, name, init_a()) setattr(self, name, init_a())
def decode(self, node): def decode(self, node):
"""decode component from DOM node"""
setattr(self, name, decode_a(node)) setattr(self, name, decode_a(node))
def encode(self, xml): def encode(self, xml, node):
"""encode self inside, possibly new, DOM node using xml"""
if hasattr(self, name): if hasattr(self, name):
value = getattr(self, name) value = getattr(self, name)
else: else:
value = None value = None
encode_a(xml, value) return encode_a(xml, self.dom.documentElement, value)
def format(self): def format(self):
if hasattr(self, name): if hasattr(self, name):
@@ -283,11 +299,11 @@ class autoxml(type):
return (init, decode, encode, format) return (init, decode, encode, format)
def gen_tag(cls, tag, spec, readtext, writetext): def gen_tag(cls, tag, spec, readtext, createnode, writetext):
"""generate readers and writers for the tag""" """generate readers and writers for the tag"""
tag_type = spec[0] tag_type = spec[0]
if type(tag_type) is types.TypeType: if type(tag_type) is types.TypeType:
return cls.gen_anon_basic(tag, spec, readtext, writetext) return cls.gen_anon_basic(tag, spec, readtext, createnode, writetext)
elif type(tag_type) is types.ListType: elif type(tag_type) is types.ListType:
return cls.gen_list_tag(tag, spec) return cls.gen_list_tag(tag, spec)
elif type(tag_type) is autoxml or type(tag_type) is types.ClassType: elif type(tag_type) is autoxml or type(tag_type) is types.ClassType:
@@ -298,9 +314,16 @@ class autoxml(type):
identifier_p = identifier[0].lower() + identifier[1:] identifier_p = identifier[0].lower() + identifier[1:]
return identifier_p return identifier_p
def tagpath_head_last(cls, tag_path):
"returns split of the tag path into last tag and the rest"
try:
lastsep = tagpath.rindex('/')
except ValueError, e:
return ('', tag_path)
return (tag_path[:laststep], tag_path[laststep+1:])
def parse_spec(cls, token, spec): def parse_spec(cls, token, spec):
"""decompose member specification""" """decompose member specification"""
name = cls.mixed_case(token) name = cls.mixed_case(token)
token_type = spec[0] token_type = spec[0]
req = spec[1] req = spec[1]
@@ -312,14 +335,14 @@ class autoxml(type):
# the token # the token
return name, token_type, req, path return name, token_type, req, path
def gen_anon_basic(cls, token, spec, readtext, writetext): def gen_anon_basic(cls, token, spec, readtext, createnode, writetext):
"""Generate a tag or attribute with one of the basic """Generate a tag or attribute with one of the basic
types like integer. This has got to be pretty generic types like integer. This has got to be pretty generic
so we can invoke it from the complex types such as Class so that we can invoke it from the complex types such as Class
and List. The readtext and writetext arguments achieve and List. The readtext and writetext arguments achieve
the text input I/O for this datatype.""" the DOM text access for this datatype."""
name, token_type, req, path = cls.parse_spec(token, spec) name, token_type, req, tagpath = cls.parse_spec(token, spec)
def initialize(): def initialize():
"""default value for all basic types is None""" """default value for all basic types is None"""
@@ -327,7 +350,7 @@ class autoxml(type):
def decode(node): def decode(node):
"""decode from DOM node, the value, watching the spec""" """decode from DOM node, the value, watching the spec"""
text = readtext(node, token) text = readtext(node, tagpath)
print 'read text ', text print 'read text ', text
if text: if text:
try: try:
@@ -341,16 +364,19 @@ class autoxml(type):
else: else:
return None return None
def encode(xml, value): def encode(xml, node, value):
"""encode given value into xml file""" """encode given value inside DOM node"""
node = xml.newNode(cls.tag)
if value: if value:
writetext(xml, node, token, str(value)) path = cls.tagpath_head_last(tagpath)
node = createnode(xml, token)
writetext(node, str(value))
return node
else: else:
if req == mandatory: if req == mandatory:
raise Error('Mandatory argument not available') raise Error('Mandatory argument not available')
def format(value): def format(value):
"""format value for pretty printing"""
return str(value) return str(value)
return initialize, decode, encode, format return initialize, decode, encode, format
@@ -383,7 +409,7 @@ class autoxml(type):
def encode(xml, obj): def encode(xml, obj):
if obj: if obj:
try: try:
obj.encode(xml) return obj.encode(xml)
except Error: except Error:
raise Error('Object cannot be encoded') raise Error('Object cannot be encoded')
else: else:
@@ -401,12 +427,14 @@ class autoxml(type):
if len(tag_type) != 1: if len(tag_type) != 1:
raise Error('List type must contain only one element') raise Error('List type must contain only one element')
def readtext_item(node, tag): def readtext(node, tagpath):
return getNodeText(node) return getNodeText(getNode(node, tagpath))
def writetext_item(xml, node, tag, value): def createnode(xml, tag):
xml.addTextNode(node, value) return xml.newNode(tag)
def writetext(node, text):
node.addText(node, text)
x = cls.gen_tag(tag, [tag_type[0], mandatory], x = cls.gen_tag(tag, [tag_type[0], mandatory],
readtext_item, writetext_item) readtext, createnode, writetext)
(init_item, decode_item, encode_item, format_item) = x (init_item, decode_item, encode_item, format_item) = x
def init(): def init():
@@ -422,11 +450,13 @@ class autoxml(type):
l.append(decode_item(node)) l.append(decode_item(node))
return l return l
def encode(xml, l): def encode(xml, node, l):
if len(l) > 0: if len(l) > 0:
for elt in l: for item in l:
node = xml.newNode(path) item_node = xml.newNode(path)
encode_item(xml, node) encode_item(xml, item, item_node)
xml.addTextNodeUnder(item_node)
return node
else: else:
if req is mandatory: if req is mandatory:
raise Error('Mandatory list empty') raise Error('Mandatory list empty')
@@ -488,7 +518,7 @@ class XmlFile(object):
def newTextNode(self, text): def newTextNode(self, text):
return self.dom.createTextNode(text) return self.dom.createTextNode(text)
def newAttribute(self, name): def newAttribute(self, attr):
return self.dom.createAttribute(name) return self.dom.createAttribute(name)
# read helpers # read helpers
@@ -535,17 +565,18 @@ class XmlFile(object):
# write helpers # write helpers
def addNode(self, tagPath, newnode = None): def addNode(self, tagPath, newnode = None):
"this adds the newnode under given tag path"
self.verifyRootTag() self.verifyRootTag()
return addNode(self.dom, self.dom.documentElement, tagPath, return addNode(self.dom, self.dom.documentElement, tagPath,
newnode) newnode)
def addNodeUnder(self, node, tagPath, newnode = None): def addNodeUnder(self, node, tagPath, newnode = None):
"this adds the new stuff under node" "this adds the new stuff under node and then following tag path"
self.verifyRootTag() self.verifyRootTag()
return addNode(self.dom, node, tagPath, newnode) return addNode(self.dom, node, tagPath, newnode)
def addChild(self, newnode): def addChild(self, newnode):
"""add a new child node right under root element document""" "add a new child node right under root element document"
self.dom.documentElement.appendChild(newnode) self.dom.documentElement.appendChild(newnode)
def addText(self, node, text): def addText(self, node, text):
@@ -553,7 +584,7 @@ class XmlFile(object):
node.appendChild(self.newTextNode(text)) node.appendChild(self.newTextNode(text))
def addTextNode(self, tagPath, text): def addTextNode(self, tagPath, text):
"add a text node with tag path" "add a text node with given tag path"
node = self.addNode(tagPath, self.newTextNode(text)) node = self.addNode(tagPath, self.newTextNode(text))
return node return node
-4
View File
@@ -17,9 +17,6 @@ import os
sys.path.append('.') sys.path.append('.')
sys.path.append('..') sys.path.append('..')
import pisi
import pisi.api
runTestSuite = lambda(x): unittest.TextTestRunner(verbosity=2).run(x) runTestSuite = lambda(x): unittest.TextTestRunner(verbosity=2).run(x)
def run_all(): def run_all():
@@ -62,7 +59,6 @@ def run_all():
runTestSuite(alltests) runTestSuite(alltests)
if __name__ == "__main__": if __name__ == "__main__":
pisi.api.init(False)
args = sys.argv args = sys.argv
if len(args) > 1: # run modules given from the command line if len(args) > 1: # run modules given from the command line
tests = sys.argv[1:] tests = sys.argv[1:]
+3 -2
View File
@@ -22,6 +22,7 @@ import pisi.util as util
from pisi.xmlext import * from pisi.xmlext import *
class XmlFileTestCase(unittest.TestCase): class XmlFileTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
pisi.api.init(False) pisi.api.init(False)
@@ -55,7 +56,7 @@ class XmlFileTestCase(unittest.TestCase):
print '*', string print '*', string
#self.assert_(string.startswith('Name')) #self.assert_(string.startswith('Name'))
xml = xmlfile.XmlFile('A') xml = xmlfile.XmlFile('A')
elta = a.encode(xml) a.encode(xml)
xml.writexml('/tmp/a.xml') xml.writexml('/tmp/a.xml')
xml = xmlfile.XmlFile('A') xml = xmlfile.XmlFile('A')
a2 = A() a2 = A()
@@ -63,7 +64,7 @@ class XmlFileTestCase(unittest.TestCase):
a2.email = "baris@uludag.org.tr" a2.email = "baris@uludag.org.tr"
a2.href = 'http://cekirdek.uludag.org.tr/~baris' a2.href = 'http://cekirdek.uludag.org.tr/~baris'
a2.projects = [ 'pisi', 'tasma', 'plasma' ] a2.projects = [ 'pisi', 'tasma', 'plasma' ]
elta2 = a2.encode(xml) a2.encode(xml)
xml.writexml('/tmp/a2.xml') xml.writexml('/tmp/a2.xml')
string = a2.format() string = a2.format()