# Buggy code
def assign_section_numbers(self, env):
    # type: (BuildEnvironment) -> List[unicode]
    """Assign a section number to each heading under a numbered toctree."""
    # a list of all docnames whose section numbers changed
    rewrite_needed = []

    assigned = set()  # type: Set[unicode]
    old_secnumbers = env.toc_secnumbers
    env.toc_secnumbers = {}

    def _walk_toc(node, secnums, depth, titlenode=None):
        # titlenode is the title of the document, it will get assigned a
        # secnumber too, so that it shows up in next/prev/parent rellinks
        for subnode in node.children:
            if isinstance(subnode, nodes.bullet_list):
                numstack.append(0)
                _walk_toc(subnode, secnums, depth - 1, titlenode)
                numstack.pop()
                titlenode = None
            elif isinstance(subnode, nodes.list_item):
                _walk_toc(subnode, secnums, depth, titlenode)
                titlenode = None
            elif isinstance(subnode, addnodes.only):
                # at this stage we don't know yet which sections are going
                # to be included; just include all of them, even if it leads
                # to gaps in the numbering
                _walk_toc(subnode, secnums, depth, titlenode)
                titlenode = None
            elif isinstance(subnode, addnodes.compact_paragraph):
                numstack[-1] += 1
                if depth > 0:
                    number = tuple(numstack)
                else:
                    number = None
                secnums[subnode[0]["anchorname"]] = number
                subnode[0]["secnumber"] = list(number)
                if titlenode:
                    titlenode["secnumber"] = list(number)
                    titlenode = None
            elif isinstance(subnode, addnodes.toctree):
                _walk_toctree(subnode, depth)

    def _walk_toctree(toctreenode, depth):
        if depth == 0:
            return
        for title, ref in toctreenode["entries"]:
            if url_re.match(ref) or ref == "self":
                # don't mess with those
                continue
            elif ref in assigned:
                logger.warning(
                    "%s is already assigned section numbers (nested numbered toctree?)",
                    ref,
                    location=toctreenode,
                    type="toc",
                    subtype="secnum",
                )
            elif ref in env.tocs:
                secnums = env.toc_secnumbers[ref] = {}
                assigned.add(ref)
                _walk_toc(env.tocs[ref], secnums, depth, env.titles.get(ref))
                if secnums != old_secnumbers.get(ref):
                    rewrite_needed.append(ref)

    for docname in env.numbered_toctrees:
        assigned.add(docname)
        doctree = env.get_doctree(docname)
        for toctreenode in doctree.traverse(addnodes.toctree):
            depth = toctreenode.get("numbered", 0)
            if depth:
                # every numbered toctree gets new numbering
                numstack = [0]
                _walk_toctree(toctreenode, depth)

    return rewrite_needed


# Traceback (TypeError)
# Sphinx version: 1.7.5
# Python version: 2.7.15 (CPython)
# Docutils version: 0.14
# Jinja2 version: 2.10
# Last messages:
#   reading sources... [ 77%] hadoop-server
#   reading sources... [ 80%] hive
#   reading sources... [ 83%] home
#   reading sources... [ 87%] important
#   reading sources... [ 90%] index
#   reading sources... [ 93%] media-chooser
#   reading sources... [ 96%] resource-list
#   reading sources... [100%] upm
#
#   looking for now-outdated files...
# Loaded extensions:
#   download (unknown version) from /Users/jumping.qu/Downloads/deploy-docs/dmp-deploy-docs/src/main/sphinx/ext/download.py
#   alabaster (0.7.10) from /usr/local/lib/python2.7/site-packages/alabaster/__init__.pyc
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/sphinx/cmdline.py", line 304, in main
app.build(args.force_all, filenames)
File "/usr/local/lib/python2.7/site-packages/sphinx/application.py", line 331, in build
self.builder.build_update()
File "/usr/local/lib/python2.7/site-packages/sphinx/builders/__init__.py", line 342, in build_update
'out of date' % len(to_build))
File "/usr/local/lib/python2.7/site-packages/sphinx/builders/__init__.py", line 359, in build
for docname in self.env.check_dependents(self.app, updated_docnames):
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/__init__.py", line 620, in check_dependents
for docnames in app.emit('env-get-updated', self):
File "/usr/local/lib/python2.7/site-packages/sphinx/application.py", line 444, in emit
return self.events.emit(event, self, *args)
File "/usr/local/lib/python2.7/site-packages/sphinx/events.py", line 79, in emit
results.append(callback(*args))
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 135, in get_updated_docs
return self.assign_section_numbers(env) + self.assign_figure_numbers(env)
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 206, in assign_section_numbers
_walk_toctree(toctreenode, depth)
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 194, in _walk_toctree
env.titles.get(ref))
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 157, in _walk_toc
_walk_toc(subnode, secnums, depth, titlenode)
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 153, in _walk_toc
_walk_toc(subnode, secnums, depth - 1, titlenode)
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 177, in _walk_toc
_walk_toctree(subnode, depth)
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 194, in _walk_toctree
env.titles.get(ref))
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 157, in _walk_toc
_walk_toc(subnode, secnums, depth, titlenode)
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 153, in _walk_toc
_walk_toc(subnode, secnums, depth - 1, titlenode)
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 177, in _walk_toc
_walk_toctree(subnode, depth)
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 194, in _walk_toctree
env.titles.get(ref))
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 157, in _walk_toc
_walk_toc(subnode, secnums, depth, titlenode)
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 153, in _walk_toc
_walk_toc(subnode, secnums, depth - 1, titlenode)
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 157, in _walk_toc
_walk_toc(subnode, secnums, depth, titlenode)
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 153, in _walk_toc
_walk_toc(subnode, secnums, depth - 1, titlenode)
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 157, in _walk_toc
_walk_toc(subnode, secnums, depth, titlenode)
File "/usr/local/lib/python2.7/site-packages/sphinx/environment/collectors/toctree.py", line 172, in _walk_toc
subnode[0]['secnumber'] = list(number)
TypeError: 'NoneType' object is not iterable

