--- /tmp/plistlib.py 2010年04月20日 20:59:37.000000000 +0000
+++ plistlib.py 2011年02月02日 18:56:26.000000000 +0000
@@ -81,15 +81,17 @@
return rootObject
-def writePlist(rootObject, pathOrFile):
+def writePlist(rootObject, pathOrFile, ignoreNone=False):
"""Write 'rootObject' to a .plist file. 'pathOrFile' may either be a
- file name or a (writable) file object.
+ file name or a (writable) file object. If 'ignoreNone' is set then
+ the writer will delete keys from the plist file that have a value of
+ None. Without this a TypeError is raised when None is encountered.
"""
didOpen = 0
if isinstance(pathOrFile, (str, unicode)):
pathOrFile = open(pathOrFile, "w")
didOpen = 1
- writer = PlistWriter(pathOrFile)
+ writer = PlistWriter(pathOrFile, ignoreNone=ignoreNone)
writer.writeln("")
writer.writeValue(rootObject)
writer.writeln("")
@@ -103,11 +105,12 @@
return readPlist(StringIO(data))
-def writePlistToString(rootObject):
- """Return 'rootObject' as a plist-formatted string.
+def writePlistToString(rootObject, ignoreNone=False):
+ """Return 'rootObject' as a plist-formatted string. `ignoreNone` is the
+ same as writePlist.
"""
f = StringIO()
- writePlist(rootObject, f)
+ writePlist(rootObject, f, ignoreNone)
return f.getvalue()
@@ -229,9 +232,10 @@
class PlistWriter(DumbXMLWriter):
- def __init__(self, file, indentLevel=0, indent="\t", writeHeader=1):
+ def __init__(self, file, indentLevel=0, indent="\t", writeHeader=1, ignoreNone=False):
if writeHeader:
file.write(PLISTHEADER)
+ self.ignoreNone = ignoreNone
DumbXMLWriter.__init__(self, file, indentLevel, indent)
def writeValue(self, value):
@@ -277,6 +281,8 @@
for key, value in items:
if not isinstance(key, (str, unicode)):
raise TypeError("keys must be strings")
+ if self.ignoreNone and value is None:
+ continue
self.simpleElement("key", key)
self.writeValue(value)
self.endElement("dict")
--- /mnt/home/bob/Python-2.7.1/Lib/test/test_plistlib.py 2010年04月21日 06:00:35.000000000 +0000
+++ test_plistlib.py 2011年02月02日 19:04:16.000000000 +0000
@@ -163,6 +163,33 @@
pl2 = plistlib.readPlist(StringIO(f.getvalue()))
self.assertEqual(dict(pl), dict(pl2))
+ def test_writing_none(self):
+ """Tests that the ignoreNone flag is working properly.
+
+ Generates plist files using writePlistToString() and writePlist().
+ Verifies that without ignoreNone a TypeError is raised and that
+ with ignoreNone generation succeeds. Also verifies that the two
+ methods are working the same.
+ """
+ from StringIO import StringIO
+ d = {
+ 'key1': 'Something juicy',
+ 'key2': None,
+ }
+ self.assertRaises(TypeError, plistlib.writePlistToString, d)
+ str_output = plistlib.writePlistToString(d, ignoreNone=True)
+
+ f = StringIO()
+ self.assertRaises(TypeError, plistlib.writePlist, d, f)
+
+ f = StringIO()
+ plistlib.writePlist(d, f, ignoreNone=True)
+ file_output = f.getvalue()
+
+ self.assertEqual(str_output, file_output)
+
+ plistlib.readPlistFromString(str_output)
+
def test_controlcharacters(self):
for i in range(128):
c = chr(i)