* support "string" attributes, starting with s_,
test it in xmlfiletests * fix: handle unicode in output formatting
This commit is contained in:
+1
-1
@@ -97,7 +97,7 @@ class Path:
|
||||
return s
|
||||
|
||||
class Dependency:
|
||||
t_Package = [xmlfile.String, xmlfile.mandatory]
|
||||
s_Package = [xmlfile.String, xmlfile.mandatory]
|
||||
a_versionFrom = [xmlfile.String, xmlfile.optional]
|
||||
a_versionTo = [xmlfile.String, xmlfile.optional]
|
||||
a_releaseFrom = [xmlfile.String, xmlfile.optional]
|
||||
|
||||
+43
-10
@@ -37,6 +37,8 @@ from xml.parsers.expat import ExpatError
|
||||
import locale
|
||||
import codecs
|
||||
import types
|
||||
import formatter
|
||||
import sys
|
||||
|
||||
import gettext
|
||||
__trans = gettext.translation('pisi', fallback=True)
|
||||
@@ -94,7 +96,7 @@ class LocalText(object):
|
||||
if not lang:
|
||||
lang = 'en'
|
||||
self.locs[lang] = c
|
||||
|
||||
|
||||
def encode(self, xml, node, errs):
|
||||
for key in self.locs.iterkeys():
|
||||
newnode = newNode(node, self.tag)
|
||||
@@ -123,6 +125,23 @@ class LocalText(object):
|
||||
else:
|
||||
errs.append(_("Tag should have at least an English or Turkish version"))
|
||||
|
||||
class Writer(formatter.DumbWriter):
|
||||
"""adds unicode support"""
|
||||
|
||||
def __init__(self, file=None, maxcol=78):
|
||||
formatter.DumbWriter.__init__(self, file, maxcol)
|
||||
|
||||
def send_literal_data(self, data):
|
||||
self.file.write(data.encode("utf-8"))
|
||||
i = data.rfind('\n')
|
||||
if i >= 0:
|
||||
self.col = 0
|
||||
data = data[i+1:]
|
||||
data = data.expandtabs()
|
||||
self.col = self.col + len(data)
|
||||
self.atbreak = 0
|
||||
|
||||
|
||||
class autoxml(oo.autosuper):
|
||||
"""High-level automatic XML transformation interface for xmlfile.
|
||||
The idea is to declare a class for each XML tag. Inside the
|
||||
@@ -218,18 +237,20 @@ class autoxml(oo.autosuper):
|
||||
order = dict.keys()
|
||||
order.sort()
|
||||
for var in order:
|
||||
if var.startswith('t_') or var.startswith('a_'):
|
||||
if var.startswith('t_') or var.startswith('a_') or var.startswith('s_'):
|
||||
name = var[2:]
|
||||
if var.startswith('a_'):
|
||||
x = autoxml.gen_attr_member(cls, name)
|
||||
elif var.startswith('t_'):
|
||||
x = autoxml.gen_tag_member(cls, name)
|
||||
(init, decoder, encoder, checker, formatter) = x
|
||||
elif var.startswith('s_'):
|
||||
x = autoxml.gen_str_member(cls, name)
|
||||
(init, decoder, encoder, checker, format_x) = x
|
||||
inits.append(init)
|
||||
decoders.append(decoder)
|
||||
encoders.append(encoder)
|
||||
checkers.append(checker)
|
||||
formatters.append(formatter)
|
||||
formatters.append(format_x)
|
||||
|
||||
# generate top-level helper functions
|
||||
cls.initializers = inits
|
||||
@@ -275,8 +296,7 @@ class autoxml(oo.autosuper):
|
||||
formatter(self, f, errs)
|
||||
cls.format = format
|
||||
def print_text(self):
|
||||
import formatter
|
||||
w = formatter.DumbWriter() # plain text
|
||||
w = Writer() # plain text
|
||||
f = formatter.AbstractFormatter(w)
|
||||
errs = []
|
||||
self.format(f, errs)
|
||||
@@ -307,7 +327,7 @@ class autoxml(oo.autosuper):
|
||||
spec = getattr(cls, 't_' + tag)
|
||||
anonfuns = cls.gen_tag(tag, spec)
|
||||
return cls.gen_named_comp(tag, spec, anonfuns)
|
||||
|
||||
|
||||
def gen_tag(cls, tag, spec):
|
||||
"""generate readers and writers for the tag"""
|
||||
tag_type = spec[0]
|
||||
@@ -330,6 +350,19 @@ class autoxml(oo.autosuper):
|
||||
raise Error(_('gen_tag: unrecognized tag type %s in spec') %
|
||||
str(tag_type))
|
||||
|
||||
def gen_str_member(cls, token):
|
||||
"""generate readers and writers for a string member"""
|
||||
spec = getattr(cls, 's_' + token)
|
||||
tag_type = spec[0]
|
||||
assert type(tag_type) == type(type)
|
||||
def readtext(node, blah):
|
||||
node.normalize()
|
||||
return getNodeText(node)
|
||||
def writetext(xml, node, blah, text):
|
||||
addText(node, "", text)
|
||||
anonfuns = cls.gen_anon_basic(token, spec, readtext, writetext)
|
||||
return cls.gen_named_comp(token, spec, anonfuns)
|
||||
|
||||
def gen_named_comp(cls, token, spec, anonfuns):
|
||||
"""generate a named component tag/attr. a decoration of
|
||||
anonymous functions that do not bind to variable names"""
|
||||
@@ -430,14 +463,14 @@ class autoxml(oo.autosuper):
|
||||
return value
|
||||
else:
|
||||
if req == mandatory:
|
||||
errs.append(_('Mandatory token %s not available') % token)
|
||||
errs.append(where + _('Mandatory token %s not available') % token)
|
||||
return None
|
||||
|
||||
def encode(xml, node, value, errs):
|
||||
"""encode given value inside DOM node"""
|
||||
if value:
|
||||
#FIXME: unicode() here?
|
||||
writetext(xml, node, token, str(value))
|
||||
writetext(xml, node, token, unicode(value))
|
||||
else:
|
||||
if req == mandatory:
|
||||
errs.append(_('Mandatory argument not available'))
|
||||
@@ -528,7 +561,7 @@ class autoxml(oo.autosuper):
|
||||
l = []
|
||||
nodes = getAllNodes(node, path)
|
||||
#print node, tag + '/' + comp_tag, nodes
|
||||
if len(nodes) is 0 and req is mandatory:
|
||||
if len(nodes)==0 and req==mandatory:
|
||||
errs.append(where + _('Mandatory list empty'))
|
||||
for ix in range(len(nodes)):
|
||||
node = nodes[ix]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
|
||||
<A href="http://www.cs.bilkent.edu.tr/~erayo">
|
||||
cıvık mantardır bu
|
||||
<Name>Eray Ozkural</Name>
|
||||
<Number>868</Number>
|
||||
<Description>Lazy Tin</Description>
|
||||
|
||||
@@ -24,7 +24,7 @@ class SpecFileNewTestCase(testcase.TestCase):
|
||||
self.spec = specfile.SpecFile()
|
||||
self.spec.read("tests/popt/pspec.xml")
|
||||
|
||||
def testReadSpec(self):
|
||||
def testFields(self):
|
||||
self.assertEqual(self.spec.source.name, "popt")
|
||||
|
||||
self.assertEqual(self.spec.source.version, "1.7")
|
||||
@@ -32,7 +32,7 @@ class SpecFileNewTestCase(testcase.TestCase):
|
||||
self.assertEqual(self.spec.source.release, "3")
|
||||
|
||||
self.assertEqual(self.spec.source.archiveSHA1,
|
||||
"66f3c77b87a160951b180447f4a6dce68ad2f71b")
|
||||
"66f3c77b87a160951b180447f4a6dce68ad2f71b")
|
||||
|
||||
patches = self.spec.source.patches
|
||||
self.assertEqual(len(patches), 1)
|
||||
@@ -72,7 +72,7 @@ class SpecFileNewTestCase(testcase.TestCase):
|
||||
self.fail("Failed to match PartOf in Package")
|
||||
|
||||
def testVerify(self):
|
||||
if self.spec.has_errors():
|
||||
if self.spec.check() != []:
|
||||
self.fail("Failed to verify specfile")
|
||||
|
||||
def testCopy(self):
|
||||
|
||||
@@ -43,11 +43,12 @@ class AutoXmlTestCase(testcase.TestCase):
|
||||
a_href = [types.StringType, xmlfile.mandatory]
|
||||
t_Projects = [ [types.StringType], xmlfile.mandatory, 'Project']
|
||||
t_OtherInfo = [ OtherInfo, xmlfile.optional ]
|
||||
s_Comment = [ xmlfile.Text, xmlfile.mandatory]
|
||||
|
||||
self.A = A
|
||||
|
||||
def testDeclaration(self):
|
||||
self.assertEqual(len(self.A.decoders), 7) # we have seven fields
|
||||
self.assertEqual(len(self.A.decoders), 8) # how many fields in A?
|
||||
self.assert_(hasattr(self.A, 'encode'))
|
||||
|
||||
def testReadWrite(self):
|
||||
|
||||
Reference in New Issue
Block a user