131131except NameError :
132132 unichr = chr
133133
134+
134135class CustomHTMLParser (HTMLParser ):
135136 """simplified HTML parser.
136137
@@ -169,21 +170,25 @@ def close(self):
169170 HTMLParser .close (self )
170171 return self .__builder .close ()
171172
173+
172174Command = namedtuple ('Command' , 'negated cmd args lineno context' )
173175
176+
174177class FailedCheck (Exception ):
175178 pass
176179
180+
177181class InvalidCheck (Exception ):
178182 pass
179183
184+
180185def concat_multi_lines (f ):
181186 """returns a generator out of the file object, which
182187 - removes `\\ ` then `\n ` then a shared prefix with the previous line then
183188 optional whitespace;
184189 - keeps a line number (starting from 0) of the first line being
185190 concatenated."""
186- lastline = None # set to the last line when the last line has a backslash
191+ lastline = None # set to the last line when the last line has a backslash
187192 firstlineno = None
188193 catenated = ''
189194 for lineno , line in enumerate (f ):
@@ -208,6 +213,7 @@ def concat_multi_lines(f):
208213 if lastline is not None :
209214 print_err (lineno , line , 'Trailing backslash at the end of the file' )
210215
216+
211217LINE_PATTERN = re .compile (r'''
212218 (?<=(?<!\S)@)(?P<negated>!?)
213219 (?P<cmd>[A-Za-z]+(?:-[A-Za-z]+)*)
@@ -252,7 +258,7 @@ def flatten(node):
252258
253259def normalize_xpath (path ):
254260 if path .startswith ('//' ):
255- return '.' + path # avoid warnings
261+ return '.' + path # avoid warnings
256262 elif path .startswith ('.//' ):
257263 return path
258264 else :
@@ -316,7 +322,7 @@ def get_dir(self, path):
316322
317323def check_string (data , pat , regexp ):
318324 if not pat :
319- return True # special case a presence testing
325+ return True # special case a presence testing
320326 elif regexp :
321327 return re .search (pat , data , flags = re .UNICODE ) is not None
322328 else :
@@ -353,7 +359,7 @@ def check_tree_text(tree, path, pat, regexp):
353359 ret = check_string (value , pat , regexp )
354360 if ret :
355361 break
356- except Exception as e :
362+ except Exception :
357363 print ('Failed to get path "{}"' .format (path ))
358364 raise
359365 return ret
@@ -363,6 +369,7 @@ def get_tree_count(tree, path):
363369 path = normalize_xpath (path )
364370 return len (tree .findall (path ))
365371
372+
366373def stderr (* args ):
367374 if sys .version_info .major < 3 :
368375 file = codecs .getwriter ('utf-8' )(sys .stderr )
@@ -371,6 +378,7 @@ def stderr(*args):
371378
372379 print (* args , file = file )
373380
381+
374382def print_err (lineno , context , err , message = None ):
375383 global ERR_COUNT
376384 ERR_COUNT += 1
@@ -381,48 +389,50 @@ def print_err(lineno, context, err, message=None):
381389 if context :
382390 stderr ("\t {}" .format (context ))
383391
392+
384393ERR_COUNT = 0
385394
395+
386396def check_command (c , cache ):
387397 try :
388398 cerr = ""
389- if c .cmd == 'has' or c .cmd == 'matches' : # string test
399+ if c .cmd == 'has' or c .cmd == 'matches' : # string test
390400 regexp = (c .cmd == 'matches' )
391- if len (c .args ) == 1 and not regexp : # @has <path> = file existence
401+ if len (c .args ) == 1 and not regexp : # @has <path> = file existence
392402 try :
393403 cache .get_file (c .args [0 ])
394404 ret = True
395405 except FailedCheck as err :
396406 cerr = str (err )
397407 ret = False
398- elif len (c .args ) == 2 : # @has/matches <path> <pat> = string test
408+ elif len (c .args ) == 2 : # @has/matches <path> <pat> = string test
399409 cerr = "`PATTERN` did not match"
400410 ret = check_string (cache .get_file (c .args [0 ]), c .args [1 ], regexp )
401- elif len (c .args ) == 3 : # @has/matches <path> <pat> <match> = XML tree test
411+ elif len (c .args ) == 3 : # @has/matches <path> <pat> <match> = XML tree test
402412 cerr = "`XPATH PATTERN` did not match"
403413 tree = cache .get_tree (c .args [0 ])
404414 pat , sep , attr = c .args [1 ].partition ('/@' )
405- if sep : # attribute
415+ if sep : # attribute
406416 tree = cache .get_tree (c .args [0 ])
407417 ret = check_tree_attr (tree , pat , attr , c .args [2 ], regexp )
408- else : # normalized text
418+ else : # normalized text
409419 pat = c .args [1 ]
410420 if pat .endswith ('/text()' ):
411421 pat = pat [:- 7 ]
412422 ret = check_tree_text (cache .get_tree (c .args [0 ]), pat , c .args [2 ], regexp )
413423 else :
414424 raise InvalidCheck ('Invalid number of @{} arguments' .format (c .cmd ))
415425
416- elif c .cmd == 'count' : # count test
417- if len (c .args ) == 3 : # @count <path> <pat> <count> = count test
426+ elif c .cmd == 'count' : # count test
427+ if len (c .args ) == 3 : # @count <path> <pat> <count> = count test
418428 expected = int (c .args [2 ])
419429 found = get_tree_count (cache .get_tree (c .args [0 ]), c .args [1 ])
420430 cerr = "Expected {} occurrences but found {}" .format (expected , found )
421431 ret = expected == found
422432 else :
423433 raise InvalidCheck ('Invalid number of @{} arguments' .format (c .cmd ))
424- elif c .cmd == 'has-dir' : # has-dir test
425- if len (c .args ) == 1 : # @has-dir <path> = has-dir test
434+ elif c .cmd == 'has-dir' : # has-dir test
435+ if len (c .args ) == 1 : # @has-dir <path> = has-dir test
426436 try :
427437 cache .get_dir (c .args [0 ])
428438 ret = True
@@ -448,11 +458,13 @@ def check_command(c, cache):
448458 except InvalidCheck as err :
449459 print_err (c .lineno , c .context , str (err ))
450460
461+
451462def check (target , commands ):
452463 cache = CachedFiles (target )
453464 for c in commands :
454465 check_command (c , cache )
455466
467+
456468if __name__ == '__main__' :
457469 if len (sys .argv ) != 3 :
458470 stderr ('Usage: {} <doc dir> <template>' .format (sys .argv [0 ]))
0 commit comments