Parameterized testing with any Python test framework
====================================================

.. image:: https://img.shields.io/pypi/v/parameterized.svg
    :alt: PyPI
    :target: https://pypi.org/project/parameterized/

.. image:: https://circleci.com/gh/wolever/parameterized.svg?style=svg
    :alt: Circle CI
    :target: https://circleci.com/gh/wolever/parameterized

Parameterized testing in Python sucks.

``parameterized`` fixes that. For everything. Parameterized testing for nose,
parameterized testing for py.test, parameterized testing for unittest.

.. code:: python

   # test_math.py
   from nose.tools import assert_equal
   from parameterized import parameterized, parameterized_class

   import unittest
   import math

   @parameterized([
       (2, 2, 4),
       (2, 3, 8),
       (1, 9, 1),
       (0, 9, 0),
   ])
   def test_pow(base, exponent, expected):
      assert_equal(math.pow(base, exponent), expected)

   class TestMathUnitTest(unittest.TestCase):
      @parameterized.expand([
          ("negative", -1.5, -2.0),
          ("integer", 1, 1.0),
          ("large fraction", 1.6, 1),
      ])
      def test_floor(self, name, input, expected):
          assert_equal(math.floor(input), expected)

   @parameterized_class(('a', 'b', 'expected_sum', 'expected_product'), [
      (1, 2, 3, 2),
      (5, 5, 10, 25),
   ])
   class TestMathClass(unittest.TestCase):
      def test_add(self):
         assert_equal(self.a + self.b, self.expected_sum)

      def test_multiply(self):
         assert_equal(self.a * self.b, self.expected_product)

   @parameterized_class([
      { "a": 3, "expected": 2 },
      { "b": 5, "expected": -4 },
   ])
   class TestMathClassDict(unittest.TestCase):
      a = 1
      b = 1

      def test_subtract(self):
         assert_equal(self.a - self.b, self.expected)

With nose (and nose2)::

    $ nosetests -v test_math.py
    test_floor_0_negative (test_math.TestMathUnitTest) ... ok
    test_floor_1_integer (test_math.TestMathUnitTest) ... ok
    test_floor_2_large_fraction (test_math.TestMathUnitTest) ... ok
    test_math.test_pow(2, 2, 4, {}) ... ok
    test_math.test_pow(2, 3, 8, {}) ... ok
    test_math.test_pow(1, 9, 1, {}) ... ok
    test_math.test_pow(0, 9, 0, {}) ... ok
    test_add (test_math.TestMathClass_0) ... ok
    test_multiply (test_math.TestMathClass_0) ... ok
    test_add (test_math.TestMathClass_1) ... ok
    test_multiply (test_math.TestMathClass_1) ... ok
    test_subtract (test_math.TestMathClassDict_0) ... ok

    ----------------------------------------------------------------------
    Ran 12 tests in 0.015s

    OK

As the package name suggests, nose is best supported and will be used for all
further examples.

With py.test (version 2.0 and above)::

    $ py.test -v test_math.py
    ============================= test session starts ==============================
    platform darwin -- Python 3.6.1, pytest-3.1.3, py-1.4.34, pluggy-0.4.0
    collecting ... collected 13 items

    test_math.py::test_pow::[0] PASSED
    test_math.py::test_pow::[1] PASSED
    test_math.py::test_pow::[2] PASSED
    test_math.py::test_pow::[3] PASSED
    test_math.py::TestMathUnitTest::test_floor_0_negative PASSED
    test_math.py::TestMathUnitTest::test_floor_1_integer PASSED
    test_math.py::TestMathUnitTest::test_floor_2_large_fraction PASSED
    test_math.py::TestMathClass_0::test_add PASSED
    test_math.py::TestMathClass_0::test_multiply PASSED
    test_math.py::TestMathClass_1::test_add PASSED
    test_math.py::TestMathClass_1::test_multiply PASSED
    test_math.py::TestMathClassDict_0::test_subtract PASSED
    ==================== 12 passed, 4 warnings in 0.16 seconds =====================

With unittest (and unittest2)::

    $ python -m unittest -v test_math
    test_floor_0_negative (test_math.TestMathUnitTest) ... ok
    test_floor_1_integer (test_math.TestMathUnitTest) ... ok
    test_floor_2_large_fraction (test_math.TestMathUnitTest) ... ok
    test_add (test_math.TestMathClass_0) ... ok
    test_multiply (test_math.TestMathClass_0) ... ok
    test_add (test_math.TestMathClass_1) ... ok
    test_multiply (test_math.TestMathClass_1) ... ok
    test_subtract (test_math.TestMathClassDict_0) ... ok

    ----------------------------------------------------------------------
    Ran 8 tests in 0.001s

    OK

(note: because unittest does not support test decorators, only tests created
with ``@parameterized.expand`` will be executed)

With green::

    $ green test_math.py -vvv
    test_math
      TestMathClass_1
    .   test_method_a
    .   test_method_b
      TestMathClass_2
    .   test_method_a
    .   test_method_b
      TestMathClass_3
    .   test_method_a
    .   test_method_b
      TestMathUnitTest
    .   test_floor_0_negative
    .   test_floor_1_integer
    .   test_floor_2_large_fraction
      TestMathClass_0
    .   test_add
    .   test_multiply
      TestMathClass_1
    .   test_add
    .   test_multiply
      TestMathClassDict_0
    .   test_subtract

    Ran 12 tests in 0.121s

    OK (passes=9)

Installation
------------

::

    $ pip install parameterized

Compatibility
-------------

`Yes`__ (mostly).

__ https://travis-ci.org/wolever/parameterized

.. list-table::
   :header-rows: 1
   :stub-columns: 1

   * -
     - Py2.6
     - Py2.7
     - Py3.4
     - Py3.5
     - Py3.6
     - Py3.7
     - Py3.8
     - Py3.9
     - PyPy
     - ``@mock.patch``
   * - nose
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
   * - nose2
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
   * - py.test 2
     - yes
     - yes
     - no*
     - no*
     - no*
     - no*
     - yes
     - yes
     - yes
     - yes
   * - py.test 3
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
   * - py.test 4
     - no**
     - no**
     - no**
     - no**
     - no**
     - no**
     - no**
     - no**
     - no**
     - no**
   * - py.test fixtures
     - no†
     - no†
     - no†
     - no†
     - no†
     - no†
     - no†
     - no†
     - no†
     - no†
   * - | unittest
       | (``@parameterized.expand``)
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
   * - | unittest2
       | (``@parameterized.expand``)
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes

\*: py.test 2 does `does not appear to work (#71)`__ under Python 3. Please comment on the related issues if you are affected.

\*\*: py.test 4 is not yet supported (but coming!) in `issue #34`__

†: py.test fixture support is documented in `issue #81`__

__ https://github.com/wolever/parameterized/issues/71
__ https://github.com/wolever/parameterized/issues/34
__ https://github.com/wolever/parameterized/issues/81

Dependencies
------------

(this section left intentionally blank)

Exhaustive Usage Examples
--------------------------

The ``@parameterized`` and ``@parameterized.expand`` decorators accept a list
or iterable of tuples or ``param(...)``, or a callable which returns a list or
iterable:

.. code:: python

    from parameterized import parameterized, param

    # A list of tuples
    @parameterized([
        (2, 3, 5),
        (3, 5, 8),
    ])
    def test_add(a, b, expected):
        assert_equal(a + b, expected)

    # A list of params
    @parameterized([
        param("10", 10),
        param("10", 16, base=16),
    ])
    def test_int(str_val, expected, base=10):
        assert_equal(int(str_val, base=base), expected)

    # An iterable of params
    @parameterized(
        param.explicit(*json.loads(line))
        for line in open("testcases.jsons")
    )
    def test_from_json_file(...):
        ...

    # A callable which returns a list of tuples
    def load_test_cases():
        return [
            ("test1", ),
            ("test2", ),
        ]
    @parameterized(load_test_cases)
    def test_from_function(name):
        ...

.. **

Note that, when using an iterator or a generator, all the items will be loaded
into memory before the start of the test run (we do this explicitly to ensure
that generators are exhausted exactly once in multi-process or multi-threaded
testing environments).

The ``@parameterized`` decorator can be used test class methods, and standalone
functions:

.. code:: python

    from parameterized import parameterized

    class AddTest(object):
        @parameterized([
            (2, 3, 5),
        ])
        def test_add(self, a, b, expected):
            assert_equal(a + b, expected)

    @parameterized([
        (2, 3, 5),
    ])
    def test_add(a, b, expected):
        assert_equal(a + b, expected)

And ``@parameterized.expand`` can be used to generate test methods in
situations where test generators cannot be used (for example, when the test
class is a subclass of ``unittest.TestCase``):

.. code:: python

    import unittest
    from parameterized import parameterized

    class AddTestCase(unittest.TestCase):
        @parameterized.expand([
            ("2 and 3", 2, 3, 5),
            ("3 and 5", 2, 3, 5),
        ])
        def test_add(self, _, a, b, expected):
            assert_equal(a + b, expected)

Will create the test cases::

    $ nosetests example.py
    test_add_0_2_and_3 (example.AddTestCase) ... ok
    test_add_1_3_and_5 (example.AddTestCase) ... ok

    ----------------------------------------------------------------------
    Ran 2 tests in 0.001s

    OK

Note that ``@parameterized.expand`` works by creating new methods on the test
class. If the first parameter is a string, that string will be added to the end
of the method name. For example, the test case above will generate the methods
``test_add_0_2_and_3`` and ``test_add_1_3_and_5``.

The names of the test cases generated by ``@parameterized.expand`` can be
customized using the ``name_func`` keyword argument. The value should
be a function which accepts three arguments: ``testcase_func``, ``param_num``,
and ``params``, and it should return the name of the test case.
``testcase_func`` will be the function to be tested, ``param_num`` will be the
index of the test case parameters in the list of parameters, and ``param``
(an instance of ``param``) will be the parameters which will be used.

.. code:: python

    import unittest
    from parameterized import parameterized

    def custom_name_func(testcase_func, param_num, param):
        return "%s_%s" %(
            testcase_func.__name__,
            parameterized.to_safe_name("_".join(str(x) for x in param.args)),
        )

    class AddTestCase(unittest.TestCase):
        @parameterized.expand([
            (2, 3, 5),
            (2, 3, 5),
        ], name_func=custom_name_func)
        def test_add(self, a, b, expected):
            assert_equal(a + b, expected)

Will create the test cases::

    $ nosetests example.py
    test_add_1_2_3 (example.AddTestCase) ... ok
    test_add_2_3_5 (example.AddTestCase) ... ok

    ----------------------------------------------------------------------
    Ran 2 tests in 0.001s

    OK

The ``param(...)`` helper class stores the parameters for one specific test
case.  It can be used to pass keyword arguments to test cases:

.. code:: python

    from parameterized import parameterized, param

    @parameterized([
        param("10", 10),
        param("10", 16, base=16),
    ])
    def test_int(str_val, expected, base=10):
        assert_equal(int(str_val, base=base), expected)

If test cases have a docstring, the parameters for that test case will be
appended to the first line of the docstring. This behavior can be controlled
with the ``doc_func`` argument:

