pax_global_header00006660000000000000000000000064146035116740014521gustar00rootroot0000000000000052 comment=da8d2c18f64fabfacadaa5a7efd77738a3c83ed5 pytest-jupyter-0.10.1/000077500000000000000000000000001460351167400146305ustar00rootroot00000000000000pytest-jupyter-0.10.1/.github/000077500000000000000000000000001460351167400161705ustar00rootroot00000000000000pytest-jupyter-0.10.1/.github/dependabot.yml000066400000000000000000000005071460351167400210220ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" groups: actions: patterns: - "*" - package-ecosystem: "pip" directory: "/" schedule: interval: "weekly" groups: actions: patterns: - "*" pytest-jupyter-0.10.1/.github/workflows/000077500000000000000000000000001460351167400202255ustar00rootroot00000000000000pytest-jupyter-0.10.1/.github/workflows/downstream.yml000066400000000000000000000023461460351167400231400ustar00rootroot00000000000000name: Test downstream projects on: push: branches: ["main"] pull_request: concurrency: group: downstream-${{ github.ref }} cancel-in-progress: true jobs: jupyter_server: runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkout@v4 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1 with: package_name: jupyter_server package_download_extra_args: --pre jupyter_client: runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkout@v4 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1 with: package_name: jupyter_client package_download_extra_args: --pre downstream_check: # This job does nothing and is only used for the branch protection if: always() needs: - jupyter_server - jupyter_client runs-on: ubuntu-latest steps: - name: Decide whether the needed jobs succeeded or failed uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }} pytest-jupyter-0.10.1/.github/workflows/prep-release.yml000066400000000000000000000032311460351167400233330ustar00rootroot00000000000000name: "Step 1: Prep Release" on: workflow_dispatch: inputs: version_spec: description: "New Version Specifier" default: "next" required: false branch: description: "The branch to target" required: false post_version_spec: description: "Post Version Specifier" required: false silent: description: "Set a placeholder in the changelog and don't publish the release." required: false type: boolean since: description: "Use PRs with activity since this date or git reference" required: false since_last_stable: description: "Use PRs with activity since the last stable git tag" required: false type: boolean jobs: prep_release: runs-on: ubuntu-latest permissions: contents: write steps: - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Prep Release id: prep-release uses: jupyter-server/jupyter_releaser/.github/actions/prep-release@v2 with: token: ${{ secrets.GITHUB_TOKEN }} version_spec: ${{ github.event.inputs.version_spec }} silent: ${{ github.event.inputs.silent }} post_version_spec: ${{ github.event.inputs.post_version_spec }} target: ${{ github.event.inputs.target }} branch: ${{ github.event.inputs.branch }} since: ${{ github.event.inputs.since }} since_last_stable: ${{ github.event.inputs.since_last_stable }} - name: "** Next Step **" run: | echo "Optional): Review Draft Release: ${{ steps.prep-release.outputs.release_url }}" pytest-jupyter-0.10.1/.github/workflows/publish-changelog.yml000066400000000000000000000016401460351167400243440ustar00rootroot00000000000000name: "Publish Changelog" on: release: types: [published] workflow_dispatch: inputs: branch: description: "The branch to target" required: false jobs: publish_changelog: runs-on: ubuntu-latest environment: release steps: - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: actions/create-github-app-token@v1 id: app-token with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} - name: Publish changelog id: publish-changelog uses: jupyter-server/jupyter_releaser/.github/actions/publish-changelog@v2 with: token: ${{ steps.app-token.outputs.token }} branch: ${{ github.event.inputs.branch }} - name: "** Next Step **" run: | echo "Merge the changelog update PR: ${{ steps.publish-changelog.outputs.pr_url }}" pytest-jupyter-0.10.1/.github/workflows/publish-release.yml000066400000000000000000000034061460351167400240370ustar00rootroot00000000000000name: "Step 2: Publish Release" on: workflow_dispatch: inputs: branch: description: "The target branch" required: false release_url: description: "The URL of the draft GitHub release" required: false steps_to_skip: description: "Comma separated list of steps to skip" required: false jobs: publish_release: runs-on: ubuntu-latest environment: release permissions: id-token: write steps: - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: actions/create-github-app-token@v1 id: app-token with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} - name: Populate Release id: populate-release uses: jupyter-server/jupyter_releaser/.github/actions/populate-release@v2 with: token: ${{ steps.app-token.outputs.token }} branch: ${{ github.event.inputs.branch }} release_url: ${{ github.event.inputs.release_url }} steps_to_skip: ${{ github.event.inputs.steps_to_skip }} - name: Finalize Release id: finalize-release uses: jupyter-server/jupyter_releaser/.github/actions/finalize-release@v2 with: token: ${{ steps.app-token.outputs.token }} release_url: ${{ steps.populate-release.outputs.release_url }} - name: "** Next Step **" if: ${{ success() }} run: | echo "Verify the final release" echo ${{ steps.finalize-release.outputs.release_url }} - name: "** Failure Message **" if: ${{ failure() }} run: | echo "Failed to Publish the Draft Release Url:" echo ${{ steps.populate-release.outputs.release_url }} pytest-jupyter-0.10.1/.github/workflows/test.yml000066400000000000000000000110541460351167400217300ustar00rootroot00000000000000name: Tests on: push: branches: ["main"] pull_request: schedule: - cron: "0 8 * * *" defaults: run: shell: bash -eux {0} jobs: build: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] python-version: ["3.8", "3.12"] include: - os: windows-latest python-version: "3.9" - os: ubuntu-latest python-version: "pypy-3.9" - os: ubuntu-latest python-version: "3.8" - os: macos-latest python-version: "3.10" steps: - uses: actions/checkout@v4 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Run the tests on pypy if: ${{ startsWith(matrix.python-version, 'pypy') }} run: | hatch run test:nowarn || hatch run test:nowarn --lf - name: Run the tests if: ${{ !startsWith(matrix.python-version, 'pypy') }} run: hatch run cov:test || hatch run test:test --lf - uses: jupyterlab/maintainer-tools/.github/actions/upload-coverage@v1 coverage: runs-on: ubuntu-latest needs: - build steps: - uses: actions/checkout@v4 - uses: jupyterlab/maintainer-tools/.github/actions/report-coverage@v1 test_docs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Install Dependencies run: | sudo apt-get update sudo apt-get install enchant-2 # for spell checking - run: hatch run docs:build test_lint: name: Test Lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Run Linters run: | hatch run typing:test hatch run lint:build pipx run interrogate -v . pipx run doc8 --max-line-length=200 --ignore-path=docs/source/other/full-config.rst test_minimum_versions: name: Test Minimum Versions timeout-minutes: 20 runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 with: dependency_type: minimum - name: Run the unit tests run: | hatch -v run test:nowarn || hatch run test:nowarn --lf test_prereleases: name: Test Prereleases runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v4 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 with: dependency_type: pre - name: Run the tests run: | hatch run test:nowarn || hatch run test:nowarn --lf make_sdist: name: Make SDist runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkout@v4 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: jupyterlab/maintainer-tools/.github/actions/make-sdist@v1 test_sdist: runs-on: ubuntu-latest needs: [make_sdist] name: Install from SDist and Test timeout-minutes: 20 steps: - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: jupyterlab/maintainer-tools/.github/actions/test-sdist@v1 with: test_command: hatch run test:test check_release: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Base Setup uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Install Dependencies run: | pip install -e . - name: Check Release uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v2 with: token: ${{ secrets.GITHUB_TOKEN }} check_links: name: Check Links runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@v4 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1 tests_check: # This job does nothing and is only used for the branch protection if: always() needs: - coverage - test_lint - test_docs - test_minimum_versions - test_prereleases - check_links - check_release - test_sdist runs-on: ubuntu-latest steps: - name: Decide whether the needed jobs succeeded or failed uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }} pytest-jupyter-0.10.1/.gitignore000066400000000000000000000034701460351167400166240ustar00rootroot00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class *.vscode # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # 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/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # PEP 582; used by e.g. github.com/David-OConnor/pyflow __pypackages__/ # Celery stuff celerybeat-schedule celerybeat.pid # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Pycharm settings .idea/ # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # .DS_Store pytest-jupyter-0.10.1/.pre-commit-config.yaml000066400000000000000000000042761460351167400211220ustar00rootroot00000000000000ci: autoupdate_schedule: monthly autoupdate_commit_msg: "chore: update pre-commit hooks" repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: - id: check-case-conflict - id: check-ast - id: check-docstring-first - id: check-executables-have-shebangs - id: check-added-large-files - id: check-case-conflict - id: check-merge-conflict - id: check-json - id: check-toml - id: check-yaml - id: debug-statements - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema rev: 0.27.4 hooks: - id: check-github-workflows - repo: https://github.com/executablebooks/mdformat rev: 0.7.17 hooks: - id: mdformat - repo: https://github.com/pre-commit/mirrors-prettier rev: "v4.0.0-alpha.8" hooks: - id: prettier types_or: [yaml, html, json] - repo: https://github.com/adamchainz/blacken-docs rev: "1.16.0" hooks: - id: blacken-docs additional_dependencies: [black==23.7.0] - repo: https://github.com/codespell-project/codespell rev: "v2.2.6" hooks: - id: codespell args: ["-L", "sur,nd"] - repo: https://github.com/pre-commit/mirrors-mypy rev: "v1.8.0" hooks: - id: mypy files: pytest_jupyter stages: [manual] args: ["--install-types", "--non-interactive"] additional_dependencies: [ "pytest>=7", "jupyter_client>=8.5", "jupyter_server>=2.9", "ipykernel>=6.26", ] - repo: https://github.com/pre-commit/pygrep-hooks rev: "v1.10.0" hooks: - id: rst-backticks - id: rst-directive-colons - id: rst-inline-touching-normal - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.2.0 hooks: - id: ruff types_or: [python, jupyter] args: ["--fix", "--show-fixes"] - id: ruff-format types_or: [python, jupyter] - repo: https://github.com/scientific-python/cookie rev: "2024.01.24" hooks: - id: sp-repo-review additional_dependencies: ["repo-review[cli]"] pytest-jupyter-0.10.1/.readthedocs.yml000066400000000000000000000004741460351167400177230ustar00rootroot00000000000000# Required version: 2 # Build documentation in the docs/ directory with Sphinx sphinx: configuration: docs/conf.py build: os: ubuntu-22.04 tools: python: "3.11" # Handle requirements required to build your docs python: install: - method: pip path: . extra_requirements: - docs pytest-jupyter-0.10.1/CHANGELOG.md000066400000000000000000000443201460351167400164440ustar00rootroot00000000000000# Changes in Pytest-Jupyter ## 0.10.1 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.10.0...2211d1c87b89cba467b710d40dabfc85103eb481)) ### Bugs fixed - Fix passing of kwargs to websocket_connect [#81](https://github.com/jupyter-server/pytest-jupyter/pull/81) ([@blink1073](https://github.com/blink1073)) ### Maintenance and upkeep improvements - Set all min deps [#80](https://github.com/jupyter-server/pytest-jupyter/pull/80) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2024-04-03&to=2024-04-04&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2024-04-03..2024-04-04&type=Issues) ## 0.10.0 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.9.1...c0a675a56ba8660aa7b0859c84fa296ed441396d)) ### Enhancements made - jp_ws_fetch: passthrough kwargs to websocket_connect [#78](https://github.com/jupyter-server/pytest-jupyter/pull/78) ([@minrk](https://github.com/minrk)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2024-03-12&to=2024-04-03&type=c)) [@minrk](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Aminrk+updated%3A2024-03-12..2024-04-03&type=Issues) ## 0.9.1 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.9.0...615720a8851595b4710136b859f2e7be4fe3d81d)) ### Maintenance and upkeep improvements - Update Release Scripts [#77](https://github.com/jupyter-server/pytest-jupyter/pull/77) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2024-02-21&to=2024-03-12&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2024-02-21..2024-03-12&type=Issues) ## 0.9.0 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.8.0...ecbb00c30aa753b9d114c33a06042c5409c0e08e)) ### Enhancements made - Update event loop handling [#75](https://github.com/jupyter-server/pytest-jupyter/pull/75) ([@blink1073](https://github.com/blink1073)) ### Other merged PRs - chore: update pre-commit hooks [#76](https://github.com/jupyter-server/pytest-jupyter/pull/76) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - chore: update pre-commit hooks [#74](https://github.com/jupyter-server/pytest-jupyter/pull/74) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - Fix typo [#73](https://github.com/jupyter-server/pytest-jupyter/pull/73) ([@davidbrochart](https://github.com/davidbrochart)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2023-12-05&to=2024-02-21&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2023-12-05..2024-02-21&type=Issues) | [@davidbrochart](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Adavidbrochart+updated%3A2023-12-05..2024-02-21&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Apre-commit-ci+updated%3A2023-12-05..2024-02-21&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Awelcome+updated%3A2023-12-05..2024-02-21&type=Issues) ## 0.8.0 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.7.0...d83a09ba47b003c5bab94bb0a8c7e7bd3cd283f1)) ### Enhancements made - Allow passing request_timeout to client_fetch [#67](https://github.com/jupyter-server/pytest-jupyter/pull/67) ([@afbarbaro](https://github.com/afbarbaro)) ### Maintenance and upkeep improvements - Add missing 0.7.0 changelog entry [#69](https://github.com/jupyter-server/pytest-jupyter/pull/69) ([@blink1073](https://github.com/blink1073)) - Update ruff and typings [#66](https://github.com/jupyter-server/pytest-jupyter/pull/66) ([@blink1073](https://github.com/blink1073)) - Clean up lint and add downstream tests [#64](https://github.com/jupyter-server/pytest-jupyter/pull/64) ([@blink1073](https://github.com/blink1073)) - Use ruff format [#63](https://github.com/jupyter-server/pytest-jupyter/pull/63) ([@blink1073](https://github.com/blink1073)) - Update ruff and typing [#62](https://github.com/jupyter-server/pytest-jupyter/pull/62) ([@blink1073](https://github.com/blink1073)) - Update typings for traitlets 5.10.1 [#60](https://github.com/jupyter-server/pytest-jupyter/pull/60) ([@blink1073](https://github.com/blink1073)) - Adopt sp-repo-review [#58](https://github.com/jupyter-server/pytest-jupyter/pull/58) ([@blink1073](https://github.com/blink1073)) - Use local coverage [#54](https://github.com/jupyter-server/pytest-jupyter/pull/54) ([@blink1073](https://github.com/blink1073)) ### Other merged PRs - chore: update pre-commit hooks [#68](https://github.com/jupyter-server/pytest-jupyter/pull/68) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - chore: update pre-commit hooks [#65](https://github.com/jupyter-server/pytest-jupyter/pull/65) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - chore: update pre-commit hooks [#61](https://github.com/jupyter-server/pytest-jupyter/pull/61) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - Bump actions/checkout from 3 to 4 [#59](https://github.com/jupyter-server/pytest-jupyter/pull/59) ([@dependabot](https://github.com/dependabot)) - Update release instructions with additional commit steps [#52](https://github.com/jupyter-server/pytest-jupyter/pull/52) ([@kevin-bates](https://github.com/kevin-bates)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2023-03-30&to=2023-12-05&type=c)) [@afbarbaro](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Aafbarbaro+updated%3A2023-03-30..2023-12-05&type=Issues) | [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2023-03-30..2023-12-05&type=Issues) | [@codecov](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Acodecov+updated%3A2023-03-30..2023-12-05&type=Issues) | [@dependabot](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Adependabot+updated%3A2023-03-30..2023-12-05&type=Issues) | [@kevin-bates](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Akevin-bates+updated%3A2023-03-30..2023-12-05&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Apre-commit-ci+updated%3A2023-03-30..2023-12-05&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Awelcome+updated%3A2023-03-30..2023-12-05&type=Issues) ## 0.7.0 ## What's Changed - Add more ci checks by @blink1073 in https://github.com/jupyter-server/pytest-jupyter/pull/42 - Bump ruff from 0.0.189 to 0.0.194 by @dependabot in https://github.com/jupyter-server/pytest-jupyter/pull/43 - Bump black\[jupyter\] from 22.10.0 to 22.12.0 by @dependabot in https://github.com/jupyter-server/pytest-jupyter/pull/44 - Clean up lint by @blink1073 in https://github.com/jupyter-server/pytest-jupyter/pull/45 - \[pre-commit.ci\] pre-commit autoupdate by @pre-commit-ci in https://github.com/jupyter-server/pytest-jupyter/pull/46 - Sync lint deps by @blink1073 in https://github.com/jupyter-server/pytest-jupyter/pull/47 - Add more linting by @blink1073 in https://github.com/jupyter-server/pytest-jupyter/pull/48 - \[pre-commit.ci\] pre-commit autoupdate by @pre-commit-ci in https://github.com/jupyter-server/pytest-jupyter/pull/49 - \[pre-commit.ci\] pre-commit autoupdate by @pre-commit-ci in https://github.com/jupyter-server/pytest-jupyter/pull/50 - Enable header overrides in jp_ws_fetch fixture by @kevin-bates in https://github.com/jupyter-server/pytest-jupyter/pull/51 ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-12-19&to=2023-03-30&type=c)) ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.6.2...v0.7.0)) ## 0.6.2 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.6.1...4d3cb820e2ffb435f6b482f1b08bcddce062436d)) ### Bugs fixed - Handle asyncio timeout [#41](https://github.com/jupyter-server/pytest-jupyter/pull/41) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-12-19&to=2022-12-19&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2022-12-19..2022-12-19&type=Issues) ## 0.6.1 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.6.0...5e9a4ddd9fa138fb00e1738095139a27070558a2)) ### Bugs fixed - Handle TimeoutError During Fixture Shutdown [#40](https://github.com/jupyter-server/pytest-jupyter/pull/40) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-12-07&to=2022-12-19&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2022-12-07..2022-12-19&type=Issues) ## 0.6.0 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.5.3...0d41f3ff76324b2e158763ee17bb6e3e0075748d)) ### Enhancements made - Use native kernel by default [#36](https://github.com/jupyter-server/pytest-jupyter/pull/36) ([@blink1073](https://github.com/blink1073)) ### Bugs fixed - Fix core import in client [#38](https://github.com/jupyter-server/pytest-jupyter/pull/38) ([@blink1073](https://github.com/blink1073)) ### Maintenance and upkeep improvements - Adopt ruff and address lint [#37](https://github.com/jupyter-server/pytest-jupyter/pull/37) ([@blink1073](https://github.com/blink1073)) - hoist __version__ [#34](https://github.com/jupyter-server/pytest-jupyter/pull/34) ([@bollwyvl](https://github.com/bollwyvl)) ### Other merged PRs ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-11-30&to=2022-12-07&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2022-11-30..2022-12-07&type=Issues) | [@bollwyvl](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Abollwyvl+updated%3A2022-11-30..2022-12-07&type=Issues) | [@codecov](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Acodecov+updated%3A2022-11-30..2022-12-07&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Apre-commit-ci+updated%3A2022-11-30..2022-12-07&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Awelcome+updated%3A2022-11-30..2022-12-07&type=Issues) ## 0.5.3 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.5.2...4118fd38a44ab56b883699a73e10a5c6e59dbf90)) ### Bugs fixed - Fix fixture name [#33](https://github.com/jupyter-server/pytest-jupyter/pull/33) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-11-30&to=2022-11-30&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2022-11-30..2022-11-30&type=Issues) ## 0.5.2 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.5.1...583891706f2cb9b83557f8ac3633177cf2657f88)) ### Bugs fixed - Restore public api names [#32](https://github.com/jupyter-server/pytest-jupyter/pull/32) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-11-29&to=2022-11-30&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2022-11-29..2022-11-30&type=Issues) ## 0.5.1 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.5.0...ab53dc343abab12343aae3d46cf1ab22c67a6f36)) ### Maintenance and upkeep improvements - Add py37 support and update project config [#31](https://github.com/jupyter-server/pytest-jupyter/pull/31) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-11-29&to=2022-11-29&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2022-11-29..2022-11-29&type=Issues) ## 0.5.0 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.4.1...10cf9ca3f7256e9793059838a5d2acc9763ab982)) ### Enhancements made - Inline pytest_tornasync and add downstream tests [#30](https://github.com/jupyter-server/pytest-jupyter/pull/30) ([@blink1073](https://github.com/blink1073)) ### Other merged PRs ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-11-28&to=2022-11-29&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2022-11-28..2022-11-29&type=Issues) | [@codecov](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Acodecov+updated%3A2022-11-28..2022-11-29&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Apre-commit-ci+updated%3A2022-11-28..2022-11-29&type=Issues) ## 0.4.1 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.4.0...16b3797eecb717929148b34d0c3f3fca3d4ef0b0)) ### Bugs fixed - Fix event loop policy handling [#27](https://github.com/jupyter-server/pytest-jupyter/pull/27) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-11-27&to=2022-11-28&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2022-11-27..2022-11-28&type=Issues) ## 0.4.0 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.2.3...e6b05fed3a3d10627ffe222cd2d3ca9ca1ee7bce)) ### Enhancements made - Refactor fixtures [#26](https://github.com/jupyter-server/pytest-jupyter/pull/26) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-11-27&to=2022-11-27&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2022-11-27..2022-11-27&type=Issues) ## 0.2.3 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.2.2...5e7c41b19baaa04253f08b8e2474ea72983683d4)) ### Bugs fixed - Switch away from pytest-asyncio [#25](https://github.com/jupyter-server/pytest-jupyter/pull/25) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-11-27&to=2022-11-27&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2022-11-27..2022-11-27&type=Issues) ## 0.2.2 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.2.1...83d5ae13da2decca72fbcdfb718770340e2e6d56)) ### Bugs fixed - Allow strict mode usage [#24](https://github.com/jupyter-server/pytest-jupyter/pull/24) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-11-27&to=2022-11-27&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2022-11-27..2022-11-27&type=Issues) ## 0.2.1 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/v0.2.0...07f05b235d8c7731dda84e6738ab0252179feb38)) ### Bugs fixed - Fix imports [#23](https://github.com/jupyter-server/pytest-jupyter/pull/23) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-11-27&to=2022-11-27&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2022-11-27..2022-11-27&type=Issues) ## 0.2.0 ([Full Changelog](https://github.com/jupyter-server/pytest-jupyter/compare/0.1.0...6c530ccefdfda73ba3ed9cc4d36356c30efec6e8)) ### Enhancements made - Clean up echo kernel handling and update readme [#22](https://github.com/jupyter-server/pytest-jupyter/pull/22) ([@blink1073](https://github.com/blink1073)) ### Maintenance and upkeep improvements - Add releaser workflows [#21](https://github.com/jupyter-server/pytest-jupyter/pull/21) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyter-server/pytest-jupyter/graphs/contributors?from=2022-11-27&to=2022-11-27&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Ablink1073+updated%3A2022-11-27..2022-11-27&type=Issues) | [@codecov](https://github.com/search?q=repo%3Ajupyter-server%2Fpytest-jupyter+involves%3Acodecov+updated%3A2022-11-27..2022-11-27&type=Issues) ## 0.1.0 Initial Release pytest-jupyter-0.10.1/LICENSE000066400000000000000000000077131460351167400156450ustar00rootroot00000000000000# Licensing terms This project is licensed under the terms of the Modified BSD License (also known as New or Revised or 3-Clause BSD), as follows: - Copyright (c) 2020-, Jupyter Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Jupyter Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## About the Jupyter Development Team The Jupyter Development Team is the set of all contributors to the Jupyter project. This includes all of the Jupyter subprojects. The core team that coordinates development on GitHub can be found here: https://github.com/jupyter/. ## Our Copyright Policy Jupyter uses a shared copyright model. Each contributor maintains copyright over their contributions to Jupyter. But, it is important to note that these contributions are typically only changes to the repositories. Thus, the Jupyter source code, in its entirety is not the copyright of any single person or institution. Instead, it is the collective copyright of the entire Jupyter Development Team. If individual contributors want to maintain a record of what changes/contributions they have specific copyright on, they should indicate their copyright in the commit message of the change, when they commit the change to one of the Jupyter repositories. With this in mind, the following banner should be used in any source code file to indicate the copyright and license terms: # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. Pytest Tornasync File License ============================= The pytest_jupyter/pytest_tornasync.py was originally licensed as: The MIT License (MIT) Copyright (c) 2016 eukaryote 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-jupyter-0.10.1/README.md000066400000000000000000000057171460351167400161210ustar00rootroot00000000000000# pytest-jupyter A set of pytest plugins for Jupyter libraries and extensions. [![Build Status](https://github.com/jupyter-server/pytest-jupyter/actions/workflows/test.yml/badge.svg?query=branch%3Amain++)](https://github.com/jupyter-server/pytest-jupyter/actions/workflows/test.yml/badge.svg?query=branch%3Amain++) ## Basic Usage First, install `pytest-jupyter` from PyPI using pip: ```bash pip install pytest-jupyter ``` This installs the basic pytest-jupyter package that includes fixture definitions for the various Jupyter-based pytest plugins. To use one of these plugins, you'll also need to install their dependencies. This requires a second `pip install` call. For example, if you'd like to use the `jupyter_server` plugin, you'll need to call: ```bash pip install "pytest-jupyter[server]" ``` This *should* install everything you need for the plugin to work. To use a plugin, add it to the `pytest_plugins` list in the `conftest.py` of your project's root test directory. ```python # inside the conftest.py pytest_plugins = ["pytest_jupyter.jupyter_server"] ``` This library includes an `echo_kernel`, which is useful to speed up testing. You must have either `"pytest-jupyter[server]"` or `"pytest-jupyter[client]"` installed to use the echo kernel. The `pytest_jupyter.jupyter_client` plugin provides an installed `echo_kernel_spec` as a fixture, and a `start_kernel` fixture that provides a factory function that starts a kernel using the `echo` kernel by default. *Note*: The server plugin also includes the client plugin, so you can use both sets of fixtures with `"pytest_jupyter.jupyter_server"`. Both the `client` and `server` plugins also include the core fixtures. *Note*: The client and server plugins use `pytest-tornasync` for async test suite running. It may not compatible with `pytest-asyncio`, meaning that all fixtures must be synchronous. You can use the `asyncio_loop` fixture and run `asyncio_loop.run_until_complete` against an async function in your fixtures if needed. The server fixures use the echo kernel by default. To override this behavior, override the `jp_server_config` fixture and add the following config: ```json { "MultiKernelManager": { "default_kernel_name": " Server ``` ## Search - {ref}`genindex` - {ref}`modindex` - {ref}`search` pytest-jupyter-0.10.1/docs/make.bat000066400000000000000000000013701460351167400171660ustar00rootroot00000000000000@ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=. set BUILDDIR=_build if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :end popd pytest-jupyter-0.10.1/docs/plugins/000077500000000000000000000000001460351167400172415ustar00rootroot00000000000000pytest-jupyter-0.10.1/docs/plugins/jupyter_core.md000066400000000000000000000006431460351167400223000ustar00rootroot00000000000000# Jupyter Core plugin The following plugin is useful for setting up a test environment for Jupyter extensions and applications. To use this plugin, install the dependencies for this plugin: ``` pip install 'pytest-jupyter[core]' ``` and list the plugin in the `conftest.py` file at the root of your project's test directory. ## Fixtures ```{eval-rst} .. automodule:: pytest_jupyter.jupyter_core :members: ``` pytest-jupyter-0.10.1/docs/plugins/jupyter_server.md000066400000000000000000000010011460351167400226430ustar00rootroot00000000000000# Jupyter Server plugin The jupyter_server module provides fixtures for automatically setting-up/tearing-down Jupyter Servers. To use this plugin, install the dependencies for this plugin: ``` pip install 'pytest-jupyter[server]' ``` and list the plugin in the `conftest.py` file at the root of your project's test directory. You can make requests to a *test server* using the `jp_fetch` and `jp_ws_fetch` fixtures. ## Fixtures ```{eval-rst} .. automodule:: pytest_jupyter.jupyter_server :members: ``` pytest-jupyter-0.10.1/pyproject.toml000066400000000000000000000115671460351167400175560ustar00rootroot00000000000000[build-system] requires = [ "hatchling>=1.10.0", ] build-backend = "hatchling.build" [project] name = "pytest-jupyter" dynamic = [ "version", ] description = "A pytest plugin for testing Jupyter libraries and extensions." readme = "README.md" license = { file = "LICENSE" } authors = [ { name = "Jupyter Development Team", email = "jupyter@googlegroups.com" }, ] keywords = [ "Jupyter", "pytest", ] classifiers = [ "Development Status :: 4 - Beta", "Framework :: Jupyter", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3", ] dependencies = [ "pytest>=7.0", "jupyter_core>=5.7" ] requires-python = ">=3.8" [project.optional-dependencies] docs = [ "myst_parser", "pydata_sphinx_theme", "Sphinx", "sphinxcontrib-spelling" ] client = [ "jupyter_client>=7.4.0", "nbformat>=5.3", "ipykernel>=6.14" ] server = [ "jupyter_server>=1.21", "jupyter_client>=7.4.0", "nbformat>=5.3", "ipykernel>=6.14" ] test = [ "pytest-timeout" ] [project.urls] Homepage = "http://jupyter.org" Funding = "https://numfocus.org/donate" Source = "https://github.com/jupyter-server/pytest-jupyter" Tracker = "https://github.com/jupyter-server/pytest-jupyter/issues" [tool.hatch.version] path = "pytest_jupyter/_version.py" validate-bump = false [tool.hatch.build.targets.sdist] include = [ "/pytest_jupyter", "/tests", ] [tool.hatch.envs.docs] features = ["docs"] [tool.hatch.envs.docs.scripts] build = "make -C docs html SPHINXOPTS='-W'" [tool.hatch.envs.test] features = ["test", "server", "client"] [tool.hatch.envs.test.scripts] test = "python -m pytest -vv {args}" nowarn = "test -W default {args}" [tool.hatch.envs.cov] features = ["test", "server", "client"] dependencies = ["coverage[toml]"] [tool.hatch.envs.cov.scripts] test = "coverage run -m pytest {args}" nowarn = "test -W default {args}" [tool.hatch.envs.typing] dependencies = ["pre-commit"] detached = true [tool.hatch.envs.typing.scripts] test = "pre-commit run --all-files --hook-stage manual mypy" [tool.hatch.envs.lint] dependencies = ["pre-commit"] detached = true [tool.hatch.envs.lint.scripts] build = [ "pre-commit run --all-files ruff", "pre-commit run --all-files ruff-format" ] [tool.jupyter-releaser.options] post-version-spec = "dev" [tool.pytest.ini_options] minversion = "6.0" xfail_strict = true log_cli_level = "info" addopts = [ "-raXs", "--durations=10", "--color=yes", "--doctest-modules", "--showlocals", "--strict-markers", "--strict-config" ] testpaths = [ "tests" ] timeout = 10 # Restore this setting to debug failures timeout_method = "thread" filterwarnings= [ # Fail on warnings "error", "module:datetime.datetime.utc:DeprecationWarning", ] [tool.coverage.report] exclude_lines = [ "pragma: no cover", "def __repr__", "if self.debug:", "if settings.DEBUG", "raise AssertionError", "raise NotImplementedError", "if 0:", "if __name__ == .__main__.:", "class .*\bProtocol\\):", "@(abc\\.)?abstractmethod", ] [tool.coverage.run] relative_files = true source = ["pytest_jupyter"] [tool.mypy] files = "pytest_jupyter" python_version = "3.8" strict = true enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"] disable_error_code = ["no-untyped-def"] warn_unreachable = true [tool.ruff] line-length = 100 [tool.ruff.lint] extend-select = [ "B", # flake8-bugbear "I", # isort "ARG", # flake8-unused-arguments "C4", # flake8-comprehensions "EM", # flake8-errmsg "ICN", # flake8-import-conventions "G", # flake8-logging-format "PGH", # pygrep-hooks "PIE", # flake8-pie "PL", # pylint "PT", # flake8-pytest-style "PTH", # flake8-use-pathlib "RET", # flake8-return "RUF", # Ruff-specific "SIM", # flake8-simplify "T20", # flake8-print "UP", # pyupgrade "YTT", # flake8-2020 "EXE", # flake8-executable "NPY", # NumPy specific rules "PD", # pandas-vet "PYI", # flake8-pyi ] ignore = [ "PLR", # Design related pylint codes "SIM105", # Use `contextlib.suppress(...)` "RUF012", # Mutable class attributes should be annotated with "ARG001", # Unused function argument: ] unfixable = [ # Don't touch print statements "T201", # Don't touch noqa lines "RUF100", ] [tool.ruff.lint.per-file-ignores] # B011 Do not call assert False since python -O removes these calls # T201 `print` found # B007 Loop control variable `i` not used within the loop body. "tests/*" = ["B011", "C4", "T201", "B007", "PTH", "ARG"] [tool.interrogate] ignore-init-module=true ignore-private=true ignore-semiprivate=true ignore-property-decorators=true ignore-nested-functions=true ignore-nested-classes=true fail-under=100 exclude = ["docs", "tests"] pytest-jupyter-0.10.1/pytest_jupyter/000077500000000000000000000000001460351167400177425ustar00rootroot00000000000000pytest-jupyter-0.10.1/pytest_jupyter/__init__.py000066400000000000000000000003151460351167400220520ustar00rootroot00000000000000# Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. __all__ = ["__version__"] from ._version import __version__ from .jupyter_core import * # noqa: F403 pytest-jupyter-0.10.1/pytest_jupyter/_version.py000066400000000000000000000002441460351167400221400ustar00rootroot00000000000000"""Version info for pytest_jupyter.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. __version__ = "0.10.1" pytest-jupyter-0.10.1/pytest_jupyter/echo_kernel.py000066400000000000000000000037471460351167400226050ustar00rootroot00000000000000"""A simple echo kernel.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import annotations import logging import typing # mypy: disable-error-code="no-untyped-call" from ipykernel.kernelapp import IPKernelApp from ipykernel.kernelbase import Kernel class EchoKernel(Kernel): """An echo kernel.""" implementation = "Echo" implementation_version = "1.0" language = "echo" language_version = "0.1" language_info = { "name": "echo", "mimetype": "text/plain", "file_extension": ".txt", } banner = "Echo kernel - as useful as a parrot" def do_execute( # type:ignore[override] self, code: str, silent: bool, store_history=True, # noqa: ARG002 user_expressions: typing.Any = None, # noqa: ARG002 allow_stdin=False, *, cell_id: str | None = None, # noqa: ARG002 ) -> dict[str, typing.Any]: """Execute code on the kernel.""" if not silent: stream_content = {"name": "stdout", "text": code} self.send_response(self.iopub_socket, "stream", stream_content) # Send a input_request if code contains input command. if allow_stdin and code and code.find("input(") != -1: self._input_request( "Echo Prompt", self._parent_ident["shell"], self.get_parent(channel="shell"), password=False, ) return { "status": "ok", # The base class increments the execution count "execution_count": self.execution_count, "payload": [], "user_expressions": {}, } class EchoKernelApp(IPKernelApp): """An app for the echo kernel.""" kernel_class = EchoKernel # type:ignore[assignment] if __name__ == "__main__": logging.disable(logging.ERROR) EchoKernelApp.launch_instance() pytest-jupyter-0.10.1/pytest_jupyter/jupyter_client.py000066400000000000000000000030241460351167400233530ustar00rootroot00000000000000"""Fixtures for use with jupyter_client and downstream.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import pytest try: import ipykernel # noqa: F401 from jupyter_client.kernelspec import NATIVE_KERNEL_NAME from jupyter_client.manager import start_new_async_kernel except ImportError: import warnings warnings.warn( "The client plugin has not been installed. " "If you're trying to use this plugin and you've installed " "`pytest-jupyter`, there is likely one more step " "you need. Try: `pip install 'pytest-jupyter[client]'`", stacklevel=2, ) # Bring in local plugins. from pytest_jupyter.jupyter_core import * # noqa: F403 @pytest.fixture() def jp_zmq_context(): """Get a zmq context.""" import zmq ctx = zmq.asyncio.Context() yield ctx ctx.term() @pytest.fixture() def jp_start_kernel(jp_environ, jp_asyncio_loop): """Get a function to a kernel and clean up resources when done.""" kms = [] kcs = [] async def inner(kernel_name=NATIVE_KERNEL_NAME, **kwargs): """A function used to start a kernel.""" km, kc = await start_new_async_kernel(kernel_name=kernel_name, **kwargs) kms.append(km) kcs.append(kc) return km, kc yield inner for kc in kcs: kc.stop_channels() for km in kms: jp_asyncio_loop.run_until_complete(km.shutdown_kernel(now=True)) if not km.context.closed: raise AssertionError pytest-jupyter-0.10.1/pytest_jupyter/jupyter_core.py000066400000000000000000000112551460351167400230320ustar00rootroot00000000000000"""Fixtures for use with jupyter core and downstream.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import json import os import sys from inspect import iscoroutinefunction from pathlib import Path import jupyter_core import pytest from jupyter_core.utils import ensure_event_loop from .utils import mkdir try: import resource except ImportError: # Windows resource = None # type:ignore[assignment] # Handle resource limit # Ensure a minimal soft limit of DEFAULT_SOFT if the current hard limit is at least that much. if resource is not None: soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE) DEFAULT_SOFT = 4096 if hard >= DEFAULT_SOFT: soft = DEFAULT_SOFT if hard < soft: hard = soft resource.setrlimit(resource.RLIMIT_NOFILE, (soft, hard)) @pytest.fixture(autouse=True) def jp_asyncio_loop(): """Get an asyncio loop.""" loop = ensure_event_loop(prefer_selector_loop=True) yield loop loop.close() @pytest.hookimpl(tryfirst=True) def pytest_pycollect_makeitem(collector, name, obj): """Custom pytest collection hook.""" if collector.funcnamefilter(name) and iscoroutinefunction(obj): return list(collector._genfunctions(name, obj)) return None @pytest.hookimpl(tryfirst=True) def pytest_pyfunc_call(pyfuncitem): """Custom pytest function call hook.""" funcargs = pyfuncitem.funcargs testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames} if not iscoroutinefunction(pyfuncitem.obj): pyfuncitem.obj(**testargs) return True loop = ensure_event_loop(prefer_selector_loop=True) loop.run_until_complete(pyfuncitem.obj(**testargs)) return True @pytest.fixture() def jp_home_dir(tmp_path): """Provides a temporary HOME directory value.""" return mkdir(tmp_path, "home") @pytest.fixture() def jp_data_dir(tmp_path): """Provides a temporary Jupyter data dir directory value.""" return mkdir(tmp_path, "data") @pytest.fixture() def jp_config_dir(tmp_path): """Provides a temporary Jupyter config dir directory value.""" return mkdir(tmp_path, "config") @pytest.fixture() def jp_runtime_dir(tmp_path): """Provides a temporary Jupyter runtime dir directory value.""" return mkdir(tmp_path, "runtime") @pytest.fixture() def jp_system_jupyter_path(tmp_path): """Provides a temporary Jupyter system path value.""" return mkdir(tmp_path, "share", "jupyter") @pytest.fixture() def jp_env_jupyter_path(tmp_path): """Provides a temporary Jupyter env system path value.""" return mkdir(tmp_path, "env", "share", "jupyter") @pytest.fixture() def jp_system_config_path(tmp_path): """Provides a temporary Jupyter config path value.""" return mkdir(tmp_path, "etc", "jupyter") @pytest.fixture() def jp_env_config_path(tmp_path): """Provides a temporary Jupyter env config path value.""" return mkdir(tmp_path, "env", "etc", "jupyter") @pytest.fixture() def jp_kernel_dir(jp_data_dir): """Get the directory for kernel specs.""" return mkdir(jp_data_dir, "kernels") @pytest.fixture() def echo_kernel_spec(jp_kernel_dir): """Install a kernel spec for the echo kernel.""" test_dir = Path(jp_kernel_dir) / "echo" test_dir.mkdir(parents=True, exist_ok=True) argv = [sys.executable, "-m", "pytest_jupyter.echo_kernel", "-f", "{connection_file}"] kernel_data = {"argv": argv, "display_name": "echo", "language": "echo"} spec_file_path = Path(test_dir / "kernel.json") spec_file_path.write_text(json.dumps(kernel_data), "utf8") return str(test_dir) @pytest.fixture() def jp_environ( # noqa: PT004 monkeypatch, tmp_path, jp_home_dir, jp_data_dir, jp_config_dir, jp_runtime_dir, echo_kernel_spec, jp_system_jupyter_path, jp_system_config_path, jp_env_jupyter_path, jp_env_config_path, ): """Configures a temporary environment based on Jupyter-specific environment variables.""" monkeypatch.setenv("HOME", str(jp_home_dir)) monkeypatch.setenv("PYTHONPATH", os.pathsep.join(sys.path)) # monkeypatch.setenv("JUPYTER_NO_CONFIG", "1") monkeypatch.setenv("JUPYTER_CONFIG_DIR", str(jp_config_dir)) monkeypatch.setenv("JUPYTER_DATA_DIR", str(jp_data_dir)) monkeypatch.setenv("JUPYTER_RUNTIME_DIR", str(jp_runtime_dir)) monkeypatch.setattr(jupyter_core.paths, "SYSTEM_JUPYTER_PATH", [str(jp_system_jupyter_path)]) monkeypatch.setattr(jupyter_core.paths, "ENV_JUPYTER_PATH", [str(jp_env_jupyter_path)]) monkeypatch.setattr(jupyter_core.paths, "SYSTEM_CONFIG_PATH", [str(jp_system_config_path)]) monkeypatch.setattr(jupyter_core.paths, "ENV_CONFIG_PATH", [str(jp_env_config_path)]) pytest-jupyter-0.10.1/pytest_jupyter/jupyter_server.py000066400000000000000000000401321460351167400234040ustar00rootroot00000000000000"""Fixtures for use with jupyter server and downstream.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import annotations import importlib import inspect import io import logging import os import re import shutil import urllib.parse from binascii import hexlify from pathlib import Path import jupyter_core.paths import pytest # The try block is needed so that the documentation can # still build without needed to install all the dependencies. try: import nbformat import tornado import tornado.testing from jupyter_server._version import version_info from jupyter_server.auth import Authorizer from jupyter_server.extension import serverextension from jupyter_server.serverapp import JUPYTER_SERVICE_HANDLERS, ServerApp from jupyter_server.utils import url_path_join from tornado.escape import url_escape from tornado.httpclient import HTTPClientError from tornado.websocket import WebSocketHandler from traitlets.config import Config is_v2 = version_info[0] == 2 except ImportError: Authorizer = object # type:ignore[assignment, misc] import warnings warnings.warn( "The server plugin has not been installed. " "If you're trying to use this plugin and you've installed " "`pytest-jupyter`, there is likely one more step " "you need. Try: `pip install 'pytest-jupyter[server]'`", stacklevel=2, ) # Bring in local plugins. from pytest_jupyter.jupyter_core import * # noqa: F403 from pytest_jupyter.pytest_tornasync import * # noqa: F403 from pytest_jupyter.utils import mkdir @pytest.fixture() def jp_server_config(): """Allows tests to setup their specific configuration values.""" if is_v2: config = { "ServerApp": { "jpserver_extensions": {"jupyter_server_terminals": True}, } } else: config = {} return Config(config) @pytest.fixture() def jp_root_dir(tmp_path): """Provides a temporary Jupyter root directory value.""" return mkdir(tmp_path, "root_dir") @pytest.fixture() def jp_template_dir(tmp_path): """Provides a temporary Jupyter templates directory value.""" return mkdir(tmp_path, "templates") @pytest.fixture() def jp_argv(): """Allows tests to setup specific argv values.""" return [] @pytest.fixture() def jp_http_port(http_server_port): """Returns the port value from the http_server_port fixture.""" yield http_server_port[-1] http_server_port[0].close() @pytest.fixture() def jp_extension_environ(jp_env_config_path, monkeypatch): # noqa: PT004 """Monkeypatch a Jupyter Extension's config path into each test's environment variable""" monkeypatch.setattr(serverextension, "ENV_CONFIG_PATH", [str(jp_env_config_path)]) @pytest.fixture() def jp_nbconvert_templates(jp_data_dir): # noqa: PT004 """Setups up a temporary directory consisting of the nbconvert templates.""" # Get path to nbconvert template directory *before* # monkeypatching the paths env variable via the jp_environ fixture. possible_paths = jupyter_core.paths.jupyter_path("nbconvert", "templates") nbconvert_path = None for path in possible_paths: if Path(path).exists(): nbconvert_path = path break nbconvert_target = jp_data_dir / "nbconvert" / "templates" # copy nbconvert templates to new tmp data_dir. if nbconvert_path: shutil.copytree(nbconvert_path, str(nbconvert_target)) @pytest.fixture() def jp_logging_stream(): """StringIO stream intended to be used by the core Jupyter ServerApp logger's default StreamHandler. This helps avoid collision with stdout which is hijacked by Pytest. """ logging_stream = io.StringIO() yield logging_stream output = logging_stream.getvalue() # If output exists, print it. if output: print(output) # noqa: T201 return output @pytest.fixture() def jp_configurable_serverapp( jp_nbconvert_templates, # this fixture must precede jp_environ jp_environ, jp_server_config, jp_argv, jp_http_port, jp_base_url, tmp_path, jp_root_dir, jp_logging_stream, jp_asyncio_loop, ): """Starts a Jupyter Server instance based on the provided configuration values. The fixture is a factory; it can be called like a function inside a unit test. Here's a basic example of how use this fixture: .. code-block:: python def my_test(jp_configurable_serverapp): app = jp_configurable_serverapp(...) ... """ ServerApp.clear_instance() # Inject jupyter_server_terminals into config unless it was # explicitly put in config. serverapp_config = jp_server_config.setdefault("ServerApp", {}) exts = serverapp_config.setdefault("jpserver_extensions", {}) if "jupyter_server_terminals" not in exts and is_v2: exts["jupyter_server_terminals"] = True def _configurable_serverapp( config=jp_server_config, base_url=jp_base_url, argv=jp_argv, environ=jp_environ, http_port=jp_http_port, tmp_path=tmp_path, root_dir=jp_root_dir, **kwargs, ): c = Config(config) c.NotebookNotary.db_file = ":memory:" default_token = hexlify(os.urandom(4)).decode("ascii") if not is_v2: kwargs["token"] = default_token elif "token" not in c.ServerApp and not c.IdentityProvider.token: c.IdentityProvider.token = default_token # Allow tests to configure root_dir via a file, argv, or its # default (cwd) by specifying a value of None. if root_dir is not None: kwargs["root_dir"] = str(root_dir) app = ServerApp.instance( # Set the log level to debug for testing purposes log_level="DEBUG", port=jp_http_port, port_retries=0, open_browser=False, base_url=base_url, config=c, allow_root=True, **kwargs, ) app.init_signal = lambda: None # type:ignore[method-assign] app.log.propagate = True app.log.handlers = [] # Initialize app without httpserver if jp_asyncio_loop.is_running(): app.initialize(argv=argv, new_httpserver=False) else: async def initialize_app(): app.initialize(argv=argv, new_httpserver=False) jp_asyncio_loop.run_until_complete(initialize_app()) # type:ignore[no-untyped-call] # Reroute all logging StreamHandlers away from stdin/stdout since pytest hijacks # these streams and closes them at unfortunate times. stream_handlers = [h for h in app.log.handlers if isinstance(h, logging.StreamHandler)] for handler in stream_handlers: handler.setStream(jp_logging_stream) app.log.propagate = True app.log.handlers = [] app.start_app() return app return _configurable_serverapp @pytest.fixture() def jp_serverapp(jp_server_config, jp_argv, jp_configurable_serverapp): """Starts a Jupyter Server instance based on the established configuration values.""" return jp_configurable_serverapp(config=jp_server_config, argv=jp_argv) @pytest.fixture() def jp_web_app(jp_serverapp): """app fixture is needed by pytest_tornasync plugin""" return jp_serverapp.web_app @pytest.fixture() def jp_auth_header(jp_serverapp): """Configures an authorization header using the token from the serverapp fixture.""" if not is_v2: return {"Authorization": f"token {jp_serverapp.token}"} return {"Authorization": f"token {jp_serverapp.identity_provider.token}"} @pytest.fixture() def jp_base_url(): """Returns the base url to use for the test.""" return "/a%40b/" @pytest.fixture() def jp_fetch(jp_serverapp, http_server_client, jp_auth_header, jp_base_url): """Sends an (asynchronous) HTTP request to a test server. The fixture is a factory; it can be called like a function inside a unit test. Here's a basic example of how use this fixture: .. code-block:: python async def my_test(jp_fetch): response = await jp_fetch("api", "spec.yaml") ... """ def client_fetch(*parts, headers=None, params=None, **kwargs): if not headers: headers = {} if not params: params = {} # Handle URL strings path_url = url_escape(url_path_join(*parts), plus=False) base_path_url = url_path_join(jp_base_url, path_url) params_url = urllib.parse.urlencode(params) url = base_path_url + "?" + params_url # Add auth keys to header, if not overridden for key, value in jp_auth_header.items(): headers.setdefault(key, value) # Handle timeout request_timeout = kwargs.pop("request_timeout", 20) # Make request. return http_server_client.fetch( url, headers=headers, request_timeout=request_timeout, **kwargs ) return client_fetch @pytest.fixture() def jp_ws_fetch(jp_serverapp, http_server_client, jp_auth_header, jp_http_port, jp_base_url): """Sends a websocket request to a test server. The fixture is a factory; it can be called like a function inside a unit test. Here's a basic example of how use this fixture: .. code-block:: python async def my_test(jp_fetch, jp_ws_fetch): # Start a kernel r = await jp_fetch( "api", "kernels", method="POST", body=json.dumps({"name": "python3"}) ) kid = json.loads(r.body.decode())["id"] # Open a websocket connection. ws = await jp_ws_fetch("api", "kernels", kid, "channels") ... """ def client_fetch(*parts, headers=None, params=None, **kwargs): if not headers: headers = {} if not params: params = {} # Handle URL strings path_url = url_escape(url_path_join(*parts), plus=False) base_path_url = url_path_join(jp_base_url, path_url) urlparts = urllib.parse.urlparse(f"ws://localhost:{jp_http_port}") urlparts = urlparts._replace(path=base_path_url, query=urllib.parse.urlencode(params)) url = urlparts.geturl() # Add auth keys to header, if not overridden for key, value in jp_auth_header.items(): headers.setdefault(key, value) # Make request. req = tornado.httpclient.HTTPRequest(url, headers=headers, connect_timeout=120) allowed = list(inspect.signature(tornado.websocket.websocket_connect).parameters) for name in list(kwargs): if name not in allowed: del kwargs[name] return tornado.websocket.websocket_connect(req, **kwargs) return client_fetch @pytest.fixture() def jp_create_notebook(jp_root_dir): """Creates a notebook in the test's home directory.""" def inner(nbpath): nbpath = jp_root_dir.joinpath(nbpath) # Check that the notebook has the correct file extension. if nbpath.suffix != ".ipynb": msg = "File extension for notebook must be .ipynb" raise Exception(msg) # If the notebook path has a parent directory, make sure it's created. parent = nbpath.parent parent.mkdir(parents=True, exist_ok=True) # Create a notebook string and write to file. nb = nbformat.v4.new_notebook() # type:ignore[no-untyped-call] nbtext = nbformat.writes(nb, version=4) # type:ignore[no-untyped-call] nbpath.write_text(nbtext) return nb return inner @pytest.fixture(autouse=True) def jp_server_cleanup(jp_asyncio_loop): # noqa: PT004 """Automatically cleans up server resources.""" yield app: ServerApp = ServerApp.instance() try: jp_asyncio_loop.run_until_complete(app._cleanup()) except (RuntimeError, SystemExit) as e: print("ignoring cleanup error", e) # noqa: T201 if hasattr(app, "kernel_manager"): app.kernel_manager.context.destroy() ServerApp.clear_instance() @pytest.fixture() def send_request(jp_fetch, jp_ws_fetch): """Send to Jupyter Server and return response code.""" async def _(url, **fetch_kwargs): fetch = jp_ws_fetch if url.endswith("channels") or "/websocket/" in url else jp_fetch try: r = await fetch(url, **fetch_kwargs, allow_nonstandard_methods=True) code = r.code except HTTPClientError as err: code = err.code print(f"HTTPClientError ({err.code}): {err}") # noqa: T201 else: if fetch is jp_ws_fetch: r.close() return code return _ @pytest.fixture() def jp_server_auth_core_resources(): """The core auth resources for use with a server.""" modules = [] for mod_name in JUPYTER_SERVICE_HANDLERS.values(): if mod_name: modules.extend(mod_name) resource_map = {} for handler_module in modules: mod = importlib.import_module(handler_module) name = mod.AUTH_RESOURCE for handler in mod.default_handlers: url_regex = handler[0] resource_map[url_regex] = name return resource_map @pytest.fixture() def jp_server_auth_resources(jp_server_auth_core_resources): """The auth resources used by the server.""" return jp_server_auth_core_resources class _Authorizer(Authorizer): """A custom authorizer class for testing.""" # Set these class attributes from within a test # to verify that they match the arguments passed # by the REST API. permissions: dict[str, str] = {} _default_regex_mapping: dict[str, str] = {} HTTP_METHOD_TO_AUTH_ACTION = { "GET": "read", "HEAD": "read", "OPTIONS": "read", "POST": "write", "PUT": "write", "PATCH": "write", "DELETE": "write", "WEBSOCKET": "execute", } def match_url_to_resource( self, url: str, regex_mapping: dict[str, str] | None = None ) -> str | None: """Finds the JupyterHandler regex pattern that would match the given URL and returns the resource name (str) of that handler. e.g. /api/contents/... returns "contents" """ regex_mapping = regex_mapping or self._default_regex_mapping for regex, auth_resource in regex_mapping.items(): pattern = re.compile(regex) if pattern.fullmatch(url): return auth_resource return None def normalize_url(self, path: str) -> str: """Drop the base URL and make sure path leads with a /""" if not self.parent: msg = "Cannot normalize the url without a parent object" raise ValueError(msg) base_url = self.parent.base_url # Remove base_url if path.startswith(base_url): path = path[len(base_url) :] # Make sure path starts with / if not path.startswith("/"): path = "/" + path return path def is_authorized(self, handler, user, action, resource): # noqa: ARG002 """Test if a request is authorized.""" # Parse Request method = "WEBSOCKET" if isinstance(handler, WebSocketHandler) else handler.request.method url = self.normalize_url(handler.request.path) # Map request parts to expected action and resource. expected_action = self.HTTP_METHOD_TO_AUTH_ACTION[method] expected_resource = self.match_url_to_resource(url) # Assert that authorization layer returns the # correct action + resource. if action != expected_action or resource != expected_resource: raise AssertionError # Now, actually apply the authorization layer. return all( [ action in self.permissions.get("actions", []), resource in self.permissions.get("resources", []), ] ) @pytest.fixture() def jp_server_authorizer(jp_server_auth_resources): """An authorizer for the server.""" auth_klass = _Authorizer auth_klass._default_regex_mapping = jp_server_auth_resources return auth_klass pytest-jupyter-0.10.1/pytest_jupyter/py.typed000066400000000000000000000000001460351167400214270ustar00rootroot00000000000000pytest-jupyter-0.10.1/pytest_jupyter/pytest_tornasync.py000066400000000000000000000054711460351167400237530ustar00rootroot00000000000000"""Vendored fork of pytest_tornasync from https://github.com/eukaryote/pytest-tornasync/blob/9f1bdeec3eb5816e0183f975ca65b5f6f29fbfbb/src/pytest_tornasync/plugin.py """ import asyncio from contextlib import closing try: import tornado.ioloop import tornado.testing from tornado.simple_httpclient import SimpleAsyncHTTPClient except ImportError: SimpleAsyncHTTPClient = object # type:ignore[assignment,misc] import pytest # mypy: disable-error-code="no-untyped-call" # Bring in local plugins. from pytest_jupyter.jupyter_core import * # noqa: F403 @pytest.fixture() def io_loop(jp_asyncio_loop): """Get the current tornado event loop.""" return tornado.ioloop.IOLoop.current() @pytest.fixture() def http_server(jp_asyncio_loop, http_server_port, jp_web_app): """Start a tornado HTTP server that listens on all available interfaces.""" async def get_server(): """Get a server asynchronously.""" server = tornado.httpserver.HTTPServer(jp_web_app) server.add_socket(http_server_port[0]) return server server = jp_asyncio_loop.run_until_complete(get_server()) yield server server.stop() if hasattr(server, "close_all_connections"): try: jp_asyncio_loop.run_until_complete(server.close_all_connections()) except asyncio.TimeoutError: pass http_server_port[0].close() @pytest.fixture() def http_server_port(): """ Port used by `http_server`. """ return tornado.testing.bind_unused_port() @pytest.fixture() def http_server_client(http_server, jp_asyncio_loop): """ Create an asynchronous HTTP client that can fetch from `http_server`. """ async def get_client(): """Get a client.""" return AsyncHTTPServerClient(http_server=http_server) client = jp_asyncio_loop.run_until_complete(get_client()) with closing(client) as context: yield context class AsyncHTTPServerClient(SimpleAsyncHTTPClient): """An async http server client.""" def initialize(self, *, http_server=None): """Initialize the client.""" super().initialize() self._http_server = http_server def fetch(self, path, **kwargs): """ Fetch `path` from test server, passing `kwargs` to the `fetch` of the underlying `SimpleAsyncHTTPClient`. """ return super().fetch(self.get_url(path), **kwargs) def get_protocol(self): """Get the protocol for the client.""" return "http" def get_http_port(self): """Get a port for the client.""" for sock in self._http_server._sockets.values(): return sock.getsockname()[1] return None def get_url(self, path): """Get the url for the client.""" return f"{self.get_protocol()}://127.0.0.1:{self.get_http_port()}{path}" pytest-jupyter-0.10.1/pytest_jupyter/utils.py000066400000000000000000000006071460351167400214570ustar00rootroot00000000000000"""Utilities for pytest-jupyter.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from pathlib import Path def mkdir(tmp_path: Path, *parts: str) -> Path: """Make a directory given extra path parts.""" new_path = tmp_path.joinpath(*parts) if not new_path.exists(): new_path.mkdir(parents=True) return new_path pytest-jupyter-0.10.1/tests/000077500000000000000000000000001460351167400157725ustar00rootroot00000000000000pytest-jupyter-0.10.1/tests/conftest.py000066400000000000000000000002521460351167400201700ustar00rootroot00000000000000import os os.environ["JUPYTER_PLATFORM_DIRS"] = "1" pytest_plugins = [ "pytest_jupyter", "pytest_jupyter.jupyter_server", "pytest_jupyter.jupyter_client", ] pytest-jupyter-0.10.1/tests/test_jupyter_client.py000066400000000000000000000014061460351167400224440ustar00rootroot00000000000000from unittest.mock import Mock from jupyter_client.session import Session from pytest_jupyter.echo_kernel import EchoKernel def test_zmq_context(jp_zmq_context): assert isinstance(jp_zmq_context.underlying, int) async def test_start_kernel(jp_start_kernel): km, kc = await jp_start_kernel("echo") assert km.kernel_name == "echo" msg = await kc.execute("hello", reply=True) assert msg["content"]["status"] == "ok" km, kc = await jp_start_kernel() assert km.kernel_name == "python3" msg = await kc.execute("print('hi')", reply=True) assert msg["content"]["status"] == "ok" def test_echo_kernel(): kernel = EchoKernel() # type:ignore[no-untyped-call] kernel.session = Mock(spec=Session) kernel.do_execute("foo", False) pytest-jupyter-0.10.1/tests/test_jupyter_core.py000066400000000000000000000001761460351167400221210ustar00rootroot00000000000000import os from jupyter_core import paths def test_environ(jp_environ): assert os.path.exists(paths.jupyter_data_dir()) pytest-jupyter-0.10.1/tests/test_jupyter_server.py000066400000000000000000000042231460351167400224740ustar00rootroot00000000000000import json import os from http import HTTPStatus from unittest.mock import MagicMock import pytest from jupyter_server.auth import Authorizer from jupyter_server.serverapp import ServerApp from tornado.websocket import WebSocketHandler from pytest_jupyter.jupyter_server import _Authorizer # mypy: ignore-errors async def test_serverapp(jp_serverapp): assert isinstance(jp_serverapp, ServerApp) def test_skip(jp_serverapp): pytest.skip("Forcing a skip") async def test_get_api_spec(jp_fetch): response = await jp_fetch("api", "spec.yaml", method="GET") assert response.code == HTTPStatus.OK async def test_send_request(send_request): code = await send_request("api/spec.yaml", method="GET") assert code == HTTPStatus.OK async def test_connection(jp_fetch, jp_ws_fetch, jp_http_port, jp_auth_header): # Create kernel r = await jp_fetch("api", "kernels", method="POST", body="{}") kid = json.loads(r.body.decode())["id"] # Get kernel info r = await jp_fetch("api", "kernels", kid, method="GET") model = json.loads(r.body.decode()) assert model["connections"] == 0 # Open a websocket connection. ws = await jp_ws_fetch("api", "kernels", kid, "channels") ws.close() async def test_authorizer(jp_server_authorizer, jp_serverapp, jp_base_url): auth: _Authorizer = jp_server_authorizer(parent=jp_serverapp) assert isinstance(auth, Authorizer) assert auth.normalize_url("foo") == "/foo" assert auth.normalize_url(f"{jp_base_url}/foo") == "/foo" request = MagicMock() request.method = "GET" request.path = "foo" handler = WebSocketHandler(jp_serverapp.web_app, request=request) assert not auth.is_authorized(handler, {}, "execute", None) assert auth.match_url_to_resource("/api/kernels") == "kernels" assert auth.match_url_to_resource("/api/shutdown") == "server" async def test_create_notebook(jp_create_notebook): nb = jp_create_notebook("foo.ipynb") assert "nbformat" in nb def test_template_dir(jp_template_dir): assert os.path.exists(jp_template_dir) def test_extension_environ(jp_extension_environ): pass def test_ioloop_fixture(io_loop): pass