@@ -68,13 +68,15 @@ def readPlist(pathOrFile):
6868 usually is a dictionary).
6969 """
7070 didOpen = False
71- if isinstance (pathOrFile , str ):
72- pathOrFile = open (pathOrFile , 'rb' )
73- didOpen = True
74- p = PlistParser ()
75- rootObject = p .parse (pathOrFile )
76- if didOpen :
77- pathOrFile .close ()
71+ try :
72+ if isinstance (pathOrFile , str ):
73+ pathOrFile = open (pathOrFile , 'rb' )
74+ didOpen = True
75+ p = PlistParser ()
76+ rootObject = p .parse (pathOrFile )
77+ finally :
78+ if didOpen :
79+ pathOrFile .close ()
7880 return rootObject
7981
8082
@@ -83,15 +85,17 @@ def writePlist(rootObject, pathOrFile):
8385 file name or a (writable) file object.
8486 """
8587 didOpen = False
86- if isinstance (pathOrFile , str ):
87- pathOrFile = open (pathOrFile , 'wb' )
88- didOpen = True
89- writer = PlistWriter (pathOrFile )
90- writer .writeln ("<plist version=\" 1.0\" >" )
91- writer .writeValue (rootObject )
92- writer .writeln ("</plist>" )
93- if didOpen :
94- pathOrFile .close ()
88+ try :
89+ if isinstance (pathOrFile , str ):
90+ pathOrFile = open (pathOrFile , 'wb' )
91+ didOpen = True
92+ writer = PlistWriter (pathOrFile )
93+ writer .writeln ("<plist version=\" 1.0\" >" )
94+ writer .writeValue (rootObject )
95+ writer .writeln ("</plist>" )
96+ finally :
97+ if didOpen :
98+ pathOrFile .close ()
9599
96100
97101def readPlistFromBytes (data ):
@@ -352,7 +356,6 @@ def __eq__(self, other):
352356 def __repr__ (self ):
353357 return "%s(%s)" % (self .__class__ .__name__ , repr (self .data ))
354358
355-
356359class PlistParser :
357360
358361 def __init__ (self ):
@@ -362,11 +365,11 @@ def __init__(self):
362365
363366 def parse (self , fileobj ):
364367 from xml .parsers .expat import ParserCreate
365- parser = ParserCreate ()
366- parser .StartElementHandler = self .handleBeginElement
367- parser .EndElementHandler = self .handleEndElement
368- parser .CharacterDataHandler = self .handleData
369- parser .ParseFile (fileobj )
368+ self . parser = ParserCreate ()
369+ self . parser .StartElementHandler = self .handleBeginElement
370+ self . parser .EndElementHandler = self .handleEndElement
371+ self . parser .CharacterDataHandler = self .handleData
372+ self . parser .ParseFile (fileobj )
370373 return self .root
371374
372375 def handleBeginElement (self , element , attrs ):
@@ -385,12 +388,18 @@ def handleData(self, data):
385388
386389 def addObject (self , value ):
387390 if self .currentKey is not None :
391+ if not isinstance (self .stack [- 1 ], type ({})):
392+ raise ValueError ("unexpected element at line %d" %
393+ self .parser .CurrentLineNumber )
388394 self .stack [- 1 ][self .currentKey ] = value
389395 self .currentKey = None
390396 elif not self .stack :
391397 # this is the root object
392398 self .root = value
393399 else :
400+ if not isinstance (self .stack [- 1 ], type ([])):
401+ raise ValueError ("unexpected element at line %d" %
402+ self .parser .CurrentLineNumber )
394403 self .stack [- 1 ].append (value )
395404
396405 def getData (self ):
@@ -405,9 +414,15 @@ def begin_dict(self, attrs):
405414 self .addObject (d )
406415 self .stack .append (d )
407416 def end_dict (self ):
417+ if self .currentKey :
418+ raise ValueError ("missing value for key '%s' at line %d" %
419+ (self .currentKey ,self .parser .CurrentLineNumber ))
408420 self .stack .pop ()
409421
410422 def end_key (self ):
423+ if self .currentKey or not isinstance (self .stack [- 1 ], type ({})):
424+ raise ValueError ("unexpected key at line %d" %
425+ self .parser .CurrentLineNumber )
411426 self .currentKey = self .getData ()
412427
413428 def begin_array (self , attrs ):
0 commit comments