.. code:: python

    from parameterized import parameterized

    @parameterized([
        (1, 2, 3),
        (4, 5, 9),
    ])
    def test_add(a, b, expected):
        """ Test addition. """
        assert_equal(a + b, expected)

    def my_doc_func(func, num, param):
        return "%s: %s with %s" %(num, func.__name__, param)

    @parameterized([
        (5, 4, 1),
        (9, 6, 3),
    ], doc_func=my_doc_func)
    def test_subtraction(a, b, expected):
        assert_equal(a - b, expected)

::

    $ nosetests example.py
    Test addition. [with a=1, b=2, expected=3] ... ok
    Test addition. [with a=4, b=5, expected=9] ... ok
    0: test_subtraction with param(*(5, 4, 1)) ... ok
    1: test_subtraction with param(*(9, 6, 3)) ... ok

    ----------------------------------------------------------------------
    Ran 4 tests in 0.001s

    OK

Finally ``@parameterized_class`` parameterizes an entire class, using
either a list of attributes, or a list of dicts that will be applied to the
class:

.. code:: python

    from yourapp.models import User
    from parameterized import parameterized_class

    @parameterized_class([
       { "username": "user_1", "access_level": 1 },
       { "username": "user_2", "access_level": 2, "expected_status_code": 404 },
    ])
    class TestUserAccessLevel(TestCase):
       expected_status_code = 200

       def setUp(self):
          self.client.force_login(User.objects.get(username=self.username)[0])

       def test_url_a(self):
          response = self.client.get('/url')
          self.assertEqual(response.status_code, self.expected_status_code)

       def tearDown(self):
          self.client.logout()

    @parameterized_class(("username", "access_level", "expected_status_code"), [
       ("user_1", 1, 200),
       ("user_2", 2, 404)
    ])
    class TestUserAccessLevel(TestCase):
       def setUp(self):
          self.client.force_login(User.objects.get(username=self.username)[0])

       def test_url_a(self):
          response = self.client.get("/url")
          self.assertEqual(response.status_code, self.expected_status_code)

       def tearDown(self):
          self.client.logout()

The ``@parameterized_class`` decorator accepts a ``class_name_func`` argument,
which controls the name of the parameterized classes generated by
``@parameterized_class``:

.. code:: python

    from parameterized import parameterized, parameterized_class

    def get_class_name(cls, num, params_dict):
        # By default the generated class named includes either the "name"
        # parameter (if present), or the first string value. This example shows
        # multiple parameters being included in the generated class name:
        return "%s_%s_%s%s" %(
            cls.__name__,
            num,
            parameterized.to_safe_name(params_dict['a']),
            parameterized.to_safe_name(params_dict['b']),
        )

    @parameterized_class([
       { "a": "hello", "b": " world!", "expected": "hello world!" },
       { "a": "say ", "b": " cheese :)", "expected": "say cheese :)" },
    ], class_name_func=get_class_name)
    class TestConcatenation(TestCase):
      def test_concat(self):
          self.assertEqual(self.a + self.b, self.expected)

::

    $ nosetests -v test_math.py
    test_concat (test_concat.TestConcatenation_0_hello_world_) ... ok
    test_concat (test_concat.TestConcatenation_0_say_cheese__) ... ok

Using with Single Parameters
............................

If a test function only accepts one parameter and the value is not iterable,
then it is possible to supply a list of values without wrapping each one in a
tuple:

.. code:: python

   @parameterized([1, 2, 3])
   def test_greater_than_zero(value):
      assert value > 0

Note, however, that if the single parameter *is* iterable (such as a list or
tuple), then it *must* be wrapped in a tuple, list, or the ``param(...)``
helper:

.. code:: python

   @parameterized([
      ([1, 2, 3], ),
      ([3, 3], ),
      ([6], ),
   ])
   def test_sums_to_6(numbers):
      assert sum(numbers) == 6

(note, also, that Python requires single element tuples to be defined with a
trailing comma: ``(foo, )``)

Using with ``@mock.patch``
..........................

``parameterized`` can be used with ``mock.patch``, but the argument ordering
can be confusing. The ``@mock.patch(...)`` decorator must come *below* the
``@parameterized(...)``, and the mocked parameters must come *last*:

.. code:: python

   @mock.patch("os.getpid")
   class TestOS(object):
      @parameterized(...)
      @mock.patch("os.fdopen")
      @mock.patch("os.umask")
      def test_method(self, param1, param2, ..., mock_umask, mock_fdopen, mock_getpid):
         ...

Note: the same holds true when using ``@parameterized.expand``.

Migrating from ``nose-parameterized`` to ``parameterized``
----------------------------------------------------------

To migrate a codebase from ``nose-parameterized`` to ``parameterized``:

1. Update your requirements file, replacing ``nose-parameterized`` with
   ``parameterized``.

2. Replace all references to ``nose_parameterized`` with ``parameterized``::

    $ perl -pi -e 's/nose_parameterized/parameterized/g' your-codebase/

3. You're done!

FAQ
---

What happened to ``nose-parameterized``?
    Originally only nose was supported. But now everything is supported, and it
    only made sense to change the name!

What do you mean when you say "nose is best supported"?
    There are small caveates with ``py.test`` and ``unittest``: ``py.test``
    does not show the parameter values (ex, it will show ``test_add[0]``
    instead of ``test_add[1, 2, 3]``), and ``unittest``/``unittest2`` do not
    support test generators so ``@parameterized.expand`` must be used.

Why not use ``@pytest.mark.parametrize``?
    Because spelling is difficult. Also, ``parameterized`` doesn't require you
    to repeat argument names, and (using ``param``) it supports optional
    keyword arguments.

Why do I get an ``AttributeError: 'function' object has no attribute 'expand'`` with ``@parameterized.expand``?
    You've likely installed the ``parametrized`` (note the missing *e*)
    package. Use ``parameterized`` (with the *e*) instead and you'll be all
    set.


Parameterized testing with any Python test framework
====================================================

.. image:: https://img.shields.io/pypi/v/parameterized
    :alt: PyPI
    :target: https://pypi.org/project/parameterized/

.. image:: https://img.shields.io/pypi/dm/parameterized
    :alt: PyPI - Downloads
    :target: https://pypi.org/project/parameterized/

.. image:: https://circleci.com/gh/wolever/parameterized.svg?style=svg
    :alt: Circle CI
    :target: https://circleci.com/gh/wolever/parameterized

Parameterized testing in Python sucks.

``parameterized`` fixes that. For everything. Parameterized testing for nose,
parameterized testing for py.test, parameterized testing for unittest.

.. code:: python

   # test_math.py
   from nose.tools import assert_equal
   from parameterized import parameterized, parameterized_class

   import unittest
   import math

   @parameterized([
       (2, 2, 4),
       (2, 3, 8),
       (1, 9, 1),
       (0, 9, 0),
   ])
   def test_pow(base, exponent, expected):
      assert_equal(math.pow(base, exponent), expected)

   class TestMathUnitTest(unittest.TestCase):
      @parameterized.expand([
          ("negative", -1.5, -2.0),
          ("integer", 1, 1.0),
          ("large fraction", 1.6, 1),
      ])
      def test_floor(self, name, input, expected):
          assert_equal(math.floor(input), expected)

   @parameterized_class(('a', 'b', 'expected_sum', 'expected_product'), [
      (1, 2, 3, 2),
      (5, 5, 10, 25),
   ])
   class TestMathClass(unittest.TestCase):
      def test_add(self):
         assert_equal(self.a + self.b, self.expected_sum)

      def test_multiply(self):
         assert_equal(self.a * self.b, self.expected_product)

   @parameterized_class([
      { "a": 3, "expected": 2 },
      { "b": 5, "expected": -4 },
   ])
   class TestMathClassDict(unittest.TestCase):
      a = 1
      b = 1

      def test_subtract(self):
         assert_equal(self.a - self.b, self.expected)

With nose (and nose2)::

    $ nosetests -v test_math.py
    test_floor_0_negative (test_math.TestMathUnitTest) ... ok
    test_floor_1_integer (test_math.TestMathUnitTest) ... ok
    test_floor_2_large_fraction (test_math.TestMathUnitTest) ... ok
    test_math.test_pow(2, 2, 4, {}) ... ok
    test_math.test_pow(2, 3, 8, {}) ... ok
    test_math.test_pow(1, 9, 1, {}) ... ok
    test_math.test_pow(0, 9, 0, {}) ... ok
    test_add (test_math.TestMathClass_0) ... ok
    test_multiply (test_math.TestMathClass_0) ... ok
    test_add (test_math.TestMathClass_1) ... ok
    test_multiply (test_math.TestMathClass_1) ... ok
    test_subtract (test_math.TestMathClassDict_0) ... ok

    ----------------------------------------------------------------------
    Ran 12 tests in 0.015s

    OK

As the package name suggests, nose is best supported and will be used for all
further examples.

With py.test (version 2.0 and above)::

    $ py.test -v test_math.py
    ============================= test session starts ==============================
    platform darwin -- Python 3.6.1, pytest-3.1.3, py-1.4.34, pluggy-0.4.0
    collecting ... collected 13 items

    test_math.py::test_pow::[0] PASSED
    test_math.py::test_pow::[1] PASSED
    test_math.py::test_pow::[2] PASSED
    test_math.py::test_pow::[3] PASSED
    test_math.py::TestMathUnitTest::test_floor_0_negative PASSED
    test_math.py::TestMathUnitTest::test_floor_1_integer PASSED
    test_math.py::TestMathUnitTest::test_floor_2_large_fraction PASSED
    test_math.py::TestMathClass_0::test_add PASSED
    test_math.py::TestMathClass_0::test_multiply PASSED
    test_math.py::TestMathClass_1::test_add PASSED
    test_math.py::TestMathClass_1::test_multiply PASSED
    test_math.py::TestMathClassDict_0::test_subtract PASSED
    ==================== 12 passed, 4 warnings in 0.16 seconds =====================

With unittest (and unittest2)::

    $ python -m unittest -v test_math
    test_floor_0_negative (test_math.TestMathUnitTest) ... ok
    test_floor_1_integer (test_math.TestMathUnitTest) ... ok
    test_floor_2_large_fraction (test_math.TestMathUnitTest) ... ok
    test_add (test_math.TestMathClass_0) ... ok
    test_multiply (test_math.TestMathClass_0) ... ok
    test_add (test_math.TestMathClass_1) ... ok
    test_multiply (test_math.TestMathClass_1) ... ok
    test_subtract (test_math.TestMathClassDict_0) ... ok

    ----------------------------------------------------------------------
    Ran 8 tests in 0.001s

    OK

(note: because unittest does not support test decorators, only tests created
with ``@parameterized.expand`` will be executed)

With green::

    $ green test_math.py -vvv
    test_math
      TestMathClass_1
    .   test_method_a
    .   test_method_b
      TestMathClass_2
    .   test_method_a
    .   test_method_b
      TestMathClass_3
    .   test_method_a
    .   test_method_b
      TestMathUnitTest
    .   test_floor_0_negative
    .   test_floor_1_integer
    .   test_floor_2_large_fraction
      TestMathClass_0
    .   test_add
    .   test_multiply
      TestMathClass_1
    .   test_add
    .   test_multiply
      TestMathClassDict_0
    .   test_subtract

    Ran 12 tests in 0.121s

    OK (passes=9)

