Sebastian Wiesner avatar Sebastian Wiesner committed 248ac81

Move programoutput extension over to Github

https://github.com/lunaryorn/sphinxcontrib-programoutput

Comments (0)

Files changed (19)

 ansi:
    Sebastian Wiesner <lunaryorn@googlemail.com>
 
-programoutput:
-   Sebastian Wiesner <lunaryorn@googlemail.com>
-
 cheeseshop:
    Richard Jones <r1chardj0n3s@gmail.com>
    Georg Brandl <georg@python.org>
 - osaka: convert standard Japanese doc to Osaka dialect (it is joke extension)
 - paverutils: an alternate integration of Sphinx with Paver_.
 - plantuml: embed UML diagram by using PlantUML_
-- programoutput: include output of programs into documentation
 - requirements: declare requirements wherever you need (e.g. in test
   docstrings), mark statuses and collect them in a single list
 - rubydomain: an extension for Ruby support (Sphinx 1.0 needed)

programoutput/CHANGES.rst

-0.8 (in development)
-====================
-
-
-0.7 (Apr 17, 2012)
-==================
-
-- #28: Added ``cwd`` option to :rst:dir:`program-output`
-- #28: Working directory of executed programs defaults to documentation root
-  now
-
-
-0.6 (Jan 07, 2012)
-==================
-
-- Python 3 support
-- Require Sphinx 1.1 now
-
-
-0.5 (Sep 19, 2011)
-==================
-
-- :confval:`programoutput_prompt_template` is interpreted as format string now!
-- Require Python 2.6 now
-- Added ``returncode`` option to :rst:dir:`program-output` (thanks to Jan-Marek
-  Glogowski)
-- Support ``returncode`` formatting key in
-  :confval:`programoutput_prompt_template`
-- Warn on unexpected return codes instead of raising
-  :exc:`~subprocess.CalledProcessError`
-- Turn fatal errors during command into document error messages instead of
-  crashing the build
-
-
-0.4.1 (Mar 11, 2011)
-====================
-
-- Some source code cleanups
-- #10: Fixed installation instructions in documentation
-
-
-0.4 (May 21, 2010)
-==================
-
-- Initial release

programoutput/MANIFEST.in

-include README
-include LICENSE
-include CHANGES.*
-include tox.ini
-recursive-include doc *.rst *.py
-recursive-include tests *.py *.txt

programoutput/README

-###########################
-sphinxcontrib-programoutput
-###########################
-
-http://packages.python.org/sphinxcontrib-programoutput
-
-Sphinx 1.1 extension to insert the output of arbitrary commands into documents.
-
-The extension is available under the terms of the BSD license, see LICENSE_ for
-details.
-
-
-Installation
-------------
-
-This extension requires Sphinx_ 1.1 and at least Python 2.6 or Python 3.2.  It
-is available in the Python Package Index::
-
-   pip install sphinxcontrib-programoutput
-
-Alternatively, you can clone the sphinx-contrib_ repository from BitBucket,
-and install the extension directly from the repository::
-
-   hg clone https://bitbucket.org/birkenfeld/sphinx-contrib
-   cd sphinx-contrib/programoutput
-   python setup.py install
-
-
-Usage
------
-
-Please refer to the documentation_ for further information.
-
-
-.. _`Sphinx`: http://sphinx.pocoo.org/latest
-.. _`sphinx-contrib`: https://bitbucket.org/birkenfeld/sphinx-contrib
-.. _documentation: http://packages.python.org/sphinxcontrib-programoutput
-.. _LICENSE: https://bitbucket.org/birkenfeld/sphinx-contrib/src/tip/LICENSE

programoutput/doc/changes.rst

-#########
-Changelog
-#########
-
-.. include:: ../CHANGES.rst

programoutput/doc/conf.py

-# -*- coding: utf-8 -*-
-# Copyright (c) 2011, Sebastian Wiesner <lunaryorn@googlemail.com>
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-
-# 1. Redistributions of source code must retain the above copyright notice,
-#    this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-import os
-import sys
-
-doc_directory = os.path.dirname(os.path.abspath(__file__))
-sys.path.append(os.path.normpath(
-    os.path.join(doc_directory, os.pardir, 'sphinxcontrib')))
-
-import programoutput
-
-needs_sphinx = '1.0'
-
-extensions = ['sphinx.ext.intersphinx', 'sphinxcontrib.programoutput']
-
-source_suffix = '.rst'
-master_doc = 'index'
-
-project = u'sphinxcontrib-programoutput'
-copyright = u'2010, 2011, Sebastian Wiesner'
-version = '.'.join(programoutput.__version__.split('.')[:2])
-release = programoutput.__version__
-
-exclude_patterns = ['_build/*']
-
-html_theme = 'default'
-html_static_path = []
-
-intersphinx_mapping = {
-    'python': ('http://docs.python.org', None),
-    'ansi': ('http://packages.python.org/sphinxcontrib-ansi', None)}
-
-
-def setup(app):
-    app.add_description_unit('confval', 'confval',
-                             'pair: %s; configuration value')

programoutput/doc/index.rst

