11from __future__ import absolute_import , division , unicode_literals
2- from six import text_type
2+ from six import text_type , string_types
33
44import gettext
55_ = gettext .gettext
88spaceCharacters = "" .join (spaceCharacters )
99
1010
11+ def to_text (s , blank_if_none = True ):
12+ """Wrapper around six.text_type to convert None to empty string"""
13+ if s is None :
14+ if blank_if_none :
15+ return ""
16+ else :
17+ return None
18+ elif isinstance (s , text_type ):
19+ return s
20+ else :
21+ return text_type (s )
22+
23+
24+ def is_text_or_none (string ):
25+ """Wrapper around isinstance(string_types) or is None"""
26+ return string is None or isinstance (string , string_types )
27+
28+
1129class TreeWalker (object ):
1230 def __init__ (self , tree ):
1331 self .tree = tree
@@ -19,45 +37,47 @@ def error(self, msg):
1937 return {"type" : "SerializeError" , "data" : msg }
2038
2139 def emptyTag (self , namespace , name , attrs , hasChildren = False ):
22- assert namespace is None or isinstance (namespace , text_type ), type (namespace )
23- assert isinstance (name , text_type ), type (name )
24- assert all ((namespace is None or isinstance (namespace , text_type )) and
25- isinstance (name , text_type ) and
26- isinstance (value , text_type )
40+ assert namespace is None or isinstance (namespace , string_types ), type (namespace )
41+ assert isinstance (name , string_types ), type (name )
42+ assert all ((namespace is None or isinstance (namespace , string_types )) and
43+ isinstance (name , string_types ) and
44+ isinstance (value , string_types )
2745 for (namespace , name ), value in attrs .items ())
2846
29- yield {"type" : "EmptyTag" , "name" : name ,
30- "namespace" : namespace ,
47+ yield {"type" : "EmptyTag" , "name" : to_text ( name , False ) ,
48+ "namespace" : to_text ( namespace ) ,
3149 "data" : attrs }
3250 if hasChildren :
3351 yield self .error (_ ("Void element has children" ))
3452
3553 def startTag (self , namespace , name , attrs ):
36- assert namespace is None or isinstance (namespace , text_type ), type (namespace )
37- assert isinstance (name , text_type ), type (name )
38- assert all ((namespace is None or isinstance (namespace , text_type )) and
39- isinstance (name , text_type ) and
40- isinstance (value , text_type )
54+ assert namespace is None or isinstance (namespace , string_types ), type (namespace )
55+ assert isinstance (name , string_types ), type (name )
56+ assert all ((namespace is None or isinstance (namespace , string_types )) and
57+ isinstance (name , string_types ) and
58+ isinstance (value , string_types )
4159 for (namespace , name ), value in attrs .items ())
4260
4361 return {"type" : "StartTag" ,
44- "name" : name ,
45- "namespace" : namespace ,
46- "data" : attrs }
62+ "name" : text_type (name ),
63+ "namespace" : to_text (namespace ),
64+ "data" : dict (((to_text (namespace , False ), to_text (name )),
65+ to_text (value , False ))
66+ for (namespace , name ), value in attrs .items ())}
4767
4868 def endTag (self , namespace , name ):
49- assert namespace is None or isinstance (namespace , text_type ), type (namespace )
50- assert isinstance (name , text_type ), type (namespace )
69+ assert namespace is None or isinstance (namespace , string_types ), type (namespace )
70+ assert isinstance (name , string_types ), type (namespace )
5171
5272 return {"type" : "EndTag" ,
53- "name" : name ,
54- "namespace" : namespace ,
73+ "name" : to_text ( name , False ) ,
74+ "namespace" : to_text ( namespace ) ,
5575 "data" : {}}
5676
5777 def text (self , data ):
58- assert isinstance (data , text_type ), type (data )
78+ assert isinstance (data , string_types ), type (data )
5979
60- data = data
80+ data = to_text ( data )
6181 middle = data .lstrip (spaceCharacters )
6282 left = data [:len (data ) - len (middle )]
6383 if left :
@@ -71,25 +91,25 @@ def text(self, data):
7191 yield {"type" : "SpaceCharacters" , "data" : right }
7292
7393 def comment (self , data ):
74- assert isinstance (data , text_type ), type (data )
94+ assert isinstance (data , string_types ), type (data )
7595
76- return {"type" : "Comment" , "data" : data }
96+ return {"type" : "Comment" , "data" : text_type ( data ) }
7797
7898 def doctype (self , name , publicId = None , systemId = None , correct = True ):
79- assert name is None or isinstance (name , text_type ), type (name )
80- assert publicId is None or isinstance (publicId , text_type ), type (publicId )
81- assert systemId is None or isinstance (systemId , text_type ), type (systemId )
99+ assert is_text_or_none (name ), type (name )
100+ assert is_text_or_none (publicId ), type (publicId )
101+ assert is_text_or_none (systemId ), type (systemId )
82102
83103 return {"type" : "Doctype" ,
84- "name" : name if name is not None else "" ,
85- "publicId" : publicId ,
86- "systemId" : systemId ,
87- "correct" : correct }
104+ "name" : to_text ( name ) ,
105+ "publicId" : to_text ( publicId ) ,
106+ "systemId" : to_text ( systemId ) ,
107+ "correct" : to_text ( correct ) }
88108
89109 def entity (self , name ):
90- assert isinstance (name , text_type ), type (name )
110+ assert isinstance (name , string_types ), type (name )
91111
92- return {"type" : "Entity" , "name" : name }
112+ return {"type" : "Entity" , "name" : text_type ( name ) }
93113
94114 def unknown (self , nodeType ):
95115 return self .error (_ ("Unknown node type: " ) + nodeType )
0 commit comments