Installation
------------

::

    $ pip install parameterized

Compatibility
-------------

`Yes`__ (mostly).

__ https://app.circleci.com/pipelines/github/wolever/parameterized?branch=master

.. list-table::
   :header-rows: 1
   :stub-columns: 1

   * -
     - Py3.7
     - Py3.8
     - Py3.9
     - Py3.10
     - Py3.11
     - PyPy3
     - ``@mock.patch``
   * - nose
     - yes
     - yes
     - yes
     - yes
     - no§
     - no§
     - yes
   * - nose2
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
   * - py.test 2
     - no*
     - no*
     - no*
     - no*
     - no*
     - no*
     - no*
   * - py.test 3
     - yes
     - yes
     - yes
     - yes
     - no*
     - no*
     - yes
   * - py.test 4
     - no**
     - no**
     - no**
     - no**
     - no**
     - no**
     - no**
   * - py.test fixtures
     - no†
     - no†
     - no†
     - no†
     - no†
     - no†
     - no†
   * - | unittest
       | (``@parameterized.expand``)
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
     - yes
   * - | unittest2
       | (``@parameterized.expand``)
     - yes
     - yes
     - yes
     - yes
     - no§
     - no§
     - yes

§: nose and unittest2 - both of which were last updated in 2015 - sadly do not
appear to support Python 3.10 or 3.11.

\*: `py.test 2 does not appear to work under Python 3 (#71)`__, and
`py.test 3 does not appear to work under Python 3.10 or 3.11 (#154)`__.

\*\*: py.test 4 is not yet supported (but coming!) in `issue #34`__

†: py.test fixture support is documented in `issue #81`__

__ https://github.com/wolever/parameterized/issues/71
__ https://github.com/wolever/parameterized/issues/154
__ https://github.com/wolever/parameterized/issues/34
__ https://github.com/wolever/parameterized/issues/81

Dependencies
------------

(this section left intentionally blank)

Exhaustive Usage Examples
--------------------------

The ``@parameterized`` and ``@parameterized.expand`` decorators accept a list
or iterable of tuples or ``param(...)``, or a callable which returns a list or
iterable:

.. code:: python

    from parameterized import parameterized, param

    # A list of tuples
    @parameterized([
        (2, 3, 5),
        (3, 5, 8),
    ])
    def test_add(a, b, expected):
        assert_equal(a + b, expected)

    # A list of params
    @parameterized([
        param("10", 10),
        param("10", 16, base=16),
    ])
    def test_int(str_val, expected, base=10):
        assert_equal(int(str_val, base=base), expected)

    # An iterable of params
    @parameterized(
        param.explicit(*json.loads(line))
        for line in open("testcases.jsons")
    )
    def test_from_json_file(...):
        ...

    # A callable which returns a list of tuples
    def load_test_cases():
        return [
            ("test1", ),
            ("test2", ),
        ]
    @parameterized(load_test_cases)
    def test_from_function(name):
        ...

.. **

Note that, when using an iterator or a generator, all the items will be loaded
into memory before the start of the test run (we do this explicitly to ensure
that generators are exhausted exactly once in multi-process or multi-threaded
testing environments).

The ``@parameterized`` decorator can be used test class methods, and standalone
functions:

.. code:: python

    from parameterized import parameterized

    class AddTest(object):
        @parameterized([
            (2, 3, 5),
        ])
        def test_add(self, a, b, expected):
            assert_equal(a + b, expected)

    @parameterized([
        (2, 3, 5),
    ])
    def test_add(a, b, expected):
        assert_equal(a + b, expected)

And ``@parameterized.expand`` can be used to generate test methods in
situations where test generators cannot be used (for example, when the test
class is a subclass of ``unittest.TestCase``):

.. code:: python

    import unittest
    from parameterized import parameterized

    class AddTestCase(unittest.TestCase):
        @parameterized.expand([
            ("2 and 3", 2, 3, 5),
            ("3 and 5", 3, 5, 8),
        ])
        def test_add(self, _, a, b, expected):
            assert_equal(a + b, expected)

Will create the test cases::

    $ nosetests example.py
    test_add_0_2_and_3 (example.AddTestCase) ... ok
    test_add_1_3_and_5 (example.AddTestCase) ... ok

    ----------------------------------------------------------------------
    Ran 2 tests in 0.001s

    OK

Note that ``@parameterized.expand`` works by creating new methods on the test
class. If the first parameter is a string, that string will be added to the end
of the method name. For example, the test case above will generate the methods
``test_add_0_2_and_3`` and ``test_add_1_3_and_5``.

The names of the test cases generated by ``@parameterized.expand`` can be
customized using the ``name_func`` keyword argument. The value should
be a function which accepts three arguments: ``testcase_func``, ``param_num``,
and ``params``, and it should return the name of the test case.
``testcase_func`` will be the function to be tested, ``param_num`` will be the
index of the test case parameters in the list of parameters, and ``param``
(an instance of ``param``) will be the parameters which will be used.

.. code:: python

    import unittest
    from parameterized import parameterized

    def custom_name_func(testcase_func, param_num, param):
        return "%s_%s" %(
            testcase_func.__name__,
            parameterized.to_safe_name("_".join(str(x) for x in param.args)),
        )

    class AddTestCase(unittest.TestCase):
        @parameterized.expand([
            (2, 3, 5),
            (2, 3, 5),
        ], name_func=custom_name_func)
        def test_add(self, a, b, expected):
            assert_equal(a + b, expected)

Will create the test cases::

    $ nosetests example.py
    test_add_1_2_3 (example.AddTestCase) ... ok
    test_add_2_3_5 (example.AddTestCase) ... ok

    ----------------------------------------------------------------------
    Ran 2 tests in 0.001s

    OK

The ``param(...)`` helper class stores the parameters for one specific test
case.  It can be used to pass keyword arguments to test cases:

.. code:: python

    from parameterized import parameterized, param

    @parameterized([
        param("10", 10),
        param("10", 16, base=16),
    ])
    def test_int(str_val, expected, base=10):
        assert_equal(int(str_val, base=base), expected)

If test cases have a docstring, the parameters for that test case will be
appended to the first line of the docstring. This behavior can be controlled
with the ``doc_func`` argument:

.. code:: python

    from parameterized import parameterized

    @parameterized([
        (1, 2, 3),
        (4, 5, 9),
    ])
    def test_add(a, b, expected):
        """ Test addition. """
        assert_equal(a + b, expected)

    def my_doc_func(func, num, param):
        return "%s: %s with %s" %(num, func.__name__, param)

    @parameterized([
        (5, 4, 1),
        (9, 6, 3),
    ], doc_func=my_doc_func)
    def test_subtraction(a, b, expected):
        assert_equal(a - b, expected)

::

    $ nosetests example.py
    Test addition. [with a=1, b=2, expected=3] ... ok
    Test addition. [with a=4, b=5, expected=9] ... ok
    0: test_subtraction with param(*(5, 4, 1)) ... ok
    1: test_subtraction with param(*(9, 6, 3)) ... ok

    ----------------------------------------------------------------------
    Ran 4 tests in 0.001s

    OK

Finally ``@parameterized_class`` parameterizes an entire class, using
either a list of attributes, or a list of dicts that will be applied to the
class:

.. code:: python

    from yourapp.models import User
    from parameterized import parameterized_class

    @parameterized_class([
       { "username": "user_1", "access_level": 1 },
       { "username": "user_2", "access_level": 2, "expected_status_code": 404 },
    ])
    class TestUserAccessLevel(TestCase):
       expected_status_code = 200

       def setUp(self):
          self.client.force_login(User.objects.get(username=self.username)[0])

       def test_url_a(self):
          response = self.client.get('/url')
          self.assertEqual(response.status_code, self.expected_status_code)

       def tearDown(self):
          self.client.logout()

    @parameterized_class(("username", "access_level", "expected_status_code"), [
       ("user_1", 1, 200),
       ("user_2", 2, 404)
    ])
    class TestUserAccessLevel(TestCase):
       def setUp(self):
          self.client.force_login(User.objects.get(username=self.username)[0])

       def test_url_a(self):
          response = self.client.get("/url")
          self.assertEqual(response.status_code, self.expected_status_code)

       def tearDown(self):
          self.client.logout()

The ``@parameterized_class`` decorator accepts a ``class_name_func`` argument,
which controls the name of the parameterized classes generated by
``@parameterized_class``:

.. code:: python

    from parameterized import parameterized, parameterized_class

    def get_class_name(cls, num, params_dict):
        # By default the generated class named includes either the "name"
        # parameter (if present), or the first string value. This example shows
        # multiple parameters being included in the generated class name:
        return "%s_%s_%s%s" %(
            cls.__name__,
            num,
            parameterized.to_safe_name(params_dict['a']),
            parameterized.to_safe_name(params_dict['b']),
        )

    @parameterized_class([
       { "a": "hello", "b": " world!", "expected": "hello world!" },
       { "a": "say ", "b": " cheese :)", "expected": "say cheese :)" },
    ], class_name_func=get_class_name)
    class TestConcatenation(TestCase):
      def test_concat(self):
          self.assertEqual(self.a + self.b, self.expected)

::

    $ nosetests -v test_math.py
    test_concat (test_concat.TestConcatenation_0_hello_world_) ... ok
    test_concat (test_concat.TestConcatenation_0_say_cheese__) ... ok

Using with Single Parameters
............................

If a test function only accepts one parameter and the value is not iterable,
then it is possible to supply a list of values without wrapping each one in a
tuple:

.. code:: python

   @parameterized([1, 2, 3])
   def test_greater_than_zero(value):
      assert value > 0

Note, however, that if the single parameter *is* iterable (such as a list or
tuple), then it *must* be wrapped in a tuple, list, or the ``param(...)``
helper:

.. code:: python

   @parameterized([
      ([1, 2, 3], ),
      ([3, 3], ),
      ([6], ),
   ])
   def test_sums_to_6(numbers):
      assert sum(numbers) == 6

(note, also, that Python requires single element tuples to be defined with a
trailing comma: ``(foo, )``)

Using with ``@mock.patch``
..........................

``parameterized`` can be used with ``mock.patch``, but the argument ordering
can be confusing. The ``@mock.patch(...)`` decorator must come *below* the
``@parameterized(...)``, and the mocked parameters must come *last*:

.. code:: python

   @mock.patch("os.getpid")
   class TestOS(object):
      @parameterized(...)
      @mock.patch("os.fdopen")
      @mock.patch("os.umask")
      def test_method(self, param1, param2, ..., mock_umask, mock_fdopen, mock_getpid):
         ...

Note: the same holds true when using ``@parameterized.expand``.

Migrating from ``nose-parameterized`` to ``parameterized``
----------------------------------------------------------

To migrate a codebase from ``nose-parameterized`` to ``parameterized``:

1. Update your requirements file, replacing ``nose-parameterized`` with
   ``parameterized``.

