' in h, h)
def testNewPrettyHref(self):
+ # type: () -> None
# New style of doc
new_flags = ['--toc-tag', 'h2', '--toc-tag', 'h3', '--toc-pretty-href']
@@ -147,6 +150,7 @@ def testNewPrettyHref(self):
print(h)
def testExtractor(self):
+ # type: () -> None
parser = cmark.TocExtractor()
parser.feed(_HTML_1)
self.assertEqual(5, parser.toc_begin_line)
@@ -187,6 +191,7 @@ def testExtractor(self):
self.assertEqual('Two', ''.join(text))
def testExtractorDense(self):
+ # type: () -> None
parser = cmark.TocExtractor()
parser.feed(_HTML_1.replace('"toc"', '"dense-toc"'))
diff --git a/doctools/help_gen.py b/doctools/help_gen.py
index 48915814f..623945be3 100755
--- a/doctools/help_gen.py
+++ b/doctools/help_gen.py
@@ -1,5 +1,9 @@
#!/usr/bin/env python2
from __future__ import print_function
+from typing import List
+from typing import Any
+from typing import Dict
+from typing import Iterator
"""help_gen.py
Ideas for HTML -> ANSI converter:
@@ -85,6 +89,7 @@ def _StringToHref(s):
class TopicHtmlRenderer(object):
def __init__(self, chapter, debug_out, linkify_stop_col):
+ # type: (str, List, int) -> None
self.chapter = chapter
self.debug_out = debug_out
self.linkify_stop_col = linkify_stop_col
@@ -92,6 +97,7 @@ def __init__(self, chapter, debug_out, linkify_stop_col):
self.html_page = 'chap-%s.html' % chapter
def _PrintTopic(self, m, out, line_info):
+ # type: (Any, html.Output, Dict[str, Any]) -> None
# The X
topic_impl = True
if m.group(1):
@@ -111,6 +117,7 @@ def _PrintTopic(self, m, out, line_info):
out.Print('')
def Render(self, line):
+ # type: (str) -> str
"""Convert a line of text to HTML.
Topics are highlighted and X made red.
@@ -217,6 +224,7 @@ class Splitter(HTMLParser.HTMLParser):
"""
def __init__(self, heading_tags, out):
+ # type: (List[str], List) -> None
HTMLParser.HTMLParser.__init__(self)
self.heading_tags = heading_tags
self.out = out
@@ -271,6 +279,7 @@ def handle_data(self, data):
self.cur_group[3].append(data)
def end(self):
+ # type: () -> None
if self.cur_group:
self.out.append(self.cur_group)
@@ -282,6 +291,7 @@ def end(self):
def ExtractBody(s):
+ # type: (str) -> str
"""Extract what's in between
The splitter needs balanced tags, and what's in isn't
@@ -316,6 +326,7 @@ def ExtractBody(s):
def SplitIntoCards(heading_tags, contents):
+ # type: (List[str], str) -> Iterator
contents = ExtractBody(contents)
groups = []
diff --git a/doctools/help_gen_test.py b/doctools/help_gen_test.py
index 780188b40..b4b3ffe67 100755
--- a/doctools/help_gen_test.py
+++ b/doctools/help_gen_test.py
@@ -11,6 +11,7 @@
class HelpGenTest(unittest.TestCase):
def testTopicRe(self):
+ # type: () -> None
CASES = [
('hello ', True),
('X hello ', True),
@@ -29,6 +30,7 @@ def testTopicRe(self):
self.assertEqual(matched, bool(m))
def testTopicHtml(self):
+ # type: () -> None
os.environ['OILS_VERSION'] = '0.7.pre5'
# Three spaces before
@@ -91,6 +93,7 @@ def testTopicHtml(self):
print()
def testSplitIntoCards(self):
+ # type: () -> None
contents = """
YSH Expression Language
diff --git a/doctools/html_head.py b/doctools/html_head.py
index 54803560c..d79bd9a27 100755
--- a/doctools/html_head.py
+++ b/doctools/html_head.py
@@ -12,7 +12,8 @@
try:
import html
except ImportError:
- import cgi as html # only for cgi.escape -> html.escape
+ # only for cgi.escape -> html.escape
+ import cgi as html # type: ignore
try:
import cStringIO
except ImportError:
diff --git a/doctools/html_lib.py b/doctools/html_lib.py
index facb663ae..7a83186ed 100644
--- a/doctools/html_lib.py
+++ b/doctools/html_lib.py
@@ -9,9 +9,11 @@
import cgi
import re
+from typing import List
def AttrsToString(attrs):
+ # type: (List) -> str
if not attrs:
return ''
@@ -21,6 +23,7 @@ def AttrsToString(attrs):
def PrettyHref(s, preserve_anchor_case=False):
+ # type: (str, bool) -> str
"""Turn arbitrary heading text into href with no special characters.
This is modeled after what github does. It makes everything lower case.
diff --git a/doctools/html_lib_test.py b/doctools/html_lib_test.py
index ae2a45819..d2808ac51 100755
--- a/doctools/html_lib_test.py
+++ b/doctools/html_lib_test.py
@@ -9,6 +9,7 @@
class FunctionsTest(unittest.TestCase):
def testPrettyHref(self):
+ # type: () -> None
self.assertEqual('foo-bar', html_lib.PrettyHref('foo bar', False))
self.assertEqual('why-not', html_lib.PrettyHref('Why Not??', False))
self.assertEqual('backslash-foo',
diff --git a/doctools/oils_doc.py b/doctools/oils_doc.py
index ac9033675..e5de856c3 100755
--- a/doctools/oils_doc.py
+++ b/doctools/oils_doc.py
@@ -12,6 +12,10 @@
from __future__ import print_function
import cgi
+from typing import Iterator
+from typing import Any
+from typing import List
+from typing import Optional
try:
from cStringIO import StringIO
except ImportError:
@@ -35,6 +39,7 @@ def __init__(self, fmt):
self.fmt = fmt
def __call__(self, value):
+ # type: (str) -> str
return self.fmt % {'value': value}
@@ -100,6 +105,7 @@ def __call__(self, value):
def ExpandLinks(s):
+ # type: (str) -> str
"""Expand $xref:bash and so forth."""
f = StringIO()
out = html.Output(s, f)
@@ -165,6 +171,7 @@ class _Plugin(object):
"""
def __init__(self, s, start_pos, end_pos):
+ # type: (str, int, int) -> None
self.s = s
self.start_pos = start_pos
self.end_pos = end_pos
@@ -201,6 +208,7 @@ def PrintHighlighted(self, out):
def Lines(s, start_pos, end_pos):
+ # type: (str, int, int) -> Iterator[int]
"""Yields positions in s that end a line."""
pos = start_pos
while pos < end_pos:
@@ -218,6 +226,7 @@ class ShPromptPlugin(_Plugin):
"""Highlight shell prompts."""
def PrintHighlighted(self, out):
+ # type: (html.Output) -> None
pos = self.start_pos
for line_end in Lines(self.s, self.start_pos, self.end_pos):
@@ -368,6 +377,7 @@ def SimpleHighlightCode(s):
def HighlightCode(s, default_highlighter, debug_out=None):
+ # type: (str, Optional[Any], Optional[List]) -> str
"""
Algorithm:
1. Collect what's inside
...
diff --git a/doctools/oils_doc_test.py b/doctools/oils_doc_test.py
index 16ab72219..c173cf17e 100755
--- a/doctools/oils_doc_test.py
+++ b/doctools/oils_doc_test.py
@@ -14,6 +14,7 @@
class OilsDocTest(unittest.TestCase):
def testTopicCssClass(self):
+ # type: () -> None
CASES = [
('language-chapter-links-expr-lang', True),
@@ -25,6 +26,7 @@ def testTopicCssClass(self):
print(m.groups())
def testExpandLinks(self):
+ # type: () -> None
"""
bash
->
@@ -40,6 +42,7 @@ def testExpandLinks(self):
self.assertEqual('', h)
def testShPrompt(self):
+ # type: () -> None
r = oils_doc._PROMPT_LINE_RE
line = 'oil$ ls -l<TAB> # comment'
m = r.match(line)
@@ -54,6 +57,7 @@ def testShPrompt(self):
plugin.PrintHighlighted(out)
def testHighlightCode(self):
+ # type: () -> None
# lazylex/testdata.html has the language-sh-prompt
h = oils_doc.HighlightCode(TEST_HTML, None)
@@ -61,6 +65,7 @@ def testHighlightCode(self):
#print(h)
def testPygmentsPlugin(self):
+ # type: () -> None
# TODO: Doesn't pass on Travis because pygments isn't there
# use virtualenv or something?
return
diff --git a/doctools/spelling.py b/doctools/spelling.py
index 0fcefcfb7..57db3096b 100755
--- a/doctools/spelling.py
+++ b/doctools/spelling.py
@@ -11,9 +11,11 @@
import sys
from doctools.util import log
+from typing import Iterator
def SplitWords(contents):
+ # type: (str) -> Iterator[str]
# Remove URLs so path components don't show up as words
contents = re.sub(r'(http|https|file)://\S+', '', contents)
diff --git a/doctools/spelling_test.py b/doctools/spelling_test.py
index ca949bb86..4c2fff822 100755
--- a/doctools/spelling_test.py
+++ b/doctools/spelling_test.py
@@ -10,6 +10,7 @@
class SpellingTest(unittest.TestCase):
def testSplitWords(self):
+ # type: () -> None
docs = [
r'''
diff --git a/doctools/split_doc.py b/doctools/split_doc.py
index 0057852a6..b0f3865cb 100755
--- a/doctools/split_doc.py
+++ b/doctools/split_doc.py
@@ -6,6 +6,7 @@
import optparse
import re
import sys
+from typing import Dict, IO
DATE_RE = re.compile(r'(\d\d\d\d) / (\d\d) / (\d\d)', re.VERBOSE)
@@ -13,6 +14,7 @@
def SplitDocument(default_vals, entry_f, meta_f, content_f, strict=False):
+ # type: (Dict[str, str], IO[str], IO[str], IO[str], bool) -> None
"""Split a document into metadata JSON and content Markdown.
Used for blog posts and index.md / cross-ref.md.
diff --git a/doctools/split_doc_test.py b/doctools/split_doc_test.py
index cd74360de..cb0f16350 100755
--- a/doctools/split_doc_test.py
+++ b/doctools/split_doc_test.py
@@ -11,6 +11,7 @@
class FooTest(unittest.TestCase):
def testStrict(self):
+ # type: () -> None
entry_f = StringIO('''\
Title
=====
@@ -33,6 +34,7 @@ def testStrict(self):
print(content_f.getvalue())
def testMetadataAndTitle(self):
+ # type: () -> None
print('_' * 40)
print()
@@ -57,6 +59,7 @@ def testMetadataAndTitle(self):
print(content_f.getvalue())
def testMetadataAndTitleNoSpace(self):
+ # type: () -> None
print('_' * 40)
print()
@@ -80,6 +83,7 @@ def testMetadataAndTitleNoSpace(self):
print(content_f.getvalue())
def testTitleOnly(self):
+ # type: () -> None
print('_' * 40)
print()
diff --git a/doctools/ul_table.py b/doctools/ul_table.py
index 54cb0c034..53a8332e7 100755
--- a/doctools/ul_table.py
+++ b/doctools/ul_table.py
@@ -10,9 +10,16 @@
from doctools.util import log
from lazylex import html
+from typing import List
+from typing import Optional
+from typing import Tuple
+from typing import Union
+from typing import Any
+from typing import Dict
def RemoveComments(s):
+ # type: (str) -> str
"""Remove
This is a required preprocessing step for ul-table.
@@ -43,6 +50,7 @@ def RemoveComments(s):
class UlTableParser(object):
def __init__(self, lexer, tag_lexer):
+ # type: (html.Lexer, html.TagLexer) -> None
self.lexer = lexer
self.tag_lexer = tag_lexer
@@ -51,10 +59,12 @@ def __init__(self, lexer, tag_lexer):
self.end_pos = 0
def _CurrentString(self):
+ # type: () -> str
part = self.lexer.s[self.start_pos:self.end_pos]
return part
def _Next(self, comment_ok=False):
+ # type: (bool) -> None
"""
Advance and set self.tok_id, self.start_pos, self.end_pos
"""
@@ -86,6 +96,7 @@ def _EatRawData(self, regex):
self._Next()
def _Eat(self, expected_id, expected_tag):
+ # type: (int, str) -> None
"""
Assert that we got a start or end tag, with the given name, and advance
@@ -109,6 +120,7 @@ def _Eat(self, expected_id, expected_tag):
self._Next()
def _WhitespaceOk(self):
+ # type: () -> None
"""
Optional whitespace
"""
@@ -117,6 +129,7 @@ def _WhitespaceOk(self):
self._Next()
def FindUlTable(self):
+ # type: () -> int
"""Find
Return the START position of the
@@ -145,6 +158,7 @@ def FindUlTable(self):
return -1
def _ListItem(self):
+ # type: () -> Tuple[Optional[List[Tuple[str, str]]], Optional[str]]
"""Parse a list item nested below thead or tr.
Returns:
@@ -228,6 +242,7 @@ def _ListItem(self):
return td_attrs, inner_html
def _ParseTHead(self):
+ # type: () -> Union[List[Tuple[List[Tuple[str, str]], str]], List[Tuple[Optional[List[Tuple[str, str]]], str]]]
"""
Assume we're looking at the first tag. Now we want to find
- thead and the nested
@@ -295,6 +310,7 @@ def _ParseTHead(self):
return cells
def _ParseTr(self):
+ # type: () -> Tuple[None, Union[List[Tuple[List[Tuple[str, str]], str]], List[Tuple[None, str]], None]]
"""
Assume we're looking at the first tag. Now we want to find
- tr and the nested
@@ -356,6 +372,7 @@ def _ParseTr(self):
return tr_attrs, cells
def ParseTable(self):
+ # type: () -> Dict[str, Any]
"""
Returns a structure like this
{ 'thead': [ 'col1', 'col2' ], # TODO: columns can have CSS attributes
@@ -417,7 +434,11 @@ def ParseTable(self):
return table
-def MergeAttrs(thead_td_attrs, row_td_attrs):
+def MergeAttrs(
+ thead_td_attrs, # type: Optional[List[Tuple[str, str]]]
+ row_td_attrs, # type: Optional[List[Tuple[str, str]]]
+):
+ # type: (...) -> List[Tuple[str, str]]
merged_attrs = []
if row_td_attrs is None:
@@ -445,6 +466,7 @@ def MergeAttrs(thead_td_attrs, row_td_attrs):
def ReplaceTables(s, debug_out=None):
+ # type: (str, Optional[Any]) -> str
"""
ul-table: Write tables using bulleted list
"""
diff --git a/doctools/ul_table_test.py b/doctools/ul_table_test.py
index 6b1e17c63..1a4f37f14 100755
--- a/doctools/ul_table_test.py
+++ b/doctools/ul_table_test.py
@@ -222,6 +222,7 @@
def MarkdownToTable(md):
+ # type: (str) -> str
# markdown -> HTML
h = cmark.md2html(md)
@@ -250,9 +251,11 @@ def MarkdownToTable(md):
class UlTableTest(unittest.TestCase):
def testOne(self):
+ # type: () -> None
h = MarkdownToTable('hi\n' + TEST1 + '\n\n bye \n')
def testNoHeader(self):
+ # type: () -> None
# HTML looks like:
#
#
@@ -277,6 +280,7 @@ def testNoHeader(self):
print(h)
def testSimple(self):
+ # type: () -> None
h = MarkdownToTable("""\
@@ -313,6 +317,7 @@ def testSimple(self):
""", h)
def testMultipleTables(self):
+ # type: () -> None
# They can be right next to each other
html_one = MarkdownToTable(TEST1)
@@ -327,13 +332,16 @@ def testMultipleTables(self):
self.assertMultiLineEqual(html_one + html_one + '\n', html_two)
def testMultipleTablesWithSpace(self):
+ # type: () -> None
h = MarkdownToTable(TEST1 + '\n\n hi \n' + TEST1)
def testTdAttrs(self):
+ # type: () -> None
h = MarkdownToTable(TD_ATTRS)
self.assertMultiLineEqual(TD_ATTRS_HTML, h)
def testTdAttrsTrailing(self):
+ # type: () -> None
self.maxDiff = 2000
h = MarkdownToTable(TRAILING_ATTRS)
if 1:
@@ -342,20 +350,24 @@ def testTdAttrsTrailing(self):
self.assertMultiLineEqual(TRAILING_ATTRS_HTML, h)
def testColspan(self):
+ # type: () -> None
h = MarkdownToTable(COLSPAN)
self.assertMultiLineEqual(COLSPAN_HTML, h)
def testTrAttrs(self):
+ # type: () -> None
h = MarkdownToTable(TR_ATTRS)
self.assertMultiLineEqual(TR_ATTRS_HTML, h)
def testMixedTr(self):
+ # type: () -> None
# Not worth it
return
h = MarkdownToTable(MIXED_TR)
#self.assertMultiLineEqual(MIXED_TR, h)
def testSyntaxErrors(self):
+ # type: () -> None
# Once we get , then we TAKE OVER, and start being STRICT
try:
@@ -388,6 +400,7 @@ def testSyntaxErrors(self):
self.fail('Expected parse error')
def testColumnCheck(self):
+ # type: () -> None
# Disabled because of colspan
return
diff --git a/lazylex/html.py b/lazylex/html.py
index c26ff889a..5704a2205 100755
--- a/lazylex/html.py
+++ b/lazylex/html.py
@@ -3,8 +3,21 @@
lazylex/html.py - Low-Level HTML Processing.
See lazylex/README.md for details.
+
+TODO:
+- Get rid of AttrValueLexer - this should be in the TagLexer
+ - this also means that unquoted values can be more similar
+ - We can use a single lexer mode for everything inside <>
+ - the SPACE is the only difference
+- UTF-8 check, like JSON8
+- Static typing
+
"""
from __future__ import print_function
+from typing import Iterator
+from typing import Union
+from typing import Any
+from typing import IO
try:
from cStringIO import StringIO
@@ -19,6 +32,7 @@
def log(msg, *args):
+ # type: (str, *Any) -> None
msg = msg % args
print(msg, file=sys.stderr)
@@ -32,14 +46,17 @@ class LexError(Exception):
"""
def __init__(self, s, start_pos):
+ # type: (str, int) -> None
self.s = s
self.start_pos = start_pos
def __str__(self):
+ # type: () -> str
return '(LexError %r)' % (self.s[self.start_pos:self.start_pos + 20])
def FindLineNum(s, error_pos):
+ # type: (str, int) -> int
current_pos = 0
line_num = 1
while True:
@@ -63,11 +80,13 @@ class ParseError(Exception):
"""
def __init__(self, msg, s=None, start_pos=-1):
+ # type: (str, Optional[str], int) -> None
self.msg = msg
self.s = s
self.start_pos = start_pos
def __str__(self):
+ # type: () -> str
if self.s is not None:
assert self.start_pos != -1, self.start_pos
snippet = (self.s[self.start_pos:self.start_pos + 20])
@@ -88,26 +107,31 @@ class Output(object):
"""
def __init__(self, s, f, left_pos=0, right_pos=-1):
+ # type: (str, IO[str], int, int) -> None
self.s = s
self.f = f
self.pos = left_pos
self.right_pos = len(s) if right_pos == -1 else right_pos
def SkipTo(self, pos):
+ # type: (int) -> None
"""Skip to a position."""
self.pos = pos
def PrintUntil(self, pos):
+ # type: (int) -> None
"""Print until a position."""
piece = self.s[self.pos:pos]
self.f.write(piece)
self.pos = pos
def PrintTheRest(self):
+ # type: () -> None
"""Print until the end of the string."""
self.PrintUntil(self.right_pos)
def Print(self, s):
+ # type: (str) -> None
"""Print text to the underlying buffer."""
self.f.write(s)
@@ -135,6 +159,7 @@ class Tok(object):
def TokenName(tok_id):
+ # type: (int) -> str
return TOKEN_NAMES[tok_id]
@@ -258,6 +283,7 @@ def MakeLexer(rules):
class Lexer(object):
def __init__(self, s, left_pos=0, right_pos=-1, no_special_tags=False):
+ # type: (str, int, int, bool) -> None
self.s = s
self.pos = left_pos
self.right_pos = len(s) if right_pos == -1 else right_pos
@@ -378,6 +404,7 @@ def Read(self):
return tok_id, end_pos
def LookAhead(self, regex):
+ # type: (str) -> bool
# Cache the regex compilation. This could also be LookAheadFor(THEAD)
# or something.
pat = self.cache.get(regex)
@@ -390,6 +417,7 @@ def LookAhead(self, regex):
def _Tokens(s, left_pos, right_pos):
+ # type: (str, int, int) -> Iterator[Tuple[int, int]]
"""
Args:
s: string to parse
@@ -404,6 +432,7 @@ def _Tokens(s, left_pos, right_pos):
def ValidTokens(s, left_pos=0, right_pos=-1):
+ # type: (str, int, int) -> Iterator[Tuple[int, int]]
"""Wrapper around _Tokens to prevent callers from having to handle Invalid.
I'm not combining the two functions because I might want to do a
@@ -419,6 +448,7 @@ def ValidTokens(s, left_pos=0, right_pos=-1):
def ValidTokenList(s, no_special_tags=False):
+ # type: (str, bool) -> List[Tuple[int, int]]
"""A wrapper that can be more easily translated to C++. Doesn't use iterators."""
start_pos = 0
@@ -500,11 +530,13 @@ class TagLexer(object):
"""
def __init__(self, s):
+ # type: (str) -> None
self.s = s
self.start_pos = -1 # Invalid
self.end_pos = -1
def Reset(self, start_pos, end_pos):
+ # type: (int, int) -> None
"""Reuse instances of this object."""
assert start_pos >= 0, start_pos
assert end_pos >= 0, end_pos
@@ -516,11 +548,13 @@ def TagString(self):
return self.s[self.start_pos:self.end_pos]
def TagName(self):
+ # type: () -> str
# First event
tok_id, start, end = next(self.Tokens())
return self.s[start:end]
def GetSpanForAttrValue(self, attr_name):
+ # type: (str) -> Tuple[int, int]
"""
Used by oils_doc.py, for href shortcuts
"""
@@ -547,6 +581,7 @@ def GetSpanForAttrValue(self, attr_name):
return val
def GetAttrRaw(self, attr_name):
+ # type: (str) -> Optional[str]
"""
Return the value, which may be UNESCAPED.
"""
@@ -556,6 +591,7 @@ def GetAttrRaw(self, attr_name):
return self.s[start:end]
def AllAttrsRawSlice(self):
+ # type: () -> List[Tuple[str, int, int]]
"""
Get a list of pairs [('class', 3, 5), ('href', 9, 12)]
"""
@@ -580,6 +616,7 @@ def AllAttrsRawSlice(self):
return slices
def AllAttrsRaw(self):
+ # type: () -> List[Tuple[str, str]]
"""
Get a list of pairs [('class', 'foo'), ('href', '?foo=1&bar=2')]
@@ -593,6 +630,7 @@ def AllAttrsRaw(self):
return pairs
def Tokens(self):
+ # type: () -> Iterator[Tuple[int, int, int]]
"""
Yields a sequence of tokens: Tag (AttrName AttrValue?)*
@@ -668,11 +706,13 @@ class AttrValueLexer(object):
"""
def __init__(self, s):
+ # type: (str) -> None
self.s = s
self.start_pos = -1 # Invalid
self.end_pos = -1
def Reset(self, start_pos, end_pos):
+ # type: (int, int) -> None
"""Reuse instances of this object."""
assert start_pos >= 0, start_pos
assert end_pos >= 0, end_pos
@@ -681,6 +721,7 @@ def Reset(self, start_pos, end_pos):
self.end_pos = end_pos
def NumTokens(self):
+ # type: () -> int
num_tokens = 0
pos = self.start_pos
for tok_id, end_pos in self.Tokens():
@@ -692,6 +733,7 @@ def NumTokens(self):
return num_tokens
def Tokens(self):
+ # type: () -> Iterator[Union[Iterator, Iterator[Tuple[int, int]]]]
pos = self.start_pos
while pos < self.end_pos:
# Find the first match, like above.
@@ -735,6 +777,7 @@ def ReadUntilStartTag(it, tag_lexer, tag_name):
def ReadUntilEndTag(it, tag_lexer, tag_name):
+ # type: (Iterator, TagLexer, str) -> Tuple[int, int]
"""Find the next , returning its (start, end) position
Raise ParseError if it's not found.
@@ -766,6 +809,7 @@ def ReadUntilEndTag(it, tag_lexer, tag_name):
def ToText(s, left_pos=0, right_pos=-1):
+ # type: (str, int, int) -> str
"""Given HTML, return text by unquoting > and < etc.
Used by:
@@ -995,6 +1039,7 @@ def ToXml(htm8_str):
class Counters(object):
def __init__(self):
+ # type: () -> None
self.num_tokens = 0
self.num_start_tags = 0
self.num_start_end_tags = 0
diff --git a/lazylex/html_test.py b/lazylex/html_test.py
index e02e1c4df..7cb9f6553 100755
--- a/lazylex/html_test.py
+++ b/lazylex/html_test.py
@@ -4,6 +4,8 @@
import unittest
from lazylex import html # module under test log = html.log
+from typing import List
+from typing import Tuple
log = html.log
@@ -14,6 +16,7 @@
class RegexTest(unittest.TestCase):
def testDotAll(self):
+ # type: () -> None
import re
# Note that $ matches end of line, not end of string
@@ -33,6 +36,7 @@ def testDotAll(self):
print(p4.match('\n'))
def testAttrRe(self):
+ # type: () -> None
_ATTR_RE = html._ATTR_RE
m = _ATTR_RE.match(' empty= val')
print(m.groups())
@@ -41,23 +45,27 @@ def testAttrRe(self):
class FunctionsTest(unittest.TestCase):
def testFindLineNum(self):
+ # type: () -> None
s = 'foo\n' * 3
for pos in [1, 5, 10, 50]: # out of bounds
line_num = html.FindLineNum(s, pos)
print(line_num)
def testToText(self):
+ # type: () -> None
t = html.ToText(' three < four && five ')
self.assertEqual(' three < four && five ', t)
def _MakeTagLexer(s):
+ # type: (str) -> html.TagLexer
lex = html.TagLexer(s)
lex.Reset(0, len(s))
return lex
def _PrintTokens(lex):
+ # type: (html.TagLexer) -> None
log('')
log('tag = %r', lex.TagName())
for tok, start, end in lex.Tokens():
@@ -67,6 +75,7 @@ def _PrintTokens(lex):
class TagLexerTest(unittest.TestCase):
def testTagLexer(self):
+ # type: () -> None
# Invalid!
#lex = _MakeTagLexer('< >')
#print(lex.Tag())
@@ -98,10 +107,12 @@ def testTagLexer(self):
self.assertEqual('?foo=1&bar=2', lex.GetAttrRaw('href'))
def testTagName(self):
+ # type: () -> None
lex = _MakeTagLexer('')
self.assertEqual('a', lex.TagName())
def testAllAttrs(self):
+ # type: () -> None
"""
[('key', 'value')] for all
"""
@@ -114,6 +125,7 @@ def testAllAttrs(self):
self.assertEqual([('href', '?foo=1&bar=2')], lex.AllAttrsRaw())
def testEmptyMissingValues(self):
+ # type: () -> None
# equivalent to