# Buggy code
def __init__(
    self,
    srcdir,
    confdir,
    outdir,
    doctreedir,
    buildername,
    confoverrides=None,
    status=sys.stdout,
    warning=sys.stderr,
    freshenv=False,
    warningiserror=False,
    tags=None,
    verbosity=0,
    parallel=0,
    keep_going=False,
):
    # type: (str, str, str, str, str, Dict, IO, IO, bool, bool, List[str], int, int, bool) -> None  # NOQA
    self.phase = BuildPhase.INITIALIZATION
    self.verbosity = verbosity
    self.extensions = {}  # type: Dict[str, Extension]
    self.builder = None  # type: Builder
    self.env = None  # type: BuildEnvironment
    self.project = None  # type: Project
    self.registry = SphinxComponentRegistry()
    self.html_themes = {}  # type: Dict[str, str]

    # validate provided directories
    self.srcdir = abspath(srcdir)
    self.outdir = abspath(outdir)
    self.doctreedir = abspath(doctreedir)
    self.confdir = confdir
    if self.confdir:  # confdir is optional
        self.confdir = abspath(self.confdir)
        if not path.isfile(path.join(self.confdir, "conf.py")):
            raise ApplicationError(
                __("config directory doesn't contain a conf.py file (%s)") % confdir
            )

    if not path.isdir(self.srcdir):
        raise ApplicationError(__("Cannot find source directory (%s)") % self.srcdir)

    if self.srcdir == self.outdir:
        raise ApplicationError(
            __("Source directory and destination directory cannot be identical")
        )

    self.parallel = parallel

    if status is None:
        self._status = StringIO()  # type: IO
        self.quiet = True
    else:
        self._status = status
        self.quiet = False

    if warning is None:
        self._warning = StringIO()  # type: IO
    else:
        self._warning = warning
    self._warncount = 0
    self.keep_going = warningiserror and keep_going
    if self.keep_going:
        self.warningiserror = False
    else:
        self.warningiserror = warningiserror
    logging.setup(self, self._status, self._warning)

    self.events = EventManager(self)

    # keep last few messages for traceback
    # This will be filled by sphinx.util.logging.LastMessagesWriter
    self.messagelog = deque(maxlen=10)  # type: deque

    # say hello to the world
    logger.info(bold(__("Running Sphinx v%s") % sphinx.__display_version__))

    # status code for command-line application
    self.statuscode = 0

    # read config
    self.tags = Tags(tags)
    if self.confdir is None:
        self.config = Config({}, confoverrides or {})
    else:
        self.config = Config.read(self.confdir, confoverrides or {}, self.tags)

    # initialize some limited config variables before initialize i18n and loading
    # extensions
    self.config.pre_init_values()

    # set up translation infrastructure
    self._init_i18n()

    # check the Sphinx version if requested
    if (
        self.config.needs_sphinx
        and self.config.needs_sphinx > sphinx.__display_version__
    ):
        raise VersionRequirementError(
            __(
                "This project needs at least Sphinx v%s and therefore cannot "
                "be built with this version."
            )
            % self.config.needs_sphinx
        )

    # set confdir to srcdir if -C given (!= no confdir); a few pieces
    # of code expect a confdir to be set
    if self.confdir is None:
        self.confdir = self.srcdir

    # load all built-in extension modules
    for extension in builtin_extensions:
        self.setup_extension(extension)

    # load all user-given extension modules
    for extension in self.config.extensions:
        self.setup_extension(extension)

    # preload builder module (before init config values)
    self.preload_builder(buildername)

    if not path.isdir(outdir):
        with progress_message(__("making output directory")):
            ensuredir(outdir)

    # the config file itself can be an extension
    if self.config.setup:
        prefix = __("while setting up extension %s:") % "conf.py"
        with prefixed_warnings(prefix):
            if callable(self.config.setup):
                self.config.setup(self)
            else:
                raise ConfigError(
                    __(
                        "'setup' as currently defined in conf.py isn't a Python callable. "
                        "Please modify its definition to make it a callable function. "
                        "This is needed for conf.py to behave as a Sphinx extension."
                    )
                )

    # now that we know all config values, collect them from conf.py
    self.config.init_values()
    self.events.emit("config-inited", self.config)

    # create the project
    self.project = Project(self.srcdir, self.config.source_suffix)
    # create the builder
    self.builder = self.create_builder(buildername)
    # set up the build environment
    self._init_env(freshenv)
    # set up the builder
    self._init_builder()