2. Replace all references to ``nose_parameterized`` with ``parameterized``::

    $ perl -pi -e 's/nose_parameterized/parameterized/g' your-codebase/

3. You're done!

FAQ
---

What happened to Python 2.X, 3.5, and 3.6 support?
    As of version 0.9.0, ``parameterized`` no longer supports Python 2.X, 3.5,
    or 3.6.  Previous versions of ``parameterized`` - 0.8.1 being the latest -
    will continue to work, but will not receive any new features or bug fixes.

What do you mean when you say "nose is best supported"?
    There are small caveates with ``py.test`` and ``unittest``: ``py.test``
    does not show the parameter values (ex, it will show ``test_add[0]``
    instead of ``test_add[1, 2, 3]``), and ``unittest``/``unittest2`` do not
    support test generators so ``@parameterized.expand`` must be used.

Why not use ``@pytest.mark.parametrize``?
    Because spelling is difficult. Also, ``parameterized`` doesn't require you
    to repeat argument names, and (using ``param``) it supports optional
    keyword arguments.

Why do I get an ``AttributeError: 'function' object has no attribute 'expand'`` with ``@parameterized.expand``?
    You've likely installed the ``parametrized`` (note the missing *e*)
    package. Use ``parameterized`` (with the *e*) instead and you'll be all
    set.

What happened to ``nose-parameterized``?
    Originally only nose was supported. But now everything is supported, and it
    only made sense to change the name!

Perforator is a cluster-wide continuous profiling tool designed for large data centers


###################################################################
parso - A Python Parser
###################################################################

.. image:: https://travis-ci.org/davidhalter/parso.svg?branch=master
    :target: https://travis-ci.org/davidhalter/parso
    :alt: Travis CI build status

.. image:: https://coveralls.io/repos/github/davidhalter/parso/badge.svg?branch=master
    :target: https://coveralls.io/github/davidhalter/parso?branch=master
    :alt: Coverage Status

.. image:: https://pepy.tech/badge/parso
    :target: https://pepy.tech/project/parso
    :alt: PyPI Downloads

.. image:: https://raw.githubusercontent.com/davidhalter/parso/master/docs/_static/logo_characters.png

Parso is a Python parser that supports error recovery and round-trip parsing
for different Python versions (in multiple Python versions). Parso is also able
to list multiple syntax errors in your python file.

Parso has been battle-tested by jedi_. It was pulled out of jedi to be useful
for other projects as well.

Parso consists of a small API to parse Python and analyse the syntax tree.

A simple example:

.. code-block:: python

    >>> import parso
    >>> module = parso.parse('hello + 1', version="3.6")
    >>> expr = module.children[0]
    >>> expr
    PythonNode(arith_expr, [<Name: hello@1,0>, <Operator: +>, <Number: 1>])
    >>> print(expr.get_code())
    hello + 1
    >>> name = expr.children[0]
    >>> name
    <Name: hello@1,0>
    >>> name.end_pos
    (1, 5)
    >>> expr.end_pos
    (1, 9)

To list multiple issues:

.. code-block:: python

    >>> grammar = parso.load_grammar()
    >>> module = grammar.parse('foo +\nbar\ncontinue')
    >>> error1, error2 = grammar.iter_errors(module)
    >>> error1.message
    'SyntaxError: invalid syntax'
    >>> error2.message
    "SyntaxError: 'continue' not properly in loop"

Resources
=========

- `Testing <https://parso.readthedocs.io/en/latest/docs/development.html#testing>`_
- `PyPI <https://pypi.python.org/pypi/parso>`_
- `Docs <https://parso.readthedocs.org/en/latest/>`_
- Uses `semantic versioning <https://semver.org/>`_

Installation
============

    pip install parso

Future
======

- There will be better support for refactoring and comments. Stay tuned.
- There's a WIP PEP8 validator. It's however not in a good shape, yet.

Known Issues
============

- `async`/`await` are already used as keywords in Python3.6.
- `from __future__ import print_function` is not ignored.

Acknowledgements
================

- Guido van Rossum (@gvanrossum) for creating the parser generator pgen2
  (originally used in lib2to3).
- `Salome Schneider <https://www.crepes-schnaegg.ch/cr%C3%AApes-schn%C3%A4gg/kunst-f%C3%BCrs-cr%C3%AApes-mobil/>`_
  for the extremely awesome parso logo.

.. _jedi: https://github.com/davidhalter/jedi


###################################################################
parso - A Python Parser
###################################################################

.. image:: https://github.com/davidhalter/parso/workflows/Build/badge.svg?branch=master
    :target: https://github.com/davidhalter/parso/actions
    :alt: GitHub Actions build status

.. image:: https://coveralls.io/repos/github/davidhalter/parso/badge.svg?branch=master
    :target: https://coveralls.io/github/davidhalter/parso?branch=master
    :alt: Coverage Status

.. image:: https://pepy.tech/badge/parso
    :target: https://pepy.tech/project/parso
    :alt: PyPI Downloads

.. image:: https://raw.githubusercontent.com/davidhalter/parso/master/docs/_static/logo_characters.png

Parso is a Python parser that supports error recovery and round-trip parsing
for different Python versions (in multiple Python versions). Parso is also able
to list multiple syntax errors in your python file.

Parso has been battle-tested by jedi_. It was pulled out of jedi to be useful
for other projects as well.

Parso consists of a small API to parse Python and analyse the syntax tree.

A simple example:

.. code-block:: python

    >>> import parso
    >>> module = parso.parse('hello + 1', version="3.9")
    >>> expr = module.children[0]
    >>> expr
    PythonNode(arith_expr, [<Name: hello@1,0>, <Operator: +>, <Number: 1>])
    >>> print(expr.get_code())
    hello + 1
    >>> name = expr.children[0]
    >>> name
    <Name: hello@1,0>
    >>> name.end_pos
    (1, 5)
    >>> expr.end_pos
    (1, 9)

To list multiple issues:

.. code-block:: python

    >>> grammar = parso.load_grammar()
    >>> module = grammar.parse('foo +\nbar\ncontinue')
    >>> error1, error2 = grammar.iter_errors(module)
    >>> error1.message
    'SyntaxError: invalid syntax'
    >>> error2.message
    "SyntaxError: 'continue' not properly in loop"

Resources
=========

- `Testing <https://parso.readthedocs.io/en/latest/docs/development.html#testing>`_
- `PyPI <https://pypi.python.org/pypi/parso>`_
- `Docs <https://parso.readthedocs.org/en/latest/>`_
- Uses `semantic versioning <https://semver.org/>`_

Installation
============

    pip install parso

Future
======

- There will be better support for refactoring and comments. Stay tuned.
- There's a WIP PEP8 validator. It's however not in a good shape, yet.

Known Issues
============

- `async`/`await` are already used as keywords in Python3.6.
- `from __future__ import print_function` is not ignored.

Acknowledgements
================

- Guido van Rossum (@gvanrossum) for creating the parser generator pgen2
  (originally used in lib2to3).
- `Salome Schneider <https://www.crepes-schnaegg.ch/cr%C3%AApes-schn%C3%A4gg/kunst-f%C3%BCrs-cr%C3%AApes-mobil/>`_
  for the extremely awesome parso logo.

.. _jedi: https://github.com/davidhalter/jedi


The MIT License (MIT)

Copyright (c) 2014-2017 Matthias C. M. Troffaes
Copyright (c) 2012-2014 Antoine Pitrou and contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


pathlib2
========

|jazzband| |github| |codecov|

Fork of pathlib aiming to support the full stdlib Python API.

The `old pathlib <https://web.archive.org/web/20181106215056/https://bitbucket.org/pitrou/pathlib/>`_
module on bitbucket is no longer maintained.
The goal of pathlib2 is to provide a backport of
`standard pathlib <http://docs.python.org/dev/library/pathlib.html>`_
module which tracks the standard library module,
so all the newest features of the standard pathlib can be
used also on older Python versions.

Download
--------

Standalone releases are available on PyPI:
http://pypi.python.org/pypi/pathlib2/

Development
-----------

The main development takes place in the Python standard library: see
the `Python developer's guide <http://docs.python.org/devguide/>`_.
In particular, new features should be submitted to the
`Python bug tracker <http://bugs.python.org/>`_.

Issues that occur in this backport, but that do not occur not in the
standard Python pathlib module can be submitted on
the `pathlib2 bug tracker <https://github.com/jazzband/pathlib2/issues>`_.

Documentation
-------------

Refer to the
`standard pathlib <http://docs.python.org/dev/library/pathlib.html>`_
documentation.

Known Issues
------------

For historic reasons, pathlib2 still uses bytes to represent file paths internally.
Unfortunately, on Windows with Python 2.7, the file system encoder (``mcbs``)
has only poor support for non-ascii characters,
and can silently replace non-ascii characters without warning.
For example, ``u'тест'.encode(sys.getfilesystemencoding())`` results in ``????``
which is obviously completely useless.

Therefore, on Windows with Python 2.7, until this problem is fixed upstream,
unfortunately you cannot rely on pathlib2 to support the full unicode range for filenames.
See `issue #56 <https://github.com/jazzband/pathlib2/issues/56>`_ for more details.

.. |github| image:: https://github.com/jazzband/pathlib2/actions/workflows/python-package.yml/badge.svg
   :target: https://github.com/jazzband/pathlib2/actions/workflows/python-package.yml
   :alt: github

.. |codecov| image:: https://codecov.io/gh/jazzband/pathlib2/branch/develop/graph/badge.svg
    :target: https://codecov.io/gh/jazzband/pathlib2
    :alt: codecov

.. |jazzband| image:: https://jazzband.co/static/img/badge.svg
   :alt: Jazzband
   :target: https://jazzband.co/


.. image:: https://travis-ci.org/pexpect/pexpect.svg?branch=master
   :target: https://travis-ci.org/pexpect/pexpect
   :align: right
   :alt: Build status

Pexpect is a Pure Python Expect-like module

Pexpect makes Python a better tool for controlling other applications.

Pexpect is a pure Python module for spawning child applications; controlling
them; and responding to expected patterns in their output. Pexpect works like
Don Libes' Expect. Pexpect allows your script to spawn a child application and
control it as if a human were typing commands.

Pexpect can be used for automating interactive applications such as ssh, ftp,
passwd, telnet, etc. It can be used to automate setup scripts for duplicating
software package installations on different servers. It can be used for
automated software testing. Pexpect is in the spirit of Don Libes' Expect, but
Pexpect is pure Python.

The main features of Pexpect require the pty module in the Python standard
library, which is only available on Unix-like systems. Some features—waiting
for patterns from file descriptors or subprocesses—are also available on
Windows.

If you want to work with the development version of the source code then please
read the DEVELOPERS.rst document in the root of the source code tree.

Free, open source, and all that good stuff.

You can install Pexpect using pip::

    pip install pexpect

`Docs on ReadTheDocs <https://pexpect.readthedocs.io/>`_

PEXPECT LICENSE::

    http://opensource.org/licenses/isc-license.txt

    Copyright (c) 2013-2016, Pexpect development team
    Copyright (c) 2012, Noah Spurrier <noah@noah.org>

    PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY
    PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE
    COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES.
    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

