<commit_before>"""Run Sphinx directly through its Python API.
"""

__all__ = ('run_sphinx',)

import os
import logging
import sys

from sphinx.application import Sphinx
try:
    from sphinx.cmd.build import handle_exception
except ImportError:
    # Sphinx <1.7
    from sphinx.cmdline import handle_exception
from sphinx.util.docutils import docutils_namespace


def run_sphinx(root_dir):
    """Run the Sphinx build process.

    Parameters
    ----------
    root_dir : `str`
        Root directory of the Sphinx project and content source. This directory
        conatains both the root ``index.rst`` file and the ``conf.py``
        configuration file.

    Returns
    -------
    status : `int`
        Sphinx status code. ``0`` is expected. Greater than ``0`` indicates
        an error.

    Notes
    -----
    This function implements similar internals to Sphinx's own ``sphinx-build``
    command. Most configurations are hard-coded to defaults appropriate for
    building stack documentation, but flexibility can be added later as
    needs are identified.
    """
    logger = logging.getLogger(__name__)

    # This replicates what Sphinx's internal command line hander does
    # https://github.com/sphinx-doc/sphinx/blob/master/sphinx/cmdline.py

    # configuration
    root_dir = os.path.abspath(root_dir)
    srcdir = root_dir  # root directory of Sphinx content
    confdir = root_dir  # directory where conf.py is located
    outdir = os.path.join(root_dir, '_build', 'html')
    doctreedir = os.path.join(root_dir, '_build', 'doctree')
    builder = 'html'
    confoverrides = {}
    status = sys.stdout  # set to None for 'quiet' mode
    warning = sys.stderr
    error = sys.stderr
    freshenv = False  # attempt to re-use existing build artificats
    warningiserror = False
    tags = []
    verbosity = 0
    jobs = 1  # number of processes
    force_all = True
    filenames = []

    logger.debug('Sphinx config: srcdir={0}'.format(srcdir))
    logger.debug('Sphinx config: confdir={0}'.format(confdir))
    logger.debug('Sphinx config: outdir={0}'.format(outdir))
    logger.debug('Sphinx config: doctreedir={0}'.format(doctreedir))
    logger.debug('Sphinx config: builder={0}'.format(builder))
    logger.debug('Sphinx config: freshenv={0:b}'.format(freshenv))
    logger.debug('Sphinx config: warningiserror={0:b}'.format(warningiserror))
    logger.debug('Sphinx config: verbosity={0:d}'.format(verbosity))
    logger.debug('Sphinx config: jobs={0:d}'.format(jobs))
    logger.debug('Sphinx config: force_all={0:b}'.format(force_all))

    app = None
    try:
        # NOTE: Sphinx 1.6+ also uses a
        # sphinx.util.docutils.patch_docutils() context
        with docutils_namespace():
            app = Sphinx(
                srcdir, confdir, outdir, doctreedir, builder,
                confoverrides, status, warning, freshenv,
                warningiserror, tags, verbosity, jobs)
            app.build(force_all, filenames)
            return app.statuscode
    except (Exception, KeyboardInterrupt) as exc:
        args = MockSphinxNamespace(verbosity=verbosity, traceback=True)
        handle_exception(app, args, exc, error)
        return 1


class MockSphinxNamespace(object):
    """Mock Namespace object to mock the Sphinx command line arguments.

    This class is needed for sphinx.cmd.build.handle_exception.
    """

    def __init__(self, verbosity=0, traceback=True):
        self.verbosity = verbosity
        self.traceback = traceback<commit_msg>Update run_sphinx for Sphinx 1.7<commit_after>"""Run Sphinx directly through its Python API.
"""

__all__ = ('run_sphinx',)

import os
import logging
import sys

from sphinx.application import Sphinx
try:
    from sphinx.cmd.build import handle_exception
except ImportError:
    # Sphinx <1.8
    from sphinx.cmdline import handle_exception
from sphinx.util.docutils import docutils_namespace, patch_docutils


def run_sphinx(root_dir):
    """Run the Sphinx build process.

    Parameters
    ----------
    root_dir : `str`
        Root directory of the Sphinx project and content source. This directory
        conatains both the root ``index.rst`` file and the ``conf.py``
        configuration file.

    Returns
    -------
    status : `int`
        Sphinx status code. ``0`` is expected. Greater than ``0`` indicates
        an error.

    Notes
    -----
    This function implements similar internals to Sphinx's own ``sphinx-build``
    command. Most configurations are hard-coded to defaults appropriate for
    building stack documentation, but flexibility can be added later as
    needs are identified.
    """
    logger = logging.getLogger(__name__)

    # This replicates what Sphinx's internal command line hander does in
    # https://github.com/sphinx-doc/sphinx/blob/master/sphinx/cmd/build.py
    # build_main()

    # configuration
    root_dir = os.path.abspath(root_dir)
    srcdir = root_dir  # root directory of Sphinx content
    confdir = root_dir  # directory where conf.py is located
    outdir = os.path.join(root_dir, '_build', 'html')
    doctreedir = os.path.join(root_dir, '_build', 'doctree')
    builder = 'html'
    confoverrides = {}
    status = sys.stdout  # set to None for 'quiet' mode
    warning = sys.stderr
    error = sys.stderr
    freshenv = False  # attempt to re-use existing build artificats
    warningiserror = False
    tags = []
    verbosity = 0
    jobs = 1  # number of processes
    force_all = True
    filenames = []

    logger.debug('Sphinx config: srcdir={0}'.format(srcdir))
    logger.debug('Sphinx config: confdir={0}'.format(confdir))
    logger.debug('Sphinx config: outdir={0}'.format(outdir))
    logger.debug('Sphinx config: doctreedir={0}'.format(doctreedir))
    logger.debug('Sphinx config: builder={0}'.format(builder))
    logger.debug('Sphinx config: freshenv={0:b}'.format(freshenv))
    logger.debug('Sphinx config: warningiserror={0:b}'.format(warningiserror))
    logger.debug('Sphinx config: verbosity={0:d}'.format(verbosity))
    logger.debug('Sphinx config: jobs={0:d}'.format(jobs))
    logger.debug('Sphinx config: force_all={0:b}'.format(force_all))

    app = None
    try:
        with patch_docutils(), docutils_namespace():
            app = Sphinx(
                srcdir, confdir, outdir, doctreedir, builder,
                confoverrides, status, warning, freshenv,
                warningiserror, tags, verbosity, jobs)
            app.build(force_all, filenames)
            return app.statuscode
    except (Exception, KeyboardInterrupt) as exc:
        args = MockSphinxNamespace(verbosity=verbosity, traceback=True)
        handle_exception(app, args, exc, error)
        return 1


class MockSphinxNamespace:
    """Mock Namespace object to mock the Sphinx command line arguments.

    This class is needed for sphinx.cmd.build.handle_exception.
    """

    def __init__(self, verbosity=0, traceback=True):
        self.verbosity = verbosity
        self.traceback = traceback
{'fraction_non_alphanumeric': 0.10793423874195854, 'fraction_numerical': 0.005718370264474625, 'mean_word_length': 3.0912280701754384, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3486900', 'n_tokens_mistral': 2185, 'n_tokens_neox': 2123, 'n_words': 579}