# Fixed code
def assign_section_numbers(self, env):
    # type: (BuildEnvironment) -> List[unicode]
    """Assign a section number to each heading under a numbered toctree."""
    # a list of all docnames whose section numbers changed
    rewrite_needed = []

    assigned = set()  # type: Set[unicode]
    old_secnumbers = env.toc_secnumbers
    env.toc_secnumbers = {}

    def _walk_toc(node, secnums, depth, titlenode=None):
        # titlenode is the title of the document, it will get assigned a
        # secnumber too, so that it shows up in next/prev/parent rellinks
        for subnode in node.children:
            if isinstance(subnode, nodes.bullet_list):
                numstack.append(0)
                _walk_toc(subnode, secnums, depth - 1, titlenode)
                numstack.pop()
                titlenode = None
            elif isinstance(subnode, nodes.list_item):
                _walk_toc(subnode, secnums, depth, titlenode)
                titlenode = None
            elif isinstance(subnode, addnodes.only):
                # at this stage we don't know yet which sections are going
                # to be included; just include all of them, even if it leads
                # to gaps in the numbering
                _walk_toc(subnode, secnums, depth, titlenode)
                titlenode = None
            elif isinstance(subnode, addnodes.compact_paragraph):
                numstack[-1] += 1
                if depth > 0:
                    number = list(numstack)
                    secnums[subnode[0]["anchorname"]] = tuple(numstack)
                else:
                    number = None
                    secnums[subnode[0]["anchorname"]] = None
                subnode[0]["secnumber"] = number
                if titlenode:
                    titlenode["secnumber"] = number
                    titlenode = None
            elif isinstance(subnode, addnodes.toctree):
                _walk_toctree(subnode, depth)

    def _walk_toctree(toctreenode, depth):
        if depth == 0:
            return
        for title, ref in toctreenode["entries"]:
            if url_re.match(ref) or ref == "self":
                # don't mess with those
                continue
            elif ref in assigned:
                logger.warning(
                    "%s is already assigned section numbers (nested numbered toctree?)",
                    ref,
                    location=toctreenode,
                    type="toc",
                    subtype="secnum",
                )
            elif ref in env.tocs:
                secnums = env.toc_secnumbers[ref] = {}
                assigned.add(ref)
                _walk_toc(env.tocs[ref], secnums, depth, env.titles.get(ref))
                if secnums != old_secnumbers.get(ref):
                    rewrite_needed.append(ref)

    for docname in env.numbered_toctrees:
        assigned.add(docname)
        doctree = env.get_doctree(docname)
        for toctreenode in doctree.traverse(addnodes.toctree):
            depth = toctreenode.get("numbered", 0)
            if depth:
                # every numbered toctree gets new numbering
                numstack = [0]
                _walk_toctree(toctreenode, depth)

    return rewrite_needed