This license is approved by the OSI and FSF as GPL-compatible.


PickleShare - a small 'shelve' like datastore with concurrency support

Like shelve, a PickleShareDB object acts like a normal dictionary. Unlike shelve,
many processes can access the database simultaneously. Changing a value in
database is immediately visible to other processes accessing the same database.

Concurrency is possible because the values are stored in separate files. Hence
the "database" is a directory where *all* files are governed by PickleShare.

Both python2 and python3 are supported.

Example usage:

```python

from pickleshare import *
db = PickleShareDB('~/testpickleshare')
db.clear()
print("Should be empty:", db.items())
db['hello'] = 15
db['aku ankka'] = [1,2,313]
db['paths/are/ok/key'] = [1,(5,46)]
print(db.keys())
```

This module is certainly not ZODB, but can be used for low-load
(non-mission-critical) situations where tiny code size trumps the
advanced features of a "real" object database.

Installation guide:

```sh
pip install pickleshare
```

Or, if installing from source

```sh
pip install .
```


====================================================
pluggy - A minimalist production ready plugin system
====================================================

|pypi| |conda-forge| |versions| |travis| |appveyor| |gitter| |black| |codecov|

This is the core framework used by the `pytest`_, `tox`_, and `devpi`_ projects.

Please `read the docs`_ to learn more!

A definitive example
====================
.. code-block:: python

    import pluggy

    hookspec = pluggy.HookspecMarker("myproject")
    hookimpl = pluggy.HookimplMarker("myproject")

    class MySpec(object):
        """A hook specification namespace.
        """

        @hookspec
        def myhook(self, arg1, arg2):
            """My special little hook that you can customize.
            """

    class Plugin_1(object):
        """A hook implementation namespace.
        """

        @hookimpl
        def myhook(self, arg1, arg2):
            print("inside Plugin_1.myhook()")
            return arg1 + arg2

    class Plugin_2(object):
        """A 2nd hook implementation namespace.
        """

        @hookimpl
        def myhook(self, arg1, arg2):
            print("inside Plugin_2.myhook()")
            return arg1 - arg2

    # create a manager and add the spec
    pm = pluggy.PluginManager("myproject")
    pm.add_hookspecs(MySpec)

    # register plugins
    pm.register(Plugin_1())
    pm.register(Plugin_2())

    # call our ``myhook`` hook
    results = pm.hook.myhook(arg1=1, arg2=2)
    print(results)

Running this directly gets us::

    $ python docs/examples/toy-example.py
    inside Plugin_2.myhook()
    inside Plugin_1.myhook()
    [-1, 3]

.. badges

.. |pypi| image:: https://img.shields.io/pypi/v/pluggy.svg
    :target: https://pypi.org/pypi/pluggy

.. |versions| image:: https://img.shields.io/pypi/pyversions/pluggy.svg
    :target: https://pypi.org/pypi/pluggy

.. |travis| image:: https://img.shields.io/travis/pytest-dev/pluggy/master.svg
    :target: https://travis-ci.org/pytest-dev/pluggy

.. |appveyor| image:: https://img.shields.io/appveyor/ci/pytestbot/pluggy/master.svg
    :target: https://ci.appveyor.com/project/pytestbot/pluggy

.. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pluggy.svg
    :target: https://anaconda.org/conda-forge/pytest

.. |gitter| image:: https://badges.gitter.im/pytest-dev/pluggy.svg
    :alt: Join the chat at https://gitter.im/pytest-dev/pluggy
    :target: https://gitter.im/pytest-dev/pluggy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge

.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
    :target: https://github.com/ambv/black

.. |codecov| image:: https://codecov.io/gh/pytest-dev/pluggy/branch/master/graph/badge.svg
    :target: https://codecov.io/gh/pytest-dev/pluggy
    :alt: Code coverage Status

.. links
.. _pytest:
    http://pytest.org
.. _tox:
    https://tox.readthedocs.org
.. _devpi:
    http://doc.devpi.net
.. _read the docs:
   https://pluggy.readthedocs.io/en/latest/


====================================================
pluggy - A minimalist production ready plugin system
====================================================

|pypi| |conda-forge| |versions| |github-actions| |gitter| |black| |codecov|

This is the core framework used by the `pytest`_, `tox`_, and `devpi`_ projects.

Please `read the docs`_ to learn more!

A definitive example
====================
.. code-block:: python

    import pluggy

    hookspec = pluggy.HookspecMarker("myproject")
    hookimpl = pluggy.HookimplMarker("myproject")

    class MySpec:
        """A hook specification namespace."""

        @hookspec
        def myhook(self, arg1, arg2):
            """My special little hook that you can customize."""

    class Plugin_1:
        """A hook implementation namespace."""

        @hookimpl
        def myhook(self, arg1, arg2):
            print("inside Plugin_1.myhook()")
            return arg1 + arg2

    class Plugin_2:
        """A 2nd hook implementation namespace."""

        @hookimpl
        def myhook(self, arg1, arg2):
            print("inside Plugin_2.myhook()")
            return arg1 - arg2

    # create a manager and add the spec
    pm = pluggy.PluginManager("myproject")
    pm.add_hookspecs(MySpec)

    # register plugins
    pm.register(Plugin_1())
    pm.register(Plugin_2())

    # call our ``myhook`` hook
    results = pm.hook.myhook(arg1=1, arg2=2)
    print(results)

Running this directly gets us::

    $ python docs/examples/toy-example.py
    inside Plugin_2.myhook()
    inside Plugin_1.myhook()
    [-1, 3]

.. badges

.. |pypi| image:: https://img.shields.io/pypi/v/pluggy.svg
    :target: https://pypi.org/pypi/pluggy

.. |versions| image:: https://img.shields.io/pypi/pyversions/pluggy.svg
    :target: https://pypi.org/pypi/pluggy

.. |github-actions| image:: https://github.com/pytest-dev/pluggy/workflows/main/badge.svg
    :target: https://github.com/pytest-dev/pluggy/actions

.. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pluggy.svg
    :target: https://anaconda.org/conda-forge/pytest

.. |gitter| image:: https://badges.gitter.im/pytest-dev/pluggy.svg
    :alt: Join the chat at https://gitter.im/pytest-dev/pluggy
    :target: https://gitter.im/pytest-dev/pluggy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge

.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
    :target: https://github.com/ambv/black

.. |codecov| image:: https://codecov.io/gh/pytest-dev/pluggy/branch/master/graph/badge.svg
    :target: https://codecov.io/gh/pytest-dev/pluggy
    :alt: Code coverage Status

.. links
.. _pytest:
    http://pytest.org
.. _tox:
    https://tox.readthedocs.org
.. _devpi:
    http://doc.devpi.net
.. _read the docs:
   https://pluggy.readthedocs.io/en/latest/

Support pluggy
--------------

`Open Collective`_ is an online funding platform for open and transparent communities.
It provides tools to raise money and share your finances in full transparency.

It is the platform of choice for individuals and companies that want to make one-time or
monthly donations directly to the project.

``pluggy`` is part of the ``pytest-dev`` project, see more details in the `pytest collective`_.

.. _Open Collective: https://opencollective.com
.. _pytest collective: https://opencollective.com/pytest


Authors
=======

Creator
-------
Jonathan Slenders <jonathan AT slenders.be>

Contributors
------------

- Amjith Ramanujam <amjith.r AT gmail.com>


Python Prompt Toolkit
=====================

|Build Status|  |PyPI|

``prompt_toolkit`` is a library for building powerful interactive command lines
and terminal applications in Python.

Read the `documentation on readthedocs
<http://python-prompt-toolkit.readthedocs.io/en/stable/>`_.

Ptpython
********

`ptpython <http://github.com/jonathanslenders/ptpython/>`_ is an interactive
Python Shell, build on top of prompt_toolkit.

.. image :: https://github.com/jonathanslenders/python-prompt-toolkit/raw/master/docs/images/ptpython.png

prompt_toolkit features
***********************

``prompt_toolkit`` could be a replacement for `GNU readline
<http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html>`_, but it can be much
more than that.

Some features:

- Pure Python.
- Syntax highlighting of the input while typing. (For instance, with a Pygments lexer.)
- Multi-line input editing.
- Advanced code completion.
- Both Emacs and Vi key bindings. (Similar to readline.)
- Even some advanced Vi functionality, like named registers and digraphs.
- Reverse and forward incremental search.
- Runs on all Python versions from 2.6 up to 3.5.
- Works well with Unicode double width characters. (Chinese input.)
- Selecting text for copy/paste. (Both Emacs and Vi style.)
- Support for `bracketed paste <https://cirw.in/blog/bracketed-paste>`_.
- Mouse support for cursor positioning and scrolling.
- Auto suggestions. (Like `fish shell <http://fishshell.com/>`_.)
- Multiple input buffers.
- No global state.
- Lightweight, the only dependencies are Pygments, six and wcwidth.
- Runs on Linux, OS X, FreeBSD, OpenBSD and Windows systems.
- And much more...

Feel free to create tickets for bugs and feature requests, and create pull
requests if you have nice patches that you would like to share with others.

About Windows support
*********************

``prompt_toolkit`` is cross platform, and everything that you build on top
should run fine on both Unix and Windows systems. On Windows, it uses a
different event loop (``WaitForMultipleObjects`` instead of ``select``), and
another input and output system. (Win32 APIs instead of pseudo-terminals and
VT100.)

It's worth noting that the implementation is a "best effort of what is
possible". Both Unix and Windows terminals have their limitations. But in
general, the Unix experience will still be a little better.

For Windows, it's recommended to use either `cmder
<http://cmder.net/>`_ or `conemu <https://conemu.github.io/>`_.

Installation
************

::

    pip install prompt_toolkit

For Conda, do:

::

    conda install -c https://conda.anaconda.org/conda-forge prompt_toolkit

Getting started
***************

The most simple example of the library would look like this:

.. code:: python

    from prompt_toolkit import prompt

    if __name__ == '__main__':
        answer = prompt('Give me some input: ')
        print('You said: %s' % answer)

For more complex examples, have a look in the ``examples`` directory. All
examples are chosen to demonstrate only one thing. Also, don't be afraid to
look at the source code. The implementation of the ``prompt`` function could be
a good start.

Note for Python 2: all strings are expected to be unicode strings. So, either
put a small ``u`` in front of every string or put ``from __future__ import
unicode_literals`` at the start of the above example.

Projects using prompt_toolkit
*****************************

Shells:

- `ptpython <http://github.com/jonathanslenders/ptpython/>`_: Python REPL
- `ptpdb <http://github.com/jonathanslenders/ptpdb/>`_: Python debugger (pdb replacement)
- `pgcli <http://pgcli.com/>`_: Postgres client.
- `mycli <http://mycli.net>`_: MySql client.
- `wharfee <http://wharfee.com/>`_: A Docker command line.
- `xonsh <http://xon.sh/>`_: A Python-ish, BASHwards-compatible shell.
- `saws <https://github.com/donnemartin/saws>`_: A Supercharged AWS Command Line Interface.
- `cycli <https://github.com/nicolewhite/cycli>`_:  A Command Line Interface for Cypher.
- `crash <https://github.com/crate/crash>`_:  Crate command line client.
- `vcli <https://github.com/dbcli/vcli>`_: Vertica client.
- `aws-shell <https://github.com/awslabs/aws-shell>`_: An integrated shell for working with the AWS CLI.
- `softlayer-python <https://github.com/softlayer/softlayer-python>`_: A command-line interface to manage various SoftLayer products and services.
- `ipython <http://github.com/ipython/ipython/>`_: The IPython REPL
- `click-repl <https://github.com/click-contrib/click-repl>`_: Subcommand REPL for click apps.
- `haxor-news <https://github.com/donnemartin/haxor-news>`_: A Hacker News CLI.
- `gitsome <https://github.com/donnemartin/gitsome>`_: A Git/Shell Autocompleter with GitHub Integration.
- `http-prompt <https://github.com/eliangcs/http-prompt>`_: An interactive command-line HTTP client.
- `coconut <http://coconut-lang.org/>`_: Functional programming in Python.
- `Ergonomica <https://ergonomica.github.io/>`_: A Bash alternative written in Python.
- `Kube-shell <https://github.com/cloudnativelabs/kube-shell>`_: Kubernetes shell: An integrated shell for working with the Kubernetes CLI

Full screen applications:

- `pymux <http://github.com/jonathanslenders/pymux/>`_: A terminal multiplexer (like tmux) in pure Python.
- `pyvim <http://github.com/jonathanslenders/pyvim/>`_: A Vim clone in pure Python.

(Want your own project to be listed here? Please create a GitHub issue.)

Philosophy
**********

The source code of ``prompt_toolkit`` should be readable, concise and
efficient. We prefer short functions focussing each on one task and for which
the input and output types are clearly specified. We mostly prefer composition
over inheritance, because inheritance can result in too much functionality in
the same object. We prefer immutable objects where possible (objects don't
change after initialisation). Reusability is important. We absolutely refrain
from having a changing global state, it should be possible to have multiple
independent instances of the same code in the same process. The architecture
should be layered: the lower levels operate on primitive operations and data
structures giving -- when correctly combined -- all the possible flexibility;
while at the higher level, there should be a simpler API, ready-to-use and
sufficient for most use cases. Thinking about algorithms and efficiency is
important, but avoid premature optimization.

Special thanks to
*****************

- `Pygments <http://pygments.org/>`_: Syntax highlighter.
- `wcwidth <https://github.com/jquast/wcwidth>`_: Determine columns needed for a wide characters.

.. |Build Status| image:: https://api.travis-ci.org/jonathanslenders/python-prompt-toolkit.svg?branch=master
    :target: https://travis-ci.org/jonathanslenders/python-prompt-toolkit#

.. |PyPI| image:: https://img.shields.io/pypi/v/prompt_toolkit.svg
    :target: https://pypi.python.org/pypi/prompt-toolkit/
    :alt: Latest Version


Python Prompt Toolkit
=====================

|AppVeyor|  |PyPI|  |RTD|  |License|  |Codecov|

.. image :: https://github.com/prompt-toolkit/python-prompt-toolkit/raw/master/docs/images/logo_400px.png

``prompt_toolkit`` *is a library for building powerful interactive command line applications in Python.*

Read the `documentation on readthedocs
<http://python-prompt-toolkit.readthedocs.io/en/stable/>`_.

Gallery
*******

`ptpython <http://github.com/prompt-toolkit/ptpython/>`_ is an interactive
Python Shell, build on top of ``prompt_toolkit``.

.. image :: https://github.com/prompt-toolkit/python-prompt-toolkit/raw/master/docs/images/ptpython.png

`More examples <https://python-prompt-toolkit.readthedocs.io/en/stable/pages/gallery.html>`_

prompt_toolkit features
***********************

``prompt_toolkit`` could be a replacement for `GNU readline
<https://tiswww.case.edu/php/chet/readline/rltop.html>`_, but it can be much
more than that.

Some features:

- **Pure Python**.
- Syntax highlighting of the input while typing. (For instance, with a Pygments lexer.)
- Multi-line input editing.
- Advanced code completion.
- Both Emacs and Vi key bindings. (Similar to readline.)
- Even some advanced Vi functionality, like named registers and digraphs.
- Reverse and forward incremental search.
- Works well with Unicode double width characters. (Chinese input.)
- Selecting text for copy/paste. (Both Emacs and Vi style.)
- Support for `bracketed paste <https://cirw.in/blog/bracketed-paste>`_.
- Mouse support for cursor positioning and scrolling.
- Auto suggestions. (Like `fish shell <http://fishshell.com/>`_.)
- Multiple input buffers.
- No global state.
- Lightweight, the only dependencies are Pygments and wcwidth.
- Runs on Linux, OS X, FreeBSD, OpenBSD and Windows systems.
- And much more...

Feel free to create tickets for bugs and feature requests, and create pull
requests if you have nice patches that you would like to share with others.

Installation
************

::

    pip install prompt_toolkit

For Conda, do:

::

    conda install -c https://conda.anaconda.org/conda-forge prompt_toolkit

About Windows support
*********************

``prompt_toolkit`` is cross platform, and everything that you build on top
should run fine on both Unix and Windows systems. Windows support is best on
recent Windows 10 builds, for which the command line window supports vt100
escape sequences. (If not supported, we fall back to using Win32 APIs for color
and cursor movements).

It's worth noting that the implementation is a "best effort of what is
possible". Both Unix and Windows terminals have their limitations. But in
general, the Unix experience will still be a little better.

Getting started
***************

The most simple example of the library would look like this:

.. code:: python

    from prompt_toolkit import prompt

    if __name__ == '__main__':
        answer = prompt('Give me some input: ')
        print('You said: %s' % answer)

For more complex examples, have a look in the ``examples`` directory. All
examples are chosen to demonstrate only one thing. Also, don't be afraid to
look at the source code. The implementation of the ``prompt`` function could be
a good start.

Philosophy
**********

The source code of ``prompt_toolkit`` should be **readable**, **concise** and
**efficient**. We prefer short functions focusing each on one task and for which
the input and output types are clearly specified. We mostly prefer composition
over inheritance, because inheritance can result in too much functionality in
the same object. We prefer immutable objects where possible (objects don't
change after initialization). Reusability is important. We absolutely refrain
from having a changing global state, it should be possible to have multiple
independent instances of the same code in the same process. The architecture
should be layered: the lower levels operate on primitive operations and data
structures giving -- when correctly combined -- all the possible flexibility;
while at the higher level, there should be a simpler API, ready-to-use and
sufficient for most use cases. Thinking about algorithms and efficiency is
important, but avoid premature optimization.

`Projects using prompt_toolkit <PROJECTS.rst>`_
***********************************************

Special thanks to
*****************

- `Pygments <http://pygments.org/>`_: Syntax highlighter.
- `wcwidth <https://github.com/jquast/wcwidth>`_: Determine columns needed for a wide characters.

.. |PyPI| image:: https://img.shields.io/pypi/v/prompt_toolkit.svg
    :target: https://pypi.python.org/pypi/prompt-toolkit/
    :alt: Latest Version

.. |AppVeyor| image:: https://ci.appveyor.com/api/projects/status/32r7s2skrgm9ubva?svg=true
    :target: https://ci.appveyor.com/project/prompt-toolkit/python-prompt-toolkit/

.. |RTD| image:: https://readthedocs.org/projects/python-prompt-toolkit/badge/
    :target: https://python-prompt-toolkit.readthedocs.io/en/master/

.. |License| image:: https://img.shields.io/github/license/prompt-toolkit/python-prompt-toolkit.svg
    :target: https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/LICENSE

.. |Codecov| image:: https://codecov.io/gh/prompt-toolkit/python-prompt-toolkit/branch/master/graphs/badge.svg?style=flat
    :target: https://codecov.io/gh/prompt-toolkit/python-prompt-toolkit/


