pax_global_header00006660000000000000000000000064145275455460014533gustar00rootroot0000000000000052 comment=00262476780c1cc16944147ed5ebeaa05a604a6e pytest-venv-0.3/000077500000000000000000000000001452754554600137015ustar00rootroot00000000000000pytest-venv-0.3/.coveragerc000066400000000000000000000002531452754554600160220ustar00rootroot00000000000000[run] parallel = true source = pytest_venv tests [paths] source = src/pytest_venv */site-packages/pytest_venv [report] show_missing = true precision = 2 pytest-venv-0.3/.flake8000066400000000000000000000000611452754554600150510ustar00rootroot00000000000000[flake8] show-source = True max-line-length = 80 pytest-venv-0.3/.github/000077500000000000000000000000001452754554600152415ustar00rootroot00000000000000pytest-venv-0.3/.github/dependabot.yml000066400000000000000000000003321452754554600200670ustar00rootroot00000000000000# Set update schedule for GitHub Actions version: 2 updates: - package-ecosystem: "github-actions" directory: "/" schedule: # Check for updates to GitHub Actions every weekday interval: "daily" pytest-venv-0.3/.github/workflows/000077500000000000000000000000001452754554600172765ustar00rootroot00000000000000pytest-venv-0.3/.github/workflows/ci-tests.yml000066400000000000000000000045471452754554600215660ustar00rootroot00000000000000name: Build and test on: # Only on pushes to main or one of the release branches we build on push push: branches: - main - "[0-9].[0-9]+-branch" tags: - "*" # Build pull requests pull_request: jobs: test: strategy: matrix: py: - "3.7" - "3.8" - "3.9" - "3.10" - "3.11" - "3.12" - "pypy-3.8" os: - "ubuntu-latest" - "windows-2022" - "macos-12" architecture: - x64 - x86 exclude: # Linux and macOS don't have x86 python - os: "ubuntu-latest" architecture: x86 - os: "macos-12" architecture: x86 name: "Python: ${{ matrix.py }}-${{ matrix.architecture }} on ${{ matrix.os }}" runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - name: Setup python uses: actions/setup-python@v4 with: python-version: ${{ matrix.py }} architecture: ${{ matrix.architecture }} - run: pip install tox - name: Running tox run: tox -e py coverage: runs-on: ubuntu-latest name: Validate coverage steps: - uses: actions/checkout@v4 - name: Setup python 3.7 uses: actions/setup-python@v4 with: python-version: 3.7 architecture: x64 - name: Setup python 3.12 uses: actions/setup-python@v4 with: python-version: 3.12 architecture: x64 - run: pip install tox - run: tox -e py37,py312,coverage lint: runs-on: ubuntu-latest name: Lint the package steps: - uses: actions/checkout@v4 - name: Setup python uses: actions/setup-python@v4 with: python-version: 3.12 architecture: x64 - run: pip install tox - run: tox -e lint pytest-venv-0.3/.gitignore000066400000000000000000000013511452754554600156710ustar00rootroot00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python env/ env*/ build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *,cover .hypothesis/ # Translations *.mo *.pot # Django stuff: *.log # Sphinx documentation docs/_build/ # PyBuilder target/ .idea cover pytest-venv-0.3/CHANGES.rst000066400000000000000000000021541452754554600155050ustar00rootroot000000000000000.3 (2023-11-22) ================ - Drop Python 2.7, 3.4, 3.5, 3.6. - Add support for Python 3.9, 3.10, 3.11, 3.12. - No longer expect ``pkg_resources`` to be available in the created virtualenv. - No longer depend on ``setuptools``. - Add ``extra_args`` to ``install()`` and ``create()`` to pass extra arguments to the underlying commands. - Add ``raises=False`` option to ``get_version()`` to avoid raising an exception if a package is not installed. 0.2.1 (2020-08-04) ================== - Depend directly on ``pytest``. See https://github.com/mmerickel/pytest-venv/pull/2 - Add support for Python 3.6, 3.7, and 3.8. See https://github.com/mmerickel/pytest-venv/pull/2 0.2 (2016-11-27) ================ - Add ``VirtualEnvironment.get_version`` for querying versions from installed packages in the virtual environment. - Support custom python interpreter paths via ``VirtualEnvironment.create(python=...)``. 0.1.1 (2016-11-27) ================== - Ensure the virtual environment is started with the same Python executable as the current process. 0.1 (2016-11-27) ================ - Initial release. pytest-venv-0.3/CONTRIBUTING.rst000066400000000000000000000056741452754554600163560ustar00rootroot00000000000000.. highlight:: shell ============ Contributing ============ Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given. You can contribute in many ways: Types of Contributions ---------------------- Report Bugs ~~~~~~~~~~~ Report bugs at https://github.com/mmerickel/pytest-venv/issues. If you are reporting a bug, 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. Fix Bugs ~~~~~~~~ Look through the GitHub issues for bugs. Anything tagged with "bug" is open to whoever wants to implement it. Implement Features ~~~~~~~~~~~~~~~~~~ Look through the GitHub issues for features. Anything tagged with "feature" is open to whoever wants to implement it. Write Documentation ~~~~~~~~~~~~~~~~~~~ `pytest-venv` could always use more documentation, whether as part of the official `pytest-venv` docs, in docstrings, or even on the web in blog posts, articles, and such. Submit Feedback ~~~~~~~~~~~~~~~ The best way to send feedback is to file an issue at https://github.com/mmerickel/pytest-venv/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 contributions are welcome :) Get Started! ------------ Ready to contribute? Here's how to set up `pytest-venv` for local development. 1. Fork the `pytest-venv` repo on GitHub. 2. Clone your fork locally:: $ git clone git@github.com:your_name_here/pytest-venv.git 3. Install your local copy into a virtualenv:: $ python3 -m venv env $ env/bin/pip install -e .[docs,testing] $ env/bin/pip install tox 4. Create a branch for local development:: $ git checkout -b name-of-your-bugfix-or-feature Now you can make your changes locally. 5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:: $ env/bin/tox 6. 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 7. Submit a pull request through the GitHub website. Pull Request Guidelines ----------------------- Before you submit a pull request, check that it meets these guidelines: 1. The pull request should include tests. 2. If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.rst. 3. The pull request should work for Python 2.7, 3.4 and 3.5, and for PyPy. Check https://travis-ci.org/mmerickel/pytest-venv/pull_requests and make sure that the tests pass for all supported Python versions. Tips ---- To run a subset of tests:: $ env/bin/py.test tests.foo pytest-venv-0.3/LICENSE.txt000066400000000000000000000020441452754554600155240ustar00rootroot00000000000000Copyright (c) 2016 Michael Merickel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. pytest-venv-0.3/MANIFEST.in000066400000000000000000000004201452754554600154330ustar00rootroot00000000000000graft .github graft src graft tests prune tests/myapp/*.egg-info include README.rst include CHANGES.rst include LICENSE.txt include CONTRIBUTING.rst include pyproject.toml include .coveragerc .flake8 pytest.ini include tox.ini recursive-exclude * __pycache__ *.py[cod] pytest-venv-0.3/README.rst000066400000000000000000000032201452754554600153650ustar00rootroot00000000000000=========== pytest-venv =========== .. image:: https://img.shields.io/pypi/v/pytest-venv.svg :target: https://pypi.python.org/pypi/pytest-venv .. image:: https://github.com/mmerickel/pytest-venv/actions/workflows/ci-tests.yml/badge.svg?branch=main :target: https://github.com/mmerickel/pytest-venv/actions/workflows/ci-tests.yml?query=branch%3Amain ``pytest-venv`` is a simple pytest plugin that exposes a ``venv`` fixture. The fixture is used to create a new virtual environment which can be used to install packages and run commands inside tests. Usage ===== .. code-block:: python import os def test_it(venv): venv.install('pyramid', upgrade=True) subprocess.check_call( [os.path.join(venv.bin, 'pserve'), 'development.ini'], ) API === The ``venv`` fixture is an instance of ``pytest_venv.VirtualEnvironment(path)`` which exposes the following API: ``path`` The path to the virtualenv directory. ``bin`` The path to the bin / Scripts directory. ``python`` The path to the python executable in the virtualenv. ``create(system_site_packages=False, python=None, *, extra_args=None)`` Create a virtualenv. This is called automatically by the ``venv`` fixture. If ``python`` is ``None`` then the virtual environment will be created using the same executable as the active runtime. ``install(pkg_name, editable=False, upgrade=False, *, extra_args=None)`` Use pip to install a package into the virtualenv. ``pkg_name`` may be a path to a package on disk. ``get_version(pkg_name, *, raises=True)`` Returns a ``packaging.version.Version`` object which is sortable and convertable to a string. pytest-venv-0.3/pyproject.toml000066400000000000000000000014001452754554600166100ustar00rootroot00000000000000[build-system] requires = ["setuptools>=41.0.1", "wheel"] build-backend = "setuptools.build_meta" [tool.black] line-length = 79 skip-string-normalization = true target_version = ["py37", "py38", "py39", "py310", "py311", "py312"] exclude = ''' /( \.git | \.mypy_cache | \.tox | \.venv | \.pytest_cache | dist | build | docs )/ ''' # This next section only exists for people that have their editors # automatically call isort, black already sorts entries on its own when run. [tool.isort] profile = "black" py_version = 3 combine_as_imports = true line_length = 79 force_sort_within_sections = true no_lines_before = "THIRDPARTY" sections = "FUTURE,THIRDPARTY,FIRSTPARTY,LOCALFOLDER" default_section = "THIRDPARTY" known_first_party = "pytest_venv" pytest-venv-0.3/pytest.ini000066400000000000000000000001141452754554600157260ustar00rootroot00000000000000[pytest] python_files = test_*.py testpaths = src/pytest_venv tests pytest-venv-0.3/setup.py000066400000000000000000000033031452754554600154120ustar00rootroot00000000000000from setuptools import find_packages, setup def readfile(name): with open(name) as f: return f.read() readme = readfile('README.rst') changes = readfile('CHANGES.rst') requires = [ 'packaging', 'pytest', 'virtualenv', ] tests_require = [ 'coverage', ] setup( name='pytest-venv', version='0.3', description='py.test fixture for creating a virtual environment', long_description=readme + '\n\n' + changes, long_description_content_type='text/x-rst', author='Michael Merickel', author_email='michael@merickel.org', url='https://github.com/mmerickel/pytest-venv', packages=find_packages('src', exclude=['tests']), package_dir={'': 'src'}, include_package_data=True, install_requires=requires, extras_require={ 'testing': tests_require, }, zip_safe=False, keywords='', classifiers=[ 'Development Status :: 4 - Beta', 'Framework :: Pytest', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Natural Language :: English', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Software Development :: Testing', ], entry_points={ 'pytest11': [ 'venv = pytest_venv', ], }, ) pytest-venv-0.3/src/000077500000000000000000000000001452754554600144705ustar00rootroot00000000000000pytest-venv-0.3/src/pytest_venv/000077500000000000000000000000001452754554600170565ustar00rootroot00000000000000pytest-venv-0.3/src/pytest_venv/__init__.py000066400000000000000000000036651452754554600212010ustar00rootroot00000000000000import os import packaging.version as pv import pytest import subprocess import sys import textwrap WIN = sys.platform == 'win32' @pytest.fixture def venv(tmpdir): venv = VirtualEnvironment(tmpdir.strpath) venv.create() yield venv class VirtualEnvironment(object): def __init__(self, path): self.path = path self.bin = os.path.join( self.path, 'bin' if sys.platform != 'win32' else 'Scripts', ) self.python = os.path.join(self.bin, 'python') def create(self, system_packages=False, python=None, *, extra_args=None): cmd = [sys.executable, '-m', 'virtualenv'] cmd += ['-p', python or sys.executable] if system_packages: cmd += ['--system-site-packages'] if extra_args: cmd += extra_args cmd += [self.path] subprocess.check_call(cmd) def install( self, pkg_name, editable=False, upgrade=False, *, extra_args=None ): cmd = [self.python, '-m', 'pip', 'install'] if upgrade: cmd += ['-U'] if extra_args: cmd += extra_args if editable: cmd += ['-e'] cmd += [pkg_name] subprocess.check_call(cmd) def get_version(self, pkg_name, *, raises=True): script = textwrap.dedent( f''' try: from importlib.metadata import version except ImportError: import pkg_resources version = lambda x: pkg_resources.get_distribution(x).version try: print(version("{pkg_name}")) except Exception: print('') ''' ) version = subprocess.check_output([self.python, '-c', script]).strip() if not version: if raises: raise Exception('package is not installed') return None return pv.Version(version.decode('utf8')) pytest-venv-0.3/tests/000077500000000000000000000000001452754554600150435ustar00rootroot00000000000000pytest-venv-0.3/tests/myapp/000077500000000000000000000000001452754554600161715ustar00rootroot00000000000000pytest-venv-0.3/tests/myapp/myapp.py000066400000000000000000000000251452754554600176660ustar00rootroot00000000000000print('hello world') pytest-venv-0.3/tests/myapp/setup.py000066400000000000000000000003031452754554600176770ustar00rootroot00000000000000from setuptools import setup setup( name='myapp', version='0.1', description='', long_description='', author='', author_email='', url='', py_modules=['myapp'], ) pytest-venv-0.3/tests/test_it.py000066400000000000000000000041411452754554600170700ustar00rootroot00000000000000import os import pytest import subprocess import sys here = os.path.abspath(os.path.dirname(__file__)) def test_it(venv): result = subprocess.check_output( [venv.python, '-c', 'print("hello world")'], ) assert result.strip() == b'hello world' def test_it_installs_dep(venv): venv.install('webob') subprocess.check_call([venv.python, '-c', 'import webob']) def test_it_installs_dep_with_extra_args(venv): venv.install('webob', extra_args=['--prefer-binary']) subprocess.check_call([venv.python, '-c', 'import webob']) @pytest.mark.skipif( sys.version_info < (3, 12), reason="Make sense only for Python 3.12" ) def test_it_installs_dep_without_setuptools(venv): # micropipenv does not depend on setuptools # so this test verifies that `get_version` works # fine even when setuptools/pkg_resources are # not available in the virtual environment. venv.install('micropipenv') subprocess.check_call([venv.python, '-c', 'import micropipenv']) venv.get_version('micropipenv') def test_it_installs_editable_dep(venv): venv.install(os.path.join(here, 'myapp'), editable=True) result = subprocess.check_output([venv.python, '-c', 'import myapp']) assert result.strip() == b'hello world' def test_it_upgrades_dep(venv): venv.install('pyramid==1.6') version1 = venv.get_version('pyramid') assert str(version1) == '1.6' venv.install('pyramid', upgrade=True) version2 = venv.get_version('pyramid') assert version2 > version1 def test_get_version_returns_none(venv): version = venv.get_version('pyramid', raises=False) assert version is None def test_get_version_raises(venv): with pytest.raises(Exception, match='package is not installed'): venv.get_version('pyramid') def test_it_creates_with_system_packages(tmpdir): from pytest_venv import VirtualEnvironment venv = VirtualEnvironment(tmpdir.strpath) venv.create(system_packages=True, extra_args=['--no-setuptools']) result = subprocess.check_output( [venv.python, '-c', 'print("hello world")'], ) assert b'hello world' in result pytest-venv-0.3/tox.ini000066400000000000000000000023131452754554600152130ustar00rootroot00000000000000[tox] envlist = lint, py37,py38,py39,py310,py311,py312,pypy3 coverage [testenv] commands = coverage run -m pytest {posargs:} extras = testing [testenv:coverage] commands = coverage combine coverage report --fail-under=100 deps = coverage [testenv:lint] skip_install = True commands = isort --check-only --df src/pytest_venv tests setup.py black --check --diff src/pytest_venv tests setup.py flake8 src/pytest_venv tests setup.py check-manifest # build sdist/wheel python -m build . twine check dist/* deps = black build check-manifest flake8 flake8-bugbear isort readme_renderer twine [testenv:format] skip_install = true commands = isort src/pytest_venv tests setup.py black src/pytest_venv tests setup.py deps = black isort [testenv:build] skip_install = true commands = # clean up build/ and dist/ folders python -c 'import shutil; shutil.rmtree("build", ignore_errors=True)' # Make sure we aren't forgetting anything check-manifest # build sdist/wheel python -m build . # Verify all is well twine check dist/* deps = build check-manifest readme_renderer twine