-.. default-domain:: rst
-.. highlight:: rest
-
-:py:mod:`sphinxcontrib.programoutput` – Insert command output
-=============================================================
-
-.. py:module:: sphinxcontrib.programoutput
-   :synopsis:  Include the output of programs into documents
-
-Sphinx_ extension to insert the output of arbitrary commands into documents.
-
-The extension is available under the terms of the BSD license, see LICENSE_
-for more information.
-
-
-Installation
-------------
-
-This extension requires Sphinx_ 1.1 and at least Python 2.6 or Python 3.2.  It
-is available in the Python Package Index::
-
-   pip install sphinxcontrib-programoutput
-
-Alternatively, you can clone the sphinx-contrib_ repository from BitBucket,
-and install the extension directly from the repository::
-
-   hg clone https://bitbucket.org/birkenfeld/sphinx-contrib
-   cd sphinx-contrib/programoutput
-   python setup.py install
-
-
-Usage
------
-
-To include the output of a command into your document, use the
-:dir:`program-output` directive provided by this extension::
-
-   .. program-output:: python -V
-
-The whole output of ``python -V``, including any messages on standard error, is
-inserted into the current document, formatted as literal text without any
-syntax highlighting:
-
-.. program-output:: python -V
-
-You can omit the content of the standard error stream with the ``nostderr``
-option.
-
-By default, commands are executed in the top-level source directory.  You can
-choose an alternate working directory with the ``cwd`` option.  The argument of
-this option is either a path relative to the current source file, or a absolute
-path which means that it is relative to the top level source directory.
-
-
-Shortening the output
-^^^^^^^^^^^^^^^^^^^^^
-
-Lengthy output can be shortened with the ``ellipsis`` option.  Its value
-denotes lines to omit when inserting the output of the command.  Instead, a
-single ellipsis ``...`` is inserted.
-
-If used with a single number, all lines after the specified line are omitted::
-
-   .. program-output:: python --help
-      :ellipsis: 2
-
-The above omits all lines after the second one:
-
-.. program-output:: python --help
-   :ellipsis: 2
-
-Negative numbers count from the last line backwards, thus replacing ``2`` with
-``-2`` in the above example would only omit the last two lines.
-
-If used with two comma-separated line numbers, all lines in between the
-specified lines are omitted.  Again, a negative number counts from the last
-line backwards::
-
-   .. program-output:: python --help
-      :ellipsis: 2,-2
-
-The above omits all lines except the first two and the last two lines:
-
-.. program-output:: python --help
-   :ellipsis: 2,-2
-
-
-Mimicing shell input
-^^^^^^^^^^^^^^^^^^^^
-
-You can mimic shell input with the :dir:`command-output` directive [#alias]_.
-This directive inserts the command along with its output into the document::
-
-   .. command-output:: python -V
-
-.. command-output:: python -V
-
-The appearance of this output can be configured with
-:confval:`programoutput_prompt_template`.  When used in conjunction with
-``ellipsis``, the command itself and any additional text is *never* omitted.
-``ellipsis`` always refers to the *immediate output* of the command::
-
-   .. command-output:: python --help
-      :ellipsis: 2
-
-.. command-output:: python --help
-   :ellipsis: 2
-
-
-Command execution and shell expansion
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Normally the command is splitted according to the POSIX shell syntax (see
-:py:mod:`shlex`), and executed directly.  Thus special shell features like
-expansion of environment variables will not work::
-
-   .. command-output:: echo "$USER"
-
-.. command-output:: echo "$USER"
-
-To enable these features, enable the ``shell`` option.  With this option, the
-command is literally passed to the system shell::
-
-   .. command-output:: echo "$USER"
-      :shell:
-
-.. command-output:: echo "$USER"
-   :shell:
-
-Other shell features like process expansion consequently work, too::
-
-   .. command-output:: ls -l $(which grep)
-      :shell:
-
-.. command-output:: ls -l $(which grep)
-   :shell:
-
-Remember to use ``shell`` carefully to avoid unintented interpretation of shell
-syntax and swallowing of fatal errors!
-
-
-Error handling
-^^^^^^^^^^^^^^
-
-If an unexpected exit code (also known as *return code*) is returned by a
-command, it is considered to have failed.  In this case, a build warning is
-emitted to help you to detect misspelled commands or similar errors.  By
-default, a command is expected to exit with an exit code of 0, all other codes
-indicate an error.  In some cases however, it may be reasonable to demonstrate
-failed programs.  To avoid a (superfluous) warning in such a case, you can
-specify the expected return code of a command with the ``returncode`` option::
-
-   .. command-output:: python -c 'import sys; sys.exit(1)'
-      :returncode: 1
-
-The above command returns the exit code 1 (as given to :py:func:`sys.exit()`),
-but no warning will be emitted.  On the contrary, a warning will be emitted,
-should the command return 0!
-
-.. note::
-
-   Upon fatal errors which even prevent the execution of the command neither
-   return code nor command output are available.  In this case an error message
-   is inserted into the document instead.
-
-   If ``shell`` is set however, most of these fatal errors are handled by the
-   system shell and turned into return codes instead.  In this case the error
-   message will only appear in the output of the shell.  If you're using
-   ``shell``, double-check the output for errors.  Best avoid ``shell``, if possible.
-
-
-Reference
----------
-
-.. directive:: .. program-output:: command
-
-   Include the output of ``command`` in the documentation.
-
-   The output is formatted as literal text, without any syntax highlighting.
-
-   By default, the command is split according to the POSIX shell syntax (using
-   :py:func:`shlex.split()`), and executed directly.  Both standard output and
-   standard error are captured from the invocation of ``command`` and included
-   in the document.  However, if the option ``shell`` is given, ``command`` is
-   literally passed to the system shell.  With the ``nostderr`` option,
-   standard error is hidden from the output.
-
-   The working directory of the command can be configured with the ``cwd``
-   option.  The argument of this option is a directory path, relative to the
-   current source file.  Absolute paths are interpreted as relative to the
-   root of the source directory.  The default working directory is ``/``, i.e.
-   the root of the source directory.
-
-   If the ``prompt`` option is given, the ``command`` itself is included in the
-   document, so that the output mimics input in a shell prompt.
-   :confval:`programoutput_prompt_template` controlls the appearance of this.
-   The value of the ``extraargs`` option is appended at the end of ``command``
-   (separated by a whitespace) before executing the command, but not included
-   in the output of the ``prompt`` option.  Use this to pass extra arguments
-   which should not appear in the document.
-
-   The output can be shortened with the ``ellipsis`` option.  The value of this
-   option is of the form ``start[,end]`` with ``start`` and ``end`` being
-   integers which refer to lines in the output of ``command``.  ``end`` is
-   optional and defaults to the last line.  Negative line numbers count
-   backwards from the last line.  Everything in the interval ``[start, end[``
-   is replaced with a single ellipsis ``...``.  The ``ellipsis`` option only
-   affects the immediate output of ``command``, but never any additional text
-   inserted by option ``prompt``.
-
-   If the command does return an exit code different from the expected one, a
-   build warning is issued.  The expected return code defaults to 0, and can be
-   changed with the ``returncode`` option.
-
-.. directive:: command-output
-
-   Same as :dir:`program-output`, but with enabled ``prompt`` option.
-
-
-Configuration
-^^^^^^^^^^^^^
-
-This extension understands the following configuration options:
-
-.. confval:: programoutput_prompt_template
-
-   A `format string`_ template for the output of the ``prompt`` option to
-   :dir:`command-output`.  Defaults to ``$ {command}\n{output}`` which renders
-   as follows:
-
-   .. command-output:: python -V
-
-   The following keys are provided to the format string:
-
-   * ``command`` is replaced with the literal command as given to the
-     directive, *without* any ``extraargs``.
-   * ``output`` is the output of the command, after the ``ellipsis`` option has
-     been applied.
-   * ``returncode`` is the return code of the command as integer.
-
-.. confval:: programoutput_use_ansi
-
-   If ``True``, ANSI colour sequences in program output are interpreted.  To
-   use this feature, the extension :py:mod:`sphinxcontrib.ansi` must be enabled
-   and configured.  If missing or ``False``, these sequences are not
-   interpreted, but appear in documentation unchanged.
-
-
-Contribution
-------------
-
-Please contact the author or create an issue in the `issue tracker`_ of the
-sphinx-contrib_ repository, if you have found any bugs or miss some
-functionality (e.g. integration of some other issue tracker).  Patches are
-welcome!
-
-.. rubric:: Footnotes
-
-.. [#alias] This directive is just an alias for the :dir:`program-output`
-            directive with the ``prompt`` option set.
-
-.. toctree::
-   :maxdepth: 2
-   :hidden:
-
-   changes.rst
-
-
-.. _Sphinx: http://sphinx.pocoo.org/
-.. _sphinx-contrib: https://bitbucket.org/birkenfeld/sphinx-contrib
-.. _issue tracker: https://bitbucket.org/birkenfeld/sphinx-contrib/issues
-.. _LICENSE: https://bitbucket.org/birkenfeld/sphinx-contrib/src/tip/LICENSE
-.. _format string: http://docs.python.org/library/string.html#formatstrings

programoutput/setup.cfg

-[egg_info]
-tag_build = dev
-tag_date = true
-
-[aliases]
-release = egg_info -RDb ''
-
-[upload_docs]
-upload_dir = build/sphinx/html

programoutput/setup.py

-# -*- coding: utf-8 -*-
-# Copyright (c) 2011, 2012, Sebastian Wiesner <lunaryorn@googlemail.com>
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-
-# 1. Redistributions of source code must retain the above copyright notice,
-#    this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-import os
-import re
-
-from setuptools import setup, find_packages
-
-
-with open('README') as stream:
-    long_desc = stream.read()
-
-
-VERSION_PATTERN = re.compile(r"__version__ = '([^']+)'")
-
-
-def read_version_number():
-    with open(os.path.join('sphinxcontrib', 'programoutput.py')) as stream:
-        for line in stream:
-            match = VERSION_PATTERN.search(line)
-            if match:
-                return match.group(1)
-        else:
-            raise ValueError('Could not extract version number')
-
-
-setup(
-    name='sphinxcontrib-programoutput',
-    version=read_version_number(),
-    url='http://packages.python.org/sphinxcontrib-programoutput',
-    download_url='http://pypi.python.org/pypi/sphinxcontrib-programoutput',
-    license='BSD',
-    author='Sebastian Wiesner',
-    author_email='lunaryorn@googlemail.com',
-    description='Sphinx extension to include program output',
-    long_description=long_desc,
-    zip_safe=False,
-    classifiers=[
-        'Development Status :: 5 - Production/Stable',
-        'Intended Audience :: Developers',
-        'License :: OSI Approved :: BSD License',
-        'Operating System :: OS Independent',
-        'Programming Language :: Python',
-        'Programming Language :: Python :: 2',
-        'Programming Language :: Python :: 3',
-        'Topic :: Documentation',
-        'Topic :: Utilities',
-    ],
-    platforms='any',
-    packages=find_packages(),
-    include_package_data=True,
-    install_requires=['Sphinx>=1.1'],
-    namespace_packages=['sphinxcontrib'],
-)

programoutput/sphinxcontrib/__init__.py

-# -*- coding: utf-8 -*-
-"""
-    sphinxcontrib
-    ~~~~~~~~~~~~~
-
-    This package is a namespace package that contains all extensions
-    distributed in the ``sphinx-contrib`` distribution.
-
-    :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
-    :license: BSD, see LICENSE for details.
-"""
-
-__import__('pkg_resources').declare_namespace(__name__)
-

programoutput/sphinxcontrib/programoutput.py

-# -*- coding: utf-8 -*-
-# Copyright (c) 2010, 2011, 2012, Sebastian Wiesner <lunaryorn@googlemail.com>
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-
-# 1. Redistributions of source code must retain the above copyright notice,
-#    this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-"""
-    sphinxcontrib.programoutput
-    ===========================
-
-    This extension provides a directive to include the output of commands as
-    literal block while building the docs.
-
-    .. moduleauthor::  Sebastian Wiesner  <lunaryorn@googlemail.com>
-"""
-
-from __future__ import (print_function, division, unicode_literals,
-                        absolute_import)
-
-import sys
-import os
-import shlex
-from subprocess import Popen, PIPE, STDOUT
-from collections import defaultdict, namedtuple
-
-from docutils import nodes
-from docutils.parsers import rst
-from docutils.parsers.rst.directives import flag, unchanged, nonnegative_int
-
-
-__version__ = '0.8'
-
-
-class program_output(nodes.Element):
-    pass
-
-
-def _slice(value):
-    parts = [int(v.strip()) for v in value.split(',')]
-    if len(parts) > 2:
-        raise ValueError('too many slice parts')
-    return tuple((parts + [None] * 2)[:2])
-
-
-class ProgramOutputDirective(rst.Directive):
-    has_content = False
-    final_argument_whitespace = True
-    required_arguments = 1
-
-    option_spec = dict(shell=flag, prompt=flag, nostderr=flag,
-                       ellipsis=_slice, extraargs=unchanged,
-                       returncode=nonnegative_int, cwd=unchanged)
-
-    def run(self):
-        env = self.state.document.settings.env
-
-        node = program_output()
-        node.line = self.lineno
-        node['command'] = self.arguments[0]
-
-        if self.name == 'command-output':
-            node['show_prompt'] = True
-        else:
-            node['show_prompt'] = 'prompt' in self.options
-
-        node['hide_standard_error'] = 'nostderr' in self.options
-        node['extraargs'] = self.options.get('extraargs', '')
-        _, cwd = env.relfn2path(self.options.get('cwd', '/'))
-        node['working_directory'] = cwd
-        node['use_shell'] = 'shell' in self.options
-        node['returncode'] = self.options.get('returncode', 0)
-        if 'ellipsis' in self.options:
-            node['strip_lines'] = self.options['ellipsis']
-        return [node]
-
-
-_Command = namedtuple(
-    'Command', 'command shell hide_standard_error working_directory')
-
-
-class Command(_Command):
-    """
-    A command to be executed.
-    """
-
-    def __new__(cls, command, shell=False, hide_standard_error=False,
-                working_directory='/'):
-        if isinstance(command, list):
-            command = tuple(command)
-        # `chdir()` resolves symlinks, so we need to resolve them too for
-        # caching to make sure that different symlinks to the same directory
-        # don't result in different cache keys.  Also normalize paths to make
-        # sure that identical paths are also equal as strings.
-        working_directory = os.path.normpath(os.path.realpath(
-            working_directory))
-        return _Command.__new__(cls, command, shell, hide_standard_error,
-                                working_directory)
-
-    @classmethod
-    def from_program_output_node(cls, node):
-        """
-        Create a command from a :class:`program_output` node.
-        """
-        extraargs = node.get('extraargs', '')
-        command = (node['command'] + ' ' + extraargs).strip()
-        return cls(command, node['use_shell'],
-                   node['hide_standard_error'], node['working_directory'])
-
-    def execute(self):
-        """
-        Execute this command.
-
-        Return the :class:`~subprocess.Popen` object representing the running
-        command.
-        """
-        if self.shell:
-            if sys.version_info[0] < 3 and isinstance(self.command, unicode):
-                command = self.command.encode(sys.getfilesystemencoding())
-            else:
-                command = self.command
-        else:
-            if sys.version_info[0] < 3 and isinstance(self.command, unicode):
-                command = shlex.split(self.command.encode(
-                    sys.getfilesystemencoding()))
-            elif isinstance(self.command, str):
-                command = shlex.split(self.command)
-            else:
-                command = self.command
-        return Popen(command, shell=self.shell, stdout=PIPE,
-                     stderr=PIPE if self.hide_standard_error else STDOUT,
-                     cwd=self.working_directory)
-
-    def get_output(self):
-        """
-        Get the output of this command.
-
-        Return a tuple ``(returncode, output)``.  ``returncode`` is the
-        integral return code of the process, ``output`` is the output as
-        unicode string, with final trailing spaces and new lines stripped.
-        """
-        process = self.execute()
-        output = process.communicate()[0].decode(
-            sys.getfilesystemencoding()).rstrip()
-        return process.returncode, output
-
-    def __str__(self):
-        if isinstance(self.command, tuple):
-            return repr(list(self.command))
-        return repr(self.command)
-
-
-class ProgramOutputCache(defaultdict):
-    """
-    Execute command and cache their output.
-
-    This class is a mapping.  Its keys are :class:`Command` objects represeting
-    command invocations.  Its values are tuples of the form ``(returncode,
-    output)``, where ``returncode`` is the integral return code of the command,
-    and ``output`` is the output as unicode string.
-
-    The first time, a key is retrieved from this object, the command is
-    invoked, and its result is cached.  Subsequent access to the same key
-    returns the cached value.
-    """
-
-    def __missing__(self, command):
-        """
-        Called, if a command was not found in the cache.
-
-        ``command`` is an instance of :class:`Command`.
-        """
-        result = command.get_output()
-        self[command] = result
-        return result
-
-
-def run_programs(app, doctree):
-    """
-    Execute all programs represented by ``program_output`` nodes in
-    ``doctree``.  Each ``program_output`` node in ``doctree`` is then
-    replaced with a node, that represents the output of this program.
-
-    The program output is retrieved from the cache in
-    ``app.env.programoutput_cache``.
-    """
-    if app.config.programoutput_use_ansi:
-        # enable ANSI support, if requested by config
-        from sphinxcontrib.ansi import ansi_literal_block
-        node_class = ansi_literal_block
-    else:
-        node_class = nodes.literal_block
-
-    cache = app.env.programoutput_cache
-
-    for node in doctree.traverse(program_output):
-        command = Command.from_program_output_node(node)
-        try:
-            returncode, output = cache[command]
-        except EnvironmentError as error:
-            error_message = 'Command {0} failed: {1}'.format(command, error)
-            error_node = doctree.reporter.error(error_message, base_node=node)
-            node.replace_self(error_node)
-        else:
-            if returncode != node['returncode']:
-                app.warn('Unexpected return code {0} from command {1}'.format(
-                    returncode, command))
-
-            # replace lines with ..., if ellipsis is specified
-            if 'strip_lines' in node:
-                lines = output.splitlines()
-                start, stop = node['strip_lines']
-                lines[start:stop] = ['...']
-                output = '\n'.join(lines)
-
-            if node['show_prompt']:
-                tmpl = app.config.programoutput_prompt_template
-                output = tmpl.format(command=node['command'], output=output,
-                                     returncode=returncode)
-
-            new_node = node_class(output, output)
-            new_node['language'] = 'text'
-            node.replace_self(new_node)
-
-
-def init_cache(app):
-    """
-    Initialize the cache for program output at
-    ``app.env.programoutput_cache``, if not already present (e.g. being
-    loaded from a pickled environment).
-
-    The cache is of type :class:`ProgramOutputCache`.
-    """
-    if not hasattr(app.env, 'programoutput_cache'):
-        app.env.programoutput_cache = ProgramOutputCache()
-
-
-def setup(app):
-    app.add_config_value('programoutput_use_ansi', False, 'env')
-    app.add_config_value('programoutput_prompt_template',
-                         '$ {command}\n{output}', 'env')
-    app.add_directive('program-output', ProgramOutputDirective)
-    app.add_directive('command-output', ProgramOutputDirective)
-    app.connect(str('builder-inited'), init_cache)
-    app.connect(str('doctree-read'), run_programs)

programoutput/tests/conftest.py

-# Copyright (c) 2011, Sebastian Wiesner <lunaryorn@googlemail.com>
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-
-# 1. Redistributions of source code must retain the above copyright notice,
-#    this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-from __future__ import (print_function, division, unicode_literals,
-                        absolute_import)
-
-import pytest
-from sphinx.application import Sphinx
-
-
-#: conf.py for tests
-CONF_PY = """\
-extensions = ['sphinxcontrib.programoutput']
-
-source_suffix = '.rst'
-
-master_doc = 'index'
-
-project = u'epydoc-test'
-copyright = u'2011, foo'
-
-version = '1'
-release = '1'
-
-exclude_patterns = []
-
-pygments_style = 'sphinx'
-html_theme = 'default'
-"""
-
-
-def pytest_funcarg__content(request):
-    """
-    Return the content for the current test, extracted from ``with_content``
-    marker.
-    """
-    # prepend a title to the content to avoid a Sphinx warning emitted for
-    # toctree-referenced documents without titles
-    content = """\
-Content
-#######
-
-{0}""".format(request.keywords['with_content'].args[0])
-    return content
-
-
-def pytest_funcarg__srcdir(request):
-    """
-    Generated source directory for test Sphinx application.
-    """
-    tmpdir = request.getfuncargvalue('tmpdir')
-    srcdir = tmpdir.join('src')
-    srcdir.ensure(dir=True)
-    confpy = srcdir.join('conf.py')
-    confpy.write(CONF_PY)
-    index_document = srcdir.join('index.rst')
-    index_document.write("""\
-.. toctree::
-
-   content/doc""")
-    content_directory = srcdir.join('content')
-    content_directory.ensure(dir=True)
-    content_document = content_directory.join('doc.rst')
-    content_document.write(request.getfuncargvalue('content'))
-    return srcdir
-
-
-def pytest_funcarg__outdir(request):
-    """
-    Output directory for current test.
-    """
-    tmpdir = request.getfuncargvalue('tmpdir')
-    return tmpdir.join('html')
-
-
-def pytest_funcarg__doctreedir(request):
-    """
-    The doctree directory for the current.
-    """
-    tmpdir = request.getfuncargvalue('tmpdir')
-    return tmpdir.join('doctrees')
-
-
-def pytest_funcarg__confoverrides(request):
-    """
-    Confoverrides for the current test as dict, extracted from the keyword
-    arguments to the ``confoverrides`` marker.
-    """
-    confoverrides_marker = request.keywords.get('confoverrides')
-    if confoverrides_marker:
-        return confoverrides_marker.kwargs
-    else:
-        return {}
-
-
-def pytest_funcarg__app(request):
-    """
-    Sphinx application for the current test.
-    """
-    srcdir = request.getfuncargvalue('srcdir')
-    outdir = request.getfuncargvalue('outdir')
-    doctreedir = request.getfuncargvalue('doctreedir')
-    confoverrides = request.getfuncargvalue('confoverrides')
-    warningiserror = 'ignore_warnings' not in request.keywords
-    app = Sphinx(str(srcdir), str(srcdir), str(outdir), str(doctreedir), 'html',
-                 status=None, warning=None, freshenv=None,
-                 warningiserror=warningiserror, confoverrides=confoverrides)
-    if 'build_app' in request.keywords:
-        app.build()
-    return app
-
-
-def pytest_funcarg__doctree(request):
-    request.applymarker(pytest.mark.build_app)
-    app = request.getfuncargvalue('app')
-    return app.env.get_doctree('content/doc')
-
-
-def pytest_funcarg__cache(request):
-    request.applymarker(pytest.mark.build_app)
-    app = request.getfuncargvalue('app')
-    return app.env.programoutput_cache

programoutput/tests/test_cache.py

-# -*- coding: utf-8 -*-
-# Copyright (c) 2011, 2012, Sebastian Wiesner <lunaryorn@googlemail.com>
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-
-# 1. Redistributions of source code must retain the above copyright notice,
-#    this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-from __future__ import (print_function, division, unicode_literals,
-                        absolute_import)
-
-import os
-
-import pytest
-
-from sphinxcontrib.programoutput import ProgramOutputCache, Command
-
-
-def pytest_funcarg__cache(request):
-    return ProgramOutputCache()
-
-
-def assert_cache(cache, cmd, output, returncode=0):
-    result = (returncode, output)
-    assert not cache
-    assert cache[cmd] == result
-    assert cache == {cmd: result}
-
-
-def test_simple(cache):
-    assert_cache(cache, Command(['echo', 'blök']), 'blök')
-
-
-def test_shell(cache):
-    assert_cache(cache, Command('echo blök', shell=True), 'blök')
-
-
-def test_working_directory(cache, tmpdir):
-    cwd = tmpdir.join('wd')
-    cwd.ensure(dir=True)
-    cwd = os.path.realpath(os.path.normpath(str(cwd)))
-    cmd = ['python', '-c', 'import sys, os; sys.stdout.write(os.getcwd())']
-    assert_cache(cache, Command(cmd, working_directory=cwd), cwd)
-
-
-def test_working_directory_shell(cache, tmpdir):
-    cwd = tmpdir.join('wd')
-    cwd.ensure(dir=True)
-    cwd = os.path.realpath(os.path.normpath(str(cwd)))
-    cmd = Command('echo $PWD', working_directory=cwd, shell=True)
-    assert_cache(cache, cmd, cwd)
-
-
-def test_hidden_standard_error(cache):
-    cmd = ['python', '-c', 'import sys; sys.stderr.write("spam")']
-    assert_cache(cache, Command(cmd, hide_standard_error=True), '')
-
-
-def test_nonzero_return_code(cache):
-    cmd = ['python', '-c', 'import sys; sys.exit(1)']
-    assert_cache(cache, Command(cmd), '', returncode=1)
-
-
-def test_nonzero_return_code_shell(cache):
-    cmd = "python -c 'import sys; sys.exit(1)'"
-    assert_cache(cache, Command(cmd, shell=True), '', returncode=1)
-
-
-@pytest.mark.with_content('dummy content')
-def test_cache_pickled(app, doctreedir):
-    cmd = Command(['echo', 'spam'])
-    result = (0, 'spam')
-    assert app.env.programoutput_cache[cmd] == result
-    app.build()
-    pickled_env = doctreedir.join('environment.pickle').load()
-    assert pickled_env.programoutput_cache == {cmd: result}

programoutput/tests/test_command.py

-# -*- coding: utf-8 -*-
-# Copyright (c) 2011, Sebastian Wiesner <lunaryorn@googlemail.com>
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-
-# 1. Redistributions of source code must retain the above copyright notice,
-#    this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-from __future__ import (print_function, division, unicode_literals,
-                        absolute_import)
-
-import os.path
-
-from sphinxcontrib.programoutput import Command, program_output
-
-
-def test_new_with_string_command():
-    cmd = 'echo "spam with eggs"'
-    assert Command(cmd).command == cmd
-    assert Command(cmd, shell=True).command == cmd
-
-
-def test_new_with_list():
-    cmd = Command(['echo', 'spam'])
-    assert cmd.command == ('echo', 'spam')
-
-
-def test_new_with_list_hashable():
-    """
-    Test that Command objects are hashable even when passed a non-hashable
-    list.  Important for caching!
-    """
-    hash(Command(['echo', 'spam']))
-
-
-def test_from_programoutput_node():
-    node = program_output()
-    node['command'] = 'echo spam'
-    node['use_shell'] = False
-    node['hide_standard_error'] = False
-    node['working_directory'] = '/spam/with/eggs'
-    command = Command.from_program_output_node(node)
-    assert command.command == 'echo spam'
-    assert command.working_directory == '/spam/with/eggs'
-    assert not command.shell
-    assert not command.hide_standard_error
-    node['use_shell'] = True
-    assert Command.from_program_output_node(node).shell
-    assert not Command.from_program_output_node(node).hide_standard_error
-    node['hide_standard_error'] = True
-    assert Command.from_program_output_node(node).hide_standard_error
-
-
-def test_from_programoutput_node_extraargs():
-    node = program_output()
-    node['command'] = 'echo spam'
-    node['use_shell'] = False
-    node['hide_standard_error'] = False
-    node['extraargs'] = 'with eggs'
-    node['working_directory'] = '/'
-    command = Command.from_program_output_node(node)
-    assert command.command == 'echo spam with eggs'
-
-
-def test_execute():
-    process = Command('echo spam').execute()
-    assert process.stderr is None
-    assert not process.stdout.closed
-    assert process.wait() == 0
-
-
-def test_execute_with_shell():
-    process = Command('echo spam', shell=True).execute()
-    assert process.stderr is None
-    assert not process.stdout.closed
-    assert process.wait() == 0
-
-
-def test_execute_with_hidden_standard_error():
-    process = Command('echo spam', hide_standard_error=True).execute()
-    assert not process.stderr.closed
-    assert process.wait() == 0
-
-
-def test_get_output():
-    returncode, output = Command('echo spam').get_output()
-    assert returncode == 0
-    assert output == 'spam'
-
-
-def test_get_output_non_zero():
-    returncode, output = Command(
-        'python -c "import sys; print(\'spam\'); sys.exit(1)"').get_output()
-    assert returncode == 1
-    assert output == 'spam'
-
-
-def test_get_output_with_hidden_standard_error():
-    returncode, output = Command(
-        'python -c "import sys; sys.stderr.write(\'spam\')"',
-        hide_standard_error=True).get_output()
-    assert returncode == 0
-    assert output == ''
-
-
-def test_get_output_with_working_directory(tmpdir):
-    cwd = os.path.realpath(str(tmpdir))
-    returncode, output = Command(
-        'python -c "import sys, os; sys.stdout.write(os.getcwd())"',
-        working_directory=cwd).get_output()
-    assert returncode == 0
-    assert output == cwd

programoutput/tests/test_directive.py

-# -*- coding: utf-8 -*-
-# Copyright (c) 2011, 2012, Sebastian Wiesner <lunaryorn@googlemail.com>
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-
-# 1. Redistributions of source code must retain the above copyright notice,
-#    this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-from __future__ import (print_function, division, unicode_literals,
-                        absolute_import)
-
-import os
-import sys
-
-import pytest
-from sphinx.errors import SphinxWarning
-from docutils.nodes import literal_block, system_message
-
-from sphinxcontrib.programoutput import Command
-
-
-def assert_output(doctree, output):
-    __tracebackhide__ = True
-    literal = doctree.next_node(literal_block)
-    assert literal
-    assert literal.astext() == output
-
-
-def assert_cache(app, cmd, output, use_shell=False,
-                 hide_standard_error=False, returncode=0,
-                 working_directory=None):
-    cache = app.env.programoutput_cache
-    working_directory = working_directory or app.srcdir
-    working_directory = os.path.normpath(os.path.realpath(
-        working_directory))
-    cache_key = Command(cmd, use_shell, hide_standard_error,
-                        working_directory)
-    assert cache == {cache_key: (returncode, output)}
-
-
-@pytest.mark.with_content('.. program-output:: echo eggs')
-def test_simple(doctree, app):
-    assert_output(doctree, 'eggs')
-    assert_cache(app, 'echo eggs', 'eggs')
-
-
-@pytest.mark.with_content("""\
-.. program-output:: python -c 'print("spam with eggs")'""")
-def test_with_spaces(doctree, app):
-    """
-    Test for command splitting with spaces involved.  Do *not* use ``echo`` for
-    this test, because ``echo`` handles multiple arguments just as well as
-    single arguments.
-    """
-    assert_output(doctree, 'spam with eggs')
-    assert_cache(app, 'python -c \'print("spam with eggs")\'',
-                 'spam with eggs')
-
-
-@pytest.mark.with_content('.. program-output:: python -V')
-def test_standard_error(doctree, app):
-    output = 'Python {0}.{1}.{2}'.format(*sys.version_info)
-    assert_output(doctree, output)
-    assert_cache(app, 'python -V', output)
-
-
-@pytest.mark.with_content("""\
-.. program-output:: python -V
-   :nostderr:""")
-def test_standard_error_disabled(doctree, app):
-    assert_output(doctree, '')
-    assert_cache(app, 'python -V', '', hide_standard_error=True)
-
-
-@pytest.mark.with_content("""\
-.. program-output:: python -c 'import os; print(os.getcwd())'""")
-def test_working_directory_defaults_to_srcdir(doctree, app, srcdir):
-    output = str(srcdir.realpath())
-    assert_output(doctree, output)
-    assert_cache(app, "python -c 'import os; print(os.getcwd())'", output,
-                 working_directory=str(srcdir))
-
-
-@pytest.mark.with_content("""\
-.. program-output:: python -c 'import os; print(os.getcwd())'
-   :cwd: /""")
-def test_working_directory_relative_to_srcdir(doctree, app, srcdir):
-    output = str(srcdir.realpath())
-    assert_output(doctree, output)
-    assert_cache(app, "python -c 'import os; print(os.getcwd())'", output,
-                 working_directory=str(srcdir))
-
-
-@pytest.mark.with_content("""\
-.. program-output:: python -c 'import os; print(os.getcwd())'
-   :cwd: .""")
-def test_working_directory_relative_to_document(doctree, app, srcdir):
-    contentdir = srcdir.join('content')
-    output = str(contentdir.realpath())
-    assert_output(doctree, output)
-    assert_cache(app, "python -c 'import os; print(os.getcwd())'", output,
-                 working_directory=str(contentdir))
-
-
-@pytest.mark.with_content("""\
-.. program-output:: echo "${PWD}"
-   :shell:
-   :cwd: .""")
-def test_working_directory_with_shell(doctree, app, srcdir):
-    contentdir = srcdir.join('content')
-    output = str(contentdir.realpath())
-    assert_output(doctree, output)
-    assert_cache(app, 'echo "${PWD}"', output, use_shell=True,
-                 working_directory=str(contentdir))
-
-
-@pytest.mark.with_content('.. program-output:: echo "${HOME}"')
-def test_no_expansion_without_shell(doctree, app):
-    assert_output(doctree, '${HOME}')
-    assert_cache(app, 'echo "${HOME}"', '${HOME}')
-
-
-@pytest.mark.with_content("""\
-.. program-output:: echo "${HOME}"
-   :shell:""")
-def test_expansion_with_shell(doctree, app):
-    assert_output(doctree, os.environ['HOME'])
-    assert_cache(app, 'echo "${HOME}"', os.environ['HOME'], use_shell=True)
-
-
-@pytest.mark.with_content("""\
-.. program-output:: echo "spam with eggs"
-   :prompt:""")
-def test_prompt(doctree, app):
-    assert_output(doctree, """\
-$ echo "spam with eggs"
-spam with eggs""")
-    assert_cache(app, 'echo "spam with eggs"', 'spam with eggs')
-
-
-@pytest.mark.with_content('.. command-output:: echo "spam with eggs"')
-def test_command(doctree, app):
-    assert_output(doctree, """\
-$ echo "spam with eggs"
-spam with eggs""")
-    assert_cache(app, 'echo "spam with eggs"', 'spam with eggs')
-
-
-@pytest.mark.with_content('.. command-output:: echo spam')
-@pytest.mark.confoverrides(
-    programoutput_prompt_template='>> {command}\n<< {output}')
-def test_command_non_default_prompt(doctree, app):
-    assert_output(doctree, '>> echo spam\n<< spam')
-    assert_cache(app, 'echo spam', 'spam')
-
-
-@pytest.mark.with_content("""\
-.. program-output:: echo spam
-   :extraargs: with eggs""")
-def test_extraargs(doctree, app):
-    assert_output(doctree, 'spam with eggs')
-    assert_cache(app, 'echo spam with eggs', 'spam with eggs')
-
-
-@pytest.mark.with_content('''\
-.. program-output:: echo
-   :shell:
-   :extraargs: "${HOME}"''')
-def test_extraargs_with_shell(doctree, app):
-    assert_output(doctree, os.environ['HOME'])
-    assert_cache(app, 'echo "${HOME}"', os.environ['HOME'], use_shell=True)
-
-
-@pytest.mark.with_content("""\
-.. program-output:: echo spam
-   :prompt:
-   :extraargs: with eggs""")
-def test_extraargs_with_prompt(doctree, app):
-    assert_output(doctree, '$ echo spam\nspam with eggs')
-    assert_cache(app, 'echo spam with eggs', 'spam with eggs')
-
-
-@pytest.mark.with_content("""\
-.. program-output:: python -c 'print("spam\\nwith\\neggs")'
-   :ellipsis: 2""")
-def test_ellipsis_stop_only(doctree, app):
-    assert_output(doctree, 'spam\nwith\n...')
-    assert_cache(app, 'python -c \'print("spam\\nwith\\neggs")\'',
-                 'spam\nwith\neggs')
-
-
-@pytest.mark.with_content("""\
-.. program-output:: python -c 'print("spam\\nwith\\neggs")'
-   :ellipsis: -2""")
-def test_ellipsis_negative_stop(doctree, app):
-    assert_output(doctree, 'spam\n...')
-    assert_cache(app, """python -c 'print("spam\\nwith\\neggs")'""",
-                 'spam\nwith\neggs')
-
-
-@pytest.mark.with_content("""\
-.. program-output:: python -c 'print("spam\\nwith\\neggs")'
-   :ellipsis: 1, 2""")
-def test_ellipsis_start_and_stop(doctree, app):
-    assert_output(doctree, 'spam\n...\neggs')
-    assert_cache(app, """python -c 'print("spam\\nwith\\neggs")'""",
-                 'spam\nwith\neggs')
-
-
-@pytest.mark.with_content("""\
-.. program-output:: python -c 'print("spam\\nwith\\neggs")'
-   :ellipsis: 1, -1""")
-def test_ellipsis_start_and_negative_stop(doctree, app):
-    assert_output(doctree, 'spam\n...\neggs')
-    assert_cache(app, """python -c 'print("spam\\nwith\\neggs")'""",
-                 'spam\nwith\neggs')
-
-
-@pytest.mark.with_content("""\
-.. program-output:: python -c 'import sys; sys.exit(1)'""")
-def test_unexpected_return_code(app):
-    with pytest.raises(SphinxWarning) as excinfo:
-        app.build()
-    exc_message = 'WARNING: Unexpected return code 1 from command {0!r}\n'.format(
-        "python -c 'import sys; sys.exit(1)'")
-    assert str(excinfo.value) == exc_message
-
-
-@pytest.mark.with_content("""\
-.. program-output:: python -c 'import sys; sys.exit(1)'
-   :shell:""")
-def test_shell_with_unexpected_return_code(app):
-    with pytest.raises(SphinxWarning) as excinfo:
-        app.build()
-    exc_message = 'WARNING: Unexpected return code 1 from command {0!r}\n'.format(
-        "python -c 'import sys; sys.exit(1)'")
-    assert str(excinfo.value) == exc_message
-
-
-@pytest.mark.with_content("""\
-.. program-output:: python -c 'import sys; print("foo"); sys.exit(1)'
-   :returncode: 1""")
-def test_expected_non_zero_return_code(doctree, app):
-    assert_output(doctree, 'foo')
-    assert_cache(app, 'python -c \'import sys; print("foo"); sys.exit(1)\'',
-                 'foo', returncode=1)
-
-
-@pytest.mark.with_content("""\
-.. command-output:: python -c 'import sys; sys.exit(1)'
-   :returncode: 1""")
-@pytest.mark.confoverrides(
-    programoutput_prompt_template='> {command}\n{output}\n[{returncode}]>')
-def test_prompt_with_return_code(doctree, app):
-    assert_output(doctree, """\
-> python -c 'import sys; sys.exit(1)'
-
-[1]>""")
-    assert_cache(app, "python -c 'import sys; sys.exit(1)'", '',
-                 returncode=1)
-
-
-@pytest.mark.with_content(".. program-output:: 'spam with eggs'")
-@pytest.mark.ignore_warnings
-def test_non_existing_executable(doctree, srcdir):
-    # check that a proper error message appears in the document
-    message = doctree.next_node(system_message)
-    assert message
-    srcfile = str(srcdir.join('content').join('doc.rst'))
-    assert message['source'] == srcfile
-    assert message['line'] == 4
-    if sys.version_info[0] < 3:
-        msgtemplate = ("{0}:4: (ERROR/3) Command {1!r} failed: "
-                       "[Errno 2] No such file or directory")
-    else:
-        msgtemplate = ("{0}:4: (ERROR/3) Command {1!r} failed: "
-                       "[Errno 2] No such file or directory: {1}")
-    assert message.astext() == msgtemplate.format(srcfile, "'spam with eggs'")
-
-
-@pytest.mark.with_content("""\
-.. program-output:: echo spam
-   :cwd: ./subdir""")
-@pytest.mark.ignore_warnings
-def test_non_existing_working_directry(doctree, srcdir):
-    # check that a proper error message appears in the document
-    message = doctree.next_node(system_message)
-    assert message
-    srcfile = str(srcdir.join('content').join('doc.rst'))
-    assert message['source'] == srcfile
-    assert message['line'] == 4
-    msgtemplate = ("{0}:4: (ERROR/3) Command {1!r} failed: "
-                   "[Errno 2] No such file or directory: {2!r}")
-    if sys.version_info[0] < 3:
-        filename = srcdir.join('content').realpath().join('subdir')
-    else:
-        # Python 3 breaks the error message here :(
-        filename = 'echo'
-    msg = msgtemplate.format(srcfile, 'echo spam', str(filename))
-    assert message.astext() == msg

programoutput/tests/test_setup.py

-# -*- coding: utf-8 -*-
-# Copyright (c) 2011, Sebastian Wiesner <lunaryorn@googlemail.com>
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-
-# 1. Redistributions of source code must retain the above copyright notice,
-#    this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-from __future__ import (print_function, division, unicode_literals,
-                        absolute_import)
-
-
-from sphinxcontrib.programoutput import ProgramOutputCache
-
-
-def pytest_funcarg__content(request): # pylint: disable=W0613
-    return 'dummy content'
-
-
-def test_init_cache(app):
-    assert isinstance(app.env.programoutput_cache, ProgramOutputCache)
-    assert not app.env.programoutput_cache

programoutput/tests/test_util.py

-# -*- coding: utf-8 -*-
-# Copyright (c) 2011, Sebastian Wiesner <lunaryorn@googlemail.com>
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-
-# 1. Redistributions of source code must retain the above copyright notice,
-#    this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-from __future__ import (print_function, division, unicode_literals,
-                        absolute_import)
-
-import pytest
-
-from sphinxcontrib.programoutput import _slice
-
-
-def test_slice_simple():
-    assert _slice('2') == (2, None)
-    assert _slice('2,2') == (2, 2)
-
-
-def test_slice_empty():
-    with pytest.raises(ValueError) as exc:
-        assert _slice('')
-    assert str(exc.value) == "invalid literal for int() with base 10: ''"
-
-
-def test_slice_no_int():
-    with pytest.raises(ValueError) as exc:
-        _slice('foo,2')
-    assert str(exc.value) == "invalid literal for int() with base 10: 'foo'"
-
-
-def test_slice_too_many():
-    with pytest.raises(ValueError) as exc:
-        _slice('2,2,2')
-    assert str(exc.value) == 'too many slice parts'

programoutput/tox.ini

-[tox]
-envlist=py27,py32,doc
-
-[testenv]
-deps=
-    Sphinx>=1.1
-    pytest>=2.2
-commands=
-    py.test {posargs:--junitxml={envname}-tests.xml}
-
-[testenv:doc]
-deps=
-    sphinx>=1.1
-commands=
-    sphinx-build -W -b linkcheck -d {envtmpdir}/doctrees doc {envtmpdir}/linkcheck
-    sphinx-build -W -b html -d {envtmpdir}/doctrees doc {envtmpdir}/html
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.