This project is governed by
[Protobuf's Code of Conduct](https://github.com/protocolbuffers/.github/blob/main/profile/CODE_OF_CONDUCT.md).


# Contributing to Protocol Buffers

We welcome some types of contributions to protocol buffers. This doc describes the
process to contribute patches to protobuf and the general guidelines we
expect contributors to follow.

## What We Accept

* Bug fixes with unit tests demonstrating the problem are very welcome.
  We also appreciate bug reports, even when they don't come with a patch.
  Bug fixes without tests are usually not accepted.
* New APIs and features with adequate test coverage and documentation
  may be accepted if they do not compromise backwards
  compatibility. However there's a fairly high bar of usefulness a new public
  method must clear before it will be accepted. Features that are fine in
  isolation are often rejected because they don't have enough impact to justify the
  conceptual burden and ongoing maintenance cost. It's best to file an issue
  and get agreement from maintainers on the value of a new feature before
  working on a PR.
* Performance optimizations may be accepted if they have convincing benchmarks that demonstrate
  an improvement and they do not significantly increase complexity.
* Changes to existing APIs are almost never accepted. Stability and
  backwards compatibility are paramount. In the unlikely event a breaking change
  is required, it must usually be implemented in google3 first.
* Changes to the wire and text formats are never accepted. Any breaking change
  to these formats would have to be implemented as a completely new format.
  We cannot begin generating protos that cannot be parsed by existing code.

## Before You Start

We accept patches in the form of github pull requests. If you are new to
github, please read [How to create github pull requests](https://help.github.com/articles/about-pull-requests/)
first.

### Contributor License Agreements

Contributions to this project must be accompanied by a Contributor License
Agreement. You (or your employer) retain the copyright to your contribution,
this simply gives us permission to use and redistribute your contributions
as part of the project.

* If you are an individual writing original source code and you're sure you
  own the intellectual property, then you'll need to sign an [individual CLA](https://cla.developers.google.com/about/google-individual?csw=1).
* If you work for a company that wants to allow you to contribute your work,
  then you'll need to sign a [corporate CLA](https://cla.developers.google.com/about/google-corporate?csw=1).

### Coding Style

This project follows [Google’s Coding Style Guides](https://github.com/google/styleguide).
Before sending out your pull request, please familiarize yourself with the
corresponding style guides and make sure the proposed code change is style
conforming.

## Contributing Process

Most pull requests should go to the main branch and the change will be
included in the next major/minor version release (e.g., 3.6.0 release). If you
need to include a bug fix in a patch release (e.g., 3.5.2), make sure it’s
already merged to main, and then create a pull request cherry-picking the
commits from main branch to the release branch (e.g., branch 3.5.x).

For each pull request, a protobuf team member will be assigned to review the
pull request. For minor cleanups, the pull request may be merged right away
after an initial review. For larger changes, you will likely receive multiple
rounds of comments and it may take some time to complete. We will try to keep
our response time within 7-days but if you don’t get any response in a few
days, feel free to comment on the threads to get our attention. We also expect
you to respond to our comments within a reasonable amount of time. If we don’t
hear from you for 2 weeks or longer, we may close the pull request. You can
still send the pull request again once you have time to work on it.

Once a pull request is merged, we will take care of the rest and get it into
the final release.

## Pull Request Guidelines

* If you are a Googler, it is preferable to first create an internal CL and
  have it reviewed and submitted. The code propagation process will deliver the
  change to GitHub.
* Create small PRs that are narrowly focused on addressing a single concern.
  We often receive PRs that are trying to fix several things at a time, but if
  only one fix is considered acceptable, nothing gets merged and both author's
  & reviewer's time is wasted. Create more PRs to address different concerns and
  everyone will be happy.
* For speculative changes, consider opening an issue and discussing it first.
  If you are suggesting a behavioral or API change, make sure you get explicit
  support from a protobuf team member before sending us the pull request.
* Provide a good PR description as a record of what change is being made and
  why it was made. Link to a GitHub issue if it exists.
* Don't fix code style and formatting unless you are already changing that
  line to address an issue. PRs with irrelevant changes won't be merged. If
  you do want to fix formatting or style, do that in a separate PR.
* Unless your PR is trivial, you should expect there will be reviewer comments
  that you'll need to address before merging. We expect you to be reasonably
  responsive to those comments, otherwise the PR will be closed after 2-3 weeks
  of inactivity.
* Maintain clean commit history and use meaningful commit messages. PRs with
  messy commit history are difficult to review and won't be merged. Use rebase
  -i upstream/main to curate your commit history and/or to bring in latest
  changes from main (but avoid rebasing in the middle of a code review).
* Keep your PR up to date with upstream/main (if there are merge conflicts,
  we can't really merge your change).
* All tests need to be passing before your change can be merged. We recommend
  you run tests locally before creating your PR to catch breakages early on.
  Ultimately, the green signal will be provided by our testing infrastructure.
  The reviewer will help you if there are test failures that seem not related
  to the change you are making.

## Reviewer Guidelines

* Make sure that all tests are passing before approval.
* Apply the "release notes: yes" label if the pull request's description should
  be included in the next release (e.g., any new feature / bug fix).
  Apply the "release notes: no" label if the pull request's description should
  not be included in the next release (e.g., refactoring changes that does not
  change behavior, integration from Google internal, updating tests, etc.).
* Apply the appropriate language label (e.g., C++, Java, Python, etc.) to the
  pull request. This will make it easier to identify which languages the pull
  request affects, allowing us to better identify appropriate reviewer, create
  a better release note, and make it easier to identify issues in the future.


Protocol Buffers - Google's data interchange format
===================================================

Copyright 2008 Google Inc.

[Protocol Buffers documentation](https://developers.google.com/protocol-buffers/)

Overview
--------

Protocol Buffers (a.k.a., protobuf) are Google's language-neutral,
platform-neutral, extensible mechanism for serializing structured data. You
can find [protobuf's documentation on the Google Developers site](https://developers.google.com/protocol-buffers/).

This README file contains protobuf installation instructions. To install
protobuf, you need to install the protocol compiler (used to compile .proto
files) and the protobuf runtime for your chosen programming language.

Protocol Compiler Installation
------------------------------

The protocol compiler is written in C++. If you are using C++, please follow
the [C++ Installation Instructions](src/README.md) to install protoc along
with the C++ runtime.

For non-C++ users, the simplest way to install the protocol compiler is to
download a pre-built binary from our [GitHub release page](https://github.com/protocolbuffers/protobuf/releases).

In the downloads section of each release, you can find pre-built binaries in
zip packages: `protoc-$VERSION-$PLATFORM.zip`. It contains the protoc binary
as well as a set of standard `.proto` files distributed along with protobuf.

If you are looking for an old version that is not available in the release
page, check out the [Maven repository](https://repo1.maven.org/maven2/com/google/protobuf/protoc/).

These pre-built binaries are only provided for released versions. If you want
to use the github main version at HEAD, or you need to modify protobuf code,
or you are using C++, it's recommended to build your own protoc binary from
source.

If you would like to build protoc binary from source, see the [C++ Installation Instructions](src/README.md).

Protobuf Runtime Installation
-----------------------------

Protobuf supports several different programming languages. For each programming
language, you can find instructions in the corresponding source directory about
how to install protobuf runtime for that specific language:

| Language                             | Source                                                      |
|--------------------------------------|-------------------------------------------------------------|
| C++ (include C++ runtime and protoc) | [src](src)                                                  |
| Java                                 | [java](java)                                                |
| Python                               | [python](python)                                            |
| Objective-C                          | [objectivec](objectivec)                                    |
| C#                                   | [csharp](csharp)                                            |
| Ruby                                 | [ruby](ruby)                                                |
| Go                                   | [protocolbuffers/protobuf-go](https://github.com/protocolbuffers/protobuf-go)|
| PHP                                  | [php](php)                                                  |
| Dart                                 | [dart-lang/protobuf](https://github.com/dart-lang/protobuf) |
| Javascript                           | [protocolbuffers/protobuf-javascript](https://github.com/protocolbuffers/protobuf-javascript)|

Quick Start
-----------

The best way to learn how to use protobuf is to follow the [tutorials in our
developer guide](https://developers.google.com/protocol-buffers/docs/tutorials).

If you want to learn from code examples, take a look at the examples in the
[examples](examples) directory.

Documentation
-------------

The complete documentation is available via the [Protocol Buffers documentation](https://developers.google.com/protocol-buffers/).

Developer Community
-------------------

To be alerted to upcoming changes in Protocol Buffers and connect with protobuf developers and users,
[join the Google Group](https://groups.google.com/g/protobuf).


To report security concerns or vulnerabilities within protobuf, please use
Google's official channel for reporting these.

https://www.google.com/appserve/security-bugs/m2/new


Launch a subprocess in a pseudo terminal (pty), and interact with both the
process and its pty.

Sometimes, piping stdin and stdout is not enough. There might be a password
prompt that doesn't read from stdin, output that changes when it's going to a
pipe rather than a terminal, or curses-style interfaces that rely on a terminal.
If you need to automate these things, running the process in a pseudo terminal
(pty) is the answer.

Interface::

    p = PtyProcessUnicode.spawn(['python'])
    p.read(20)
    p.write('6+6\n')
    p.read(20)


.. image:: https://img.shields.io/pypi/v/py.svg
    :target: https://pypi.org/project/py

.. image:: https://img.shields.io/conda/vn/conda-forge/py.svg
    :target: https://anaconda.org/conda-forge/py

.. image:: https://img.shields.io/pypi/pyversions/py.svg
  :target: https://pypi.org/project/py

.. image:: https://github.com/pytest-dev/py/workflows/build/badge.svg
  :target: https://github.com/pytest-dev/py/actions

**NOTE**: this library is in **maintenance mode** and should not be used in new code.

The py lib is a Python development support library featuring
the following tools and modules:

* ``py.path``:  uniform local and svn path objects  -> please use pathlib/pathlib2 instead
* ``py.apipkg``:  explicit API control and lazy-importing -> please use the standalone package instead
* ``py.iniconfig``:  easy parsing of .ini files -> please use the standalone package instead
* ``py.code``: dynamic code generation and introspection (deprecated, moved to ``pytest`` as a implementation detail).

**NOTE**: prior to the 1.4 release this distribution used to
contain py.test which is now its own package, see https://docs.pytest.org

For questions and more information please visit https://py.readthedocs.io

Bugs and issues: https://github.com/pytest-dev/py

Authors: Holger Krekel and others, 2004-2017


PyParsing -- A Python Parsing Module
====================================

|Build Status|

Introduction
============

The pyparsing module is an alternative approach to creating and
executing simple grammars, vs. the traditional lex/yacc approach, or the
use of regular expressions. The pyparsing module provides a library of
classes that client code uses to construct the grammar directly in
Python code.

*[Since first writing this description of pyparsing in late 2003, this
technique for developing parsers has become more widespread, under the
name Parsing Expression Grammars - PEGs. See more information on PEGs at*
https://en.wikipedia.org/wiki/Parsing_expression_grammar *.]*

Here is a program to parse ``"Hello, World!"`` (or any greeting of the form
``"salutation, addressee!"``):

.. code:: python

    from pyparsing import Word, alphas
    greet = Word(alphas) + "," + Word(alphas) + "!"
    hello = "Hello, World!"
    print(hello, "->", greet.parseString(hello))

The program outputs the following::

    Hello, World! -> ['Hello', ',', 'World', '!']

The Python representation of the grammar is quite readable, owing to the
self-explanatory class names, and the use of '+', '|' and '^' operator
definitions.

The parsed results returned from ``parseString()`` can be accessed as a
nested list, a dictionary, or an object with named attributes.

The pyparsing module handles some of the problems that are typically
vexing when writing text parsers:

- extra or missing whitespace (the above program will also handle ``"Hello,World!"``, ``"Hello , World !"``, etc.)
- quoted strings
- embedded comments

The examples directory includes a simple SQL parser, simple CORBA IDL
parser, a config file parser, a chemical formula parser, and a four-
function algebraic notation parser, among many others.

Documentation
=============

There are many examples in the online docstrings of the classes
and methods in pyparsing. You can find them compiled into online docs
at https://pyparsing-docs.readthedocs.io/en/latest/. Additional
documentation resources and project info are listed in the online
GitHub wiki, at https://github.com/pyparsing/pyparsing/wiki. An
entire directory of examples is at
https://github.com/pyparsing/pyparsing/tree/master/examples.

License
=======

MIT License. See header of pyparsing.py

History
=======

See CHANGES file.

.. |Build Status| image:: https://travis-ci.org/pyparsing/pyparsing.svg?branch=master
   :target: https://travis-ci.org/pyparsing/pyparsing


PyParsing -- A Python Parsing Module
====================================

|Version| |Build Status| |Coverage| |License| |Python Versions| |Snyk Score|

Introduction
============

The pyparsing module is an alternative approach to creating and
executing simple grammars, vs. the traditional lex/yacc approach, or the
use of regular expressions. The pyparsing module provides a library of
classes that client code uses to construct the grammar directly in
Python code.

*[Since first writing this description of pyparsing in late 2003, this
technique for developing parsers has become more widespread, under the
name Parsing Expression Grammars - PEGs. See more information on PEGs*
`here <https://en.wikipedia.org/wiki/Parsing_expression_grammar>`__
*.]*

Here is a program to parse ``"Hello, World!"`` (or any greeting of the form
``"salutation, addressee!"``):

.. code:: python

    from pyparsing import Word, alphas
    greet = Word(alphas) + "," + Word(alphas) + "!"
    hello = "Hello, World!"
    print(hello, "->", greet.parseString(hello))

The program outputs the following::

    Hello, World! -> ['Hello', ',', 'World', '!']

The Python representation of the grammar is quite readable, owing to the
self-explanatory class names, and the use of '+', '|' and '^' operator
definitions.

The parsed results returned from ``parseString()`` is a collection of type
``ParseResults``, which can be accessed as a
nested list, a dictionary, or an object with named attributes.

The pyparsing module handles some of the problems that are typically
vexing when writing text parsers:

- extra or missing whitespace (the above program will also handle ``"Hello,World!"``, ``"Hello , World !"``, etc.)
- quoted strings
- embedded comments

The examples directory includes a simple SQL parser, simple CORBA IDL
parser, a config file parser, a chemical formula parser, and a four-
function algebraic notation parser, among many others.

Documentation
=============

There are many examples in the online docstrings of the classes
and methods in pyparsing. You can find them compiled into `online docs <https://pyparsing-docs.readthedocs.io/en/latest/>`__. Additional
documentation resources and project info are listed in the online
`GitHub wiki <https://github.com/pyparsing/pyparsing/wiki>`__. An
entire directory of examples can be found `here <https://github.com/pyparsing/pyparsing/tree/master/examples>`__.

License
=======

MIT License. See header of the `pyparsing __init__.py <https://github.com/pyparsing/pyparsing/blob/master/pyparsing/__init__.py#L1-L23>`__ file.

History
=======

See `CHANGES <https://github.com/pyparsing/pyparsing/blob/master/CHANGES>`__ file.

.. |Build Status| image:: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml/badge.svg
   :target: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml

.. |Coverage| image:: https://codecov.io/gh/pyparsing/pyparsing/branch/master/graph/badge.svg
  :target: https://codecov.io/gh/pyparsing/pyparsing

.. |Version| image:: https://img.shields.io/pypi/v/pyparsing?style=flat-square
    :target: https://pypi.org/project/pyparsing/
    :alt: Version

.. |License| image:: https://img.shields.io/pypi/l/pyparsing.svg?style=flat-square
    :target: https://pypi.org/project/pyparsing/
    :alt: License

.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/pyparsing.svg?style=flat-square
    :target: https://pypi.org/project/python-liquid/
    :alt: Python versions

.. |Snyk Score| image:: https://snyk.io//advisor/python/pyparsing/badge.svg
   :target: https://snyk.io//advisor/python/pyparsing
   :alt: pyparsing


.. image:: https://docs.pytest.org/en/latest/_static/pytest1.png
   :target: https://docs.pytest.org/en/latest/
   :align: center
   :alt: pytest

------

.. image:: https://img.shields.io/pypi/v/pytest.svg
    :target: https://pypi.org/project/pytest/

.. image:: https://img.shields.io/conda/vn/conda-forge/pytest.svg
    :target: https://anaconda.org/conda-forge/pytest

.. image:: https://img.shields.io/pypi/pyversions/pytest.svg
    :target: https://pypi.org/project/pytest/

.. image:: https://codecov.io/gh/pytest-dev/pytest/branch/master/graph/badge.svg
    :target: https://codecov.io/gh/pytest-dev/pytest
    :alt: Code coverage Status

.. image:: https://travis-ci.org/pytest-dev/pytest.svg?branch=master
    :target: https://travis-ci.org/pytest-dev/pytest

.. image:: https://dev.azure.com/pytest-dev/pytest/_apis/build/status/pytest-CI?branchName=master
    :target: https://dev.azure.com/pytest-dev/pytest

.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
    :target: https://github.com/python/black

.. image:: https://www.codetriage.com/pytest-dev/pytest/badges/users.svg
    :target: https://www.codetriage.com/pytest-dev/pytest

The ``pytest`` framework makes it easy to write small tests, yet
scales to support complex functional testing for applications and libraries.

An example of a simple test:

.. code-block:: python

    # content of test_sample.py
    def inc(x):
        return x + 1

    def test_answer():
        assert inc(3) == 5

To execute it::

    $ pytest
    ============================= test session starts =============================
    collected 1 items

    test_sample.py F

    ================================== FAILURES ===================================
    _________________________________ test_answer _________________________________

        def test_answer():
    >       assert inc(3) == 5
    E       assert 4 == 5
    E        +  where 4 = inc(3)

    test_sample.py:5: AssertionError
    ========================== 1 failed in 0.04 seconds ===========================

Due to ``pytest``'s detailed assertion introspection, only plain ``assert`` statements are used. See `getting-started <https://docs.pytest.org/en/latest/getting-started.html#our-first-test-run>`_ for more examples.

Features
--------

- Detailed info on failing `assert statements <https://docs.pytest.org/en/latest/assert.html>`_ (no need to remember ``self.assert*`` names);

- `Auto-discovery
  <https://docs.pytest.org/en/latest/goodpractices.html#python-test-discovery>`_
  of test modules and functions;

- `Modular fixtures <https://docs.pytest.org/en/latest/fixture.html>`_ for
  managing small or parametrized long-lived test resources;

- Can run `unittest <https://docs.pytest.org/en/latest/unittest.html>`_ (or trial),
  `nose <https://docs.pytest.org/en/latest/nose.html>`_ test suites out of the box;

- Python 2.7, Python 3.4+, PyPy 2.3, Jython 2.5 (untested);

- Rich plugin architecture, with over 315+ `external plugins <http://plugincompat.herokuapp.com>`_ and thriving community;

Documentation
-------------

For full documentation, including installation, tutorials and PDF documents, please see https://docs.pytest.org/en/latest/.

Bugs/Requests
-------------

Please use the `GitHub issue tracker <https://github.com/pytest-dev/pytest/issues>`_ to submit bugs or request features.

Changelog
---------

Consult the `Changelog <https://docs.pytest.org/en/latest/changelog.html>`__ page for fixes and enhancements of each version.

Support pytest
--------------

You can support pytest by obtaining a `Tideflift subscription`_.

Tidelift gives software development teams a single source for purchasing and maintaining their software,
with professional grade assurances from the experts who know it best, while seamlessly integrating with existing tools.

.. _`Tideflift subscription`: https://tidelift.com/subscription/pkg/pypi-pytest?utm_source=pypi-pytest&utm_medium=referral&utm_campaign=readme

Security
^^^^^^^^

pytest has never been associated with a security vunerability, but in any case, to report a
security vulnerability please use the `Tidelift security contact <https://tidelift.com/security>`_.
Tidelift will coordinate the fix and disclosure.

License
-------

Copyright Holger Krekel and others, 2004-2020.

Distributed under the terms of the `MIT`_ license, pytest is free and open source software.

.. _`MIT`: https://github.com/pytest-dev/pytest/blob/master/LICENSE


.. image:: https://github.com/pytest-dev/pytest/raw/main/doc/en/img/pytest_logo_curves.svg
   :target: https://docs.pytest.org/en/stable/
   :align: center
   :height: 200
   :alt: pytest

------

.. image:: https://img.shields.io/pypi/v/pytest.svg
    :target: https://pypi.org/project/pytest/

.. image:: https://img.shields.io/conda/vn/conda-forge/pytest.svg
    :target: https://anaconda.org/conda-forge/pytest

.. image:: https://img.shields.io/pypi/pyversions/pytest.svg
    :target: https://pypi.org/project/pytest/

.. image:: https://codecov.io/gh/pytest-dev/pytest/branch/main/graph/badge.svg
    :target: https://codecov.io/gh/pytest-dev/pytest
    :alt: Code coverage Status

.. image:: https://github.com/pytest-dev/pytest/workflows/test/badge.svg
    :target: https://github.com/pytest-dev/pytest/actions?query=workflow%3Atest

.. image:: https://results.pre-commit.ci/badge/github/pytest-dev/pytest/main.svg
   :target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest/main
   :alt: pre-commit.ci status

.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
    :target: https://github.com/psf/black

.. image:: https://www.codetriage.com/pytest-dev/pytest/badges/users.svg
    :target: https://www.codetriage.com/pytest-dev/pytest

.. image:: https://readthedocs.org/projects/pytest/badge/?version=latest
    :target: https://pytest.readthedocs.io/en/latest/?badge=latest
    :alt: Documentation Status

.. image:: https://img.shields.io/badge/Discord-pytest--dev-blue
    :target: https://discord.com/invite/pytest-dev
    :alt: Discord

.. image:: https://img.shields.io/badge/Libera%20chat-%23pytest-orange
    :target: https://web.libera.chat/#pytest
    :alt: Libera chat

The ``pytest`` framework makes it easy to write small tests, yet
scales to support complex functional testing for applications and libraries.

An example of a simple test:

.. code-block:: python

    # content of test_sample.py
    def inc(x):
        return x + 1

    def test_answer():
        assert inc(3) == 5

To execute it::

    $ pytest
    ============================= test session starts =============================
    collected 1 items

    test_sample.py F

    ================================== FAILURES ===================================
    _________________________________ test_answer _________________________________

        def test_answer():
    >       assert inc(3) == 5
    E       assert 4 == 5
    E        +  where 4 = inc(3)

    test_sample.py:5: AssertionError
    ========================== 1 failed in 0.04 seconds ===========================

Due to ``pytest``'s detailed assertion introspection, only plain ``assert`` statements are used. See `getting-started <https://docs.pytest.org/en/stable/getting-started.html#our-first-test-run>`_ for more examples.

Features
--------

- Detailed info on failing `assert statements <https://docs.pytest.org/en/stable/how-to/assert.html>`_ (no need to remember ``self.assert*`` names)

- `Auto-discovery
  <https://docs.pytest.org/en/stable/explanation/goodpractices.html#python-test-discovery>`_
  of test modules and functions

- `Modular fixtures <https://docs.pytest.org/en/stable/explanation/fixtures.html>`_ for
  managing small or parametrized long-lived test resources

- Can run `unittest <https://docs.pytest.org/en/stable/how-to/unittest.html>`_ (or trial),
  `nose <https://docs.pytest.org/en/stable/how-to/nose.html>`_ test suites out of the box

- Python 3.7+ or PyPy3

- Rich plugin architecture, with over 850+ `external plugins <https://docs.pytest.org/en/latest/reference/plugin_list.html>`_ and thriving community

Documentation
-------------

For full documentation, including installation, tutorials and PDF documents, please see https://docs.pytest.org/en/stable/.

Bugs/Requests
-------------

Please use the `GitHub issue tracker <https://github.com/pytest-dev/pytest/issues>`_ to submit bugs or request features.

Changelog
---------

Consult the `Changelog <https://docs.pytest.org/en/stable/changelog.html>`__ page for fixes and enhancements of each version.

Support pytest
--------------

`Open Collective`_ is an online funding platform for open and transparent communities.
It provides tools to raise money and share your finances in full transparency.

It is the platform of choice for individuals and companies that want to make one-time or
monthly donations directly to the project.

See more details in the `pytest collective`_.

.. _Open Collective: https://opencollective.com
.. _pytest collective: https://opencollective.com/pytest

pytest for enterprise
---------------------

Available as part of the Tidelift Subscription.

The maintainers of pytest and thousands of other packages are working with Tidelift to deliver commercial support and
maintenance for the open source dependencies you use to build your applications.
Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use.

`Learn more. <https://tidelift.com/subscription/pkg/pypi-pytest?utm_source=pypi-pytest&utm_medium=referral&utm_campaign=enterprise&utm_term=repo>`_

Security
^^^^^^^^

pytest has never been associated with a security vulnerability, but in any case, to report a
security vulnerability please use the `Tidelift security contact <https://tidelift.com/security>`_.
Tidelift will coordinate the fix and disclosure.

License
-------

Copyright Holger Krekel and others, 2004.

Distributed under the terms of the `MIT`_ license, pytest is free and open source software.

.. _`MIT`: https://github.com/pytest-dev/pytest/blob/main/LICENSE