# Traceback (AttributeError)
# Sphinx version: 2.2.1
# Python version: 3.8.0 (CPython)
# Docutils version: 0.15.2 release
# Jinja2 version: 2.10.3
# Last messages:
#
#   looking for now-outdated files...
#   none found
#   pickling environment...
#   done
#   checking consistency...
#   done
#   preparing documents...
#   done
#   writing output... [ 11%] configuring/index
# Loaded extensions:
#   sphinx.ext.mathjax (2.2.1) from /Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinx/ext/mathjax.py
#   sphinxcontrib.applehelp (1.0.1) from /Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinxcontrib/applehelp/__init__.py
#   sphinxcontrib.devhelp (1.0.1) from /Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinxcontrib/devhelp/__init__.py
#   sphinxcontrib.htmlhelp (1.0.2) from /Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinxcontrib/htmlhelp/__init__.py
#   sphinxcontrib.serializinghtml (1.1.3) from /Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinxcontrib/serializinghtml/__init__.py
#   sphinxcontrib.qthelp (1.0.2) from /Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinxcontrib/qthelp/__init__.py
#   alabaster (0.7.12) from /Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/alabaster/__init__.py
#   sphinx.ext.autodoc (2.2.1) from /Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py
#   sphinx.ext.intersphinx (2.2.1) from /Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinx/ext/intersphinx.py
Traceback (most recent call last):
File "/Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinx/cmd/build.py", line 276, in build_main
app.build(args.force_all, filenames)
File "/Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinx/application.py", line 346, in build
self.builder.build_update()
File "/Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 297, in build_update
self.build(to_build,
File "/Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 361, in build
self.write(docnames, list(updated_docnames), method)
File "/Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 532, in write
self._write_parallel(sorted(docnames),
File "/Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 572, in _write_parallel
tasks.add_task(write_process, arg)
File "/Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinx/util/parallel.py", line 96, in add_task
self._join_one()
File "/Users/ssbarnea/os/ansible-lint/.tox/docs/lib/python3.8/site-packages/sphinx/util/parallel.py", line 120, in _join_one
self._procs[newtid].start()
File "/Users/ssbarnea/.pyenv/versions/3.8.0/lib/python3.8/multiprocessing/process.py", line 121, in start
self._popen = self._Popen(self)
File "/Users/ssbarnea/.pyenv/versions/3.8.0/lib/python3.8/multiprocessing/context.py", line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "/Users/ssbarnea/.pyenv/versions/3.8.0/lib/python3.8/multiprocessing/context.py", line 283, in _Popen
return Popen(process_obj)
File "/Users/ssbarnea/.pyenv/versions/3.8.0/lib/python3.8/multiprocessing/popen_spawn_posix.py", line 32, in __init__
super().__init__(process_obj)
File "/Users/ssbarnea/.pyenv/versions/3.8.0/lib/python3.8/multiprocessing/popen_fork.py", line 19, in __init__
self._launch(process_obj)
File "/Users/ssbarnea/.pyenv/versions/3.8.0/lib/python3.8/multiprocessing/popen_spawn_posix.py", line 47, in _launch
reduction.dump(process_obj, fp)
File "/Users/ssbarnea/.pyenv/versions/3.8.0/lib/python3.8/multiprocessing/reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'ParallelTasks.add_task.<locals>.<lambda>'

# Fixed code
def __init__(
    self,
    srcdir,
    confdir,
    outdir,
    doctreedir,
    buildername,
    confoverrides=None,
    status=sys.stdout,
    warning=sys.stderr,
    freshenv=False,
    warningiserror=False,
    tags=None,
    verbosity=0,
    parallel=0,
    keep_going=False,
):
    # type: (str, str, str, str, str, Dict, IO, IO, bool, bool, List[str], int, int, bool) -> None  # NOQA
    self.phase = BuildPhase.INITIALIZATION
    self.verbosity = verbosity
    self.extensions = {}  # type: Dict[str, Extension]
    self.builder = None  # type: Builder
    self.env = None  # type: BuildEnvironment
    self.project = None  # type: Project
    self.registry = SphinxComponentRegistry()
    self.html_themes = {}  # type: Dict[str, str]

    # validate provided directories
    self.srcdir = abspath(srcdir)
    self.outdir = abspath(outdir)
    self.doctreedir = abspath(doctreedir)
    self.confdir = confdir
    if self.confdir:  # confdir is optional
        self.confdir = abspath(self.confdir)
        if not path.isfile(path.join(self.confdir, "conf.py")):
            raise ApplicationError(
                __("config directory doesn't contain a conf.py file (%s)") % confdir
            )

    if not path.isdir(self.srcdir):
        raise ApplicationError(__("Cannot find source directory (%s)") % self.srcdir)

    if self.srcdir == self.outdir:
        raise ApplicationError(
            __("Source directory and destination directory cannot be identical")
        )

    self.parallel = parallel

    if status is None:
        self._status = StringIO()  # type: IO
        self.quiet = True
    else:
        self._status = status
        self.quiet = False

    if warning is None:
        self._warning = StringIO()  # type: IO
    else:
        self._warning = warning
    self._warncount = 0
    self.keep_going = warningiserror and keep_going
    if self.keep_going:
        self.warningiserror = False
    else:
        self.warningiserror = warningiserror
    logging.setup(self, self._status, self._warning)

    self.events = EventManager(self)

    # keep last few messages for traceback
    # This will be filled by sphinx.util.logging.LastMessagesWriter
    self.messagelog = deque(maxlen=10)  # type: deque

    # say hello to the world
    logger.info(bold(__("Running Sphinx v%s") % sphinx.__display_version__))

    # notice for parallel build on macOS and py38+
    if sys.version_info > (3, 8) and platform.system() == "Darwin" and parallel > 1:
        logger.info(
            bold(
                __(
                    "For security reason, parallel mode is disabled on macOS and "
                    "python3.8 and above.  For more details, please read "
                    "https://github.com/sphinx-doc/sphinx/issues/6803"
                )
            )
        )

    # status code for command-line application
    self.statuscode = 0

    # read config
    self.tags = Tags(tags)
    if self.confdir is None:
        self.config = Config({}, confoverrides or {})
    else:
        self.config = Config.read(self.confdir, confoverrides or {}, self.tags)

    # initialize some limited config variables before initialize i18n and loading
    # extensions
    self.config.pre_init_values()

    # set up translation infrastructure
    self._init_i18n()

    # check the Sphinx version if requested
    if (
        self.config.needs_sphinx
        and self.config.needs_sphinx > sphinx.__display_version__
    ):
        raise VersionRequirementError(
            __(
                "This project needs at least Sphinx v%s and therefore cannot "
                "be built with this version."
            )
            % self.config.needs_sphinx
        )

    # set confdir to srcdir if -C given (!= no confdir); a few pieces
    # of code expect a confdir to be set
    if self.confdir is None:
        self.confdir = self.srcdir

    # load all built-in extension modules
    for extension in builtin_extensions:
        self.setup_extension(extension)

    # load all user-given extension modules
    for extension in self.config.extensions:
        self.setup_extension(extension)

    # preload builder module (before init config values)
    self.preload_builder(buildername)

    if not path.isdir(outdir):
        with progress_message(__("making output directory")):
            ensuredir(outdir)

    # the config file itself can be an extension
    if self.config.setup:
        prefix = __("while setting up extension %s:") % "conf.py"
        with prefixed_warnings(prefix):
            if callable(self.config.setup):
                self.config.setup(self)
            else:
                raise ConfigError(
                    __(
                        "'setup' as currently defined in conf.py isn't a Python callable. "
                        "Please modify its definition to make it a callable function. "
                        "This is needed for conf.py to behave as a Sphinx extension."
                    )
                )

    # now that we know all config values, collect them from conf.py
    self.config.init_values()
    self.events.emit("config-inited", self.config)

    # create the project
    self.project = Project(self.srcdir, self.config.source_suffix)
    # create the builder
    self.builder = self.create_builder(buildername)
    # set up the build environment
    self._init_env(freshenv)
    # set up the builder
    self._init_builder()