New Upstream Release - pytest-cython

Ready changes

Summary

Merged new upstream version: 0.2.1 (was: 0.2.0).

Diff

diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index f776777..9badf3b 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,12 +1,20 @@
 [bumpversion]
-current_version = 0.1.1
-commit = True
-tag = True
+current_version = 0.2.1
+parse = 
+	(?P<major>\d+)\.(?P<minor>\d+)\.(?P<micro>\d+)
+	(?:\.(?P<release>dev)(?P<devnum>\d+))?
+serialize = 
+	{major}.{minor}.{micro}.{release}{devnum}
+	{major}.{minor}.{micro}
+commit = False
+tag = False
 
-[bumpversion:file:setup.py]
-
-[bumpversion:file:docs/conf.py]
+[bumpversion:part:release]
+optional_value = stable
+values = 
+	dev
+	stable
 
-[bumpversion:file:src/pytest_cython/__init__.py]
+[bumpversion:file:setup.py]
 
 [bumpversion:file:tests/example-project/setup.py]
diff --git a/.cookiecutterrc b/.cookiecutterrc
deleted file mode 100644
index 31422fa..0000000
--- a/.cookiecutterrc
+++ /dev/null
@@ -1,49 +0,0 @@
-# This file exists so you can easily regenerate your project.
-#
-# `cookiepatcher` is a convenient shim around `cookiecutter`
-# for regenerating projects (it will generate a .cookiecutterrc
-# automatically for any template). To use it:
-#
-#    pip install cookiepatcher
-#    cookiepatcher gh:ionelmc/cookiecutter-pylibrary project-path
-#
-# See:
-#    https://pypi.org/project/cookiecutter
-#
-# Alternatively, you can run:
-#
-#    cookiecutter --overwrite-if-exists --config-file=project-path/.cookiecutterrc gh:ionelmc/cookiecutter-pylibrary
-
-default_context:
-
-    appveyor:                  'yes'
-    c_extension_cython:        'no'
-    c_extension_optional:      'no'
-    c_extension_support:       'no'
-    codacy:                    'no'
-    codeclimate:               'no'
-    codecov:                   'no'
-    command_line_interface:    'no'
-    command_line_interface_bin_name: 'pytest-cython'
-    coveralls:                 'no'
-    distribution_name:         'pytest-cython'
-    email:                     'page.lg@gmail.com'
-    full_name:                 'Logan Page'
-    github_username:           'lgpage'
-    landscape:                 'no'
-    package_name:              'pytest_cython'
-    project_name:              'pytest-cython'
-    project_short_description: 'A plugin for testing Cython extension modules'
-    release_date:              'today'
-    repo_name:                 'pytest-cython'
-    requiresio:                'yes'
-    scrutinizer:               'no'
-    sphinx_doctest:            'no'
-    sphinx_theme:              'sphinx-py3doc-enhanced-theme'
-    test_matrix_configurator:  'yes'
-    test_matrix_separate_coverage: 'no'
-    test_runner:               'pytest'
-    travis:                    'yes'
-    version:                   '0.1.0'
-    website:                   'https://github.com/lgpage/pytest-cython'
-    year:                      'now'
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index e27fe32..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,67 +0,0 @@
-*.py[cod]
-
-# C extensions
-*.so
-
-# IDE
-.vscode/settings.json
-
-# Packages
-*.egg
-*.egg-info
-dist
-build
-eggs
-.eggs
-parts
-bin
-var
-sdist
-develop-eggs
-.installed.cfg
-lib
-lib64
-venv*/
-.venv
-pyvenv*/
-
-# Installer logs
-pip-log.txt
-
-# Unit test / coverage reports
-.coverage
-.tox
-.coverage.*
-nosetests.xml
-coverage.xml
-htmlcov
-
-# Translations
-*.mo
-
-# Mr Developer
-.mr.developer.cfg
-.project
-.pydevproject
-.idea
-*.iml
-*.komodoproject
-
-# Complexity
-output/*.html
-output/*/index.html
-
-# Sphinx
-docs/_build
-
-.DS_Store
-*~
-.*.sw[po]
-.build
-.ve
-.env
-.cache
-.pytest
-.bootstrap
-.appveyor.token
-*.bak
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index d5a65e5..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-language: python
-python: '3.5'
-sudo: false
-env:
-  global:
-    - LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so
-    - SEGFAULT_SIGNALS=all
-  matrix:
-    - TOXENV=check
-
-    - TOXENV=py26-27-023
-    - TOXENV=py26-27-024
-    - TOXENV=py26-28-023
-    - TOXENV=py26-28-024
-    - TOXENV=py26-29-023
-    - TOXENV=py26-29-024
-    - TOXENV=py27-27-023
-    - TOXENV=py27-27-024
-    - TOXENV=py27-28-023
-    - TOXENV=py27-28-024
-    - TOXENV=py27-29-023
-    - TOXENV=py27-29-024
-    - TOXENV=py33-27-023
-    - TOXENV=py33-27-024
-    - TOXENV=py33-28-023
-    - TOXENV=py33-28-024
-    - TOXENV=py33-29-023
-    - TOXENV=py33-29-024
-    - TOXENV=py34-27-023
-    - TOXENV=py34-27-024
-    - TOXENV=py34-28-023
-    - TOXENV=py34-28-024
-    - TOXENV=py34-29-023
-    - TOXENV=py34-29-024
-    - TOXENV=py35-27-023
-    - TOXENV=py35-27-024
-    - TOXENV=py35-28-023
-    - TOXENV=py35-28-024
-    - TOXENV=py35-29-023
-    - TOXENV=py35-29-024
-    - TOXENV=pypy-27-024
-    - TOXENV=pypy-28-024
-    - TOXENV=pypy-29-024
-before_install:
-  - python --version
-  - uname -a
-  - lsb_release -a
-install:
-  - pip install tox
-  - virtualenv --version
-  - easy_install --version
-  - pip --version
-  - tox --version
-script:
-  - tox -v
-after_failure:
-  - more .tox/log/* | cat
-  - more .tox/*/log/* | cat
-before_cache:
-  - rm -rf $HOME/.cache/pip/log
-cache:
-  directories:
-    - $HOME/.cache/pip
-notifications:
-  email:
-    on_success: never
-    on_failure: always
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..a5bd1bf
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,51 @@
+# Changelog
+
+## 0.2.1
+
+The full list of merged changes is:
+
+- #26: fix: pytest_collect_file to take into account pytest fspath deprecation in Node constructors
+- #29: chore: use GitHub workflows in place of Travis
+- #30: chore: use markdown project files
+- #31: chore: add renovate bot
+
+Special thanks to the following contributors that made this release possible:
+
+- @AlenkaF
+- @shvenkat
+
+## 0.2.0
+
+The full list of merged changes is:
+
+- #11: Update tests
+- #15, #17: Dropped support for Python 2, added support for Python 3.6+
+- #18: New patched pyimport implementation, maintaining better compatibility with the installed pytest version
+- #19: Rework how test collection works, making it possible to directly specify .pyx files to run, and reporting
+    tests as being from the .pyx files as opposed to the compiled extension modules
+- #20: Fix handling of cython generated autotestdicts; prevents running the same tests repeatedly, and adds better
+    reporting of test line numbers
+- #21: Add CI job with Windows
+- #22: Various documentation improvements
+
+Special thanks to the following contributors that made this release possible:
+
+- @embray
+
+## 0.1.1
+
+The full list of merged changes is:
+
+- #5: Fix DoctestModule deprecated error
+- #6: Fix typo from #5
+- #7: Fix support for relative imports
+- #9: Maintain backwards compatibility for pytest 4.x
+
+Special thanks to the following contributors that made this release possible:
+
+- @embray
+- @thrasibule
+
+## 0.1.0
+
+First release on PyPI (2016-04-17)
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
deleted file mode 100644
index 2e940e4..0000000
--- a/CHANGELOG.rst
+++ /dev/null
@@ -1,26 +0,0 @@
-
-Changelog
-=========
-
-0.1.x
------
-
-0.1.0
-~~~~~
-
-First release on PyPI (2016-04-17).
-
-0.1.1
-~~~~~
-
-The full list of merged PRs is:
-
-* PR #5: Fix DoctestModule deprecated error
-* PR #6: Fix typo from PR #5
-* PR #7: Fix support for relative imports
-* PR #9: Maintain backwards compatibility for pytest 4.x
-
-Thanks to the following contributors who submitted PRs or reported issues that were merged/closed for this release:
-
-- embray
-- thrasibule
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..a08a151
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,128 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+  and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+  overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+  advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+  address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+  professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+pytestcython@gmail.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior,  harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+<https://www.contributor-covenant.org/version/2/0/code_of_conduct.html>.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+<https://www.contributor-covenant.org/faq>. Translations are available at
+<https://www.contributor-covenant.org/translations>.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..6fc1d4b
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,84 @@
+# Contributing
+
+Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.
+
+## Bug reports
+
+When [reporting a bug](https://github.com/lgpage/pytest-cython/issues)
+please include:
+
+- Your operating system name and version.
+- The `cython` and `pytest` versions you are using
+- Detailed steps to reproduce the bug.
+- Any other details about your local setup that might be helpful in troubleshooting.
+
+## Documentation improvements
+
+`pytest-cython` could always use more documentation, whether as part of the official `pytest-cython` docs, in
+docstrings, or even on the web in blog posts, articles, and such.
+
+## Feature requests and feedback
+
+The best way to send feedback is to [file an issue](https://github.com/lgpage/pytest-cython/issues). If you are
+proposing a new feature:
+
+- Explain in detail how it would work.
+- Keep the scope as narrow as possible, to make it easier to implement.
+- Remember that this is a volunteer-driven project, and that code contributions are welcome :)
+
+## Development
+
+To set up `pytest-cython` for local development:
+
+1. Fork [pytest-cython](https://github.com/lgpage/pytest-cython) (look for the \"fork\" button).
+
+2. Clone your fork locally:
+
+    ```shell
+    git clone git@github.com:your_name_here/pytest-cython.git
+    ```
+
+3. Create a branch for local development:
+
+    ```shell
+    git checkout -b name-of-your-bugfix-or-feature
+    ```
+
+4. When you're done making changes, run all the checks and tests with  the [nox](https://tox.wiki/en/latest) command:
+
+    ```shell
+    nox
+    ```
+
+5. Commit your changes and push your branch to GitHub:
+
+    ```shell
+    git add .
+    git commit -m "Your detailed description of your changes."
+    git push origin name-of-your-bugfix-or-feature
+    ```
+
+6. Submit a pull request through the GitHub website.
+
+## Pull Request Guidelines
+
+If you need some code review or feedback while you're developing the code just make the pull request.
+
+Before merging, you should:
+
+1. Update the documentation when there's new API, functionality etc.
+2. Add a note to `CHANGELOG.rst` about the changes.
+
+## Tips
+
+To list all [nox](https://tox.wiki/en/latest) tasks:
+
+```shell
+nox --list
+```
+
+To run a subset of tests use one of the task from the above list, for example:
+
+```shell
+nox --session "test(cython='0.29', python='3.9', pytest='7')"
+```
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
deleted file mode 100644
index d6509a1..0000000
--- a/CONTRIBUTING.rst
+++ /dev/null
@@ -1,100 +0,0 @@
-============
-Contributing
-============
-
-Contributions are welcome, and they are greatly appreciated! Every
-little bit helps, and credit will always be given.
-
-Bug reports
-===========
-
-When `reporting a bug <https://github.com/lgpage/pytest-cython/issues>`_ please
-include:
-
-    * Your operating system name and version.
-    * Any details about your local setup that might be helpful in
-      troubleshooting.
-    * Detailed steps to reproduce the bug.
-
-Documentation improvements
-==========================
-
-pytest-cython could always use more documentation, whether as part of the
-official pytest-cython docs, in docstrings, or even on the web in blog posts,
-articles, and such.
-
-Feature requests and feedback
-=============================
-
-The best way to send feedback is to file an issue at
-https://github.com/lgpage/pytest-cython/issues.
-
-If you are proposing a feature:
-
-* Explain in detail how it would work.
-* Keep the scope as narrow as possible, to make it easier to implement.
-* Remember that this is a volunteer-driven project, and that code contributions
-  are welcome :)
-
-Development
-===========
-
-To set up `pytest-cython` for local development:
-
-1. Fork `pytest-cython <https://github.com/lgpage/pytest-cython>`_
-   (look for the "Fork" button).
-2. Clone your fork locally::
-
-    git clone git@github.com:your_name_here/pytest-cython.git
-
-3. Create a branch for local development::
-
-    git checkout -b name-of-your-bugfix-or-feature
-
-   Now you can make your changes locally.
-
-4. When you're done making changes, run all the checks, doc builder and spell
-   checker with `tox <https://tox.readthedocs.io/en/latest/install.html>`_ one
-   command::
-
-    tox
-
-5. Commit your changes and push your branch to GitHub::
-
-    git add .
-    git commit -m "Your detailed description of your changes."
-    git push origin name-of-your-bugfix-or-feature
-
-6. Submit a pull request through the GitHub website.
-
-Pull Request Guidelines
------------------------
-
-If you need some code review or feedback while you're developing the code just
-make the pull request.
-
-For merging, you should:
-
-1. Include passing tests (run ``tox``) [1]_.
-2. Update documentation when there's new API, functionality etc.
-3. Add a note to ``CHANGELOG.rst`` about the changes.
-4. Add yourself to ``AUTHORS.rst``.
-
-.. [1] If you don't have all the necessary python versions available locally
-       you can rely on Travis - it will `run the tests
-       <https://travis-ci.org/lgpage/pytest-cython/pull_requests>`_ for each
-       change you add in the pull request.
-
-       It will be slower though ...
-
-Tips
-----
-
-To run a subset of tests::
-
-    tox -e envname -- py.test -k test_myfeature
-
-To run all the test environments in *parallel* (you need to
-``pip install detox``)::
-
-    detox
diff --git a/LICENSE b/LICENSE.md
similarity index 97%
rename from LICENSE
rename to LICENSE.md
index 422cdc3..72ceae0 100644
--- a/LICENSE
+++ b/LICENSE.md
@@ -1,4 +1,5 @@
 The MIT License (MIT)
+=====================
 
 Copyright (c) 2016 Logan Page
 
diff --git a/MANIFEST.in b/MANIFEST.in
index fcc3765..d6a4ba1 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,25 +1,26 @@
 graft docs
-graft examples
-graft cython
-graft ci
 graft tests
 
 include .bumpversion.cfg
 include .coveragerc
-include .cookiecutterrc
 include .editorconfig
-include .isort.cfg
 
-include CHANGELOG.rst
-include CONTRIBUTING.rst
-include LICENSE
-include README.rst
+include CHANGELOG.md
+include CODE_OF_CONDUCT.md
+include CONTRIBUTING.md
+include LICENSE.md
+include README.md
 
-include tox.ini .travis.yml appveyor.yml
+include noxfile.py
+include requirements-dev.txt
 
-global-exclude *.py[cod] __pycache__ *.so *.dylib
+global-exclude *.py[cod] __pycache__ *.so *.pyd *.dylib
 
-global-exclude tests/example-project/build
-global-exclude tests/example-project/build/*
-global-exclude tests/example-project/src/pypackage/*.c
-global-exclude tests/example-project/src/pypackage/*.cpp
+exclude renovate.json
+
+exclude .github/**/*
+exclude .vscode/*
+
+exclude tests/example-project/build/**/*
+exclude tests/example-project/src/pypackage/*.c
+exclude tests/example-project/src/pypackage/*.cpp
diff --git a/PKG-INFO b/PKG-INFO
index 3504047..3d581e5 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,155 +1,77 @@
 Metadata-Version: 2.1
 Name: pytest-cython
-Version: 0.1.1
+Version: 0.2.1
 Summary: A plugin for testing Cython extension modules
 Home-page: https://github.com/lgpage/pytest-cython
 Author: Logan Page
 Author-email: page.lg@gmail.com
 License: MIT
-Description: Overview
-        ========
-        
-        .. start-badges
-        
-        .. list-table::
-            :stub-columns: 1
-        
-            * - docs
-              - |docs|
-            * - tests
-              - |travis| |appveyor| |requires|
-            * - package
-              - |version| |downloads| |wheel| |supported-versions| |supported-implementations|
-        
-        .. |docs| image:: https://readthedocs.org/projects/pytest-cython/badge/?style=flat
-            :target: https://readthedocs.org/projects/pytest-cython
-            :alt: Documentation Status
-        
-        .. |travis| image:: https://api.travis-ci.org/lgpage/pytest-cython.svg?branch=master
-            :alt: Travis-CI Build Status
-            :target: https://travis-ci.org/lgpage/pytest-cython
-        
-        .. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/lgpage/pytest-cython?branch=master&svg=true
-            :alt: AppVeyor Build Status
-            :target: https://ci.appveyor.com/project/lgpage/pytest-cython
-        
-        .. |requires| image:: https://requires.io/github/lgpage/pytest-cython/requirements.svg?branch=master
-            :alt: Requirements Status
-            :target: https://requires.io/github/lgpage/pytest-cython/requirements/?branch=master
-        
-        .. |version| image:: https://img.shields.io/pypi/v/pytest-cython.svg?style=flat
-            :alt: PyPI Package latest release
-            :target: https://pypi.org/project/pytest-cython
-        
-        .. |downloads| image:: https://img.shields.io/pypi/dm/pytest-cython.svg?style=flat
-            :alt: PyPI Package monthly downloads
-            :target: https://pypi.org/project/pytest-cython
-        
-        .. |wheel| image:: https://img.shields.io/pypi/wheel/pytest-cython.svg?style=flat
-            :alt: PyPI Wheel
-            :target: https://pypi.org/project/pytest-cython
-        
-        .. |supported-versions| image:: https://img.shields.io/pypi/pyversions/pytest-cython.svg?style=flat
-            :alt: Supported versions
-            :target: https://pypi.org/project/pytest-cython
-        
-        .. |supported-implementations| image:: https://img.shields.io/pypi/implementation/pytest-cython.svg?style=flat
-            :alt: Supported implementations
-            :target: https://pypi.org/project/pytest-cython
-        
-        .. end-badges
-        
-        This `Pytest`_ plugin allows for the doctesting of C extension modules
-        for Python, specifically created through `Cython`_.
-        
-        
-        Installation
-        ============
-        
-        You can install "pytest-cython" via `pip`_ from `PyPI`_::
-        
-            pip install pytest-cython
-        
-        
-        Usage
-        =====
-        
-        Basic usage::
-        
-            py.test --doctest-cython
-        
-        Note
-        ----
-        
-        * It is assumed that the C extension modules have been build inplace before
-          running `py.test` and there is a matching Cython `.pyx` file
-        * The `embedsignature` `Cython compiler directive`_ must be set to `True`
-        
-        
-        Contributing
-        ============
-        Contributions are very welcome. Tests can be run with `tox`_::
-        
-            tox
-        
-        
-        License
-        =======
-        
-        * Free software: MIT license
-        
-        Distributed under the terms of the `MIT`_ license, "pytest-cython" is free and
-        open source software
-        
-        
-        Issues
-        ======
-        
-        If you encounter any problems, please `file an issue`_ along with a detailed
-        description.
-        
-        
-        Acknowledgements
-        ================
-        
-        This `Pytest`_ plugin was generated with `Cookiecutter`_ along with
-        `@hackebrot`_'s `Cookiecutter-pytest-plugin`_ and `@ionelmc`_'s
-        `cookiecutter-pylibrary`_ templates.
-        
-        
-        .. _`Cookiecutter`: https://github.com/cookiecutter/cookiecutter
-        .. _`@hackebrot`: https://github.com/hackebrot
-        .. _`@ionelmc`: https://github.com/ionelmc
-        .. _`MIT`: https://opensource.org/licenses/MIT
-        .. _`BSD-3`: https://opensource.org/licenses/BSD-3-Clause
-        .. _`GNU GPL v3.0`: https://www.gnu.org/licenses/gpl-3.0.txt
-        .. _`Apache Software License 2.0`: https://www.apache.org/licenses/LICENSE-2.0
-        .. _`cookiecutter-pytest-plugin`: https://github.com/pytest-dev/cookiecutter-pytest-plugin
-        .. _`cookiecutter-pylibrary`: https://github.com/ionelmc/cookiecutter-pylibrary
-        .. _`file an issue`: https://github.com/lgpage/pytest-cython/issues
-        .. _`pytest`: https://github.com/pytest-dev/pytest
-        .. _`tox`: https://tox.readthedocs.io/en/latest/
-        .. _`pip`: https://pypi.org/project/pip/
-        .. _`PyPI`: https://pypi.org
-        .. _`Cython`: https://cython.org/
-        .. _`Cython compiler directive`: https://docs.cython.org/en/latest/src/reference/compilation.html#compiler-directives
-        
 Keywords: pytest,py.test,cython,doctest
-Platform: UNKNOWN
-Classifier: Development Status :: 4 - Beta
+Classifier: Development Status :: 5 - Production/Stable
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: Unix
 Classifier: Operating System :: POSIX
 Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2.6
-Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Topic :: Software Development :: Testing
 Classifier: Topic :: Utilities
-Description-Content-Type: text/x-rst
+Description-Content-Type: text/markdown
+License-File: LICENSE.md
+
+# Overview
+
+[![PyPI Package latest release](https://img.shields.io/pypi/v/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+[![PyPI Package monthly downloads](https://img.shields.io/pypi/dm/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+[![PyPI Wheel](https://img.shields.io/pypi/wheel/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+[![Supported versions](https://img.shields.io/pypi/pyversions/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+[![Supported implementations](https://img.shields.io/pypi/implementation/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+
+[![CI Check Status](https://github.com/lgpage/pytest-cython/actions/workflows/python-check.yml/badge.svg?branch=main)](https://github.com/lgpage/pytest-cython/actions/workflows/python-check.yml?query=branch%3Amain)
+[![CI Tests Status](https://github.com/lgpage/pytest-cython/actions/workflows/python-test.yml/badge.svg?branch=main)](https://github.com/lgpage/pytest-cython/actions/workflows/python-test.yml?query=branch%3Amain)
+[![Documentation Status](https://readthedocs.org/projects/pytest-cython/badge/?style=flat)](https://readthedocs.org/projects/pytest-cython)
+
+This [pytest](https://github.com/pytest-dev/pytest) plugin allows for the doctesting of C extension modules for
+Python, specifically created through [cython](https://cython.org/).
+
+## Installation
+
+You can install "pytest-cython" via [pip](https://pypi.org/project/pip/) from [PyPI](https://pypi.org):
+
+``` shell
+pip install pytest-cython
+```
+
+## Usage
+
+Basic usage:
+
+``` shell
+pytest --doctest-cython
+```
+
+You can also run the doctests for a single `.pyx` file as such:
+
+``` shell
+pytest --doctest-cython path/to/module.pyx
+```
+
+### Note
+
+It is assumed that the C extension modules have been build in place before running `py.test` and there is a
+matching Cython `.pyx` file
+
+## Issues
+
+If you encounter any problems, please [file an issue](https://github.com/lgpage/pytest-cython/issues) along with a
+detailed description.
+
+## Acknowledgements
+
+This [pytest](https://github.com/pytest-dev/pytest) plugin was generated with
+[cookiecutter](https://github.com/cookiecutter/cookiecutter) along with [\@hackebrot](https://github.com/hackebrot)'s
+[cookiecutter-pytest-plugin](https://github.com/pytest-dev/cookiecutter-pytest-plugin) and
+[\@ionelmc](https://github.com/ionelmc)'s [cookiecutter-pylibrary](https://github.com/ionelmc/cookiecutter-pylibrary)
+templates.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6fa18ae
--- /dev/null
+++ b/README.md
@@ -0,0 +1,54 @@
+# Overview
+
+[![PyPI Package latest release](https://img.shields.io/pypi/v/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+[![PyPI Package monthly downloads](https://img.shields.io/pypi/dm/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+[![PyPI Wheel](https://img.shields.io/pypi/wheel/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+[![Supported versions](https://img.shields.io/pypi/pyversions/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+[![Supported implementations](https://img.shields.io/pypi/implementation/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+
+[![CI Check Status](https://github.com/lgpage/pytest-cython/actions/workflows/python-check.yml/badge.svg?branch=main)](https://github.com/lgpage/pytest-cython/actions/workflows/python-check.yml?query=branch%3Amain)
+[![CI Tests Status](https://github.com/lgpage/pytest-cython/actions/workflows/python-test.yml/badge.svg?branch=main)](https://github.com/lgpage/pytest-cython/actions/workflows/python-test.yml?query=branch%3Amain)
+[![Documentation Status](https://readthedocs.org/projects/pytest-cython/badge/?style=flat)](https://readthedocs.org/projects/pytest-cython)
+
+This [pytest](https://github.com/pytest-dev/pytest) plugin allows for the doctesting of C extension modules for
+Python, specifically created through [cython](https://cython.org/).
+
+## Installation
+
+You can install "pytest-cython" via [pip](https://pypi.org/project/pip/) from [PyPI](https://pypi.org):
+
+``` shell
+pip install pytest-cython
+```
+
+## Usage
+
+Basic usage:
+
+``` shell
+pytest --doctest-cython
+```
+
+You can also run the doctests for a single `.pyx` file as such:
+
+``` shell
+pytest --doctest-cython path/to/module.pyx
+```
+
+### Note
+
+It is assumed that the C extension modules have been build in place before running `py.test` and there is a
+matching Cython `.pyx` file
+
+## Issues
+
+If you encounter any problems, please [file an issue](https://github.com/lgpage/pytest-cython/issues) along with a
+detailed description.
+
+## Acknowledgements
+
+This [pytest](https://github.com/pytest-dev/pytest) plugin was generated with
+[cookiecutter](https://github.com/cookiecutter/cookiecutter) along with [\@hackebrot](https://github.com/hackebrot)'s
+[cookiecutter-pytest-plugin](https://github.com/pytest-dev/cookiecutter-pytest-plugin) and
+[\@ionelmc](https://github.com/ionelmc)'s [cookiecutter-pylibrary](https://github.com/ionelmc/cookiecutter-pylibrary)
+templates.
diff --git a/README.rst b/README.rst
deleted file mode 100644
index 0196d51..0000000
--- a/README.rst
+++ /dev/null
@@ -1,127 +0,0 @@
-Overview
-========
-
-.. start-badges
-
-.. list-table::
-    :stub-columns: 1
-
-    * - docs
-      - |docs|
-    * - tests
-      - |travis| |appveyor| |requires|
-    * - package
-      - |version| |downloads| |wheel| |supported-versions| |supported-implementations|
-
-.. |docs| image:: https://readthedocs.org/projects/pytest-cython/badge/?style=flat
-    :target: https://readthedocs.org/projects/pytest-cython
-    :alt: Documentation Status
-
-.. |travis| image:: https://api.travis-ci.org/lgpage/pytest-cython.svg?branch=master
-    :alt: Travis-CI Build Status
-    :target: https://travis-ci.org/lgpage/pytest-cython
-
-.. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/lgpage/pytest-cython?branch=master&svg=true
-    :alt: AppVeyor Build Status
-    :target: https://ci.appveyor.com/project/lgpage/pytest-cython
-
-.. |requires| image:: https://requires.io/github/lgpage/pytest-cython/requirements.svg?branch=master
-    :alt: Requirements Status
-    :target: https://requires.io/github/lgpage/pytest-cython/requirements/?branch=master
-
-.. |version| image:: https://img.shields.io/pypi/v/pytest-cython.svg?style=flat
-    :alt: PyPI Package latest release
-    :target: https://pypi.org/project/pytest-cython
-
-.. |downloads| image:: https://img.shields.io/pypi/dm/pytest-cython.svg?style=flat
-    :alt: PyPI Package monthly downloads
-    :target: https://pypi.org/project/pytest-cython
-
-.. |wheel| image:: https://img.shields.io/pypi/wheel/pytest-cython.svg?style=flat
-    :alt: PyPI Wheel
-    :target: https://pypi.org/project/pytest-cython
-
-.. |supported-versions| image:: https://img.shields.io/pypi/pyversions/pytest-cython.svg?style=flat
-    :alt: Supported versions
-    :target: https://pypi.org/project/pytest-cython
-
-.. |supported-implementations| image:: https://img.shields.io/pypi/implementation/pytest-cython.svg?style=flat
-    :alt: Supported implementations
-    :target: https://pypi.org/project/pytest-cython
-
-.. end-badges
-
-This `Pytest`_ plugin allows for the doctesting of C extension modules
-for Python, specifically created through `Cython`_.
-
-
-Installation
-============
-
-You can install "pytest-cython" via `pip`_ from `PyPI`_::
-
-    pip install pytest-cython
-
-
-Usage
-=====
-
-Basic usage::
-
-    py.test --doctest-cython
-
-Note
-----
-
-* It is assumed that the C extension modules have been build inplace before
-  running `py.test` and there is a matching Cython `.pyx` file
-* The `embedsignature` `Cython compiler directive`_ must be set to `True`
-
-
-Contributing
-============
-Contributions are very welcome. Tests can be run with `tox`_::
-
-    tox
-
-
-License
-=======
-
-* Free software: MIT license
-
-Distributed under the terms of the `MIT`_ license, "pytest-cython" is free and
-open source software
-
-
-Issues
-======
-
-If you encounter any problems, please `file an issue`_ along with a detailed
-description.
-
-
-Acknowledgements
-================
-
-This `Pytest`_ plugin was generated with `Cookiecutter`_ along with
-`@hackebrot`_'s `Cookiecutter-pytest-plugin`_ and `@ionelmc`_'s
-`cookiecutter-pylibrary`_ templates.
-
-
-.. _`Cookiecutter`: https://github.com/cookiecutter/cookiecutter
-.. _`@hackebrot`: https://github.com/hackebrot
-.. _`@ionelmc`: https://github.com/ionelmc
-.. _`MIT`: https://opensource.org/licenses/MIT
-.. _`BSD-3`: https://opensource.org/licenses/BSD-3-Clause
-.. _`GNU GPL v3.0`: https://www.gnu.org/licenses/gpl-3.0.txt
-.. _`Apache Software License 2.0`: https://www.apache.org/licenses/LICENSE-2.0
-.. _`cookiecutter-pytest-plugin`: https://github.com/pytest-dev/cookiecutter-pytest-plugin
-.. _`cookiecutter-pylibrary`: https://github.com/ionelmc/cookiecutter-pylibrary
-.. _`file an issue`: https://github.com/lgpage/pytest-cython/issues
-.. _`pytest`: https://github.com/pytest-dev/pytest
-.. _`tox`: https://tox.readthedocs.io/en/latest/
-.. _`pip`: https://pypi.org/project/pip/
-.. _`PyPI`: https://pypi.org
-.. _`Cython`: https://cython.org/
-.. _`Cython compiler directive`: https://docs.cython.org/en/latest/src/reference/compilation.html#compiler-directives
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index d1a29fd..0000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,262 +0,0 @@
-version: '{branch}-{build}'
-build: off
-cache:
-  - '%LOCALAPPDATA%\pip\Cache'
-environment:
-  global:
-    WITH_COMPILER: 'cmd /E:ON /V:ON /C .\ci\appveyor-with-compiler.cmd'
-  matrix:
-    - TOXENV: check
-      PYTHON_HOME: C:\Python27
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py27-27-023'
-      TOXPYTHON: C:\Python27\python.exe
-      PYTHON_HOME: C:\Python27
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py27-27-023'
-      TOXPYTHON: C:\Python27-x64\python.exe
-      WINDOWS_SDK_VERSION: v7.0
-      PYTHON_HOME: C:\Python27-x64
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py27-27-024'
-      TOXPYTHON: C:\Python27\python.exe
-      PYTHON_HOME: C:\Python27
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py27-27-024'
-      TOXPYTHON: C:\Python27-x64\python.exe
-      WINDOWS_SDK_VERSION: v7.0
-      PYTHON_HOME: C:\Python27-x64
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py27-28-023'
-      TOXPYTHON: C:\Python27\python.exe
-      PYTHON_HOME: C:\Python27
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py27-28-023'
-      TOXPYTHON: C:\Python27-x64\python.exe
-      WINDOWS_SDK_VERSION: v7.0
-      PYTHON_HOME: C:\Python27-x64
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py27-28-024'
-      TOXPYTHON: C:\Python27\python.exe
-      PYTHON_HOME: C:\Python27
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py27-28-024'
-      TOXPYTHON: C:\Python27-x64\python.exe
-      WINDOWS_SDK_VERSION: v7.0
-      PYTHON_HOME: C:\Python27-x64
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py27-29-023'
-      TOXPYTHON: C:\Python27\python.exe
-      PYTHON_HOME: C:\Python27
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py27-29-023'
-      TOXPYTHON: C:\Python27-x64\python.exe
-      WINDOWS_SDK_VERSION: v7.0
-      PYTHON_HOME: C:\Python27-x64
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py27-29-024'
-      TOXPYTHON: C:\Python27\python.exe
-      PYTHON_HOME: C:\Python27
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py27-29-024'
-      TOXPYTHON: C:\Python27-x64\python.exe
-      WINDOWS_SDK_VERSION: v7.0
-      PYTHON_HOME: C:\Python27-x64
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py34-27-023'
-      TOXPYTHON: C:\Python34\python.exe
-      PYTHON_HOME: C:\Python34
-      PYTHON_VERSION: '3.4'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py34-27-023'
-      TOXPYTHON: C:\Python34-x64\python.exe
-      WINDOWS_SDK_VERSION: v7.1
-      PYTHON_HOME: C:\Python34-x64
-      PYTHON_VERSION: '3.4'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py34-27-024'
-      TOXPYTHON: C:\Python34\python.exe
-      PYTHON_HOME: C:\Python34
-      PYTHON_VERSION: '3.4'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py34-27-024'
-      TOXPYTHON: C:\Python34-x64\python.exe
-      WINDOWS_SDK_VERSION: v7.1
-      PYTHON_HOME: C:\Python34-x64
-      PYTHON_VERSION: '3.4'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py34-28-023'
-      TOXPYTHON: C:\Python34\python.exe
-      PYTHON_HOME: C:\Python34
-      PYTHON_VERSION: '3.4'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py34-28-023'
-      TOXPYTHON: C:\Python34-x64\python.exe
-      WINDOWS_SDK_VERSION: v7.1
-      PYTHON_HOME: C:\Python34-x64
-      PYTHON_VERSION: '3.4'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py34-28-024'
-      TOXPYTHON: C:\Python34\python.exe
-      PYTHON_HOME: C:\Python34
-      PYTHON_VERSION: '3.4'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py34-28-024'
-      TOXPYTHON: C:\Python34-x64\python.exe
-      WINDOWS_SDK_VERSION: v7.1
-      PYTHON_HOME: C:\Python34-x64
-      PYTHON_VERSION: '3.4'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py34-29-023'
-      TOXPYTHON: C:\Python34\python.exe
-      PYTHON_HOME: C:\Python34
-      PYTHON_VERSION: '3.4'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py34-29-023'
-      TOXPYTHON: C:\Python34-x64\python.exe
-      WINDOWS_SDK_VERSION: v7.1
-      PYTHON_HOME: C:\Python34-x64
-      PYTHON_VERSION: '3.4'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py34-29-024'
-      TOXPYTHON: C:\Python34\python.exe
-      PYTHON_HOME: C:\Python34
-      PYTHON_VERSION: '3.4'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py34-29-024'
-      TOXPYTHON: C:\Python34-x64\python.exe
-      WINDOWS_SDK_VERSION: v7.1
-      PYTHON_HOME: C:\Python34-x64
-      PYTHON_VERSION: '3.4'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py35-27-023'
-      TOXPYTHON: C:\Python35\python.exe
-      PYTHON_HOME: C:\Python35
-      PYTHON_VERSION: '3.5'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py35-27-023'
-      TOXPYTHON: C:\Python35-x64\python.exe
-      PYTHON_HOME: C:\Python35-x64
-      PYTHON_VERSION: '3.5'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py35-27-024'
-      TOXPYTHON: C:\Python35\python.exe
-      PYTHON_HOME: C:\Python35
-      PYTHON_VERSION: '3.5'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py35-27-024'
-      TOXPYTHON: C:\Python35-x64\python.exe
-      PYTHON_HOME: C:\Python35-x64
-      PYTHON_VERSION: '3.5'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py35-28-023'
-      TOXPYTHON: C:\Python35\python.exe
-      PYTHON_HOME: C:\Python35
-      PYTHON_VERSION: '3.5'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py35-28-023'
-      TOXPYTHON: C:\Python35-x64\python.exe
-      PYTHON_HOME: C:\Python35-x64
-      PYTHON_VERSION: '3.5'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py35-28-024'
-      TOXPYTHON: C:\Python35\python.exe
-      PYTHON_HOME: C:\Python35
-      PYTHON_VERSION: '3.5'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py35-28-024'
-      TOXPYTHON: C:\Python35-x64\python.exe
-      PYTHON_HOME: C:\Python35-x64
-      PYTHON_VERSION: '3.5'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py35-29-023'
-      TOXPYTHON: C:\Python35\python.exe
-      PYTHON_HOME: C:\Python35
-      PYTHON_VERSION: '3.5'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py35-29-023'
-      TOXPYTHON: C:\Python35-x64\python.exe
-      PYTHON_HOME: C:\Python35-x64
-      PYTHON_VERSION: '3.5'
-      PYTHON_ARCH: '64'
-
-    - TOXENV: 'py35-29-024'
-      TOXPYTHON: C:\Python35\python.exe
-      PYTHON_HOME: C:\Python35
-      PYTHON_VERSION: '3.5'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: 'py35-29-024'
-      TOXPYTHON: C:\Python35-x64\python.exe
-      PYTHON_HOME: C:\Python35-x64
-      PYTHON_VERSION: '3.5'
-      PYTHON_ARCH: '64'
-
-init:
-  - ps: echo $env:TOXENV
-  - ps: ls C:\Python*
-install:
-  - python -u ci\appveyor-bootstrap.py
-  - '%PYTHON_HOME%\Scripts\virtualenv --version'
-  - '%PYTHON_HOME%\Scripts\easy_install --version'
-  - '%PYTHON_HOME%\Scripts\pip --version'
-  - '%PYTHON_HOME%\Scripts\tox --version'
-test_script:
-  - '%WITH_COMPILER% %PYTHON_HOME%\Scripts\tox'
-
-on_failure:
-  - ps: dir "env:"
-  - ps: get-content .tox\*\log\*
-artifacts:
-  - path: dist\*
-
-### To enable remote debugging uncomment this (also, see: http://www.appveyor.com/docs/how-to/rdp-to-build-worker):
-# on_finish:
-#   - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
diff --git a/ci/appveyor-bootstrap.py b/ci/appveyor-bootstrap.py
deleted file mode 100644
index f9f8ebb..0000000
--- a/ci/appveyor-bootstrap.py
+++ /dev/null
@@ -1,120 +0,0 @@
-"""
-AppVeyor will at least have few Pythons around so there's no point of
-implementing a bootstrapper in PowerShell.
-
-This is a port of
-https://github.com/pypa/python-packaging-user-guide/blob/master/source/code/install.ps1
-with various fixes and improvements that just weren't feasible to implement in
-PowerShell.
-"""
-from __future__ import print_function
-from os import environ
-from os.path import exists
-from subprocess import check_call
-
-try:
-    from urllib.request import urlretrieve
-except ImportError:
-    from urllib import urlretrieve
-
-BASE_URL = "https://www.python.org/ftp/python/"
-GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
-GET_PIP_PATH = "C:\get-pip.py"
-URLS = {
-    ("2.6", "64"): BASE_URL + "2.6.6/python-2.6.6.amd64.msi",
-    ("2.6", "32"): BASE_URL + "2.6.6/python-2.6.6.msi",
-    ("2.7", "64"): BASE_URL + "2.7.10/python-2.7.10.amd64.msi",
-    ("2.7", "32"): BASE_URL + "2.7.10/python-2.7.10.msi",
-    # NOTE: no .msi installer for 3.3.6
-    ("3.3", "64"): BASE_URL + "3.3.3/python-3.3.3.amd64.msi",
-    ("3.3", "32"): BASE_URL + "3.3.3/python-3.3.3.msi",
-    ("3.4", "64"): BASE_URL + "3.4.3/python-3.4.3.amd64.msi",
-    ("3.4", "32"): BASE_URL + "3.4.3/python-3.4.3.msi",
-    ("3.5", "64"): BASE_URL + "3.5.0/python-3.5.0-amd64.exe",
-    ("3.5", "32"): BASE_URL + "3.5.0/python-3.5.0.exe",
-}
-INSTALL_CMD = {
-    # Commands are allowed to fail only if they are not the last command.  Eg: uninstall (/x) allowed to fail.
-    "2.6": [["msiexec.exe", "/L*+!", "install.log", "/qn", "/x", "{path}"],
-            ["msiexec.exe", "/L*+!", "install.log", "/qn", "/i", "{path}", "TARGETDIR={home}"]],
-    "2.7": [["msiexec.exe", "/L*+!", "install.log", "/qn", "/x", "{path}"],
-            ["msiexec.exe", "/L*+!", "install.log", "/qn", "/i", "{path}", "TARGETDIR={home}"]],
-    "3.3": [["msiexec.exe", "/L*+!", "install.log", "/qn", "/x", "{path}"],
-            ["msiexec.exe", "/L*+!", "install.log", "/qn", "/i", "{path}", "TARGETDIR={home}"]],
-    "3.4": [["msiexec.exe", "/L*+!", "install.log", "/qn", "/x", "{path}"],
-            ["msiexec.exe", "/L*+!", "install.log", "/qn", "/i", "{path}", "TARGETDIR={home}"]],
-    "3.5": [["{path}", "/quiet", "TargetDir={home}"]],
-}
-
-
-def download_file(url, path):
-    print("Downloading: {} (into {})".format(url, path))
-    progress = [0, 0]
-
-    def report(count, size, total):
-        progress[0] = count * size
-        if progress[0] - progress[1] > 1000000:
-            progress[1] = progress[0]
-            print("Downloaded {:,}/{:,} ...".format(progress[1], total))
-
-    dest, _ = urlretrieve(url, path, reporthook=report)
-    return dest
-
-
-def install_python(version, arch, home):
-    print("Installing Python", version, "for", arch, "bit architecture to", home)
-    if exists(home):
-        return
-
-    path = download_python(version, arch)
-    print("Installing", path, "to", home)
-    success = False
-    for cmd in INSTALL_CMD[version]:
-        cmd = [part.format(home=home, path=path) for part in cmd]
-        print("Running:", " ".join(cmd))
-        try:
-            check_call(cmd)
-        except Exception as exc:
-            print("Failed command", cmd, "with:", exc)
-            if exists("install.log"):
-                with open("install.log") as fh:
-                    print(fh.read())
-        else:
-            success = True
-    if success:
-        print("Installation complete!")
-    else:
-        print("Installation failed")
-
-
-def download_python(version, arch):
-    for _ in range(3):
-        try:
-            return download_file(URLS[version, arch], "installer.exe")
-        except Exception as exc:
-            print("Failed to download:", exc)
-        print("Retrying ...")
-
-
-def install_pip(home):
-    pip_path = home + "/Scripts/pip.exe"
-    python_path = home + "/python.exe"
-    if exists(pip_path):
-        print("pip already installed.")
-    else:
-        print("Installing pip...")
-        download_file(GET_PIP_URL, GET_PIP_PATH)
-        print("Executing:", python_path, GET_PIP_PATH)
-        check_call([python_path, GET_PIP_PATH])
-
-
-def install_packages(home, *packages):
-    cmd = [home + "/Scripts/pip.exe", "install"]
-    cmd.extend(packages)
-    check_call(cmd)
-
-
-if __name__ == "__main__":
-    install_python(environ['PYTHON_VERSION'], environ['PYTHON_ARCH'], environ['PYTHON_HOME'])
-    install_pip(environ['PYTHON_HOME'])
-    install_packages(environ['PYTHON_HOME'], "setuptools>=18.0.1", "wheel", "tox", "virtualenv>=13.1.0")
diff --git a/ci/appveyor-download.py b/ci/appveyor-download.py
deleted file mode 100755
index 78e1d78..0000000
--- a/ci/appveyor-download.py
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/env python
-"""
-Use the AppVeyor API to download Windows artifacts.
-
-Taken from: https://bitbucket.org/ned/coveragepy/src/tip/ci/download_appveyor.py
-# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
-# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
-"""
-from __future__ import unicode_literals
-
-import argparse
-import os
-import requests
-import zipfile
-
-
-def make_auth_headers():
-    """Make the authentication headers needed to use the Appveyor API."""
-    path = os.path.expanduser("~/.appveyor.token")
-    if not os.path.exists(path):
-        raise RuntimeError(
-            "Please create a file named `.appveyor.token` in your home directory. "
-            "You can get the token from https://ci.appveyor.com/api-token"
-        )
-    with open(path) as f:
-        token = f.read().strip()
-
-    headers = {
-        'Authorization': 'Bearer {}'.format(token),
-    }
-    return headers
-
-
-def download_latest_artifacts(account_project, build_id):
-    """Download all the artifacts from the latest build."""
-    if build_id is None:
-        url = "https://ci.appveyor.com/api/projects/{}".format(account_project)
-    else:
-        url = "https://ci.appveyor.com/api/projects/{}/build/{}".format(account_project, build_id)
-    build = requests.get(url, headers=make_auth_headers()).json()
-    jobs = build['build']['jobs']
-    print(u"Build {0[build][version]}, {1} jobs: {0[build][message]}".format(build, len(jobs)))
-
-    for job in jobs:
-        name = job['name']
-        print(u"  {0}: {1[status]}, {1[artifactsCount]} artifacts".format(name, job))
-
-        url = "https://ci.appveyor.com/api/buildjobs/{}/artifacts".format(job['jobId'])
-        response = requests.get(url, headers=make_auth_headers())
-        artifacts = response.json()
-
-        for artifact in artifacts:
-            is_zip = artifact['type'] == "Zip"
-            filename = artifact['fileName']
-            print(u"    {0}, {1} bytes".format(filename, artifact['size']))
-
-            url = "https://ci.appveyor.com/api/buildjobs/{}/artifacts/{}".format(job['jobId'], filename)
-            download_url(url, filename, make_auth_headers())
-
-            if is_zip:
-                unpack_zipfile(filename)
-                os.remove(filename)
-
-
-def ensure_dirs(filename):
-    """Make sure the directories exist for `filename`."""
-    dirname, _ = os.path.split(filename)
-    if dirname and not os.path.exists(dirname):
-        os.makedirs(dirname)
-
-
-def download_url(url, filename, headers):
-    """Download a file from `url` to `filename`."""
-    ensure_dirs(filename)
-    response = requests.get(url, headers=headers, stream=True)
-    if response.status_code == 200:
-        with open(filename, 'wb') as f:
-            for chunk in response.iter_content(16 * 1024):
-                f.write(chunk)
-    else:
-        print(u"    Error downloading {}: {}".format(url, response))
-
-
-def unpack_zipfile(filename):
-    """Unpack a zipfile, using the names in the zip."""
-    with open(filename, 'rb') as fzip:
-        z = zipfile.ZipFile(fzip)
-        for name in z.namelist():
-            print(u"      extracting {}".format(name))
-            ensure_dirs(name)
-            z.extract(name)
-
-parser = argparse.ArgumentParser(description='Download artifacts from AppVeyor.')
-parser.add_argument('--id',
-                    metavar='PROJECT_ID',
-                    default='lgpage/pytest-cython',
-                    help='Project ID in AppVeyor.')
-parser.add_argument('build',
-                    nargs='?',
-                    metavar='BUILD_ID',
-                    help='Build ID in AppVeyor. Eg: master-123')
-
-if __name__ == "__main__":
-    # import logging
-    # logging.basicConfig(level="DEBUG")
-    args = parser.parse_args()
-    download_latest_artifacts(args.id, args.build)
diff --git a/ci/appveyor-with-compiler.cmd b/ci/appveyor-with-compiler.cmd
deleted file mode 100644
index 7f82a02..0000000
--- a/ci/appveyor-with-compiler.cmd
+++ /dev/null
@@ -1,46 +0,0 @@
-:: To build extensions for 64 bit Python 3, we need to configure environment
-:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
-:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1)
-::
-:: To build extensions for 64 bit Python 2, we need to configure environment
-:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of:
-:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0)
-::
-:: 32 bit builds do not require specific environment configurations.
-::
-:: Note: this script needs to be run with the /E:ON and /V:ON flags for the
-:: cmd interpreter, at least for (SDK v7.0)
-::
-:: More details at:
-:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
-:: http://stackoverflow.com/a/13751649/163740
-::
-:: Author: Olivier Grisel
-:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
-SET COMMAND_TO_RUN=%*
-SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
-SET WIN_WDK="c:\Program Files (x86)\Windows Kits\10\Include\wdf"
-ECHO SDK: %WINDOWS_SDK_VERSION% ARCH: %PYTHON_ARCH%
-
-
-IF "%PYTHON_VERSION%"=="3.5" (
-    IF EXIST %WIN_WDK% (
-        REM See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/
-        REN %WIN_WDK% 0wdf
-    )
-    GOTO main
-)
-
-IF "%PYTHON_ARCH%"=="32" (
-    GOTO main
-)
-
-SET DISTUTILS_USE_SDK=1
-SET MSSdk=1
-"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION%
-CALL "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
-
-:main
-
-ECHO Executing: %COMMAND_TO_RUN%
-CALL %COMMAND_TO_RUN% || EXIT 1
diff --git a/ci/bootstrap.py b/ci/bootstrap.py
deleted file mode 100644
index b3808dc..0000000
--- a/ci/bootstrap.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-from __future__ import absolute_import, print_function, unicode_literals
-
-import os
-import sys
-from os.path import exists
-from os.path import join
-from os.path import dirname
-from os.path import abspath
-
-
-if __name__ == "__main__":
-    base_path = dirname(dirname(abspath(__file__)))
-    print("Project path: {0}".format(base_path))
-    env_path = join(base_path, ".tox", "bootstrap")
-    if sys.platform == "win32":
-        bin_path = join(env_path, "Scripts")
-    else:
-        bin_path = join(env_path, "bin")
-    if not exists(env_path):
-        import subprocess
-        print("Making bootstrap env in: {0} ...".format(env_path))
-        try:
-            subprocess.check_call(["virtualenv", env_path])
-        except Exception:
-            subprocess.check_call([sys.executable, "-m", "virtualenv", env_path])
-        print("Installing `jinja2` into bootstrap environment ...")
-        subprocess.check_call([join(bin_path, "pip"), "install", "jinja2"])
-    activate = join(bin_path, "activate_this.py")
-    exec(compile(open(activate, "rb").read(), activate, "exec"), dict(__file__=activate))
-
-    import jinja2
-
-    import subprocess
-
-
-    jinja = jinja2.Environment(
-        loader=jinja2.FileSystemLoader(join(base_path, "ci", "templates")),
-        trim_blocks=True,
-        lstrip_blocks=True,
-        keep_trailing_newline=True
-    )
-
-    tox_environments = [line.strip() for line in subprocess.check_output(['tox', '--listenvs']).splitlines()]
-    tox_environments = [line for line in tox_environments if line not in ['clean', 'report', 'docs', 'check']]
-
-
-    for name in os.listdir(join("ci", "templates")):
-        with open(join(base_path, name), "w") as fh:
-            fh.write(jinja.get_template(name).render(tox_environments=tox_environments))
-        print("Wrote {}".format(name))
-    print("DONE.")
diff --git a/ci/templates/.travis.yml b/ci/templates/.travis.yml
deleted file mode 100644
index f54e82c..0000000
--- a/ci/templates/.travis.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-language: python
-python: '3.5'
-sudo: false
-env:
-  global:
-    - LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so
-    - SEGFAULT_SIGNALS=all
-  matrix:
-    - TOXENV=check
-{% for env in tox_environments %}{{ '' }}
-    - TOXENV={{ env }}{% if 'cover' in env %},coveralls{% endif -%}
-{% endfor %}
-
-before_install:
-  - python --version
-  - uname -a
-  - lsb_release -a
-install:
-  - pip install tox
-  - virtualenv --version
-  - easy_install --version
-  - pip --version
-  - tox --version
-script:
-  - tox -v
-after_failure:
-  - more .tox/log/* | cat
-  - more .tox/*/log/* | cat
-before_cache:
-  - rm -rf $HOME/.cache/pip/log
-cache:
-  directories:
-    - $HOME/.cache/pip
-notifications:
-  email:
-    on_success: never
-    on_failure: always
diff --git a/ci/templates/appveyor.yml b/ci/templates/appveyor.yml
deleted file mode 100644
index 7ee4110..0000000
--- a/ci/templates/appveyor.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-version: '{branch}-{build}'
-build: off
-cache:
-  - '%LOCALAPPDATA%\pip\Cache'
-environment:
-  global:
-    WITH_COMPILER: 'cmd /E:ON /V:ON /C .\ci\appveyor-with-compiler.cmd'
-  matrix:
-    - TOXENV: check
-      PYTHON_HOME: C:\Python27
-      PYTHON_VERSION: '2.7'
-      PYTHON_ARCH: '32'
-
-{% for env in tox_environments %}{% if env.startswith(('py27', 'py34', 'py35')) %}
-    - TOXENV: '{{ env }}{% if 'cover' in env %},codecov{% endif %}'
-      TOXPYTHON: C:\Python{{ env[2:4] }}\python.exe
-      PYTHON_HOME: C:\Python{{ env[2:4] }}
-      PYTHON_VERSION: '{{ env[2] }}.{{ env[3] }}'
-      PYTHON_ARCH: '32'
-
-    - TOXENV: '{{ env }}{% if 'cover' in env %},codecov{% endif %}'
-      TOXPYTHON: C:\Python{{ env[2:4] }}-x64\python.exe
-      {%- if env.startswith(('py2', 'py33', 'py34')) %}
-
-      WINDOWS_SDK_VERSION: v7.{{ '1' if env.startswith('py3') else '0' }}
-      {%- endif %}
-
-      PYTHON_HOME: C:\Python{{ env[2:4] }}-x64
-      PYTHON_VERSION: '{{ env[2] }}.{{ env[3] }}'
-      PYTHON_ARCH: '64'
-
-{% endif %}{% endfor %}
-init:
-  - ps: echo $env:TOXENV
-  - ps: ls C:\Python*
-install:
-  - python -u ci\appveyor-bootstrap.py
-  - '%PYTHON_HOME%\Scripts\virtualenv --version'
-  - '%PYTHON_HOME%\Scripts\easy_install --version'
-  - '%PYTHON_HOME%\Scripts\pip --version'
-  - '%PYTHON_HOME%\Scripts\tox --version'
-test_script:
-  - '%WITH_COMPILER% %PYTHON_HOME%\Scripts\tox'
-
-on_failure:
-  - ps: dir "env:"
-  - ps: get-content .tox\*\log\*
-artifacts:
-  - path: dist\*
-
-### To enable remote debugging uncomment this (also, see: http://www.appveyor.com/docs/how-to/rdp-to-build-worker):
-# on_finish:
-#   - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
diff --git a/debian/changelog b/debian/changelog
index 7bf0e95..a52c587 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+pytest-cython (0.2.1-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Mon, 03 Apr 2023 07:25:47 -0000
+
 pytest-cython (0.1.1-1) unstable; urgency=medium
 
   * New upstream release.
diff --git a/docs/changelog.rst b/docs/changelog.rst
deleted file mode 100644
index 565b052..0000000
--- a/docs/changelog.rst
+++ /dev/null
@@ -1 +0,0 @@
-.. include:: ../CHANGELOG.rst
diff --git a/docs/conf.py b/docs/conf.py
index 5fc95ce..1e97012 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,10 +1,16 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 import os
+import sys
+
+import sphinx_py3doc_enhanced_theme
+
+from pytest_cython import __version__ as release
+
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
 
 
 extensions = [
+    'myst_parser',
     'sphinx.ext.autodoc',
     'sphinx.ext.autosummary',
     'sphinx.ext.coverage',
@@ -15,26 +21,30 @@ extensions = [
     'sphinx.ext.todo',
     'sphinx.ext.viewcode',
 ]
+
 if os.getenv('SPELLCHECK'):
     extensions += 'sphinxcontrib.spelling',
     spelling_show_suggestions = True
     spelling_lang = 'en_US'
 
-source_suffix = '.rst'
+source_suffix = {
+    '.rst': 'restructuredtext',
+    '.md': 'markdown',
+}
+
 master_doc = 'index'
-project = u'pytest-cython'
-year = '2016'
-author = u'Logan Page'
+project = 'pytest-cython'
+year = '2021'
+author = 'Logan Page'
 copyright = '{0}, {1}'.format(year, author)
-version = release = u'0.1.1'
 
 pygments_style = 'trac'
 templates_path = ['.']
 extlinks = {
-    'issue': ('https://github.com/lgpage/pytest-cython/issues/%s', '#'),
-    'pr': ('https://github.com/lgpage/pytest-cython/pull/%s', 'PR #'),
+    'issue': ('https://github.com/lgpage/pytest-cython/issues/%s', '#%s'),
+    'pr': ('https://github.com/lgpage/pytest-cython/pull/%s', 'PR #%s'),
 }
-import sphinx_py3doc_enhanced_theme
+
 html_theme = "sphinx_py3doc_enhanced_theme"
 html_theme_path = [sphinx_py3doc_enhanced_theme.get_html_theme_path()]
 html_theme_options = {
@@ -45,9 +55,10 @@ html_use_smartypants = True
 html_last_updated_fmt = '%b %d, %Y'
 html_split_index = True
 html_sidebars = {
-   '**': ['searchbox.html', 'globaltoc.html', 'sourcelink.html'],
+   '**': ['searchbox.html', 'localtoc.html', 'sourcelink.html'],
 }
-html_short_title = '%s-%s' % (project, version)
+
+html_short_title = f'{project}-{release}'
 
 napoleon_use_ivar = True
 napoleon_use_rtype = False
diff --git a/docs/contributing.rst b/docs/contributing.rst
deleted file mode 100644
index e582053..0000000
--- a/docs/contributing.rst
+++ /dev/null
@@ -1 +0,0 @@
-.. include:: ../CONTRIBUTING.rst
diff --git a/docs/index.rst b/docs/index.rst
index 542e9a7..c03e78b 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,21 +1,15 @@
-========
-Contents
-========
+#############
+pytest-cython
+#############
 
-.. toctree::
-   :maxdepth: 2
+.. contents::
+   :depth: 2
 
-   readme
-   installation
-   usage
-   reference/index
-   contributing
-   changelog
+.. include:: ../README.md
+    :parser: myst_parser.sphinx_
 
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
+.. include:: ../CHANGELOG.md
+    :parser: myst_parser.sphinx_
 
+.. include:: ../CONTRIBUTING.md
+    :parser: myst_parser.sphinx_
diff --git a/docs/installation.rst b/docs/installation.rst
deleted file mode 100644
index eb6e98a..0000000
--- a/docs/installation.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-============
-Installation
-============
-
-At the command line::
-
-    pip install pytest-cython
diff --git a/docs/readme.rst b/docs/readme.rst
deleted file mode 100644
index 72a3355..0000000
--- a/docs/readme.rst
+++ /dev/null
@@ -1 +0,0 @@
-.. include:: ../README.rst
diff --git a/docs/reference/index.rst b/docs/reference/index.rst
deleted file mode 100644
index 9878703..0000000
--- a/docs/reference/index.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-Reference
-=========
-
-.. toctree::
-    :glob:
-
-    pytest_cython*
diff --git a/docs/reference/pytest_cython.rst b/docs/reference/pytest_cython.rst
deleted file mode 100644
index 9543868..0000000
--- a/docs/reference/pytest_cython.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-pytest_cython
-=============
-
-.. testsetup::
-
-    from pytest_cython import *
-
-.. automodule:: pytest_cython
-    :members:
diff --git a/docs/requirements.txt b/docs/requirements.txt
index ef4a013..e7b3920 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,3 +1,5 @@
-sphinx>=1.3
+myst-parser
+pyenchant
 sphinx-py3doc-enhanced-theme
--e .
+sphinx>=1.3
+sphinxcontrib-spelling
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index f95eb78..0424d15 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -1,11 +1,25 @@
+Acknowledgements
+AlenkaF
+args
+autotestdicts
 builtin
 builtins
-classmethod
-staticmethod
-classmethods
-staticmethods
-args
-kwargs
 callstack
 Changelog
+classmethod
+classmethods
+cython
+docstrings
+doctesting
+doctests
+embray
+fspath
 Indices
+inplace
+kwargs
+pyimport
+pytest
+shvenkat
+staticmethod
+staticmethods
+thrasibule
diff --git a/docs/usage.rst b/docs/usage.rst
deleted file mode 100644
index 107ec44..0000000
--- a/docs/usage.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-=====
-Usage
-=====
-
-To use pytest-cython in a project::
-
-	import pytest_cython
diff --git a/noxfile.py b/noxfile.py
new file mode 100644
index 0000000..557cccc
--- /dev/null
+++ b/noxfile.py
@@ -0,0 +1,48 @@
+import nox
+
+
+@nox.session()
+def lint(session):
+    session.install("flake8")
+    session.run("flake8", "src", "tests", "setup.py", "noxfile.py", "docs/conf.py")
+
+
+@nox.session()
+def check(session):
+    session.install("build")
+    session.install("twine")
+    session.install("wheel")
+    session.install("check-manifest")
+
+    session.run("check-manifest")
+    session.run("python", "-m", "build")
+    session.run("twine", "check", "dist/*.*")
+
+
+@nox.session
+@nox.parametrize(
+    "python,pytest",
+    [
+        (python, pytest)
+        for python in ("3.9", "3.10", "3.11", "pypy3")
+        for pytest in ("5", "6", "7")
+        if (python, pytest) != ("3.10", "5") and (python, pytest) != ("3.11", "5")
+    ],
+)
+@nox.parametrize('cython', ["0.29"])
+def test(session, pytest, cython):
+    session.install(f"pytest=={pytest}.*")
+    session.install(f"cython=={cython}.*")
+    session.install("-e", ".")
+
+    session.run("pytest", "-vv", "tests", "src")
+
+
+@nox.session()
+def docs(session):
+    session.install("-r", "docs/requirements.txt")
+    session.install("-e", ".")
+
+    session.run("sphinx-build", "-b", "spelling", "docs", "dist/docs")
+    session.run("sphinx-build", "-b", "linkcheck", "docs", "dist/docs")
+    session.run("sphinx-build", "-E", "-b", "html", "docs", "dist/docs")
diff --git a/requirements-dev.txt b/requirements-dev.txt
new file mode 100644
index 0000000..c45da54
--- /dev/null
+++ b/requirements-dev.txt
@@ -0,0 +1,5 @@
+check-manifest
+cython
+flake8
+nox
+pytest
diff --git a/setup.cfg b/setup.cfg
index 861091c..91f6081 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -5,7 +5,8 @@ universal = 1
 release = register clean --all sdist bdist_wheel
 
 [flake8]
-max-line-length = 140
+max-line-length = 120
+max-complexity = 15
 exclude = tests/*,*/migrations/*,*/south_migrations/*
 
 [tool:pytest]
@@ -13,27 +14,26 @@ norecursedirs =
 	.git
 	.tox
 	.env
+	.venv
 	dist
 	build
-	south_migrations
-	migrations
-	example
+	tests/example-project
 python_files = 
 	test_*.py
 	*_test.py
 	tests.py
 addopts = 
 	-rxEfsw
-	--strict
-	--ignore=docs/conf.py
-	--ignore=setup.py
-	--ignore=src
-	--ignore=ci
-	--ignore=.eggs
+	--strict-markers
 	--doctest-modules
 	--doctest-glob=\*.rst
+	--ignore=docs/conf.py
 	--tb=short
-	-p pytester
+filterwarnings = 
+	ignore:the imp module is deprecated in favour of importlib
+	ignore:Using or importing the ABCs from 'collections'
+	ignore:The TerminalReporter.writer attribute is deprecated
+	ignore:lib2to3 package is deprecated
 
 [isort]
 force_single_line = True
diff --git a/setup.py b/setup.py
old mode 100644
new mode 100755
index f414e88..2a7cfbb
--- a/setup.py
+++ b/setup.py
@@ -1,26 +1,25 @@
 #!/usr/bin/env python
 # -*- encoding: utf-8 -*-
-from __future__ import absolute_import
-from __future__ import print_function
-
 from glob import glob
 from os import path
 
 from setuptools import find_packages
 from setuptools import setup
 
+
 this_directory = path.abspath(path.dirname(__file__))
 
-with open(path.join(this_directory, 'README.rst'), encoding='utf-8') as readme_file:
+
+with open(path.join(this_directory, 'README.md')) as readme_file:
     long_description = readme_file.read()
 
 
 setup(
     name='pytest-cython',
-    version='0.1.1',
+    version='0.2.1',
     description='A plugin for testing Cython extension modules',
     long_description=long_description,
-    long_description_content_type='text/x-rst',
+    long_description_content_type='text/markdown',
     author='Logan Page',
     author_email='page.lg@gmail.com',
     license='MIT',
@@ -31,26 +30,15 @@ setup(
     include_package_data=True,
     zip_safe=False,
     classifiers=[
-        # complete classifier list: https://pypi.org/pypi?%3Aaction=list_classifiers
-        'Development Status :: 4 - Beta',
+        'Development Status :: 5 - Production/Stable',
         'Intended Audience :: Developers',
         'License :: OSI Approved :: MIT License',
         'Operating System :: Unix',
         'Operating System :: POSIX',
-        # 'Operating System :: Microsoft :: Windows',
         'Programming Language :: Python',
-        'Programming Language :: Python :: 2.6',
-        'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.3',
-        'Programming Language :: Python :: 3.4',
-        'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: Implementation :: CPython',
         'Programming Language :: Python :: Implementation :: PyPy',
-        # uncomment if you test on these interpreters:
-        # 'Programming Language :: Python :: Implementation :: IronPython',
-        # 'Programming Language :: Python :: Implementation :: Jython',
-        # 'Programming Language :: Python :: Implementation :: Stackless',
         'Topic :: Software Development :: Testing',
         'Topic :: Utilities',
     ],
@@ -58,12 +46,8 @@ setup(
         'pytest', 'py.test', 'cython', 'doctest',
     ],
     install_requires=[
-        'pytest>=2.7.3',
+        'pytest>=4.6.0',
     ],
-    extras_require={
-    },
-    cmdclass={
-    },
     entry_points={
         'pytest11': [
             'pytest_cython = pytest_cython.plugin',
diff --git a/src/pytest_cython.egg-info/PKG-INFO b/src/pytest_cython.egg-info/PKG-INFO
index 3504047..3d581e5 100644
--- a/src/pytest_cython.egg-info/PKG-INFO
+++ b/src/pytest_cython.egg-info/PKG-INFO
@@ -1,155 +1,77 @@
 Metadata-Version: 2.1
 Name: pytest-cython
-Version: 0.1.1
+Version: 0.2.1
 Summary: A plugin for testing Cython extension modules
 Home-page: https://github.com/lgpage/pytest-cython
 Author: Logan Page
 Author-email: page.lg@gmail.com
 License: MIT
-Description: Overview
-        ========
-        
-        .. start-badges
-        
-        .. list-table::
-            :stub-columns: 1
-        
-            * - docs
-              - |docs|
-            * - tests
-              - |travis| |appveyor| |requires|
-            * - package
-              - |version| |downloads| |wheel| |supported-versions| |supported-implementations|
-        
-        .. |docs| image:: https://readthedocs.org/projects/pytest-cython/badge/?style=flat
-            :target: https://readthedocs.org/projects/pytest-cython
-            :alt: Documentation Status
-        
-        .. |travis| image:: https://api.travis-ci.org/lgpage/pytest-cython.svg?branch=master
-            :alt: Travis-CI Build Status
-            :target: https://travis-ci.org/lgpage/pytest-cython
-        
-        .. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/lgpage/pytest-cython?branch=master&svg=true
-            :alt: AppVeyor Build Status
-            :target: https://ci.appveyor.com/project/lgpage/pytest-cython
-        
-        .. |requires| image:: https://requires.io/github/lgpage/pytest-cython/requirements.svg?branch=master
-            :alt: Requirements Status
-            :target: https://requires.io/github/lgpage/pytest-cython/requirements/?branch=master
-        
-        .. |version| image:: https://img.shields.io/pypi/v/pytest-cython.svg?style=flat
-            :alt: PyPI Package latest release
-            :target: https://pypi.org/project/pytest-cython
-        
-        .. |downloads| image:: https://img.shields.io/pypi/dm/pytest-cython.svg?style=flat
-            :alt: PyPI Package monthly downloads
-            :target: https://pypi.org/project/pytest-cython
-        
-        .. |wheel| image:: https://img.shields.io/pypi/wheel/pytest-cython.svg?style=flat
-            :alt: PyPI Wheel
-            :target: https://pypi.org/project/pytest-cython
-        
-        .. |supported-versions| image:: https://img.shields.io/pypi/pyversions/pytest-cython.svg?style=flat
-            :alt: Supported versions
-            :target: https://pypi.org/project/pytest-cython
-        
-        .. |supported-implementations| image:: https://img.shields.io/pypi/implementation/pytest-cython.svg?style=flat
-            :alt: Supported implementations
-            :target: https://pypi.org/project/pytest-cython
-        
-        .. end-badges
-        
-        This `Pytest`_ plugin allows for the doctesting of C extension modules
-        for Python, specifically created through `Cython`_.
-        
-        
-        Installation
-        ============
-        
-        You can install "pytest-cython" via `pip`_ from `PyPI`_::
-        
-            pip install pytest-cython
-        
-        
-        Usage
-        =====
-        
-        Basic usage::
-        
-            py.test --doctest-cython
-        
-        Note
-        ----
-        
-        * It is assumed that the C extension modules have been build inplace before
-          running `py.test` and there is a matching Cython `.pyx` file
-        * The `embedsignature` `Cython compiler directive`_ must be set to `True`
-        
-        
-        Contributing
-        ============
-        Contributions are very welcome. Tests can be run with `tox`_::
-        
-            tox
-        
-        
-        License
-        =======
-        
-        * Free software: MIT license
-        
-        Distributed under the terms of the `MIT`_ license, "pytest-cython" is free and
-        open source software
-        
-        
-        Issues
-        ======
-        
-        If you encounter any problems, please `file an issue`_ along with a detailed
-        description.
-        
-        
-        Acknowledgements
-        ================
-        
-        This `Pytest`_ plugin was generated with `Cookiecutter`_ along with
-        `@hackebrot`_'s `Cookiecutter-pytest-plugin`_ and `@ionelmc`_'s
-        `cookiecutter-pylibrary`_ templates.
-        
-        
-        .. _`Cookiecutter`: https://github.com/cookiecutter/cookiecutter
-        .. _`@hackebrot`: https://github.com/hackebrot
-        .. _`@ionelmc`: https://github.com/ionelmc
-        .. _`MIT`: https://opensource.org/licenses/MIT
-        .. _`BSD-3`: https://opensource.org/licenses/BSD-3-Clause
-        .. _`GNU GPL v3.0`: https://www.gnu.org/licenses/gpl-3.0.txt
-        .. _`Apache Software License 2.0`: https://www.apache.org/licenses/LICENSE-2.0
-        .. _`cookiecutter-pytest-plugin`: https://github.com/pytest-dev/cookiecutter-pytest-plugin
-        .. _`cookiecutter-pylibrary`: https://github.com/ionelmc/cookiecutter-pylibrary
-        .. _`file an issue`: https://github.com/lgpage/pytest-cython/issues
-        .. _`pytest`: https://github.com/pytest-dev/pytest
-        .. _`tox`: https://tox.readthedocs.io/en/latest/
-        .. _`pip`: https://pypi.org/project/pip/
-        .. _`PyPI`: https://pypi.org
-        .. _`Cython`: https://cython.org/
-        .. _`Cython compiler directive`: https://docs.cython.org/en/latest/src/reference/compilation.html#compiler-directives
-        
 Keywords: pytest,py.test,cython,doctest
-Platform: UNKNOWN
-Classifier: Development Status :: 4 - Beta
+Classifier: Development Status :: 5 - Production/Stable
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: Unix
 Classifier: Operating System :: POSIX
 Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2.6
-Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Topic :: Software Development :: Testing
 Classifier: Topic :: Utilities
-Description-Content-Type: text/x-rst
+Description-Content-Type: text/markdown
+License-File: LICENSE.md
+
+# Overview
+
+[![PyPI Package latest release](https://img.shields.io/pypi/v/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+[![PyPI Package monthly downloads](https://img.shields.io/pypi/dm/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+[![PyPI Wheel](https://img.shields.io/pypi/wheel/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+[![Supported versions](https://img.shields.io/pypi/pyversions/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+[![Supported implementations](https://img.shields.io/pypi/implementation/pytest-cython.svg?style=flat)](https://pypi.org/project/pytest-cython)
+
+[![CI Check Status](https://github.com/lgpage/pytest-cython/actions/workflows/python-check.yml/badge.svg?branch=main)](https://github.com/lgpage/pytest-cython/actions/workflows/python-check.yml?query=branch%3Amain)
+[![CI Tests Status](https://github.com/lgpage/pytest-cython/actions/workflows/python-test.yml/badge.svg?branch=main)](https://github.com/lgpage/pytest-cython/actions/workflows/python-test.yml?query=branch%3Amain)
+[![Documentation Status](https://readthedocs.org/projects/pytest-cython/badge/?style=flat)](https://readthedocs.org/projects/pytest-cython)
+
+This [pytest](https://github.com/pytest-dev/pytest) plugin allows for the doctesting of C extension modules for
+Python, specifically created through [cython](https://cython.org/).
+
+## Installation
+
+You can install "pytest-cython" via [pip](https://pypi.org/project/pip/) from [PyPI](https://pypi.org):
+
+``` shell
+pip install pytest-cython
+```
+
+## Usage
+
+Basic usage:
+
+``` shell
+pytest --doctest-cython
+```
+
+You can also run the doctests for a single `.pyx` file as such:
+
+``` shell
+pytest --doctest-cython path/to/module.pyx
+```
+
+### Note
+
+It is assumed that the C extension modules have been build in place before running `py.test` and there is a
+matching Cython `.pyx` file
+
+## Issues
+
+If you encounter any problems, please [file an issue](https://github.com/lgpage/pytest-cython/issues) along with a
+detailed description.
+
+## Acknowledgements
+
+This [pytest](https://github.com/pytest-dev/pytest) plugin was generated with
+[cookiecutter](https://github.com/cookiecutter/cookiecutter) along with [\@hackebrot](https://github.com/hackebrot)'s
+[cookiecutter-pytest-plugin](https://github.com/pytest-dev/cookiecutter-pytest-plugin) and
+[\@ionelmc](https://github.com/ionelmc)'s [cookiecutter-pylibrary](https://github.com/ionelmc/cookiecutter-pylibrary)
+templates.
diff --git a/src/pytest_cython.egg-info/SOURCES.txt b/src/pytest_cython.egg-info/SOURCES.txt
index 63a1fd2..0c02bb2 100644
--- a/src/pytest_cython.egg-info/SOURCES.txt
+++ b/src/pytest_cython.egg-info/SOURCES.txt
@@ -1,35 +1,20 @@
 .bumpversion.cfg
-.cookiecutterrc
 .coveragerc
 .editorconfig
-.gitignore
-.travis.yml
-CHANGELOG.rst
-CONTRIBUTING.rst
-LICENSE
+CHANGELOG.md
+CODE_OF_CONDUCT.md
+CONTRIBUTING.md
+LICENSE.md
 MANIFEST.in
-README.rst
-appveyor.yml
+README.md
+noxfile.py
+requirements-dev.txt
 setup.cfg
 setup.py
-tox.ini
-ci/appveyor-bootstrap.py
-ci/appveyor-download.py
-ci/appveyor-with-compiler.cmd
-ci/bootstrap.py
-ci/templates/.travis.yml
-ci/templates/appveyor.yml
-docs/changelog.rst
 docs/conf.py
-docs/contributing.rst
 docs/index.rst
-docs/installation.rst
-docs/readme.rst
 docs/requirements.txt
 docs/spelling_wordlist.txt
-docs/usage.rst
-docs/reference/index.rst
-docs/reference/pytest_cython.rst
 src/pytest_cython/__init__.py
 src/pytest_cython/plugin.py
 src/pytest_cython.egg-info/PKG-INFO
@@ -43,19 +28,6 @@ tests/conftest.py
 tests/test_pytest_cython.py
 tests/example-project/.gitignore
 tests/example-project/setup.py
-tests/example-project/build/temp.linux-x86_64-2.7/src/pypackage/cython_ext_module.o
-tests/example-project/build/temp.linux-x86_64-2.7/src/pypackage/wrap_c_ext_module.o
-tests/example-project/build/temp.linux-x86_64-2.7/src/pypackage/wrap_cpp_ext_module.o
-tests/example-project/build/temp.linux-x86_64-3.6/src/pypackage/cython_ext_module.o
-tests/example-project/build/temp.linux-x86_64-3.6/src/pypackage/wrap_c_ext_module.o
-tests/example-project/build/temp.linux-x86_64-3.6/src/pypackage/wrap_cpp_ext_module.o
-tests/example-project/build/temp.linux-x86_64-3.7/src/pypackage/cython_ext_module.o
-tests/example-project/build/temp.linux-x86_64-3.7/src/pypackage/wrap_c_ext_module.o
-tests/example-project/build/temp.linux-x86_64-3.7/src/pypackage/wrap_cpp_ext_module.o
-tests/example-project/build/temp.linux-x86_64-3.8/src/pypackage/cython_ext_module.o
-tests/example-project/build/temp.linux-x86_64-3.8/src/pypackage/wrap_c_ext_module.o
-tests/example-project/build/temp.linux-x86_64-3.8/src/pypackage/wrap_cpp_ext_module.o
-tests/example-project/src/__init__.py
 tests/example-project/src/clib/CMakeLists.txt
 tests/example-project/src/clib/sqrc.c
 tests/example-project/src/clib/sqrcpp.cpp
diff --git a/src/pytest_cython.egg-info/entry_points.txt b/src/pytest_cython.egg-info/entry_points.txt
index cca7476..d5764f8 100644
--- a/src/pytest_cython.egg-info/entry_points.txt
+++ b/src/pytest_cython.egg-info/entry_points.txt
@@ -1,3 +1,2 @@
 [pytest11]
 pytest_cython = pytest_cython.plugin
-
diff --git a/src/pytest_cython.egg-info/requires.txt b/src/pytest_cython.egg-info/requires.txt
index da42a29..c5ba1ca 100644
--- a/src/pytest_cython.egg-info/requires.txt
+++ b/src/pytest_cython.egg-info/requires.txt
@@ -1 +1 @@
-pytest>=2.7.3
+pytest>=4.6.0
diff --git a/src/pytest_cython/__init__.py b/src/pytest_cython/__init__.py
index 485f44a..ff5a702 100644
--- a/src/pytest_cython/__init__.py
+++ b/src/pytest_cython/__init__.py
@@ -1 +1,9 @@
-__version__ = "0.1.1"
+try:
+    from pkg_resources import get_distribution
+    __version__ = get_distribution('pytest-cython').version
+    del get_distribution
+except Exception:
+    import warnings
+    warnings.warn('could not get pytest-cython version; pkg_resources '
+                  'not available or package not installed')
+    __version__ = '0.0.0'
diff --git a/src/pytest_cython/plugin.py b/src/pytest_cython/plugin.py
index 5a34e24..28be1ba 100644
--- a/src/pytest_cython/plugin.py
+++ b/src/pytest_cython/plugin.py
@@ -1,136 +1,136 @@
 """ discover and run doctests in Cython extension modules."""
-from __future__ import absolute_import
 
-import keyword
+import pathlib
 import re
 import sys
-import tokenize
-import pytest
+import sysconfig
 
-try:
-    import sysconfig
-except ImportError:
-    from distutils import sysconfig
+import pytest
+import py.path
 
 import _pytest
 from _pytest.doctest import get_optionflags
 from _pytest.doctest import DoctestItem
 
+try:
+    from _pytest.pathlib import import_path  # pytest>=6.0 only
+except ImportError:
+    import_path = None
+
 try:
     from _pytest.doctest import _get_checker
 except ImportError:
     _get_checker = None
 
 
+EXT_SUFFIX = sysconfig.get_config_var("EXT_SUFFIX")
+
+
 def pytest_addoption(parser):
     group = parser.getgroup("cython")
+
     group.addoption(
         "--doctest-cython",
         action="store_true",
         default=False,
         help="run doctests in all .so and .pyd modules",
         dest="doctest_cython",
-        )
+    )
+
     group.addoption(
         "--cython-ignore-import-errors",
         action="store_true",
         default=False,
         help="ignore doctest ImportErrors",
         dest="doctest_ignore_import_errors",
-        )
+    )
 
 
-def _find_matching_pyx_file(path, extensions):
-    for ext in extensions:
-        newpath = path.new(ext=ext)
-        if newpath.check():
-            return newpath
+def check_python_versions():
+    (major, minor, patch, *_) = sys.version_info
+    if (major == 3):
+        if (minor == 8 and patch < 7) or (minor == 9 and patch < 2):
+            raise RuntimeError(' '.join([
+                "Please update your Python patch version.",
+                "Your current Python version has a known bug w.r.t. EXT_SUFFIX that prevents this plugin from working.",
+            ]))
 
 
 def pytest_collect_file(path, parent):
-    bin_exts = ['.so']
-    cy_exts = ['.pyx', '.py']  # collect .so files if .py file exists
-    ext_suffix = sysconfig.get_config_var("EXT_SUFFIX")
+    cy_exts = ['.py', '.pyx']
 
     config = parent.config
-    if path.ext in bin_exts:
-        if config.getoption('--doctest-cython'):
-            if ext_suffix is None:
-                bin_file = path
-                # XXX EXT_SUFFIX is None for pypy (python2.7)
-                if '.pypy' in path.basename:
-                    basename = path.basename.split('.')[0]
-                    bin_file = path.new(purebasename=basename, ext=path.ext)
 
-            else:
-                basename = path.basename.replace(ext_suffix, "")
-                bin_file = path.new(purebasename=basename, ext=path.ext)
+    if path.ext in cy_exts and config.getoption('--doctest-cython'):
+        bin_path = path.new(ext=EXT_SUFFIX)
+        bin_check = bin_path.check()
+        check_python_versions()
 
-            pyx_file = _find_matching_pyx_file(bin_file, cy_exts)
+        if bin_check:
             # only run test if matching .so and .pyx files exist
             # create addoption for this ??
-            if pyx_file is not None:
-                if hasattr(DoctestModule, 'from_parent'):
+            if hasattr(DoctestModule, 'from_parent'):
+                try:
+                    # fspath for Node constructors deprecated since
+                    # pytest version 7.0., replaced with pathlib.Path
+                    return DoctestModule.from_parent(parent, path=pathlib.Path(str(path)))
+                except TypeError:
                     return DoctestModule.from_parent(parent, fspath=path)
-                else:
-                    # Backwards-compat for older pytest
-                    return DoctestModule(path, parent)
+            else:
+                # Backwards-compat for older pytest
+                return DoctestModule(path, parent)
+
 
+class _PatchedLocalPath(py.path.local):
+    """
+    py.path.local path patched so that py.path.local.pyimport() will work
+    if it is a PEP 3149 ABI extension module.  See _patch_pyimport.
+    """
 
-# XXX if python2 support is dropped just use str.isidentifier
-def _isidentifier(s):
-    return (re.match('^' + tokenize.Name + '$', s)
-            and not keyword.iskeyword(s))
+    @property
+    def purebasename(self):
+        return super().basename.replace(EXT_SUFFIX, '')
 
+    def new(self, **kwargs):
+        kwargs.pop('purebasename', None)
+        return super().new(purebasename=self.purebasename, **kwargs)
 
-# XXX copied from pytest but modified to use py.path instead; if Python 2
-# support is dropped and support for more modern pytest added we can just use
-# the one from pytest
-def _resolve_package_path(path):
-    """Return the Python package path by looking for the last
-    directory upwards which still contains an __init__.py.
 
-    Returns None if it can not be determined.
+class _PatchedPath(pathlib.Path):
+    """
+    Similar to _PatchedLocalPath but implements the equivalent hacks so that
+    the `pathlib`-based ``import_path`` computes the module name correctly.
     """
-    result = None
-    for parent in path.parts(reverse=True):
-        if parent.isdir():
-            if not parent.join('__init__.py').isfile():
-                break
-            if not _isidentifier(parent.basename):
-                break
-            result = parent
-    return result
 
+    @property
+    def stem(self):
+        return super().name.replace(EXT_SUFFIX, '')
 
-# XXX patch pyimport to support PEP 3149
-def _patch_pyimport(fspath, **kwargs):
-    ext_suffix = sysconfig.get_config_var("EXT_SUFFIX")
-    # XXX EXT_SUFFIX is None for pypy (python2.7)
-    if ext_suffix is None and '.pypy' not in fspath.basename:
-        return fspath.pyimport(**kwargs)
+    def with_suffix(self, suffix):
+        return self.with_name(self.stem + suffix)
 
-    else:
-        # XXX EXT_SUFFIX is None for pypy (python2.7)
-        if '.pypy' in fspath.basename:
-            ext_suffix = fspath.ext
-            basename = fspath.basename.split('.')[0]
-            fspath = fspath.new(purebasename=basename, ext=fspath.ext)
-
-        pkg_path = _resolve_package_path(fspath)
-        if pkg_path is not None:
-            pkg_root = pkg_path.dirname
-            names = fspath.relto(pkg_root).split(fspath.sep)
-            if names[-1].startswith('__init__.'):
-                names.pop()
-            module_name = '.'.join(names).replace(ext_suffix, '')
-        else:
-            pkg_root = fspath.parent
-            module_name = fspath.basename.replace(ext_suffix, '')
 
-        fspath._ensuresyspath(True, pkg_root)
-        __import__(module_name)
-        return sys.modules[module_name]
+# XXX patch pyimport to support PEP 3149
+def _patch_pyimport(fspath, import_mode='prepend'):
+    # pytest does not properly support PEP 3149 ABI tagged extension modules
+    # (this should be fixed upstream); this provides an alternative
+    # implementation (mostly copied from the original) which provides it
+
+    # this supports pytest>=6.0 which uses import_path, as well as older
+    # versions that use py.path.local.pyimport
+    if isinstance(fspath, py.path.local):
+        if fspath.basename.endswith(EXT_SUFFIX):
+            fspath = _PatchedLocalPath(fspath)
+
+        if import_mode == 'prepend':
+            # the equivalent spelling in py.path.local.pyimport's
+            # ensuresyspath argument
+            import_mode = True
+
+        return fspath.pyimport(ensuresyspath=import_mode)
+    else:
+        fspath = _PatchedPath(fspath)
+        return import_path(fspath, import_mode=import_mode)
 
 
 class DoctestModule(pytest.Module):
@@ -141,12 +141,16 @@ class DoctestModule(pytest.Module):
         if self.fspath.basename == "conftest.py":
             module = self.config.pluginmanager._importconftest(self.fspath)
         else:
+            bin_path = self.fspath.new(ext=EXT_SUFFIX)
             try:
                 # XXX patch pyimport in pytest._pytest.doctest.DoctestModule
-                module = _patch_pyimport(self.fspath)
+                # import the extension module, not the .py/.pyx module
+                module = _patch_pyimport(bin_path)
             except ImportError:
                 if self.config.getoption('--cython-ignore-import-errors'):
-                    pytest.skip('unable to import module %r' % self.fspath)
+                    pytest.skip(
+                        f'unable to import module {self.fspath} from '
+                        f'{bin_path}')
                 else:
                     raise
 
@@ -154,26 +158,60 @@ class DoctestModule(pytest.Module):
         finder = doctest.DocTestFinder()
         optionflags = get_optionflags(self)
         checker = None if _get_checker is None else _get_checker()
-        runner = doctest.DebugRunner(verbose=0, optionflags=optionflags,
-                                     checker=checker)
-        for test in finder.find(module, module.__name__):
+        runner = doctest.DebugRunner(verbose=0, optionflags=optionflags, checker=checker)
+        tests = {test.name: test for test in finder.find(module, module.__name__)}
+
+        # handle tests from Cython's internal __test__ dict generated by
+        # the autotestdict directive; we exclude the tests from __test__,
+        # though they do give us a little bonus if they exist: we can extract
+        # the line number of the test
+        lineno_re = re.compile(r'\(line (\d+)\)')
+        test_dict = module.__name__ + '.__test__'
+
+        for test_name in list(tests):
+            if not test_name.startswith(test_dict + '.'):
+                continue
+
+            match = lineno_re.search(test_name)
+            lineno = int(match.group(1)) if match else None
+
+            # If somehow the equivalent test does not already exist, we
+            # keep the __test__ test (maybe it is something else not
+            # generated by autotestdict)
+            equiv_test_name = test_name.split()[0].replace(test_dict, module.__name__)
+            if (equiv_test_name not in tests or not tests[equiv_test_name].examples):
+                # for some reason the equivalent test was not found (e.g.
+                # the module was compiled with docstrings stripped) so keep
+                # the __test__ test but hide the fact that it came from the
+                # __test__ dict
+                tests[test_name].name = equiv_test_name
+                # set lineno on the __test__ test as well, since normally
+                # it is not set by doctest
+                tests[test_name].lineno = lineno
+                continue
+
+            # Delete the __test__ test, but try to update the lineno of the
+            # equivalent test
+            del tests[test_name]
+            tests[equiv_test_name].lineno = lineno
+
+        for test in tests.values():
             if test.examples:  # skip empty doctests
                 if hasattr(DoctestItem, 'from_parent'):
-                    yield DoctestItem.from_parent(self, name=test.name,
-                                                  runner=runner, dtest=test)
+                    yield DoctestItem.from_parent(self, name=test.name, runner=runner, dtest=test)
                 else:
                     # Backwards-compat for older pytest
                     yield DoctestItem(test.name, self, runner, test)
 
     def _importtestmodule(self):
         # we assume we are only called once per module
-        importmode = self.config.getoption("--import-mode", default=True)
+        importmode = self.config.getoption("--import-mode", default="prepend")
+
         try:
             # XXX patch pyimport in pytest._pytest.pythod.Module
-            mod = _patch_pyimport(self.fspath, ensuresyspath=importmode)
+            mod = _patch_pyimport(self.fspath, importmode=importmode)
         except SyntaxError:
-            raise self.CollectError(
-                _pytest._code.ExceptionInfo().getrepr(style="short"))
+            raise self.CollectError(_pytest._code.ExceptionInfo().getrepr(style="short"))
         except self.fspath.ImportMismatchError:
             e = sys.exc_info()[1]
             raise self.CollectError(
@@ -186,6 +224,6 @@ class DoctestModule(pytest.Module):
                 "unique basename for your test file modules"
                 % e.args
             )
-        # print "imported test module", mod
+
         self.config.pluginmanager.consider_module(mod)
         return mod
diff --git a/tests/example-project/build/temp.linux-x86_64-2.7/src/pypackage/cython_ext_module.o b/tests/example-project/build/temp.linux-x86_64-2.7/src/pypackage/cython_ext_module.o
deleted file mode 100644
index fe20848..0000000
Binary files a/tests/example-project/build/temp.linux-x86_64-2.7/src/pypackage/cython_ext_module.o and /dev/null differ
diff --git a/tests/example-project/build/temp.linux-x86_64-2.7/src/pypackage/wrap_c_ext_module.o b/tests/example-project/build/temp.linux-x86_64-2.7/src/pypackage/wrap_c_ext_module.o
deleted file mode 100644
index 0abb79c..0000000
Binary files a/tests/example-project/build/temp.linux-x86_64-2.7/src/pypackage/wrap_c_ext_module.o and /dev/null differ
diff --git a/tests/example-project/build/temp.linux-x86_64-2.7/src/pypackage/wrap_cpp_ext_module.o b/tests/example-project/build/temp.linux-x86_64-2.7/src/pypackage/wrap_cpp_ext_module.o
deleted file mode 100644
index ee3d0aa..0000000
Binary files a/tests/example-project/build/temp.linux-x86_64-2.7/src/pypackage/wrap_cpp_ext_module.o and /dev/null differ
diff --git a/tests/example-project/build/temp.linux-x86_64-3.6/src/pypackage/cython_ext_module.o b/tests/example-project/build/temp.linux-x86_64-3.6/src/pypackage/cython_ext_module.o
deleted file mode 100644
index 6efef4a..0000000
Binary files a/tests/example-project/build/temp.linux-x86_64-3.6/src/pypackage/cython_ext_module.o and /dev/null differ
diff --git a/tests/example-project/build/temp.linux-x86_64-3.6/src/pypackage/wrap_c_ext_module.o b/tests/example-project/build/temp.linux-x86_64-3.6/src/pypackage/wrap_c_ext_module.o
deleted file mode 100644
index 92b2e13..0000000
Binary files a/tests/example-project/build/temp.linux-x86_64-3.6/src/pypackage/wrap_c_ext_module.o and /dev/null differ
diff --git a/tests/example-project/build/temp.linux-x86_64-3.6/src/pypackage/wrap_cpp_ext_module.o b/tests/example-project/build/temp.linux-x86_64-3.6/src/pypackage/wrap_cpp_ext_module.o
deleted file mode 100644
index b71141d..0000000
Binary files a/tests/example-project/build/temp.linux-x86_64-3.6/src/pypackage/wrap_cpp_ext_module.o and /dev/null differ
diff --git a/tests/example-project/build/temp.linux-x86_64-3.7/src/pypackage/cython_ext_module.o b/tests/example-project/build/temp.linux-x86_64-3.7/src/pypackage/cython_ext_module.o
deleted file mode 100644
index 348280f..0000000
Binary files a/tests/example-project/build/temp.linux-x86_64-3.7/src/pypackage/cython_ext_module.o and /dev/null differ
diff --git a/tests/example-project/build/temp.linux-x86_64-3.7/src/pypackage/wrap_c_ext_module.o b/tests/example-project/build/temp.linux-x86_64-3.7/src/pypackage/wrap_c_ext_module.o
deleted file mode 100644
index 38dcf16..0000000
Binary files a/tests/example-project/build/temp.linux-x86_64-3.7/src/pypackage/wrap_c_ext_module.o and /dev/null differ
diff --git a/tests/example-project/build/temp.linux-x86_64-3.7/src/pypackage/wrap_cpp_ext_module.o b/tests/example-project/build/temp.linux-x86_64-3.7/src/pypackage/wrap_cpp_ext_module.o
deleted file mode 100644
index 5a22e0e..0000000
Binary files a/tests/example-project/build/temp.linux-x86_64-3.7/src/pypackage/wrap_cpp_ext_module.o and /dev/null differ
diff --git a/tests/example-project/build/temp.linux-x86_64-3.8/src/pypackage/cython_ext_module.o b/tests/example-project/build/temp.linux-x86_64-3.8/src/pypackage/cython_ext_module.o
deleted file mode 100644
index 77bcd06..0000000
Binary files a/tests/example-project/build/temp.linux-x86_64-3.8/src/pypackage/cython_ext_module.o and /dev/null differ
diff --git a/tests/example-project/build/temp.linux-x86_64-3.8/src/pypackage/wrap_c_ext_module.o b/tests/example-project/build/temp.linux-x86_64-3.8/src/pypackage/wrap_c_ext_module.o
deleted file mode 100644
index 7a50a1b..0000000
Binary files a/tests/example-project/build/temp.linux-x86_64-3.8/src/pypackage/wrap_c_ext_module.o and /dev/null differ
diff --git a/tests/example-project/build/temp.linux-x86_64-3.8/src/pypackage/wrap_cpp_ext_module.o b/tests/example-project/build/temp.linux-x86_64-3.8/src/pypackage/wrap_cpp_ext_module.o
deleted file mode 100644
index 588dd08..0000000
Binary files a/tests/example-project/build/temp.linux-x86_64-3.8/src/pypackage/wrap_cpp_ext_module.o and /dev/null differ
diff --git a/tests/example-project/setup.py b/tests/example-project/setup.py
index decc6b7..18bd581 100644
--- a/tests/example-project/setup.py
+++ b/tests/example-project/setup.py
@@ -1,21 +1,23 @@
 #!/usr/bin/env python
 # -*- encoding: utf-8 -*-
-from __future__ import absolute_import
 
 
 if __name__ == "__main__":
     import os
     import sys
-    import glob
 
     from setuptools import setup
     from setuptools import Extension
+    from Cython.Build import cythonize
 
-    root = os.path.dirname(__file__)
     directives = {
         'profile': True,
-        'embedsignature': True,
+        'embedsignature': False,
         'linetrace': False,
+        'language_level': sys.version_info[0],
+        # this is the default, but use it explicitly in case that ever
+        # changes
+        'autotestdict': True
     }
 
     # Enable code coverage for C code: we can't use CFLAGS=-coverage in
@@ -30,79 +32,16 @@ if __name__ == "__main__":
             macros = [[('CYTHON_TRACE', '1'), ('CYTHON_TRACE_NOGIL', '1')]]
 
 
-    try:
-        sys.argv.remove("--use-cython")
-        use_cython = True
-        from Cython.Build import cythonize
-        from Cython.Distutils import build_ext
-    except ValueError:
-        use_cython = False
-        from distutils.command.build_ext import build_ext
-
-    if 'clean' in sys.argv:
-        [os.remove(x) for x in glob.glob(os.path.join(root, 'src/pypackage/*.c'))]
-        [os.remove(x) for x in glob.glob(os.path.join(root, 'src/pypackage/*.so'))]
-        [os.remove(x) for x in glob.glob(os.path.join(root, 'src/pypackage/*.cpp'))]
-
-    if use_cython:
-        ext_files = glob.glob(os.path.join(root, 'src/pypackage/*.pyx'))
-        ext_files.extend(glob.glob(os.path.join(root, 'src/pypackage/*.py')))
-    else:
-        ext_files = glob.glob(os.path.join(root, 'src/pypackage/*.c'))
-        ext_files.extend(glob.glob(os.path.join(root, 'src/pypackage/*.cpp')))
-
-    extensions = []
-    exclude_files = ['__init__.py']
-    include_dirs = [os.path.abspath(os.path.join(root, 'src/clib'))]
-    for file_ in ext_files:
-        basename = os.path.basename(file_)
-        if basename in exclude_files:
-            continue
-        pyx_file, _ = os.path.splitext(basename)
-        extensions.append(Extension(
-                'src.pypackage.' + pyx_file,
-                [file_],
-                define_macros=macros,
-                include_dirs=include_dirs,
-            )
-        )
-
-    if use_cython:
-        extensions = cythonize(
-            extensions,
-            force=True,
-            compiler_directives=directives,
-        )
-
-
-    class optional_build_ext(build_ext):
-        """Allow the building of C extensions to fail."""
-        def run(self):
-            try:
-                build_ext.run(self)
-            except Exception as e:
-                self._unavailable(e)
-                self.extensions = []  # avoid copying missing files (it would fail).
-
-        def _unavailable(self, e):
-            print('*' * 80)
-            print('''WARNING:
-
-        An optional code optimization (C extension) could not be compiled.
-
-        Optimizations for this package will not be available!
-            ''')
-
-            print('CAUSE:')
-            print('')
-            print('    ' + repr(e))
-            print('*' * 80)
+    extensions = [
+        Extension('*', ['src/pypackage/*.pyx'], define_macros=macros)
+    ]
 
     setup(
         name='pytest-cython',
-        version='0.1.1',
+        version='0.2.1',
         description="Example Cython project for pytest-cython tests",
+        package_dir={'': 'src'},
+        packages=['pypackage'],
         zip_safe=False,
-        cmdclass={'build_ext': optional_build_ext},
-        ext_modules=extensions,
+        ext_modules=cythonize(extensions, compiler_directives=directives)
     )
diff --git a/tests/example-project/src/__init__.py b/tests/example-project/src/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/example-project/src/pypackage/cython_ext_module.pyx b/tests/example-project/src/pypackage/cython_ext_module.pyx
index 27dcd7a..4ff6786 100644
--- a/tests/example-project/src/pypackage/cython_ext_module.pyx
+++ b/tests/example-project/src/pypackage/cython_ext_module.pyx
@@ -73,3 +73,11 @@ cdef class Eggs:
         2
         """
         return self.a + self.b
+
+    def failing_test(self):
+        """
+        >>> eggs = Eggs(1, 1)
+        >>> eggs.failing_test()
+        False
+        """
+        return True
diff --git a/tests/test_pytest_cython.py b/tests/test_pytest_cython.py
index e546fe3..3d64ebf 100644
--- a/tests/test_pytest_cython.py
+++ b/tests/test_pytest_cython.py
@@ -1,51 +1,87 @@
 from __future__ import absolute_import
 
 import py
-import sys
+import pytest
+from setuptools.sandbox import run_setup
 
 import pytest_cython.plugin
 
+
 PATH = py.path.local(__file__).dirpath()
 PATH = PATH.join('example-project', 'src', 'pypackage')
-sys.path.insert(0, str(PATH))
 
+PYTEST_MAJOR_VERSION = int(pytest.__version__.split('.')[0])
+IMPORT_MODES = ['prepend', 'append']
+if PYTEST_MAJOR_VERSION >= 6:
+    IMPORT_MODES.insert(0, 'importlib')
+
+
+def get_module(basename, suffix='.pyx'):
+    return PATH.join(basename + suffix)
+
+
+def run_pytest(testdir, module, import_mode):
+    return testdir.runpytest('-vv', '--doctest-cython', '--import-mode', import_mode, str(module))
 
-def test_cython_ext_module(testdir):
-    module = PATH.listdir(fil='cython_ext_module*.so')[0]
+
+@pytest.fixture(scope='module', autouse=True)
+def build_example_project():
+    path = py.path.local(__file__).dirpath()
+    setup_py = path.join('example-project', 'setup.py')
+    run_setup(str(setup_py), ['build_ext', '--inplace'])
+
+
+@pytest.mark.parametrize('import_mode', IMPORT_MODES)
+def test_cython_ext_module(testdir, import_mode):
+    module = get_module('cython_ext_module')
     assert module.check()
-    result = testdir.runpytest('-vv', '--doctest-cython', str(module))
+    result = run_pytest(testdir, module, import_mode)
     result.stdout.fnmatch_lines([
         "*Eggs.__init__ *PASSED*",
         "*Eggs.blarg*PASSED*",
+        "*Eggs.failing_test*FAILED*",
         "*Eggs.fubar*PASSED*",
+        "*",
+        "*FAILURES*",
+        "*pypackage.cython_ext_module.Eggs.failing_test*",
+        "078*",
+        "079         >>> eggs = Eggs(1, 1)*",
+        "080         >>> eggs.failing_test()*",
+        "Expected:*",
+        "    False*",
+        "Got:*",
+        "    True*"
     ])
-    assert result.ret == 0
+    assert result.ret == 1
 
 
-def test_wrap_c_ext_module(testdir):
-    module = PATH.listdir(fil='wrap_c_ext_module*.so')[0]
+@pytest.mark.parametrize('import_mode', IMPORT_MODES)
+def test_wrap_c_ext_module(testdir, import_mode):
+    module = get_module('wrap_c_ext_module')
     assert module.check()
-    result = testdir.runpytest('-vv', '--doctest-cython', str(module))
+    result = run_pytest(testdir, module, import_mode)
     result.stdout.fnmatch_lines([
         "*sqr*PASSED*",
     ])
     assert result.ret == 0
 
 
-def test_wrap_cpp_ext_module(testdir):
-    module = PATH.listdir(fil='wrap_cpp_ext_module*.so')[0]
+@pytest.mark.parametrize('import_mode', IMPORT_MODES)
+def test_wrap_cpp_ext_module(testdir, import_mode):
+    module = get_module('wrap_cpp_ext_module')
     assert module.check()
-    result = testdir.runpytest('-vv', '--doctest-cython', str(module))
+    result = run_pytest(testdir, module, import_mode)
     result.stdout.fnmatch_lines([
         "*sqr*PASSED*",
     ])
     assert result.ret == 0
 
 
-def test_pure_py_module(testdir):
-    module = PATH.listdir(fil='pure_py_module*.py')[0]
+@pytest.mark.parametrize('import_mode', IMPORT_MODES)
+def test_pure_py_module(testdir, import_mode):
+    module = get_module('pure_py_module', suffix='.py')
     assert module.check()
-    result = testdir.runpytest('-vv', '--doctest-cython', str(module))
+    result = run_pytest(testdir, module, import_mode)
     result.stdout.fnmatch_lines([
         "*Eggs.__init__*PASSED*",
         "*Eggs.foo*PASSED*",
diff --git a/tox.ini b/tox.ini
deleted file mode 100644
index 42eac2a..0000000
--- a/tox.ini
+++ /dev/null
@@ -1,70 +0,0 @@
-; a generative tox configuration, see: https://testrun.org/tox/latest/config.html#generative-envlist
-
-[tox]
-envlist =
-    check,
-    {py26,py27,py33,py34,py35}-{27,28,29}-{023,024},
-    {pypy}-{27,28,29}-{024},
-    docs
-
-[testenv]
-basepython =
-    pypy: pypy
-    py26: {env:TOXPYTHON:python2.6}
-    py27: {env:TOXPYTHON:python2.7}
-    py33: {env:TOXPYTHON:python3.3}
-    py34: {env:TOXPYTHON:python3.4}
-    py35: {env:TOXPYTHON:python3.5}
-    {clean,check,docs,report,extension-coveralls,coveralls,spell}: python3
-setenv =
-    PYTHONPATH = {toxinidir}/tests
-    PYTHONUNBUFFERED = yes
-passenv =
-    *
-deps =
-    virtualenv
-    27: pytest==2.7.3
-    28: pytest==2.8.7
-    29: pytest==2.9.1
-    020: cython==0.20.2
-    021: cython==0.21.2
-    022: cython==0.22.1
-    023: cython==0.23.5
-    024: cython==0.24
-pip_pre = true
-commands =
-    python tests/example-project/setup.py clean build_ext --inplace --use-cython
-    {posargs:py.test -vv tests/test_pytest_cython.py}
-
-[testenv:spell]
-setenv =
-    SPELLCHECK=1
-commands =
-    sphinx-build -b spelling docs dist/docs
-skip_install = true
-usedevelop = false
-deps =
-    -r{toxinidir}/docs/requirements.txt
-    sphinxcontrib-spelling
-    pyenchant
-
-[testenv:docs]
-deps =
-    -r{toxinidir}/docs/requirements.txt
-commands =
-    sphinx-build {posargs:-E} -b html docs dist/docs
-    sphinx-build -b linkcheck docs dist/docs
-
-[testenv:check]
-deps =
-    docutils
-    check-manifest
-    flake8
-    readme-renderer
-    pygments
-skip_install = true
-usedevelop = false
-commands =
-    python setup.py check --strict --metadata --restructuredtext
-    check-manifest {toxinidir}
-    flake8 src tests setup.py

More details

Full run details

Historical runs