././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6892881 cwltest-2.4.20240129145612/0000755000175000017500000000000014555737104014272 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/.coveragerc0000644000175000017500000000060714555736633016424 0ustar00michaelmichael[paths] source = cwltest */site-packages/cwltest */cwltest [run] branch = True source_pkgs = cwltest omit = tests/* */site-packages/cwltest/tests/* [report] exclude_lines = if self.debug: pragma: no cover raise NotImplementedError if __name__ == .__main__.: if TYPE_CHECKING: \.\.\. ignore_errors = True omit = tests/* */site-packages/cwltest/tests/* ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/.flake80000644000175000017500000000030614555736633015452 0ustar00michaelmichael[flake8] ignore = E203,W503 max-line-length = 100 select = B,C,E,F,W,T4 extend-ignore = E501,B905 # when Python 3.10 is the minimum version, re-enable check B905 for zip + strict extend-select = B9 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6772878 cwltest-2.4.20240129145612/.github/0000755000175000017500000000000014555737104015632 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/.github/dependabot.yml0000644000175000017500000000113314555736633020466 0ustar00michaelmichael# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "pip" directory: "/" # Location of package manifests schedule: interval: "daily" # Maintain dependencies for GitHub Actions - package-ecosystem: "github-actions" directory: "/" schedule: interval: "daily" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6772878 cwltest-2.4.20240129145612/.github/workflows/0000755000175000017500000000000014555737104017667 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/.github/workflows/ci-tests.yml0000644000175000017500000000644714555736633022166 0ustar00michaelmichaelname: Continuous integration tests on: push: branches: [ main ] pull_request: branches: [ main ] concurrency: group: build-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: tox: name: CI tests via Tox runs-on: ubuntu-20.04 # 22.04 doesn't support Python 3.6 strategy: matrix: # The README.rst file mentions the versions tested, please update it as well py-ver-major: [3] py-ver-minor: [8, 9, 10, 11, 12] step: [lint, unit, mypy, bandit] env: py-semver: ${{ format('{0}.{1}', matrix.py-ver-major, matrix.py-ver-minor) }} TOXENV: ${{ format('py{0}{1}-{2}', matrix.py-ver-major, matrix.py-ver-minor, matrix.step) }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v5 with: python-version: ${{ env.py-semver }} cache: pip cache-dependency-path: | requirements.txt test-requirements.txt mypy-requirements.txt - name: Upgrade setuptools and install tox run: | pip install -U pip setuptools wheel pip install "tox>4,<5" "tox-gh-actions>3" - name: MyPy cache if: ${{ matrix.step == 'mypy' }} uses: actions/cache@v4 with: path: .mypy_cache/${{ env.py-semver }} key: mypy-${{ env.py-semver }} - name: Test with tox run: tox - name: Upload coverage to Codecov if: ${{ matrix.step == 'unit' }} uses: codecov/codecov-action@v3 with: fail_ci_if_error: true token: ${{ secrets.CODECOV_TOKEN }} tox-style: name: CI linters via Tox runs-on: ubuntu-22.04 strategy: matrix: step: [lintreadme, pydocstyle] env: py-semver: "3.12" TOXENV: ${{ format('py312-{0}', matrix.step) }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v5 with: python-version: ${{ env.py-semver }} cache: pip cache-dependency-path: | requirements.txt test-requirements.txt mypy-requirements.txt - name: Upgrade setuptools and install tox run: | pip install -U pip setuptools wheel pip install "tox>4,<5" "tox-gh-actions>3" - if: ${{ matrix.step == 'pydocstyle' && github.event_name == 'pull_request'}} name: Create local branch for diff-quality for PRs run: git branch ${{github.base_ref}} origin/${{github.base_ref}} - name: Test with tox run: tox release_test: name: cwltest release test runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.12" cache: pip cache-dependency-path: | requirements.txt test-requirements.txt mypy-requirements.txt - name: Install packages run: | pip install -U pip setuptools wheel pip install virtualenv - name: Release test env: RELEASE_SKIP: head run: ./release-test.sh ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/.github/workflows/codeql-analysis.yml0000644000175000017500000000176214555736633023516 0ustar00michaelmichaelname: "Code scanning - action" on: push: branches: [main] pull_request: branches: [main] schedule: - cron: '0 17 * * 0' concurrency: group: scan-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: CodeQL-Build: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. fetch-depth: 2 # If this run was triggered by a pull request event, then checkout # the head of the pull request instead of the merge commit. - run: git checkout HEAD^2 if: ${{ github.event_name == 'pull_request' }} # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: python - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/.gitignore0000644000175000017500000000010214555736633016261 0ustar00michaelmichael*.pyc .eggs .idea .tox *.egg-info build dist cwltest/_version.py ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/.readthedocs.yml0000644000175000017500000000100014555736633017355 0ustar00michaelmichael# .readthedocs.yml # Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Required version: 2 # Build documentation in the docs/ directory with Sphinx sphinx: configuration: docs/conf.py # Optionally build your docs in additional formats such as PDF and ePub formats: all build: os: ubuntu-22.04 tools: python: "3.11" apt_packages: - graphviz python: install: - requirements: docs/requirements.txt - method: pip path: . ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/LICENSE0000644000175000017500000002613514555736633015314 0ustar00michaelmichael Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/MANIFEST.in0000644000175000017500000000064614555736633016044 0ustar00michaelmichaelinclude Makefile test-requirements.txt mypy-requirements.txt requirements.txt tox.ini mypy.ini include dev-requirements.txt .flake8 .coveragerc release-test.sh include docs/Makefile docs/conf.py docs/requirements.txt docs/_static/favicon.ico docs/*.rst include cwltest/*.yml include tests/* include tests/test-data/* include tests/test-data/v1.0/* recursive-include mypy-stubs *.py? global-exclude *~ global-exclude *.pyc ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/Makefile0000644000175000017500000001443414555736633015746 0ustar00michaelmichael# This file is part of cwltest, # https://github.com/common-workflow-language/cwltest/, and is # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Contact: common-workflow-language@googlegroups.com # make format to fix most python formatting errors # make pylint to check Python code for enhanced compliance including naming # and documentation # make coverage-report to check coverage of the python scripts by the tests MODULE=cwltest PACKAGE=cwltest # `SHELL=bash` doesn't work for some, so don't use BASH-isms like # `[[` conditional expressions. PYSOURCES=$(wildcard ${MODULE}/**.py tests/*.py) DEVPKGS=-rdev-requirements.txt -rtest-requirements.txt -rmypy-requirements.txt DEBDEVPKGS=pep8 python-autopep8 pylint python-coverage pydocstyle sloccount \ python-flake8 python-mock shellcheck VERSION=2.4.$(shell TZ=UTC git log --first-parent --max-count=1 \ --format=format:%cd --date=format-local:%Y%m%d%H%M%S) ## all : default task (install in dev mode) all: dev ## help : print this help message and exit help: Makefile @sed -n 's/^##//p' $< ## cleanup : shortcut for "make sort_imports format flake8 diff_pydocstyle_report" cleanup: sort_imports format flake8 diff_pydocstyle_report ## install-dep : install most of the development dependencies via pip install-dep: install-dependencies install-dependencies: FORCE pip install --upgrade $(DEVPKGS) pip install -r requirements.txt ## install-deb-dep : install most of the dev dependencies via apt-get install-deb-dep: sudo apt-get install $(DEBDEVPKGS) ## install : install the cwltest package and cwltest script install: FORCE pip install . ## dev : install the cwltest package in dev mode dev: install-dep pip install -U pip setuptools wheel pip install -e . ## dist : create a module package for distribution dist: dist/${MODULE}-$(VERSION).tar.gz dist/${MODULE}-$(VERSION).tar.gz: $(SOURCES) python -m build ## docs : make the docs docs: FORCE cd docs && $(MAKE) html ## clean : clean up all temporary / machine-generated files clean: FORCE rm -f ${MODILE}/*.pyc tests/*.pyc rm -Rf .coverage\.* .coverage rm -f diff-cover.html # Linting and code style related targets ## sort_import : sorting imports using isort: https://github.com/timothycrosley/isort sort_imports: $(PYSOURCES) mypy-stubs isort $^ remove_unused_imports: $(filter-out schema_salad/metaschema.py,$(PYSOURCES)) autoflake --in-place --remove-all-unused-imports $^ pep257: pydocstyle ## pydocstyle : check Python docstring style pydocstyle: $(PYSOURCES) pydocstyle --add-ignore=D100,D101,D102,D103 $^ || true pydocstyle_report.txt: $(PYSOURCES) pydocstyle $^ > $@ 2>&1 || true ## diff_pydocstyle_report : check Python docstring style for changed files only diff_pydocstyle_report: pydocstyle_report.txt diff-quality --compare-branch=main --violations=pydocstyle --fail-under=100 $^ ## codespell : check for common misspellings codespell: codespell -w $(shell git ls-files | grep -v mypy-stubs | grep -v gitignore) ## format : check/fix all code indentation and formatting (runs black) format: $(filter-out cwltest/_version.py,$(PYSOURCES)) mypy-stubs black $^ format-check: $(filter-out cwltest/_version.py,$(PYSOURCES)) mypy-stubs black --diff --check $^ ## pylint : run static code analysis on Python code pylint: $(PYSOURCES) pylint --msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" \ $^ -j0|| true pylint_report.txt: $(PYSOURCES) pylint --msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" \ $^ -j0> $@ || true diff_pylint_report: pylint_report.txt diff-quality --compare-branch=main --violations=pylint pylint_report.txt .coverage: $(PYSOURCES) COV_CORE_SOURCE=cwltest COV_CORE_CONFIG=.coveragerc COV_CORE_DATAFILE=.coverage \ python -m pytest --cov --cov-append --cov-report= # https://pytest-cov.readthedocs.io/en/latest/plugins.html#plugin-coverage coverage.xml: .coverage coverage xml coverage.html: htmlcov/index.html htmlcov/index.html: .coverage coverage html @echo Test coverage of the Python code is now in htmlcov/index.html coverage-report: .coverage coverage report diff-cover: coverage.xml diff-cover --compare-branch=main $^ diff-cover.html: coverage.xml diff-cover --compare-branch=main $^ --html-report $@ ## test : run the cwltest test suite test: $(PYSOURCES) python -m pytest -rs ${PYTEST_EXTRA} ## testcov : run the cwltest test suite and collect coverage testcov: $(PYSOURCES) pytest --cov ${PYTEST_EXTRA} sloccount.sc: $(PYSOURCES) Makefile sloccount --duplicates --wide --details $^ > $@ ## sloccount : count lines of code sloccount: $(PYSOURCES) Makefile sloccount $^ list-author-emails: @echo 'name, E-Mail Address' @git log --format='%aN,%aE' | sort -u | grep -v 'root' mypy3: mypy mypy: $(PYSOURCES) MYPYPATH=$$MYPYPATH:mypy-stubs mypy $^ pyupgrade: $(filter-out schema_salad/metaschema.py,$(PYSOURCES)) pyupgrade --exit-zero-even-if-changed --py38-plus $^ auto-walrus $^ release-test: FORCE git diff-index --quiet HEAD -- || ( echo You have uncommitted changes, please commit them and try again; false ) ./release-test.sh release: export SETUPTOOLS_SCM_PRETEND_VERSION=${VERSION} && \ ./release-test.sh && \ . testenv2/bin/activate && \ pip install build && \ python -m build testenv2/src/${PACKAGE} && \ pip install twine && \ twine upload testenv2/src/${PACKAGE}/dist/* && \ git tag ${VERSION} && git push --tags flake8: FORCE flake8 $(PYSOURCES) FORCE: # Use this to print the value of a Makefile variable # Example `make print-VERSION` # From https://www.cmcrossroads.com/article/printing-value-makefile-variable print-% : ; @echo $* = $($*) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6892881 cwltest-2.4.20240129145612/PKG-INFO0000644000175000017500000001035614555737104015374 0ustar00michaelmichaelMetadata-Version: 2.1 Name: cwltest Version: 2.4.20240129145612 Summary: Common Workflow Language testing framework Author-email: Common workflow language working group License: Apache 2.0 Project-URL: Homepage, https://github.com/common-workflow-language/cwltest Project-URL: Download, https://github.com/common-workflow-language/cwltest Classifier: Environment :: Console Classifier: Framework :: Pytest Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX Classifier: Operating System :: MacOS :: MacOS X Classifier: Development Status :: 5 - Production/Stable Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Typing :: Typed Requires-Python: <3.13,>=3.8 Description-Content-Type: text/x-rst License-File: LICENSE Requires-Dist: schema-salad<9,>=5.0.20200220195218 Requires-Dist: junit-xml>=1.8 Requires-Dist: pytest<9,>=7 Requires-Dist: defusedxml Requires-Dist: importlib_resources>=1.4; python_version < "3.9" Provides-Extra: pytest-plugin Requires-Dist: pytest; extra == "pytest-plugin" ########################################## Common Workflow Language testing framework ########################################## |Linux Build Status| |Code coverage| PyPI: |PyPI Version| |PyPI Downloads Month| |Total PyPI Downloads| Conda: |Conda Version| |Conda Installs| .. |Linux Build Status| image:: https://github.com/common-workflow-language/cwltest/actions/workflows/ci-tests.yml/badge.svg?branch=main :target: https://github.com/common-workflow-language/cwltest/actions/workflows/ci-tests.yml .. |Code coverage| image:: https://codecov.io/gh/common-workflow-language/cwltest/branch/master/graph/badge.svg :target: https://codecov.io/gh/common-workflow-language/cwltest .. |PyPI Version| image:: https://badge.fury.io/py/cwltest.svg :target: https://badge.fury.io/py/cwltest .. |PyPI Downloads Month| image:: https://pepy.tech/badge/cwltest/month :target: https://pepy.tech/project/cwltest .. |Total PyPI Downloads| image:: https://static.pepy.tech/personalized-badge/cwltest?period=total&units=international_system&left_color=black&right_color=orange&left_text=Total%20PyPI%20Downloads :target: https://pepy.tech/project/cwltest .. |Conda Version| image:: https://anaconda.org/bioconda/cwltest/badges/version.svg :target: https://anaconda.org/bioconda/cwltest .. |Conda Installs| image:: https://anaconda.org/bioconda/cwltest/badges/downloads.svg :target: https://anaconda.org/bioconda/cwltest This is a testing tool for checking the output of Tools and Workflows described with the Common Workflow Language. Among other uses, it is used to run the CWL conformance tests. This is written and tested for Python 3.8, 3.9, 3.10, 3.11, and 3.12. .. contents:: Table of Contents :local: ******* Install ******* Installing the official package from PyPi .. code:: bash pip install cwltest Or from bioconda .. code:: bash conda install -c bioconda cwltest Or from source .. code:: bash git clone https://github.com/common-workflow-language/cwltest.git cd cwltest && pip install . *********************** Run on the command line *********************** Simple command:: cwltest --test test-descriptions.yml --tool cwl-runner ***************************************** Generate conformance badges using cwltest ***************************************** To make badges that show the results of the conformance test, you can generate JSON files for https://badgen.net by using --badgedir option To generate JSON files:: cwltest --test test-descriptions.yml --tool cwl-runner --badgedir badges ... $ cat badges/command_line_tool.json | jq . { "subject": "command_line_tool", "status": "100%", "color": "green" } Once you upload JSON file to a server, you make a badge by using a link like https://badgen.net/https/path/to/generated/json or https://flat.badgen.net/https/path/to/generated/json (for flat badges). Here is an example of markdown to add a badge:: ![test result](https://flat.badgen.net/https/path/to/generated/json?icon=commonwl) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/README.rst0000644000175000017500000000572714555736633016002 0ustar00michaelmichael########################################## Common Workflow Language testing framework ########################################## |Linux Build Status| |Code coverage| PyPI: |PyPI Version| |PyPI Downloads Month| |Total PyPI Downloads| Conda: |Conda Version| |Conda Installs| .. |Linux Build Status| image:: https://github.com/common-workflow-language/cwltest/actions/workflows/ci-tests.yml/badge.svg?branch=main :target: https://github.com/common-workflow-language/cwltest/actions/workflows/ci-tests.yml .. |Code coverage| image:: https://codecov.io/gh/common-workflow-language/cwltest/branch/master/graph/badge.svg :target: https://codecov.io/gh/common-workflow-language/cwltest .. |PyPI Version| image:: https://badge.fury.io/py/cwltest.svg :target: https://badge.fury.io/py/cwltest .. |PyPI Downloads Month| image:: https://pepy.tech/badge/cwltest/month :target: https://pepy.tech/project/cwltest .. |Total PyPI Downloads| image:: https://static.pepy.tech/personalized-badge/cwltest?period=total&units=international_system&left_color=black&right_color=orange&left_text=Total%20PyPI%20Downloads :target: https://pepy.tech/project/cwltest .. |Conda Version| image:: https://anaconda.org/bioconda/cwltest/badges/version.svg :target: https://anaconda.org/bioconda/cwltest .. |Conda Installs| image:: https://anaconda.org/bioconda/cwltest/badges/downloads.svg :target: https://anaconda.org/bioconda/cwltest This is a testing tool for checking the output of Tools and Workflows described with the Common Workflow Language. Among other uses, it is used to run the CWL conformance tests. This is written and tested for Python 3.8, 3.9, 3.10, 3.11, and 3.12. .. contents:: Table of Contents :local: ******* Install ******* Installing the official package from PyPi .. code:: bash pip install cwltest Or from bioconda .. code:: bash conda install -c bioconda cwltest Or from source .. code:: bash git clone https://github.com/common-workflow-language/cwltest.git cd cwltest && pip install . *********************** Run on the command line *********************** Simple command:: cwltest --test test-descriptions.yml --tool cwl-runner ***************************************** Generate conformance badges using cwltest ***************************************** To make badges that show the results of the conformance test, you can generate JSON files for https://badgen.net by using --badgedir option To generate JSON files:: cwltest --test test-descriptions.yml --tool cwl-runner --badgedir badges ... $ cat badges/command_line_tool.json | jq . { "subject": "command_line_tool", "status": "100%", "color": "green" } Once you upload JSON file to a server, you make a badge by using a link like https://badgen.net/https/path/to/generated/json or https://flat.badgen.net/https/path/to/generated/json (for flat badges). Here is an example of markdown to add a badge:: ![test result](https://flat.badgen.net/https/path/to/generated/json?icon=commonwl) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6772878 cwltest-2.4.20240129145612/cwltest/0000755000175000017500000000000014555737104015757 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/cwltest/__init__.py0000755000175000017500000000051614555736633020103 0ustar00michaelmichael"""Run CWL descriptions with a cwl-runner, and look for expected output.""" import logging import threading UNSUPPORTED_FEATURE = 33 DEFAULT_TIMEOUT = 600 # 10 minutes REQUIRED = "required" logger = logging.getLogger("cwltest") logger.addHandler(logging.StreamHandler()) logger.setLevel(logging.INFO) templock = threading.Lock() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/cwltest/__main__.py0000644000175000017500000000012214555736633020052 0ustar00michaelmichael"""Default entrypoint for the cwltest module.""" from . import main main.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540611.0 cwltest-2.4.20240129145612/cwltest/_version.py0000644000175000017500000000066514555737103020163 0ustar00michaelmichael# file generated by setuptools_scm # don't change, don't track in version control TYPE_CHECKING = False if TYPE_CHECKING: from typing import Tuple, Union VERSION_TUPLE = Tuple[Union[int, str], ...] else: VERSION_TUPLE = object version: str __version__: str __version_tuple__: VERSION_TUPLE version_tuple: VERSION_TUPLE __version__ = version = '2.4.20240129145612' __version_tuple__ = version_tuple = (2, 4, 20240129145612) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/cwltest/argparser.py0000644000175000017500000000707514555736633020336 0ustar00michaelmichael"""Command line argument parsing for cwltest.""" import argparse import sys from importlib.metadata import PackageNotFoundError, version from cwltest import DEFAULT_TIMEOUT def arg_parser() -> argparse.ArgumentParser: """Generate a command Line argument parser for cwltest.""" parser = argparse.ArgumentParser( description="Common Workflow Language testing framework" ) parser.add_argument( "--test", type=str, help="YAML file describing test cases", required=True ) parser.add_argument( "--basedir", type=str, help="Basedir to use for tests", default="." ) parser.add_argument("-l", action="store_true", help="List tests then exit") parser.add_argument( "-n", type=str, default=None, help="Run specific tests, format is 1,3-6,9" ) parser.add_argument( "-s", type=str, default=None, help="Run specific tests using their short names separated by comma", ) parser.add_argument( "-N", type=str, default=None, help="Exclude specific tests by number, format is 1,3-6,9", ) parser.add_argument( "-S", type=str, default=None, help="Exclude specific tests by short names separated by comma", ) parser.add_argument( "--tool", type=str, default="cwl-runner", help="CWL runner executable to use (default 'cwl-runner'", ) parser.add_argument( "--only-tools", action="store_true", help="Only test CommandLineTools" ) parser.add_argument("--tags", type=str, default=None, help="Tags to be tested") parser.add_argument( "--exclude-tags", type=str, default=None, help="Tags not to be tested" ) parser.add_argument("--show-tags", action="store_true", help="Show all Tags.") parser.add_argument( "--junit-xml", type=str, default=None, help="Path to JUnit xml file" ) parser.add_argument( "--junit-verbose", action="store_true", help="Store more verbose output to JUnit XML file by not passing " "'--quiet' to the CWL runner.", ) parser.add_argument( "--test-arg", type=str, help="Additional argument " "given in test cases and required prefix for tool runner.", default=None, metavar="cache==--cache-dir", action="append", dest="testargs", ) parser.add_argument( "args", help="arguments to pass first to tool runner", nargs=argparse.REMAINDER ) parser.add_argument( "-j", type=int, default=1, help="Specifies the number of tests to run simultaneously " "(defaults to one).", ) parser.add_argument( "--verbose", action="store_true", help="More verbose output during test run." ) parser.add_argument( "--classname", type=str, default="", help="Specify classname for the Test Suite.", ) parser.add_argument( "--timeout", type=int, default=DEFAULT_TIMEOUT, help="Time of execution in seconds after which the test will be " "skipped. Defaults to {} seconds ({} minutes).".format( DEFAULT_TIMEOUT, DEFAULT_TIMEOUT / 60 ), ) parser.add_argument( "--badgedir", type=str, help="Create JSON badges and store them in this directory.", ) try: ver = version("cwltest") except PackageNotFoundError: ver = "unknown version" parser.add_argument("--version", action="version", version=f"{sys.argv[0]} {ver}") return parser ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/cwltest/compare.py0000644000175000017500000002133014555736633017764 0ustar00michaelmichael"""Compare utilities for CWL objects.""" import hashlib import json import os.path import urllib.parse from typing import Any, Callable, Dict, Optional, Set class CompareFail(Exception): """Compared CWL objects are not equal.""" @classmethod def format( cls, expected: Any, actual: Any, cause: Optional[Any] = None ) -> "CompareFail": """Load the difference details into the error message.""" message = "expected: {}\ngot: {}".format( json.dumps(expected, indent=4, sort_keys=True), json.dumps(actual, indent=4, sort_keys=True), ) if cause: message += "\ncaused by: %s" % cause return cls(message) def _check_keys( keys: Set[str], expected: Dict[str, Any], actual: Dict[str, Any], skip_details: bool ) -> None: for k in keys: try: compare(expected.get(k), actual.get(k), skip_details) except CompareFail as e: raise CompareFail.format( expected, actual, f"field {k!r} failed comparison: {str(e)}" ) from e def _compare_contents(expected: Dict[str, Any], actual: Dict[str, Any]) -> None: with open(actual["path"]) as f: actual_contents = f.read() if (expected_contents := expected["contents"]) != actual_contents: raise CompareFail.format( expected, actual, json.dumps( "Output file contents do not match: actual '%s' is not equal to expected '%s'" % (actual_contents, expected_contents) ), ) def _compare_dict( expected: Dict[str, Any], actual: Dict[str, Any], skip_details: bool ) -> None: for c in expected: try: compare(expected[c], actual.get(c), skip_details) except CompareFail as e: raise CompareFail.format( expected, actual, f"failed comparison for key {c!r}: {e}" ) from e extra_keys = set(actual.keys()).difference(list(expected.keys())) for k in extra_keys: if actual[k] is not None: raise CompareFail.format(expected, actual, "unexpected key '%s'" % k) def _compare_directory( expected: Dict[str, Any], actual: Dict[str, Any], skip_details: bool ) -> None: if actual.get("class") != "Directory": raise CompareFail.format( expected, actual, "expected object with a class 'Directory'" ) if "listing" not in actual: raise CompareFail.format( expected, actual, "'listing' is mandatory field in Directory object" ) for i in expected["listing"]: found = False for j in actual["listing"]: try: compare(i, j, skip_details) found = True break except CompareFail: pass if not found: raise CompareFail.format( expected, actual, "%s not found" % json.dumps(i, indent=4, sort_keys=True), ) _compare_file(expected, actual, skip_details) def _compare_file( expected: Dict[str, Any], actual: Dict[str, Any], skip_details: bool ) -> None: _compare_location(expected, actual, skip_details) if "contents" in expected: _compare_contents(expected, actual) if actual.get("class") == "File" and not skip_details: _compare_checksum(expected, actual) _compare_size(expected, actual) other_keys = set(expected.keys()) - { "path", "location", "listing", "contents", "checksum", "size", } _check_keys(other_keys, expected, actual, skip_details) def _compare_location( expected: Dict[str, Any], actual: Dict[str, Any], skip_details: bool ) -> None: if "path" in expected: expected_comp = "path" if "path" not in actual: actual["path"] = actual["location"] elif "location" in expected: expected_comp = "location" else: return if "path" in actual: actual_comp = "path" else: actual_comp = "location" path = urllib.parse.urlparse(actual[actual_comp]).path if actual.get("class") == "Directory": actual[actual_comp] = actual[actual_comp].rstrip("/") exist_fun: Callable[[str], bool] = os.path.isdir else: exist_fun = os.path.isfile if not exist_fun(path) and not skip_details: raise CompareFail.format( expected, actual, f"{actual[actual_comp]} does not exist", ) if expected[expected_comp] != "Any" and ( not ( actual[actual_comp].endswith("/" + expected[expected_comp]) or ( "/" not in actual[actual_comp] and expected[expected_comp] == actual[actual_comp] ) ) ): raise CompareFail.format( expected, actual, f"{actual[actual_comp]} does not end with {expected[expected_comp]}", ) def _compare_checksum(expected: Dict[str, Any], actual: Dict[str, Any]) -> None: if "path" in actual: path = urllib.parse.urlparse(actual["path"]).path else: path = urllib.parse.urlparse(actual["location"]).path checksum = hashlib.sha1() # nosec with open(path, "rb") as f: contents = f.read(1024 * 1024) while contents != b"": checksum.update(contents) contents = f.read(1024 * 1024) actual_checksum_on_disk = f"sha1${checksum.hexdigest()}" if "checksum" in actual: actual_checksum_declared = actual["checksum"] if actual_checksum_on_disk != actual_checksum_declared: raise CompareFail.format( expected, actual, "Output file checksums do not match: actual " f"{actual_checksum_on_disk!r} on disk is not equal to actual " f"{actual_checksum_declared!r} in the output object", ) if "checksum" in expected: expected_checksum = expected["checksum"] if expected_checksum != actual_checksum_on_disk: raise CompareFail.format( expected, actual, "Output file checksums do not match: actual " f"{actual_checksum_on_disk!r} is not equal to expected {expected_checksum!r}", ) def _compare_size(expected: Dict[str, Any], actual: Dict[str, Any]) -> None: if "path" in actual: path = urllib.parse.urlparse(actual["path"]).path else: path = urllib.parse.urlparse(actual["location"]).path actual_size_on_disk = os.path.getsize(path) if "size" in actual: actual_size_declared = actual["size"] if actual_size_on_disk != actual_size_declared: raise CompareFail.format( expected, actual, "Output file sizes do not match: actual " f"{actual_size_on_disk!r} on disk is not equal to actual " f"{actual_size_declared!r}' in the output object", ) if "size" in expected: expected_size = expected["size"] if expected_size != actual_size_on_disk: raise CompareFail.format( expected, actual, "Output file sizes do not match: actual " f"{actual_size_on_disk!r} is not equal to expected {expected_size!r}", ) def compare(expected: Any, actual: Any, skip_details: bool = False) -> None: """Compare two CWL objects.""" if expected == "Any": return if expected is not None and actual is None: raise CompareFail.format(expected, actual) try: if isinstance(expected, dict): if not isinstance(actual, dict): raise CompareFail.format(expected, actual) if expected.get("class") == "File": _compare_file(expected, actual, skip_details) elif expected.get("class") == "Directory": _compare_directory(expected, actual, skip_details) else: _compare_dict(expected, actual, skip_details) elif isinstance(expected, list): if not isinstance(actual, list): raise CompareFail.format(expected, actual) if len(expected) != len(actual): raise CompareFail.format(expected, actual, "lengths don't match") for c in range(0, len(expected)): try: compare(expected[c], actual[c], skip_details) except CompareFail as e: raise CompareFail.format(expected, actual, e) from e else: if expected != actual: raise CompareFail.format(expected, actual) except Exception as e: raise CompareFail(str(e)) from e ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/cwltest/cwltest-schema-strict.yml0000644000175000017500000000104414555736633022740 0ustar00michaelmichael$base: "https://w3id.org/cwl/cwltest#" $graph: - name: TestCase type: record documentRoot: true fields: id: type: string jsonldPredicate: _type: "@id" identity: true short_name: string? doc: string? tags: string[] tool: type: string jsonldPredicate: _type: "@id" job: type: string? jsonldPredicate: _type: "@id" should_fail: type: boolean? default: false output: type: Any? ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/cwltest/cwltest-schema.yml0000644000175000017500000000111114555736633021425 0ustar00michaelmichael$base: "https://w3id.org/cwl/cwltest#" $graph: - name: TestCase type: record documentRoot: true fields: id: type: ["null", int, string] jsonldPredicate: _type: "@id" identity: true label: string? short_name: string? doc: string? tags: string[]? tool: type: string jsonldPredicate: _type: "@id" job: type: string? jsonldPredicate: _type: "@id" should_fail: type: boolean? default: false output: type: Any? ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/cwltest/hooks.py0000644000175000017500000000134214555736633017462 0ustar00michaelmichael"""Hooks for pytest-cwl users.""" from typing import Any, Dict, Optional, Tuple from cwltest import utils def pytest_cwl_execute_test( # type: ignore[empty-body] config: utils.CWLTestConfig, processfile: str, jobfile: Optional[str] ) -> Tuple[int, Optional[Dict[str, Any]]]: """ Execute CWL test using a Python function instead of a command line runner. The return value is a tuple. - status code - 0 = success - :py:attr:`cwltest.UNSUPPORTED_FEATURE` for an unsupported feature - and any other number for failure - CWL output object using plain Python objects. :param processfile: a path to a CWL document :param jobfile: an optionl path to JSON/YAML input object """ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/cwltest/main.py0000644000175000017500000001643314555736633017272 0ustar00michaelmichael#!/usr/bin/env python3 """Entry point for cwltest.""" import argparse import os import sys from collections import defaultdict from concurrent.futures import ThreadPoolExecutor from typing import Dict, List, Optional, Set, cast import junit_xml import schema_salad.avro import schema_salad.ref_resolver import schema_salad.schema from cwltest.argparser import arg_parser from cwltest.utils import CWLTestConfig, TestResult from schema_salad.exceptions import ValidationException from cwltest import logger, utils if sys.stderr.isatty(): PREFIX = "\r" SUFFIX = "" else: PREFIX = "" SUFFIX = "\n" def _run_test( args: argparse.Namespace, test: Dict[str, str], test_number: int, total_tests: int, ) -> TestResult: if test.get("short_name"): sys.stderr.write( "%sTest [%i/%i] %s: %s%s\n" % ( PREFIX, test_number, total_tests, test.get("short_name"), test.get("doc", "").replace("\n", " ").strip(), SUFFIX, ) ) else: sys.stderr.write( "%sTest [%i/%i] %s%s\n" % ( PREFIX, test_number, total_tests, test.get("doc", "").replace("\n", " ").strip(), SUFFIX, ) ) sys.stderr.flush() config = CWLTestConfig( basedir=args.basedir, classname=args.classname, tool=args.tool, args=args.args, testargs=args.testargs, timeout=args.timeout, verbose=args.verbose, runner_quiet=not args.junit_verbose, ) return utils.run_test_plain(config, test, test_number) def _expand_number_range(nr: str) -> List[int]: result: List[int] = [] for s in nr.split(","): sp = s.split("-") if len(sp) == 2: result.extend(range(int(sp[0]) - 1, int(sp[1]))) else: result.append(int(s) - 1) return result def main() -> int: """Run the main logic loop.""" args = arg_parser().parse_args(sys.argv[1:]) if "--" in args.args: args.args.remove("--") # Remove test arguments with wrong syntax if args.testargs is not None: args.testargs = [ testarg for testarg in args.testargs if testarg.count("==") == 1 ] if not args.test: arg_parser().print_help() return 1 try: tests, metadata = utils.load_and_validate_tests(args.test) except ValidationException: return 1 failures = 0 unsupported = 0 suite_name, _ = os.path.splitext(os.path.basename(args.test)) report: Optional[junit_xml.TestSuite] = junit_xml.TestSuite(suite_name, []) ntotal = defaultdict(int) # type: Dict[str, int] npassed = defaultdict(int) # type: Dict[str, int] if args.only_tools: alltests = tests tests = [] for t in alltests: loader = schema_salad.ref_resolver.Loader({"id": "@id"}) cwl = loader.resolve_ref(t["tool"])[0] if isinstance(cwl, dict): if cwl["class"] == "CommandLineTool": tests.append(t) else: raise Exception("Unexpected code path.") if args.tags: tags = set(args.tags.split(",")) tests = [t for t in tests if tags.intersection(t.get("tags", []))] if args.exclude_tags: tags = set(args.exclude_tags.split(",")) tests = [t for t in tests if not tags.intersection(t.get("tags", []))] for t in tests: if t.get("label"): logger.warning("The `label` field is deprecated. Use `id` field instead.") t["short_name"] = t["label"] elif t.get("id"): if isinstance(t.get("id"), str): t["short_name"] = utils.shortname(t["id"]) else: logger.warning( "The `id` field with integer is deprecated. Use string identifier instead." ) else: logger.warning("The `id` field is missing.") if args.show_tags: alltags: Set[str] = set() for t in tests: ts = t.get("tags", []) alltags |= set(ts) for tag in alltags: print(tag) return 0 if args.l: for i, t in enumerate(tests): if t.get("short_name"): print( "[%i] %s: %s" % ( i + 1, t["short_name"], t.get("doc", "").replace("\n", " ").strip(), ) ) else: print("[%i] %s" % (i + 1, t.get("doc", "").replace("\n", " ").strip())) return 0 if args.n is not None or args.s is not None: ntest = [] if args.n is not None: ntest = _expand_number_range(args.n) if args.s is not None: for s in args.s.split(","): test_number = utils.get_test_number_by_key(tests, "short_name", s) if test_number: ntest.append(test_number) else: logger.error('Test with short name "%s" not found ', s) return 1 else: ntest = list(range(0, len(tests))) exclude_n = [] if args.N is not None: exclude_n = _expand_number_range(args.N) if args.S is not None: for s in args.S.split(","): test_number = utils.get_test_number_by_key(tests, "short_name", s) if test_number: exclude_n.append(test_number) else: logger.error('Test with short name "%s" not found ', s) return 1 ntest = list(filter(lambda x: x not in exclude_n, ntest)) total = 0 with ThreadPoolExecutor(max_workers=args.j) as executor: jobs = [ executor.submit( _run_test, args, tests[i], i + 1, len(tests), ) for i in ntest ] try: ( total, passed, failures, unsupported, ntotal, npassed, nfailures, nunsupported, report, ) = utils.parse_results( (job.result() for job in jobs), tests, suite_name, report ) except KeyboardInterrupt: for job in jobs: job.cancel() logger.error("Tests interrupted") if args.junit_xml: with open(args.junit_xml, "w") as xml: junit_xml.to_xml_report_file(xml, [cast(junit_xml.TestSuite, report)]) if args.badgedir: utils.generate_badges(args.badgedir, ntotal, npassed) if failures == 0 and unsupported == 0: logger.info("All tests passed") return 0 if failures == 0 and unsupported > 0: logger.warning( "%i tests passed, %i unsupported features", total - unsupported, unsupported ) return 0 logger.warning( "%i tests passed, %i failures, %i unsupported features", total - (failures + unsupported), failures, unsupported, ) return 1 if __name__ == "__main__": sys.exit(main()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/cwltest/plugin.py0000644000175000017500000003072414555736633017643 0ustar00michaelmichael"""Discovers CWL test files and converts them to pytest.Items.""" import argparse import json import os import time import traceback from io import StringIO from pathlib import Path from typing import ( TYPE_CHECKING, Any, Dict, Iterator, List, Optional, Protocol, Set, Tuple, Union, cast, ) import pytest from cwltest.compare import CompareFail, compare from cwltest import REQUIRED, UNSUPPORTED_FEATURE, logger, utils if TYPE_CHECKING: from _pytest._code.code import ExceptionInfo, _TracebackStyle from _pytest.compat import LEGACY_PATH from _pytest.config import Config from _pytest.config import Config as PytestConfig from _pytest.config import PytestPluginManager from _pytest.config.argparsing import Parser as PytestParser from _pytest.nodes import Node from pluggy import HookCaller class TestRunner(Protocol): """Protocol to type-check test runner functions via the pluggy hook.""" def __call__( self, config: utils.CWLTestConfig, processfile: str, jobfile: Optional[str] ) -> List[Optional[Dict[str, Any]]]: """Type signature for pytest_cwl_execute_test hook results.""" ... def _get_comma_separated_option(config: "Config", name: str) -> List[str]: options = config.getoption(name) if options is None: return [] elif "," in options: return [opt.strip() for opt in options.split(",")] else: return [options.strip()] def _run_test_hook_or_plain( test: Dict[str, str], config: utils.CWLTestConfig, hook: "HookCaller", ) -> utils.TestResult: """Run tests using a provided pytest_cwl_execute_test hook or the --cwl-runner.""" processfile, jobfile = utils.prepare_test_paths(test, config.basedir) start_time = time.time() outerr = "" hook_out = hook(config=config, processfile=processfile, jobfile=jobfile) if not hook_out: return utils.run_test_plain(config, test) returncode, out = cast(Tuple[int, Optional[Dict[str, Any]]], hook_out[0]) duration = time.time() - start_time outstr = json.dumps(out) if out is not None else "{}" if returncode == UNSUPPORTED_FEATURE: if REQUIRED not in test.get("tags", ["required"]): return utils.TestResult( UNSUPPORTED_FEATURE, outstr, "", duration, config.classname ) elif returncode != 0: if not bool(test.get("should_fail", False)): logger.warning("Test failed unexpectedly: %s %s", processfile, jobfile) logger.warning(test.get("doc")) message = "Returned non-zero but it should be zero" return utils.TestResult( 1, outstr, outerr, duration, config.classname, message ) return utils.TestResult(0, outstr, outerr, duration, config.classname) if bool(test.get("should_fail", False)): return utils.TestResult( 1, outstr, outerr, duration, config.classname, "Test should failed, but it did not.", ) fail_message = "" try: compare(test.get("output"), out) except CompareFail as ex: logger.warning("""Test failed: %s %s""", processfile, jobfile) logger.warning(test.get("doc")) logger.warning("Compare failure %s", ex) fail_message = str(ex) return utils.TestResult( (1 if fail_message else 0), outstr, outerr, duration, config.classname, fail_message, ) class CWLTestException(Exception): """custom exception for error reporting.""" class CWLItem(pytest.Item): """A CWL test Item.""" def __init__( self, name: str, parent: Optional["Node"], spec: Dict[str, Any], ) -> None: """Initialize this CWLItem.""" super().__init__(name, parent) self.spec = spec def runtest(self) -> None: """Execute using cwltest.""" cwl_args = self.config.getoption("cwl_args") config = utils.CWLTestConfig( basedir=self.config.getoption("cwl_basedir"), outdir=str( self.config._tmp_path_factory.mktemp( # type: ignore[attr-defined] self.spec.get("label", "unlabled_test") ) ), tool=self.config.getoption("cwl_runner"), args=cwl_args.split(" ") if cwl_args else None, testargs=self.config.getoption("cwl_test_arg"), timeout=self.config.getoption("timeout", None), verbose=self.config.getoption("verbose", 0) >= 1, runner_quiet=not self.config.getoption("cwl_runner_verbose", False), ) hook = self.config.hook.pytest_cwl_execute_test result = _run_test_hook_or_plain( self.spec, config, hook, ) cwl_results = self.config.cwl_results # type: ignore[attr-defined] cast(List[Tuple[Dict[str, Any], utils.TestResult]], cwl_results).append( (self.spec, result) ) if result.return_code != 0: raise CWLTestException(self, result) def repr_failure( self, excinfo: "ExceptionInfo[BaseException]", style: Optional["_TracebackStyle"] = None, ) -> str: """ Document failure reason. Called when self.runtest() raises an exception. """ if isinstance(excinfo.value, CWLTestException): from ruamel.yaml.main import YAML yaml = YAML() result = excinfo.value.args[1] stream = StringIO() yaml.dump(self.spec, stream) return "\n".join( [ "CWL test execution failed. ", result.message, f"Test: {stream.getvalue()}", ] ) else: return ( f"{excinfo.type.__name__} occurred during CWL test execution:\n" + "".join( traceback.format_exception( excinfo.type, excinfo.value, excinfo.traceback[0]._rawentry ) ) ) def reportinfo(self) -> Tuple[Union["os.PathLike[str]", str], Optional[int], str]: """Status report.""" return self.fspath, 0, "cwl test: %s" % self.name class CWLYamlFile(pytest.File): """A CWL test file.""" def _add_global_properties(self) -> None: """Nonfunctional if xdist is installed and anything besides "-n 0" is used.""" from _pytest.junitxml import xml_key if xml := self.config._store.get(xml_key, None): xml.add_global_property("runner", self.config.getoption("cwl_runner")) xml.add_global_property( "runner_extra_args", self.config.getoption("cwl_args") ) def collect(self) -> Iterator[CWLItem]: """Load the cwltest file and yield parsed entries.""" include: Set[str] = set(_get_comma_separated_option(self.config, "cwl_include")) exclude: Set[str] = set(_get_comma_separated_option(self.config, "cwl_exclude")) tags: Set[str] = set(_get_comma_separated_option(self.config, "cwl_tags")) exclude_tags: Set[str] = set( _get_comma_separated_option(self.config, "cwl_exclude_tags") ) tests, _ = utils.load_and_validate_tests(str(self.path)) self._add_global_properties() for entry in tests: entry_tags = entry.get("tags", []) if "label" in entry: name = entry["label"] elif "id" in entry: name = utils.shortname(entry["id"]) else: name = entry.get("doc", "") item = CWLItem.from_parent(self, name=name, spec=entry) if include and name not in include: item.add_marker( pytest.mark.skip( reason=f"Test {name!r} is not in the include list: {','.join(include)}." ) ) elif exclude and name in exclude: item.add_marker( pytest.mark.skip(reason=f"Test {name!r} is in the exclude list.") ) elif tags and not tags.intersection(entry_tags): item.add_marker( pytest.mark.skip( reason=f"Test {name!r} with tags {','.join(entry_tags)}" f" doesn't have a tag on the allowed tag list: {','.join(tags)}." ) ) elif exclude_tags and exclude_tags.intersection(entry_tags): item.add_marker( pytest.mark.skip( reason=f"Test {name!r} has one or more tags on the exclusion " f" tag list: {','.join(exclude_tags.intersection(entry_tags))}." ) ) yield item __OPTIONS: List[Tuple[str, Dict[str, Any]]] = [ ( "--cwl-runner", { "type": str, "dest": "cwl_runner", "default": "cwl-runner", "help": "Name of the CWL runner to use.", }, ), ( "--cwl-runner-verbose", { "dest": "cwl_runner_verbose", "default": False, "action": "store_true", "help": "If set, don't pass --quiet to the CWL runner.", }, ), ( "--cwl-badgedir", { "type": str, "help": "Create badge JSON files and store them in this directory.", }, ), ( "--cwl-include", { "type": str, "help": "Run specific CWL tests using their short names separated by comma", }, ), ( "--cwl-exclude", { "type": str, "help": "Exclude specific CWL tests using their short names separated by comma", }, ), ("--cwl-tags", {"type": str, "help": "Tags to be tested."}), ("--cwl-exclude-tags", {"type": str, "help": "Tags not to be tested."}), ( "--cwl-args", { "type": str, "help": "one or more arguments to pass first to tool runner (separated by spaces)", }, ), ( "--cwl-test-arg", { "type": str, "help": "Additional argument given in test cases and required prefix for tool runner.", "action": "append", }, ), ( "--cwl-basedir", { "help": "Basedir to use for tests", "default": os.getcwd(), }, ), ] def pytest_addoption(parser: "PytestParser") -> None: """Add our options to the pytest command line.""" for entry in __OPTIONS: parser.addoption(entry[0], **entry[1]) def _doc_options() -> argparse.ArgumentParser: """Generate a stand-alone ArgumentParser to aid in documention.""" parser = argparse.ArgumentParser("cwltest options for pytest.", add_help=False) for entry in __OPTIONS: parser.add_argument(entry[0], **entry[1]) return parser def pytest_collect_file( file_path: Path, path: "LEGACY_PATH", parent: pytest.Collector ) -> Optional[pytest.Collector]: """Is this file for us.""" if ( file_path.suffix == ".yml" or file_path.suffix == ".yaml" ) and file_path.stem.endswith(".cwltest"): return cast( Optional[pytest.Collector], CWLYamlFile.from_parent(parent, path=file_path), ) return None def pytest_configure(config: "PytestConfig") -> None: """Store the raw tests and the test results.""" cwl_results: List[Tuple[Dict[str, Any], utils.TestResult]] = [] config.cwl_results = cwl_results # type: ignore[attr-defined] def pytest_sessionfinish(session: pytest.Session, exitstatus: int) -> None: """Generate badges.""" cwl_results = cast( List[Tuple[Dict[str, Any], utils.TestResult]], getattr(session.config, "cwl_results", None), ) if not cwl_results: return tests, results = (list(item) for item in zip(*cwl_results)) ( total, passed, failures, unsupported, ntotal, npassed, nfailures, nunsupported, _, ) = utils.parse_results(results, tests) if cwl_badgedir := session.config.getoption("cwl_badgedir"): utils.generate_badges(cwl_badgedir, ntotal, npassed) def pytest_addhooks(pluginmanager: "PytestPluginManager") -> None: """Register our cwl hooks.""" from cwltest import hooks pluginmanager.add_hookspecs(hooks) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/cwltest/py.typed0000644000175000017500000000000014555736633017452 0ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/cwltest/utils.py0000644000175000017500000003627414555736633017513 0ustar00michaelmichaelimport json import os import re import shlex import shutil import subprocess # nosec import sys import tempfile import time from collections import defaultdict from typing import ( Any, Dict, Iterable, List, MutableMapping, MutableSequence, Optional, Tuple, Union, cast, ) import junit_xml import ruamel.yaml.scanner import schema_salad.avro import schema_salad.ref_resolver import schema_salad.schema from cwltest.compare import CompareFail, compare from rdflib import Graph from ruamel.yaml.scalarstring import ScalarString from schema_salad.exceptions import ValidationException if sys.version_info >= (3, 9): from importlib.resources import as_file, files else: from importlib_resources import as_file, files from cwltest import REQUIRED, UNSUPPORTED_FEATURE, logger, templock __all__ = ["files", "as_file"] class CWLTestConfig: """Store configuration values for cwltest.""" def __init__( self, basedir: Optional[str] = None, outdir: Optional[str] = None, classname: Optional[str] = None, tool: Optional[str] = None, args: Optional[List[str]] = None, testargs: Optional[List[str]] = None, timeout: Optional[int] = None, verbose: Optional[bool] = None, runner_quiet: Optional[bool] = None, ) -> None: """Initialize test configuration.""" self.basedir: str = basedir or os.getcwd() self.outdir: Optional[str] = outdir self.classname: str = classname or "" self.tool: str = tool or "cwl-runner" self.args: List[str] = args or [] self.testargs: List[str] = testargs or [] self.timeout: Optional[int] = timeout self.verbose: bool = verbose or False self.runner_quiet: bool = runner_quiet or True class TestResult: """Encapsulate relevant test result data.""" def __init__( self, return_code: int, standard_output: str, error_output: str, duration: float, classname: str, message: str = "", ) -> None: """Initialize a TestResult object.""" self.return_code = return_code self.standard_output = standard_output self.error_output = error_output self.duration = duration self.message = message self.classname = classname def create_test_case(self, test: Dict[str, Any]) -> junit_xml.TestCase: """Create a jUnit XML test case from this test result.""" doc = test.get("doc", "N/A").strip() if test.get("tags"): category = ", ".join(test["tags"]) else: category = REQUIRED short_name = test.get("short_name") case = junit_xml.TestCase( doc, elapsed_sec=self.duration, file=short_name, category=category, stdout=self.standard_output, stderr=self.error_output, ) if self.return_code > 0: case.failure_message = self.message return case def _clean_ruamel(obj: Any) -> Any: """Transform roundtrip loaded ruamel.yaml to plain objects.""" if isinstance(obj, MutableMapping): new_dict = {} for k, v in obj.items(): new_dict[str(k)] = _clean_ruamel(v) return new_dict if isinstance(obj, MutableSequence): new_list = [] for entry in obj: new_list.append(_clean_ruamel(entry)) return new_list if isinstance(obj, ScalarString): return str(obj) for typ in int, float, bool, str: if isinstance(obj, typ): return typ(obj) if obj is None: return None raise Exception(f"Unsupported type {type(obj)} of {obj!r}.") def generate_badges( badgedir: str, ntotal: Dict[str, int], npassed: Dict[str, int] ) -> None: """Generate badges with conformance levels.""" os.mkdir(badgedir) for t, v in ntotal.items(): percent = int((npassed[t] / float(v)) * 100) if npassed[t] == v: color = "green" elif t == "required": color = "red" else: color = "yellow" with open(f"{badgedir}/{t}.json", "w") as out: out.write( json.dumps( { "subject": f"{t}", "status": f"{percent}%", "color": color, } ) ) def get_test_number_by_key( tests: List[Dict[str, str]], key: str, value: str ) -> Optional[int]: """Retrieve the test index from its name.""" for i, test in enumerate(tests): if key in test and test[key] == value: return i return None def load_and_validate_tests(path: str) -> Tuple[Any, Dict[str, Any]]: """ Load and validate the given test file against the cwltest schema. This also processes $import directives. """ schema_resource = files("cwltest").joinpath("cwltest-schema.yml") with schema_resource.open("r", encoding="utf-8") as fp: cache: Optional[Dict[str, Union[str, Graph, bool]]] = { "https://w3id.org/cwl/cwltest/cwltest-schema.yml": fp.read() } ( document_loader, avsc_names, _, _, ) = schema_salad.schema.load_schema( "https://w3id.org/cwl/cwltest/cwltest-schema.yml", cache=cache ) if not isinstance(avsc_names, schema_salad.avro.schema.Names): print(avsc_names) raise ValidationException(f"Wrong instance for avsc_names: {type(avsc_names)}") tests, metadata = schema_salad.schema.load_and_validate( document_loader, avsc_names, path, True ) tests = cast(List[Dict[str, Any]], _clean_ruamel(tests)) return tests, metadata def parse_results( results: Iterable[TestResult], tests: List[Dict[str, Any]], suite_name: Optional[str] = None, report: Optional[junit_xml.TestSuite] = None, ) -> Tuple[ int, # total int, # passed int, # failures int, # unsupported Dict[str, int], Dict[str, int], Dict[str, int], Dict[str, int], Optional[junit_xml.TestSuite], ]: """ Parse the results and return statistics and an optional report. Returns the total number of tests, dictionary of test counts (total, passed, failed, unsupported) by tag, and a jUnit XML report. """ total = 0 passed = 0 failures = 0 unsupported = 0 ntotal: Dict[str, int] = defaultdict(int) nfailures: Dict[str, int] = defaultdict(int) nunsupported: Dict[str, int] = defaultdict(int) npassed: Dict[str, int] = defaultdict(int) for i, test_result in enumerate(results): test_case = test_result.create_test_case(tests[i]) test_case.url = ( f"cwltest:{suite_name}#{i + 1}" if suite_name is not None else "cwltest:#{i + 1}" ) total += 1 tags = tests[i].get("tags", []) for t in tags: ntotal[t] += 1 return_code = test_result.return_code category = test_case.category if return_code == 0: passed += 1 for t in tags: npassed[t] += 1 elif return_code != 0 and return_code != UNSUPPORTED_FEATURE: failures += 1 for t in tags: nfailures[t] += 1 test_case.add_failure_info(output=test_result.message) elif return_code == UNSUPPORTED_FEATURE and category == REQUIRED: failures += 1 for t in tags: nfailures[t] += 1 test_case.add_failure_info(output=test_result.message) elif category != REQUIRED and return_code == UNSUPPORTED_FEATURE: unsupported += 1 for t in tags: nunsupported[t] += 1 test_case.add_skipped_info("Unsupported") else: raise Exception( "This is impossible, return_code: {}, category: " "{}".format(return_code, category) ) if report: report.test_cases.append(test_case) return ( total, passed, failures, unsupported, ntotal, npassed, nfailures, nunsupported, report, ) def prepare_test_command( tool: str, args: List[str], testargs: Optional[List[str]], test: Dict[str, Any], cwd: str, quiet: Optional[bool] = True, ) -> List[str]: """Turn the test into a command line.""" test_command = [tool] test_command.extend(args) # Add additional arguments given in test case if testargs is not None: for testarg in testargs: (test_case_name, prefix) = testarg.split("==") if test_case_name in test: test_command.extend([prefix, test[test_case_name]]) # Add prefixes if running on MacOSX so that boot2docker writes to /Users with templock: if "darwin" in sys.platform and tool.endswith("cwltool"): outdir = tempfile.mkdtemp(prefix=os.path.abspath(os.path.curdir)) test_command.extend( [ f"--tmp-outdir-prefix={outdir}", f"--tmpdir-prefix={outdir}", ] ) else: outdir = tempfile.mkdtemp() test_command.extend([f"--outdir={outdir}"]) if quiet: test_command.extend(["--quiet"]) processfile, jobfile = prepare_test_paths(test, cwd) test_command.extend([os.path.normcase(processfile)]) if jobfile: test_command.append(os.path.normcase(jobfile)) return test_command def prepare_test_paths( test: Dict[str, str], cwd: str, ) -> Tuple[str, Optional[str]]: """Determine the test path and the tool path.""" cwd = schema_salad.ref_resolver.file_uri(cwd) processfile = test["tool"] if processfile.startswith(cwd): processfile = processfile[len(cwd) + 1 :] jobfile = test.get("job") if jobfile: if jobfile.startswith(cwd): jobfile = jobfile[len(cwd) + 1 :] return processfile, jobfile def run_test_plain( config: CWLTestConfig, test: Dict[str, str], test_number: Optional[int] = None, ) -> TestResult: """Plain test runner.""" out: Dict[str, Any] = {} outstr = outerr = "" test_command: List[str] = [] duration = 0.0 number = "?" if test_number is not None: number = str(test_number) process: Optional[subprocess.Popen[str]] = None try: cwd = os.getcwd() test_command = prepare_test_command( config.tool, config.args, config.testargs, test, cwd, config.runner_quiet ) if config.verbose: sys.stderr.write(f"Running: {' '.join(test_command)}\n") sys.stderr.flush() start_time = time.time() stderr = subprocess.PIPE if not config.verbose else None process = subprocess.Popen( # nosec test_command, stdout=subprocess.PIPE, stderr=stderr, universal_newlines=True, cwd=cwd, ) outstr, outerr = process.communicate(timeout=config.timeout) return_code = process.poll() duration = time.time() - start_time if return_code: raise subprocess.CalledProcessError(return_code, " ".join(test_command)) logger.debug('outstr: "%s".', outstr) out = json.loads(outstr) if outstr else {} except subprocess.CalledProcessError as err: if err.returncode == UNSUPPORTED_FEATURE and REQUIRED not in test.get( "tags", ["required"] ): return TestResult( UNSUPPORTED_FEATURE, outstr, outerr, duration, config.classname ) if test.get("should_fail", False): return TestResult(0, outstr, outerr, duration, config.classname) if test_number: logger.error( """Test %i failed: %s""", test_number, " ".join([shlex.quote(tc) for tc in test_command]), ) else: logger.error( """Test failed: %s""", " ".join([shlex.quote(tc) for tc in test_command]), ) logger.error(test.get("doc", "").replace("\n", " ").strip()) if err.returncode == UNSUPPORTED_FEATURE: logger.error("Does not support required feature") else: logger.error("Returned non-zero") return TestResult(1, outstr, outerr, duration, config.classname, str(err)) except (ruamel.yaml.scanner.ScannerError, TypeError) as err: logger.error( """Test %s failed: %s""", number, " ".join([shlex.quote(tc) for tc in test_command]), ) logger.error(outstr) logger.error("Parse error %s", str(err)) logger.error(outerr) except KeyboardInterrupt: logger.error( """Test %s interrupted: %s""", number, " ".join([shlex.quote(tc) for tc in test_command]), ) raise except subprocess.TimeoutExpired: logger.error( """Test %s timed out: %s""", number, " ".join([shlex.quote(tc) for tc in test_command]), ) logger.error(test.get("doc", "").replace("\n", " ").strip()) # Kill and re-communicate to get the logs and reap the child, as # instructed in the subprocess docs. if process: process.kill() outstr, outerr = process.communicate() return TestResult( 2, outstr, outerr, float(cast(int, config.timeout)), config.classname, "Test timed out", ) finally: if process is not None and process.returncode is None: logger.error("""Terminating lingering process""") process.terminate() for _ in range(0, 3): time.sleep(1) if process.poll() is not None: break if process.returncode is None: process.kill() fail_message = "" if test.get("should_fail", False): logger.warning( """Test %s failed: %s""", number, " ".join([shlex.quote(tc) for tc in test_command]), ) logger.warning(test.get("doc", "").replace("\n", " ").strip()) logger.warning("Returned zero but it should be non-zero") return TestResult(1, outstr, outerr, duration, config.classname) try: compare(test.get("output"), out) except CompareFail as ex: logger.warning( """Test %s failed: %s""", number, " ".join([shlex.quote(tc) for tc in test_command]), ) logger.warning(test.get("doc", "").replace("\n", " ").strip()) logger.warning("Compare failure %s", ex) fail_message = str(ex) if config.outdir: shutil.rmtree(config.outdir, True) return TestResult( (1 if fail_message else 0), outstr, outerr, duration, config.classname, fail_message, ) def shortname(name: str) -> str: """ Return the short name of a given name. It is a workaround of https://github.com/common-workflow-language/schema_salad/issues/511. """ return [n for n in re.split("[/#]", name) if len(n)][-1] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6892881 cwltest-2.4.20240129145612/cwltest.egg-info/0000755000175000017500000000000014555737104017451 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540611.0 cwltest-2.4.20240129145612/cwltest.egg-info/PKG-INFO0000644000175000017500000001035614555737103020552 0ustar00michaelmichaelMetadata-Version: 2.1 Name: cwltest Version: 2.4.20240129145612 Summary: Common Workflow Language testing framework Author-email: Common workflow language working group License: Apache 2.0 Project-URL: Homepage, https://github.com/common-workflow-language/cwltest Project-URL: Download, https://github.com/common-workflow-language/cwltest Classifier: Environment :: Console Classifier: Framework :: Pytest Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX Classifier: Operating System :: MacOS :: MacOS X Classifier: Development Status :: 5 - Production/Stable Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Typing :: Typed Requires-Python: <3.13,>=3.8 Description-Content-Type: text/x-rst License-File: LICENSE Requires-Dist: schema-salad<9,>=5.0.20200220195218 Requires-Dist: junit-xml>=1.8 Requires-Dist: pytest<9,>=7 Requires-Dist: defusedxml Requires-Dist: importlib_resources>=1.4; python_version < "3.9" Provides-Extra: pytest-plugin Requires-Dist: pytest; extra == "pytest-plugin" ########################################## Common Workflow Language testing framework ########################################## |Linux Build Status| |Code coverage| PyPI: |PyPI Version| |PyPI Downloads Month| |Total PyPI Downloads| Conda: |Conda Version| |Conda Installs| .. |Linux Build Status| image:: https://github.com/common-workflow-language/cwltest/actions/workflows/ci-tests.yml/badge.svg?branch=main :target: https://github.com/common-workflow-language/cwltest/actions/workflows/ci-tests.yml .. |Code coverage| image:: https://codecov.io/gh/common-workflow-language/cwltest/branch/master/graph/badge.svg :target: https://codecov.io/gh/common-workflow-language/cwltest .. |PyPI Version| image:: https://badge.fury.io/py/cwltest.svg :target: https://badge.fury.io/py/cwltest .. |PyPI Downloads Month| image:: https://pepy.tech/badge/cwltest/month :target: https://pepy.tech/project/cwltest .. |Total PyPI Downloads| image:: https://static.pepy.tech/personalized-badge/cwltest?period=total&units=international_system&left_color=black&right_color=orange&left_text=Total%20PyPI%20Downloads :target: https://pepy.tech/project/cwltest .. |Conda Version| image:: https://anaconda.org/bioconda/cwltest/badges/version.svg :target: https://anaconda.org/bioconda/cwltest .. |Conda Installs| image:: https://anaconda.org/bioconda/cwltest/badges/downloads.svg :target: https://anaconda.org/bioconda/cwltest This is a testing tool for checking the output of Tools and Workflows described with the Common Workflow Language. Among other uses, it is used to run the CWL conformance tests. This is written and tested for Python 3.8, 3.9, 3.10, 3.11, and 3.12. .. contents:: Table of Contents :local: ******* Install ******* Installing the official package from PyPi .. code:: bash pip install cwltest Or from bioconda .. code:: bash conda install -c bioconda cwltest Or from source .. code:: bash git clone https://github.com/common-workflow-language/cwltest.git cd cwltest && pip install . *********************** Run on the command line *********************** Simple command:: cwltest --test test-descriptions.yml --tool cwl-runner ***************************************** Generate conformance badges using cwltest ***************************************** To make badges that show the results of the conformance test, you can generate JSON files for https://badgen.net by using --badgedir option To generate JSON files:: cwltest --test test-descriptions.yml --tool cwl-runner --badgedir badges ... $ cat badges/command_line_tool.json | jq . { "subject": "command_line_tool", "status": "100%", "color": "green" } Once you upload JSON file to a server, you make a badge by using a link like https://badgen.net/https/path/to/generated/json or https://flat.badgen.net/https/path/to/generated/json (for flat badges). Here is an example of markdown to add a badge:: ![test result](https://flat.badgen.net/https/path/to/generated/json?icon=commonwl) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540611.0 cwltest-2.4.20240129145612/cwltest.egg-info/SOURCES.txt0000644000175000017500000000735314555737103021344 0ustar00michaelmichael.coveragerc .flake8 .gitignore .readthedocs.yml LICENSE MANIFEST.in Makefile README.rst dev-requirements.txt mypy-requirements.txt mypy.ini pyproject.toml release-test.sh requirements.txt test-requirements.txt tox.ini .github/dependabot.yml .github/workflows/ci-tests.yml .github/workflows/codeql-analysis.yml cwltest/__init__.py cwltest/__main__.py cwltest/_version.py cwltest/argparser.py cwltest/compare.py cwltest/cwltest-schema-strict.yml cwltest/cwltest-schema.yml cwltest/hooks.py cwltest/main.py cwltest/plugin.py cwltest/py.typed cwltest/utils.py cwltest.egg-info/PKG-INFO cwltest.egg-info/SOURCES.txt cwltest.egg-info/dependency_links.txt cwltest.egg-info/entry_points.txt cwltest.egg-info/requires.txt cwltest.egg-info/top_level.txt cwltest.egg-info/zip-safe docs/Makefile docs/conf.py docs/index.rst docs/pytest.rst docs/requirements.txt docs/_static/favicon.ico mypy-stubs/junit_xml.pyi mypy-stubs/cachecontrol/__init__.pyi mypy-stubs/cachecontrol/cache.pyi mypy-stubs/cachecontrol/compat.pyi mypy-stubs/cachecontrol/controller.pyi mypy-stubs/cachecontrol/wrapper.pyi mypy-stubs/cachecontrol/caches/__init__.pyi mypy-stubs/cachecontrol/caches/file_cache.pyi mypy-stubs/defusedxml/ElementTree.pyi mypy-stubs/defusedxml/__init__.pyi mypy-stubs/rdflib/__init__.pyi mypy-stubs/rdflib/collection.pyi mypy-stubs/rdflib/compare.pyi mypy-stubs/rdflib/graph.pyi mypy-stubs/rdflib/parser.pyi mypy-stubs/rdflib/paths.pyi mypy-stubs/rdflib/plugin.pyi mypy-stubs/rdflib/query.pyi mypy-stubs/rdflib/resource.pyi mypy-stubs/rdflib/term.pyi mypy-stubs/rdflib/namespace/_CSVW.pyi mypy-stubs/rdflib/namespace/_DC.pyi mypy-stubs/rdflib/namespace/_DCAT.pyi mypy-stubs/rdflib/namespace/_DCTERMS.pyi mypy-stubs/rdflib/namespace/_DOAP.pyi mypy-stubs/rdflib/namespace/_FOAF.pyi mypy-stubs/rdflib/namespace/_ODRL2.pyi mypy-stubs/rdflib/namespace/_ORG.pyi mypy-stubs/rdflib/namespace/_OWL.pyi mypy-stubs/rdflib/namespace/_PROF.pyi mypy-stubs/rdflib/namespace/_PROV.pyi mypy-stubs/rdflib/namespace/_QB.pyi mypy-stubs/rdflib/namespace/_RDF.pyi mypy-stubs/rdflib/namespace/_RDFS.pyi mypy-stubs/rdflib/namespace/_SDO.pyi mypy-stubs/rdflib/namespace/_SH.pyi mypy-stubs/rdflib/namespace/_SKOS.pyi mypy-stubs/rdflib/namespace/_SOSA.pyi mypy-stubs/rdflib/namespace/_SSN.pyi mypy-stubs/rdflib/namespace/_TIME.pyi mypy-stubs/rdflib/namespace/_VOID.pyi mypy-stubs/rdflib/namespace/_XSD.pyi mypy-stubs/rdflib/namespace/__init__.pyi mypy-stubs/rdflib/plugins/__init__.pyi mypy-stubs/rdflib/plugins/parsers/__init__.pyi mypy-stubs/rdflib/plugins/parsers/notation3.pyi mypy-stubs/ruamel/__init__.pyi tests/__init__.py tests/test_argparse.py tests/test_categories.py tests/test_compare.py tests/test_exclude_tags.py tests/test_integer_id.py tests/test_multi_lined_doc.py tests/test_plugin.py tests/test_prepare.py tests/test_short_names.py tests/test_string_id.py tests/test_timeout.py tests/util.py tests/test-data/conformance_test_v1.0.cwltest.yml tests/test-data/conformance_test_v1.2.cwltest.yaml tests/test-data/cores.txt tests/test-data/cwltool-conftest.py tests/test-data/exclude-tags.yml tests/test-data/integer-id.yml tests/test-data/mock_cwl_runner.py tests/test-data/multi-lined-doc.yml tests/test-data/optional-error.yml tests/test-data/optional-unsupported.yml tests/test-data/required-unsupported.yml tests/test-data/return-0.cwl tests/test-data/return-1.cwl tests/test-data/return-unsupported.cwl tests/test-data/short-names.yml tests/test-data/string-id.yml tests/test-data/timeout.cwl tests/test-data/timeout.yml tests/test-data/with-and-without-short-names.yml tests/test-data/v1.0/args.py tests/test-data/v1.0/cat-job.json tests/test-data/v1.0/cat-n-job.json tests/test-data/v1.0/cat1-job.json tests/test-data/v1.0/cat1-testcli.cwl tests/test-data/v1.0/cat2-job.json tests/test-data/v1.0/empty.json tests/test-data/v1.0/hello.txt././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540611.0 cwltest-2.4.20240129145612/cwltest.egg-info/dependency_links.txt0000644000175000017500000000000114555737103023516 0ustar00michaelmichael ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540611.0 cwltest-2.4.20240129145612/cwltest.egg-info/entry_points.txt0000644000175000017500000000011714555737103022745 0ustar00michaelmichael[console_scripts] cwltest = cwltest.main:main [pytest11] cwl = cwltest.plugin ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540611.0 cwltest-2.4.20240129145612/cwltest.egg-info/requires.txt0000644000175000017500000000022714555737103022051 0ustar00michaelmichaelschema-salad<9,>=5.0.20200220195218 junit-xml>=1.8 pytest<9,>=7 defusedxml [:python_version < "3.9"] importlib_resources>=1.4 [pytest-plugin] pytest ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540611.0 cwltest-2.4.20240129145612/cwltest.egg-info/top_level.txt0000644000175000017500000000001014555737103022171 0ustar00michaelmichaelcwltest ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540445.0 cwltest-2.4.20240129145612/cwltest.egg-info/zip-safe0000644000175000017500000000000114555736635021111 0ustar00michaelmichael ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/dev-requirements.txt0000644000175000017500000000023614555736633020341 0ustar00michaelmichaeldiff_cover black ~= 24.1 pylint pep257 pydocstyle flake8 tox >4, < 5 virtualenv-pyenv isort wheel autoflake flake8-bugbear pyupgrade bandit auto-walrus build ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6772878 cwltest-2.4.20240129145612/docs/0000755000175000017500000000000014555737104015222 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/docs/Makefile0000644000175000017500000000117214555736633016671 0ustar00michaelmichael# Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6772878 cwltest-2.4.20240129145612/docs/_static/0000755000175000017500000000000014555737104016650 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/docs/_static/favicon.ico0000644000175000017500000003535614555736633021013 0ustar00michaelmichael00 ¨%6  ¨Þ% h†6(0` $ÿÿÿÍÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüûþÿýûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûùýÿºŸâÿ¼¡ãÿûùþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûùýÿ·žáÿvDÆÿwEÇÿ¹ âÿûúþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûúþÿ¶žáÿrDÆÿo?Åÿo?ÅÿrDÆÿȶéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûúþÿµŸáÿnCÅÿj>Ãÿk?Ãÿi<ÃÿŒhÑÿçßöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûúþÿ³ŸáÿjBÄÿf=Âÿg>Âÿe;Áÿ‡fÏÿåÞõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûþÿ±ŸàÿfAÂÿa;Áÿb<Áÿa;ÀÿƒeÎÿäÝôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôñûÿˆnÐÿZ7¾ÿ];¿ÿ];¿ÿ\:¿ÿ¤‘Ûÿýüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäßõÿ}eÍÿV7½ÿX9¾ÿX8¾ÿ_AÁÿ²¤áÿüûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãÞôÿxbËÿQ5¼ÿT8½ÿS7¼ÿY?¿ÿ°¤àÿüüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÜóÿs`ÉÿL4»ÿN7»ÿM6»ÿU>¾ÿ°¥áÿüüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÛóÿn^ÈÿG3¹ÿJ6ºÿI4ºÿQ=½ÿ®¥áÿüüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÙòÿi[ÇÿC3¹ÿE5ºÿC3¹ÿL<¼ÿ¬¦àÿüüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙÖñÿYM¿ÿ>1¸ÿ@3¸ÿ>2¸ÿF:»ÿ´¯ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿¹ÙÿG7—ÿ8-¬ÿ:1¸ÿ8/¶ÿPH¿ÿÈÅëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾¹ÜÿF7”ÿ1ÿ4!†ÿ3*©ÿJF¾ÿÄÂéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾ºÞÿG:›ÿ1 ˆÿ3 ÿ0vÿI9ÿÂÀæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾»áÿG<£ÿ1#ÿ3#‰ÿ0ÿK8ˆÿÅ¿×ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾¼ãÿG>ªÿ2&˜ÿ4%‘ÿ0 ‡ÿK:ÿÅÀÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾¼åÿGA±ÿ2( ÿ4(™ÿ2$‘ÿM?˜ÿÆÀÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïïùÿb]Áÿ0(¨ÿ4*¡ÿ4(™ÿ2$‘ÿ”ŒÂÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇÆéÿMG³ÿ1( ÿ4(™ÿ3$‘ÿG9•ÿ¼¶ÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈÆçÿMD¬ÿ1%˜ÿ4%‘ÿ1 ˆÿE4Œÿ¼µÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈÅåÿMB¥ÿ1#ÿ3#‰ÿ1ÿE1…ÿ¼´ÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈÄãÿM@žÿ0 ˆÿ3 ÿ1vÿD1‚ÿ¼¸ÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇÃàÿL>—ÿ0ÿ3}ÿ1&œÿFB»ÿ½»çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈÄÞÿM=–ÿ5)¢ÿ81·ÿ6/¶ÿJC½ÿ½ºçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçåöÿf\Ãÿ;0·ÿ=2¸ÿ<1¸ÿ;0·ÿŽˆÖÿüüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâàõÿrgËÿ@2¹ÿA3¹ÿA3¹ÿA4¹ÿ‰€ÓÿñðúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÛóÿoaÉÿC2¹ÿE5ºÿE4ºÿG6ºÿ†ÖÿóòûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙÕñÿl\ÇÿH3¹ÿJ6ºÿI5ºÿL8»ÿ—ŒØÿõôûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔÎïÿjWÆÿL4ºÿN7»ÿM6»ÿQ:¼ÿž’Úÿ÷öüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÎÆìÿjRÅÿP5¼ÿS8¼ÿR7¼ÿX?¿ÿ§™Ýÿùøýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüûþÿ–„×ÿS5¼ÿV9¾ÿW9¾ÿU7½ÿu]ÊÿëèøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëèøÿˆqÑÿY8¾ÿZ:¿ÿZ:¿ÿ\;¿ÿ—‚×ÿóñûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëç÷ÿ‹rÑÿ]:¿ÿ_;Àÿ_;Àÿ_;Àÿ›„×ÿôñûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìçøÿŽsÒÿb;Áÿc=Áÿc<Áÿc<ÁÿŸ‡Ùÿõòûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìçøÿ‘sÓÿf<Âÿg>Âÿg=Âÿg>Âÿ¢ˆÚÿõóûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìçøÿ“sÔÿj=Ãÿk?Ãÿk>Ãÿk?Äÿ¥ŠÛÿöóüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíçøÿ–tÕÿm>Äÿo@Åÿo?Åÿn?Äÿ¯”ßÿýüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíçøÿ˜tÕÿq?Åÿr?ÅÿzKÈÿdzèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíæøÿ™rÔÿ}KÉÿDzèÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìä÷ÿÖÅîÿýüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍ( @ ÿÿÿëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýüþÿýüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûùýÿº âÿ»¢ãÿûúþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûúþÿ¶žâÿsCÆÿrCÆÿÁ­æÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûúþÿ´ŸáÿmCÅÿh;Âÿ}WËÿÙÍðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüûþÿ±žàÿgAÃÿa:ÀÿwUÉÿÖÌïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøöýÿ“}ÕÿZ8¾ÿZ8¾ÿ€gÍÿíêøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîêùÿ‰tÑÿS6¼ÿT7½ÿˆuÑÿíêøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìéøÿ‚qÏÿK4ºÿL5ºÿ„uÐÿíëùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêè÷ÿ|oÎÿF5ºÿD3¹ÿ€uÐÿìêøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ×îÿRF·ÿ=1¸ÿ;/·ÿš“Úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóòùÿ…|¸ÿ6%ˆÿ3(£ÿa\ÆÿÜÛóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóòúÿ…}Àÿ3$‹ÿ0|ÿ_PšÿÜÚðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóòúÿ…Çÿ4(˜ÿ0 ‰ÿ`QœÿÝÚèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøøýÿ‡„Ïÿ4+£ÿ1%–ÿZM¢ÿÞÛëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùùýÿŠÑÿ5,¤ÿ1%–ÿWJ ÿÙÖèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõõûÿŒ†Êÿ5)˜ÿ0 ‰ÿZK˜ÿØÔåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõõûÿŒ„Ãÿ5%Œÿ/|ÿZI’ÿØÖìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõõúÿŒƒ¼ÿ7%…ÿ2%šÿ\XÃÿØ×ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâàòÿXM¶ÿ:/¶ÿ7-¶ÿ„}ÒÿûûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëêøÿwÐÿC5ºÿ@1¸ÿlaÈÿÝÚóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèå÷ÿ~oÎÿG4ºÿG3¹ÿufËÿâàôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäßõÿ|iÍÿM5»ÿO7»ÿ~mÎÿæãöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûþÿ“ÕÿR4¼ÿT7½ÿiOÅÿßÙóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙÒðÿvZÉÿY8¾ÿ^=Àÿ ŒÚÿöôüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÔñÿ{\Ëÿ`9Àÿc=Áÿ¤ŽÛÿ÷õüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝÔòÿ€]Ìÿf;Âÿi?Ãÿ©ÝÿøõüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÓòÿ…^Îÿl=Ãÿn@Äÿ±˜àÿýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÔòÿ‰^ÎÿxGÇÿ­æÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÒòÿ̸êÿýûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿë(  ÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýûþÿýûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûùþÿ¹¡âÿ¿©åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýüþÿ±žàÿrLÇÿÈ·éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûúþÿŸŒÚÿeIÃÿÏÇìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõóûÿ’…ÖÿbQÄÿÌÇìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄ¿ßÿB4¨ÿ‘‹ÖÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÍéÿUI¢ÿzn®ÿîí÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷ýÿqkÀÿF:ÿÚ×éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒÐêÿWK¢ÿwjªÿíìöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈÄáÿB5¥ÿ‰ƒÒÿüüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóñûÿ’†Öÿ[MÂÿ½éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüþÿ›‹ÙÿY@¿ÿŽéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿĸèÿnMÆÿ©•ÝÿùøýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿɺêÿxOÉÿ³›àÿþýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿμëÿÄ®çÿþýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿû././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/docs/conf.py0000644000175000017500000000667614555736633016546 0ustar00michaelmichael# Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # import os import sys import time from datetime import datetime sys.path.insert(0, os.path.abspath("..")) # -- Project information ----------------------------------------------------- build_date = datetime.utcfromtimestamp( int(os.environ.get("SOURCE_DATE_EPOCH", time.time())) ) # -- Project information ----------------------------------------------------- project = "cwltest" copyright = ( f"2016 - {build_date.year}, Common Workflow Language project and contributors" ) author = "Common Workflow Language project and contributors" # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ "sphinx.ext.autodoc", "sphinx.ext.autosummary", "sphinx.ext.intersphinx", "sphinx.ext.inheritance_diagram", "autoapi.extension", "sphinx_autodoc_typehints", "sphinx_rtd_theme", "sphinxcontrib.autoprogram", ] intersphinx_mapping = { "python": ("https://docs.python.org/3", None), "schema_salad": ("https://schema-salad.readthedocs.io/en/stable/", None), #"rdflib": ("https://rdflib.readthedocs.io/en/6.2.0/", None), #"pytest": ("https://docs.pytest.org/en/7.2.x/", None), "pytest_xdist": ("https://pytest-xdist.readthedocs.io/en/latest/", None), #"ruamel.yaml": ("https://yaml.readthedocs.io/en/stable/", None), } # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = "sphinx_rtd_theme" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] from importlib.metadata import version as metadata_version release = metadata_version("cwltest") version = ".".join(release.split(".")[:2]) autoapi_dirs = ["../cwltest"] autodoc_typehints = "description" autoapi_keep_files = True autoapi_ignore = ["*.pyi"] autoapi_options = [ "members", "undoc-members", "show-inheritance", "show-inheritance-diagram", "show-module-summary", "imported-members", "special-members", ] # sphinx-autodoc-typehints always_document_param_types = True # If False, do not add type info for undocumented parameters. # If True, add stub documentation for undocumented parameters to be able to add type info. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/docs/index.rst0000644000175000017500000000050714555736633017073 0ustar00michaelmichael.. include:: ../README.rst ******************** Command Line Options ******************** .. autoprogram:: cwltest.argparser:arg_parser() :prog: cwltest .. toctree:: :maxdepth: 2 pytest autoapi/index ****************** Indices and tables ****************** * :ref:`genindex` * :ref:`modindex` * :ref:`search` ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/docs/pytest.rst0000644000175000017500000001431314555736633017314 0ustar00michaelmichael************* Pytest plugin ************* ``cwltest`` can also be used as a Pytest plugin. The CWL test filename must end with ``.cwltest.yml`` or ``.cwltest.yaml``. In this case, the simple command:: cwltest --test conformance_xxx.cwltest.yml --tool cwl-runner becomes:: pytest conformance_xxx.cwltest.yml --cwl-runner cwl-runner Command Line Options ==================== .. autoprogram:: cwltest.plugin:_doc_options() :prog: pytest Converting ``cwltest`` options to ``pytest`` options ==================================================== The table below details all the available command conversions between the two formats. .. list-table:: :widths: 40 30 30 :header-rows: 1 * - Feature - ``cwltest`` - ``pytest`` * - YAML file describing test cases - ``--test conformance_xxx.cwltest.yml`` - ``conformance_xxx.cwltest.yml`` * - CWL runner executable to use - ``--tool CWL_RUNNER`` - :option:`--cwl-runner CWL_RUNNER` * - Specifies the number of tests to run simultaneously - ``-j CORES`` - ``-n CORES`` [#f1]_ * - Automatically scale the number of tests to run simultaneously - **UNSUPPORTED** - ``-n auto`` [#f1]_ * - Only run one test at a time (good for debugging cwltest itself) - ``-j 1`` (or leave out ``-j``) - ``-n 0 -s`` [#f1]_ * - Time of execution in seconds after which the test will be skipped - ``--timeout TIMEOUT`` - ``--timeout TIMEOUT`` [#f3]_ * - List tests then exit - ``-l`` - ``--collect-only`` * - Run specific tests using their short names - ``-s TEST_NAME[,TEST_NAME…]`` - :option:`--cwl-include TEST_NAME[,TEST_NAME…]` * - Exclude specific tests by short names - ``-S TEST_NAME[,TEST_NAME…]`` - :option:`--cwl-exclude TEST_NAME[,TEST_NAME…]` * - Tags to be tested - ``--tags TAG[,TAG…]`` - :option:`--cwl-tags TAG[,TAG…]` * - Tags not to be tested - ``--exclude-tags TAG[,TAG…]`` - :option:`--cwl-exclude-tags TAG[,TAG…]` * - Path to JUnit xml file - ``--junit-xml PATH`` - ``--junit-xml=PATH`` [#f4]_ * - More verbose output during test run - ``--verbose`` - ``-v[vv]`` * - Additional argument given in test cases and required prefix for tool runner - ``--test-arg ARG_NAME==ARG_PREFIX`` - :option:`--cwl-test-arg ARG_NAME==ARG_PREFIX` * - Arguments to pass first to tool runner - ``cwltest -- ARG [ARG …]`` - :option:`--cwl-args "ARG [ARG …]"` * - Only test CommandLineTools - ``--only-tools`` - **UNSUPPORTED** * - Show all tags - ``--show-tags`` - **UNSUPPORTED** * - Store more verbose output to JUnit xml file - ``--junit-verbose`` - :option:`--cwl-runner-verbose` [#f4]_ * - Specify classname for the Test Suite - ``--classname CLASS_NAME`` - **UNSUPPORTED** .. [#f1] Requires `pytest-xdist `_. See :ref:`pytest_xdist:parallelization`. .. [#f2] ``-s`` is a shortcut for ``--capture=no``, also helps with debugging ``cwltest`` or the cwltest plugin to ``pytest``. .. [#f3] Requires `pytest-timeout `_. Note: even if ``pytest-timeout`` is installed, there is no default timeout. This is different than ``cwltest``'s default timeout of 10 minutes. Differences in the XML output ============================= ``cwltest --junit-xml`` output * top-level ```` element has the elapsed time, and counts (errors, failures, skipped, and total) * singular ```` sub-element the same attributes as the top-level ```` plus ``name`` which is the basename of the YAML test file * each ```` element has the follow attributes * ``name``: the doc string * ``class``: the tags * ``file``: the test ID * ``url``: like "cwltest:conformance_tests#1" (contains the basename of the YAML test file) * ``time``: the elapsed time * ```` elements always contain the following sub-elements, regardless of outcome * ````: the output object * ````: stderr (docker pull, other warnings, and errors) * ```` elements for failed test cases do not have a ```` sub-element ``pytest`` with ``cwltest`` plugin XML output * top-level ```` element has no attributes * singular ```` sub-element has the same attributes as the ``cwltest`` XML version along with these additional attributes * ``name``: default is ``pytest`` (can be customized with the pytest INI option ``junit_suite_name``) * ``timestamp="2023-01-08T11:39:07.425159"`` * ``hostname``: the hostname of the machine where the tests ran * inside the ```` is a ``..`` element with two ```` elements. But this `does not work with pytest-xdist `_. * ``runner``: the name of the CWL runner * ``runner_extra_args``: the value of `--cwl-args`` * each ```` element has the following attributes * ``classname``: always the name of the YAML file (``conformance_test_v1.2.cwltest.yaml``) * ``name``: the test ID * ``time``: the elapsed time * ```` elements for failed test cases **do** have a ```` sub-element with a ``message`` attribute containing the :py:meth:`cwltest.plugin.CWLItem.repr_failure` output. This text is repeated as the content of the ```` element. The presensce of ```` and ```` sub-elements varies. [#f4]_ .. [#f4] Depending on the value of the pytest INI option ``junit_logging``, then ```` and ```` sub-elements will be generated. However the default value for ``junit_logging`` is ``no``, so to get either of these pick one from `the full list `_. You can set ``junit_logging`` in `a configuration file `_ or on the command line: ``pytest -o junit_logging=out-err``. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/docs/requirements.txt0000644000175000017500000000020714555736633020513 0ustar00michaelmichaelsphinx >= 2.2 sphinx-rtd-theme==2.0.0 sphinx-autoapi sphinx-autodoc-typehints typed_ast;python_version<'3.8' sphinxcontrib-autoprogram ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-requirements.txt0000644000175000017500000000010114555736633020550 0ustar00michaelmichaelmypy==1.8.0 types-setuptools types-requests types-PyYAML cwltool ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6772878 cwltest-2.4.20240129145612/mypy-stubs/0000755000175000017500000000000014555737104016426 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6812878 cwltest-2.4.20240129145612/mypy-stubs/cachecontrol/0000755000175000017500000000000014555737104021072 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/cachecontrol/__init__.pyi0000644000175000017500000000033314555736633023361 0ustar00michaelmichael# Stubs for cachecontrol (Python 2) # # NOTE: This dynamically typed stub was automatically generated by stubgen. from typing import Any from .wrapper import CacheControl as CacheControl __email__ = ... # type: Any ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/cachecontrol/cache.pyi0000644000175000017500000000034214555736633022665 0ustar00michaelmichaelclass BaseCache: def get(self, key: str) -> bytes | None: ... def set(self, key: str, value: bytes, expires: int | None = None) -> None: ... def delete(self, key: str) -> None: ... def close(self) -> None: ... ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6812878 cwltest-2.4.20240129145612/mypy-stubs/cachecontrol/caches/0000755000175000017500000000000014555737104022320 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/cachecontrol/caches/__init__.pyi0000644000175000017500000000042114555736633024605 0ustar00michaelmichael# Stubs for cachecontrol.caches (Python 2) # # NOTE: This dynamically typed stub was automatically generated by stubgen. from typing import Any from .file_cache import FileCache as FileCache # from .redis_cache import RedisCache as RedisCache notice = ... # type: Any ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/cachecontrol/caches/file_cache.pyi0000644000175000017500000000155114555736633025115 0ustar00michaelmichaelfrom os import PathLike from typing import ContextManager from ..cache import BaseCache as BaseCache from ..controller import CacheController as CacheController class _LockClass: path: str _lock_class = ContextManager[_LockClass] class FileCache(BaseCache): directory: str forever: bool filemode: int dirmode: int lock_class: _lock_class | None = None def __init__( self, directory: str | PathLike[str], forever: bool = ..., filemode: int = ..., dirmode: int = ..., use_dir_lock: bool | None = ..., lock_class: _lock_class | None = ..., ) -> None: ... @staticmethod def encode(x: str) -> str: ... def get(self, key: str) -> None | bytes: ... def set(self, key: str, value: bytes, expires: int | None = None) -> None: ... def delete(self, key: str) -> None: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/cachecontrol/compat.pyi0000644000175000017500000000025114555736633023104 0ustar00michaelmichael# Stubs for cachecontrol.compat (Python 2) # # NOTE: This dynamically typed stub was automatically generated by stubgen. from typing import Any str = ... # type: Any ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/cachecontrol/controller.pyi0000644000175000017500000000072614555736633024013 0ustar00michaelmichaelfrom typing import Collection from _typeshed import Incomplete from .cache import BaseCache class CacheController: cache: BaseCache cache_etags: bool serializer: Incomplete cacheable_status_codes: Collection[int] | None = None def __init__( self, cache: BaseCache | None = None, cache_etags: bool = True, serializer: Incomplete | None = None, status_codes: Collection[int] | None = None, ) -> None: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/cachecontrol/wrapper.pyi0000644000175000017500000000102414555736633023300 0ustar00michaelmichaelfrom typing import Collection, Type from _typeshed import Incomplete from requests import Session from .cache import BaseCache from .controller import CacheController def CacheControl( sess: Session, cache: BaseCache | None = None, cache_etags: bool = True, serializer: Incomplete | None = None, heuristic: Incomplete | None = None, controller_class: Type[CacheController] | None = None, adapter_class: Incomplete | None = None, cacheable_methods: Collection[str] | None = None, ) -> Session: ... ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6812878 cwltest-2.4.20240129145612/mypy-stubs/defusedxml/0000755000175000017500000000000014555737104020566 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/defusedxml/ElementTree.pyi0000644000175000017500000000026414555736633023532 0ustar00michaelmichaelimport xml.etree.ElementTree from pathlib import Path def parse( source: Path = ..., parser: xml.etree.ElementTree.XMLParser = ... ) -> xml.etree.ElementTree.ElementTree: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/defusedxml/__init__.pyi0000644000175000017500000000000014555736633023044 0ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/junit_xml.pyi0000644000175000017500000000473114555736633021175 0ustar00michaelmichael# Stubs for junit_xml (Python 3.5) # # NOTE: This dynamically typed stub was automatically generated by stubgen. from typing import IO, Any, List, Optional unichr = chr class TestSuite: name: Any = ... test_cases: Any = ... timestamp: Any = ... hostname: Any = ... id: Any = ... package: Any = ... file: Any = ... log: Any = ... url: Any = ... stdout: Any = ... stderr: Any = ... properties: Any = ... def __init__( self, name: str, test_cases: Optional[Any] = ..., hostname: Optional[Any] = ..., id: Optional[Any] = ..., package: Optional[Any] = ..., timestamp: Optional[Any] = ..., properties: Optional[Any] = ..., file: Optional[Any] = ..., log: Optional[Any] = ..., url: Optional[Any] = ..., stdout: Optional[Any] = ..., stderr: Optional[Any] = ..., ) -> None: ... class TestCase: name: Any = ... assertions: Any = ... elapsed_sec: Any = ... timestamp: Any = ... classname: Any = ... status: Any = ... category: Any = ... file: Any = ... line: Any = ... log: Any = ... url: Any = ... stdout: Any = ... stderr: Any = ... is_enabled: bool = ... error_message: Any = ... error_output: Any = ... error_type: Any = ... failure_message: Any = ... failure_output: Any = ... failure_type: Any = ... skipped_message: Any = ... skipped_output: Any = ... def __init__( self, name: str, classname: Optional[Any] = ..., elapsed_sec: Optional[Any] = ..., stdout: Optional[Any] = ..., stderr: Optional[Any] = ..., assertions: Optional[Any] = ..., timestamp: Optional[Any] = ..., status: Optional[Any] = ..., category: Optional[Any] = ..., file: Optional[Any] = ..., line: Optional[Any] = ..., log: Optional[Any] = ..., group: Optional[Any] = ..., url: Optional[Any] = ..., ) -> None: ... def add_failure_info( self, message: Optional[Any] = ..., output: Optional[Any] = ..., failure_type: Optional[Any] = ..., ) -> None: ... def add_skipped_info( self, message: Optional[Any] = ..., output: Optional[Any] = ... ) -> None: ... def to_xml_report_file( file_descriptor: IO[Any], test_suites: List[TestSuite], prettyprint: bool = True, encoding: Optional[str] = None, ) -> None: ... ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6812878 cwltest-2.4.20240129145612/mypy-stubs/rdflib/0000755000175000017500000000000014555737104017670 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/__init__.pyi0000644000175000017500000000241414555736633022161 0ustar00michaelmichaelfrom rdflib.graph import ConjunctiveGraph as ConjunctiveGraph from rdflib.graph import Graph as Graph from rdflib.namespace import CSVW as CSVW from rdflib.namespace import DC as DC from rdflib.namespace import DCAT as DCAT from rdflib.namespace import DCTERMS as DCTERMS from rdflib.namespace import DOAP as DOAP from rdflib.namespace import FOAF as FOAF from rdflib.namespace import ODRL2 as ODRL2 from rdflib.namespace import ORG as ORG from rdflib.namespace import OWL as OWL from rdflib.namespace import PROF as PROF from rdflib.namespace import PROV as PROV from rdflib.namespace import QB as QB from rdflib.namespace import RDF as RDF from rdflib.namespace import RDFS as RDFS from rdflib.namespace import SDO as SDO from rdflib.namespace import SH as SH from rdflib.namespace import SKOS as SKOS from rdflib.namespace import SOSA as SOSA from rdflib.namespace import SSN as SSN from rdflib.namespace import TIME as TIME from rdflib.namespace import VOID as VOID from rdflib.namespace import XMLNS as XMLNS from rdflib.namespace import XSD as XSD from rdflib.namespace import Namespace as Namespace from rdflib.term import BNode as BNode from rdflib.term import Literal as Literal from rdflib.term import URIRef as URIRef from rdflib.term import Variable as Variable __version__: str ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/collection.pyi0000644000175000017500000000124214555736633022553 0ustar00michaelmichaelfrom typing import Any, Iterator from rdflib.graph import Graph from rdflib.term import Node class Collection: graph: Graph uri: Node def __init__(self, graph: Graph, uri: Node, seq: Any = ...) -> None: ... def n3(self) -> str: ... def __len__(self) -> int: ... def index(self, item: Any) -> int: ... def __getitem__(self, key: str) -> Any: ... def __setitem__(self, key: str, value: Any) -> None: ... def __delitem__(self, key: str) -> None: ... def __iter__(self) -> Iterator[Any]: ... def append(self, item: Any) -> Collection: ... def __iadd__(self, other: Any) -> Collection: ... def clear(self) -> Collection: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/compare.pyi0000644000175000017500000000034714555736633022053 0ustar00michaelmichaelfrom typing import Dict, Union from rdflib.graph import ConjunctiveGraph, Graph Stats = Dict[str, Union[int, str]] class IsomorphicGraph(ConjunctiveGraph): pass def to_isomorphic(graph: Graph = ...) -> IsomorphicGraph: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/graph.pyi0000644000175000017500000002023714555736633021526 0ustar00michaelmichaelimport pathlib from typing import ( IO, Any, Iterable, Iterator, List, Optional, Set, Tuple, Union, overload, ) from rdflib import query from rdflib.collection import Collection from rdflib.paths import Path from rdflib.resource import Resource from rdflib.term import BNode, Identifier, Node class Graph(Node): base: Any = ... context_aware: bool = ... formula_aware: bool = ... default_union: bool = ... def __init__( self, store: str = ..., identifier: Optional[Any] = ..., namespace_manager: Optional[Any] = ..., base: Optional[Any] = ..., ) -> None: ... store: Any = ... identifier: Any = ... namespace_manager: Any = ... def toPython(self) -> str: ... def destroy(self, configuration: Any) -> None: ... def commit(self) -> None: ... def rollback(self) -> None: ... def open(self, configuration: Any, create: bool = ...) -> Any: ... def close(self, commit_pending_transaction: bool = ...) -> None: ... def add(self, triple: Any) -> None: ... def addN(self, quads: Any) -> None: ... def remove(self, triple: Any) -> None: ... def triples( self, triple: Tuple[ Optional[Union[str, Identifier]], Optional[Union[str, Identifier]], Optional[Identifier], ], ) -> Iterator[Tuple[Identifier, Identifier, Identifier]]: ... def __getitem__( self, item: slice | Path | Node ) -> Iterator[ Tuple[Identifier, Identifier, Identifier] | Tuple[Identifier, identifier] | Node ]: ... def __contains__(self, triple: Any) -> bool: ... def __add__(self, other: Any) -> Graph: ... def set(self, triple: Any) -> None: ... def subjects( self, predicate: Optional[Any] = ..., object: Optional[Any] = ... ) -> Iterable[Node]: ... def predicates( self, subject: Optional[Any] = ..., object: Optional[Any] = ... ) -> Iterable[Node]: ... def objects( self, subject: Optional[Any] = ..., predicate: Optional[Any] = ... ) -> Iterable[Identifier]: ... def subject_predicates(self, object: Optional[Any] = ...) -> None: ... def subject_objects(self, predicate: Optional[Any] = ...) -> None: ... def predicate_objects(self, subject: Optional[Any] = ...) -> None: ... def triples_choices(self, triple: Any, context: Optional[Any] = ...) -> None: ... def value( self, subject: Optional[Any] = ..., predicate: Any = ..., object: Optional[Any] = ..., default: Optional[Any] = ..., any: bool = ..., ) -> Any: ... def label(self, subject: Any, default: str = ...) -> Any: ... def preferredLabel( self, subject: Any, lang: Optional[Any] = ..., default: Optional[Any] = ..., labelProperties: Any = ..., ) -> List[Tuple[Any, Any]]: ... def comment(self, subject: Any, default: str = ...) -> Any: ... def items(self, list: Any) -> Iterator[Any]: ... def transitiveClosure( self, func: Any, arg: Any, seen: Optional[Any] = ... ) -> Iterator[Any]: ... def transitive_objects( self, subject: Any, property: Any, remember: Optional[Any] = ... ) -> Iterator[Any]: ... def transitive_subjects( self, predicate: Any, object: Any, remember: Optional[Any] = ... ) -> Iterator[Any]: ... def seq(self, subject: Any) -> Seq | None: ... def qname(self, uri: Any) -> Any: ... def compute_qname(self, uri: Any, generate: bool = ...) -> Any: ... def bind( self, prefix: Any, namespace: Any, override: bool = ..., replace: bool = ... ) -> Any: ... def namespaces(self) -> Iterator[Tuple[Any, Any]]: ... def absolutize(self, uri: Any, defrag: int = ...) -> Any: ... # no destination and non-None positional encoding @overload def serialize( self, destination: None, format: str, base: Optional[str], encoding: str, **args: Any, ) -> bytes: ... # no destination and non-None keyword encoding @overload def serialize( self, destination: None = ..., format: str = ..., base: Optional[str] = ..., *, encoding: str, **args: Any, ) -> bytes: ... # no destination and None encoding @overload def serialize( self, destination: None = ..., format: str = ..., base: Optional[str] = ..., encoding: None = ..., **args: Any, ) -> str: ... # non-None destination @overload def serialize( self, destination: Union[str, pathlib.PurePath, IO[bytes]], format: str = ..., base: Optional[str] = ..., encoding: Optional[str] = ..., **args: Any, ) -> "Graph": ... # fallback @overload def serialize( self, destination: Optional[Union[str, pathlib.PurePath, IO[bytes]]] = ..., format: str = ..., base: Optional[str] = ..., encoding: Optional[str] = ..., **args: Any, ) -> Union[bytes, str, "Graph"]: ... def parse( self, source: Optional[Any] = ..., publicID: Optional[Any] = ..., format: Optional[str] = ..., location: Optional[Any] = ..., file: Optional[Any] = ..., data: Optional[Any] = ..., **args: Any, ) -> "Graph": ... def load( self, source: Any, publicID: Optional[Any] = ..., format: str = ... ) -> "Graph": ... def query( self, query_object: Any, processor: str = ..., result: str = ..., initNs: Optional[Any] = ..., initBindings: Optional[Any] = ..., use_store_provided: bool = ..., **kwargs: Any, ) -> query.Result: ... def update( self, update_object: Any, processor: str = ..., initNs: Optional[Any] = ..., initBindings: Optional[Any] = ..., use_store_provided: bool = ..., **kwargs: Any, ) -> Any: ... def n3(self) -> str: ... def isomorphic(self, other: Any) -> bool: ... def connected(self) -> bool: ... def all_nodes(self) -> Set[Any]: ... def collection(self, identifier: Any) -> Collection: ... def resource(self, identifier: Any) -> Resource: ... def skolemize( self, new_graph: Optional[Any] = ..., bnode: Optional[Any] = ..., authority: Optional[Any] = ..., basepath: Optional[Any] = ..., ) -> Graph: ... def de_skolemize( self, new_graph: Optional[Any] = ..., uriref: Optional[Any] = ... ) -> Graph: ... class ConjunctiveGraph(Graph): context_aware: bool = ... default_union: bool = ... default_context: Any = ... def __init__( self, store: str = ..., identifier: Optional[Any] = ..., default_graph_base: Optional[Any] = ..., ) -> None: ... def add(self, triple_or_quad: Any) -> None: ... def addN(self, quads: Any) -> None: ... def remove(self, triple_or_quad: Any) -> None: ... # def triples(self, triple_or_quad: Tuple[Optional[Union[str, BNode]], Optional[Union[str, BNode]], Optional[BNode]], context: Tuple[Optional[Union[str, BNode]], Optional[Union[str, BNode]], Optional[BNode]]) -> Iterator[Tuple[Identifier, Identifier, Identifier]]: ... def quads(self, triple_or_quad: Optional[Any] = ...) -> None: ... def triples_choices(self, triple: Any, context: Optional[Any] = ...) -> None: ... def contexts(self, triple: Optional[Any] = ...) -> None: ... def get_context( self, identifier: Node | str | None, quoted: bool = ..., base: Optional[str] = ..., ) -> Graph: ... def remove_context(self, context: Any) -> None: ... def context_id(self, uri: Any, context_id: Optional[Any] = ...) -> Any: ... def parse( self, source: Optional[Any] = ..., publicID: Optional[Any] = ..., format: Optional[str] = ..., location: Optional[Any] = ..., file: Optional[Any] = ..., data: Optional[Any] = ..., **args: Any, ) -> Graph: ... class Seq: def __init__(self, graph: Graph, subject: Any) -> None: ... def toPython(self) -> Seq: ... ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1706540611.685288 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/0000755000175000017500000000000014555737104021624 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_CSVW.pyi0000644000175000017500000000373214555736633023303 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class CSVW(DefinedNamespace): aboutUrl: URIRef base: URIRef column: URIRef columnReference: URIRef commentPrefix: URIRef datatype: URIRef decimalChar: URIRef default: URIRef delimiter: URIRef describes: URIRef dialect: URIRef doubleQuote: URIRef encoding: URIRef foreignKey: URIRef format: URIRef groupChar: URIRef header: URIRef headerRowCount: URIRef lang: URIRef length: URIRef lineTerminators: URIRef maxExclusive: URIRef maxInclusive: URIRef maxLength: URIRef minExclusive: URIRef minInclusive: URIRef minLength: URIRef name: URIRef note: URIRef null: URIRef ordered: URIRef pattern: URIRef primaryKey: URIRef propertyUrl: URIRef quoteChar: URIRef reference: URIRef referencedRow: URIRef required: URIRef resource: URIRef row: URIRef rowTitle: URIRef rownum: URIRef schemaReference: URIRef scriptFormat: URIRef separator: URIRef skipBlankRows: URIRef skipColumns: URIRef skipInitialSpace: URIRef skipRows: URIRef source: URIRef suppressOutput: URIRef table: URIRef tableDirection: URIRef tableSchema: URIRef targetFormat: URIRef textDirection: URIRef title: URIRef transformations: URIRef trim: URIRef url: URIRef valueUrl: URIRef virtual: URIRef Cell: URIRef Column: URIRef Datatype: URIRef Dialect: URIRef Direction: URIRef ForeignKey: URIRef NumericFormat: URIRef Row: URIRef Schema: URIRef Table: URIRef TableGroup: URIRef TableReference: URIRef Transformation: URIRef JSON: URIRef uriTemplate: URIRef auto: URIRef inherit: URIRef ltr: URIRef rtl: URIRef csvEncodedTabularData: URIRef tabularMetadata: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_DC.pyi0000644000175000017500000000075514555736633023011 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class DC(DefinedNamespace): contributor: URIRef coverage: URIRef creator: URIRef date: URIRef description: URIRef format: URIRef identifier: URIRef language: URIRef publisher: URIRef relation: URIRef rights: URIRef source: URIRef subject: URIRef title: URIRef type: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_DCAT.pyi0000644000175000017500000000201214555736633023222 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class DCAT(DefinedNamespace): accessURL: URIRef bbox: URIRef byteSize: URIRef centroid: URIRef compressFormat: URIRef contactPoint: URIRef dataset: URIRef distribution: URIRef downloadURL: URIRef endDate: URIRef keyword: URIRef landingPage: URIRef mediaType: URIRef packageFormat: URIRef record: URIRef startDate: URIRef theme: URIRef themeTaxonomy: URIRef Catalog: URIRef CatalogRecord: URIRef Dataset: URIRef Distribution: URIRef DataService: URIRef Relationship: URIRef Resource: URIRef Role: URIRef spatialResolutionInMeters: URIRef temporalResolution: URIRef accessService: URIRef catalog: URIRef endpointDescription: URIRef endpointURL: URIRef hadRole: URIRef qualifiedRelation: URIRef servesDataset: URIRef service: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_DCTERMS.pyi0000644000175000017500000000447114555736633023623 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class DCTERMS(DefinedNamespace): DCMIType: URIRef DDC: URIRef IMT: URIRef LCC: URIRef LCSH: URIRef MESH: URIRef NLM: URIRef TGN: URIRef UDC: URIRef abstract: URIRef accessRights: URIRef accrualMethod: URIRef accrualPeriodicity: URIRef accrualPolicy: URIRef alternative: URIRef audience: URIRef available: URIRef bibliographicCitation: URIRef conformsTo: URIRef contributor: URIRef coverage: URIRef created: URIRef creator: URIRef date: URIRef dateAccepted: URIRef dateCopyrighted: URIRef dateSubmitted: URIRef description: URIRef educationLevel: URIRef extent: URIRef format: URIRef hasFormat: URIRef hasPart: URIRef hasVersion: URIRef identifier: URIRef instructionalMethod: URIRef isFormatOf: URIRef isPartOf: URIRef isReferencedBy: URIRef isReplacedBy: URIRef isRequiredBy: URIRef isVersionOf: URIRef issued: URIRef language: URIRef license: URIRef mediator: URIRef medium: URIRef modified: URIRef provenance: URIRef publisher: URIRef references: URIRef relation: URIRef replaces: URIRef requires: URIRef rights: URIRef rightsHolder: URIRef source: URIRef spatial: URIRef subject: URIRef tableOfContents: URIRef temporal: URIRef title: URIRef type: URIRef valid: URIRef Agent: URIRef AgentClass: URIRef BibliographicResource: URIRef FileFormat: URIRef Frequency: URIRef Jurisdiction: URIRef LicenseDocument: URIRef LinguisticSystem: URIRef Location: URIRef LocationPeriodOrJurisdiction: URIRef MediaType: URIRef MediaTypeOrExtent: URIRef MethodOfAccrual: URIRef MethodOfInstruction: URIRef PeriodOfTime: URIRef PhysicalMedium: URIRef PhysicalResource: URIRef Policy: URIRef ProvenanceStatement: URIRef RightsStatement: URIRef SizeOrDuration: URIRef Standard: URIRef Box: URIRef ISO3166: URIRef Period: URIRef Point: URIRef RFC1766: URIRef RFC3066: URIRef RFC4646: URIRef RFC5646: URIRef URI: URIRef W3CDTF: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_DOAP.pyi0000644000175000017500000000212514555736633023237 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class DOAP(DefinedNamespace): audience: URIRef blog: URIRef browse: URIRef category: URIRef created: URIRef description: URIRef developer: URIRef documenter: URIRef helper: URIRef implements: URIRef language: URIRef license: URIRef location: URIRef maintainer: URIRef module: URIRef name: URIRef os: URIRef platform: URIRef release: URIRef repository: URIRef repositoryOf: URIRef revision: URIRef screenshots: URIRef shortdesc: URIRef tester: URIRef translator: URIRef vendor: URIRef wiki: URIRef ArchRepository: URIRef BKRepository: URIRef BazaarBranch: URIRef CVSRepository: URIRef DarcsRepository: URIRef GitBranch: URIRef GitRepository: URIRef HgRepository: URIRef Project: URIRef Repository: URIRef SVNRepository: URIRef Specification: URIRef Version: URIRef homepage: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_FOAF.pyi0000644000175000017500000000346714555736633023241 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class FOAF(DefinedNamespace): account: URIRef accountName: URIRef accountServiceHomepage: URIRef age: URIRef based_near: URIRef birthday: URIRef currentProject: URIRef depiction: URIRef depicts: URIRef dnaChecksum: URIRef familyName: URIRef family_name: URIRef firstName: URIRef focus: URIRef fundedBy: URIRef geekcode: URIRef gender: URIRef givenName: URIRef givenname: URIRef holdsAccount: URIRef img: URIRef interest: URIRef knows: URIRef lastName: URIRef made: URIRef maker: URIRef member: URIRef membershipClass: URIRef myersBriggs: URIRef name: URIRef nick: URIRef page: URIRef pastProject: URIRef phone: URIRef plan: URIRef primaryTopic: URIRef publications: URIRef schoolHomepage: URIRef sha1: URIRef skypeID: URIRef status: URIRef surname: URIRef theme: URIRef thumbnail: URIRef tipjar: URIRef title: URIRef topic: URIRef topic_interest: URIRef workInfoHomepage: URIRef workplaceHomepage: URIRef Agent: URIRef Document: URIRef Group: URIRef Image: URIRef LabelProperty: URIRef OnlineAccount: URIRef OnlineChatAccount: URIRef OnlineEcommerceAccount: URIRef OnlineGamingAccount: URIRef Organization: URIRef Person: URIRef PersonalProfileDocument: URIRef Project: URIRef aimChatID: URIRef homepage: URIRef icqChatID: URIRef isPrimaryTopicOf: URIRef jabberID: URIRef logo: URIRef mbox: URIRef mbox_sha1sum: URIRef msnChatID: URIRef openid: URIRef weblog: URIRef yahooChatID: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_ODRL2.pyi0000644000175000017500000001112314555736633023334 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class ODRL2(DefinedNamespace): action: URIRef andSequence: URIRef assignee: URIRef assigneeOf: URIRef assigner: URIRef assignerOf: URIRef attributedParty: URIRef attributingParty: URIRef compensatedParty: URIRef compensatingParty: URIRef conflict: URIRef consentedParty: URIRef consentingParty: URIRef consequence: URIRef constraint: URIRef contractedParty: URIRef contractingParty: URIRef dataType: URIRef duty: URIRef failure: URIRef function: URIRef hasPolicy: URIRef implies: URIRef includedIn: URIRef informedParty: URIRef informingParty: URIRef inheritAllowed: URIRef inheritFrom: URIRef inheritRelation: URIRef leftOperand: URIRef obligation: URIRef operand: URIRef operator: URIRef output: URIRef partOf: URIRef payeeParty: URIRef permission: URIRef profile: URIRef prohibition: URIRef proximity: URIRef refinement: URIRef relation: URIRef remedy: URIRef rightOperand: URIRef rightOperandReference: URIRef scope: URIRef source: URIRef status: URIRef target: URIRef timedCount: URIRef trackedParty: URIRef trackingParty: URIRef uid: URIRef undefined: URIRef unit: URIRef xone: URIRef All: URIRef All2ndConnections: URIRef AllConnections: URIRef AllGroups: URIRef Group: URIRef Individual: URIRef absolutePosition: URIRef absoluteSize: URIRef absoluteSpatialPosition: URIRef absoluteTemporalPosition: URIRef count: URIRef dateTime: URIRef delayPeriod: URIRef deliveryChannel: URIRef device: URIRef elapsedTime: URIRef eq: URIRef event: URIRef fileFormat: URIRef gt: URIRef gteq: URIRef hasPart: URIRef ignore: URIRef industry: URIRef invalid: URIRef isA: URIRef isAllOf: URIRef isAnyOf: URIRef isNoneOf: URIRef isPartOf: URIRef language: URIRef lt: URIRef lteq: URIRef media: URIRef meteredTime: URIRef neq: URIRef payAmount: URIRef percentage: URIRef perm: URIRef policyUsage: URIRef product: URIRef prohibit: URIRef purpose: URIRef recipient: URIRef relativePosition: URIRef relativeSize: URIRef relativeSpatialPosition: URIRef relativeTemporalPosition: URIRef resolution: URIRef spatial: URIRef spatialCoordinates: URIRef support: URIRef system: URIRef systemDevice: URIRef timeInterval: URIRef unitOfCount: URIRef version: URIRef virtualLocation: URIRef Action: URIRef Agreement: URIRef Assertion: URIRef Asset: URIRef AssetCollection: URIRef AssetScope: URIRef ConflictTerm: URIRef Constraint: URIRef Duty: URIRef LeftOperand: URIRef LogicalConstraint: URIRef Offer: URIRef Operator: URIRef Party: URIRef PartyCollection: URIRef PartyScope: URIRef Permission: URIRef Policy: URIRef Privacy: URIRef Prohibition: URIRef Request: URIRef RightOperand: URIRef Rule: URIRef Set: URIRef Ticket: URIRef UndefinedTerm: URIRef acceptTracking: URIRef adHocShare: URIRef aggregate: URIRef annotate: URIRef anonymize: URIRef append: URIRef appendTo: URIRef archive: URIRef attachPolicy: URIRef attachSource: URIRef attribute: URIRef commercialize: URIRef compensate: URIRef concurrentUse: URIRef copy: URIRef core: URIRef delete: URIRef derive: URIRef digitize: URIRef display: URIRef distribute: URIRef ensureExclusivity: URIRef execute: URIRef export: URIRef extract: URIRef extractChar: URIRef extractPage: URIRef extractWord: URIRef give: URIRef grantUse: URIRef include: URIRef index: URIRef inform: URIRef install: URIRef lease: URIRef lend: URIRef license: URIRef modify: URIRef move: URIRef nextPolicy: URIRef obtainConsent: URIRef pay: URIRef play: URIRef present: URIRef preview: URIRef print: URIRef read: URIRef reproduce: URIRef reviewPolicy: URIRef secondaryUse: URIRef sell: URIRef share: URIRef shareAlike: URIRef stream: URIRef synchronize: URIRef textToSpeech: URIRef transfer: URIRef transform: URIRef translate: URIRef uninstall: URIRef use: URIRef watermark: URIRef write: URIRef writeTo: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_ORG.pyi0000644000175000017500000000235314555736633023146 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class ORG(DefinedNamespace): basedAt: URIRef changedBy: URIRef classification: URIRef hasMember: URIRef hasMembership: URIRef hasPost: URIRef hasPrimarySite: URIRef hasRegisteredSite: URIRef hasSite: URIRef hasSubOrganization: URIRef hasUnit: URIRef headOf: URIRef heldBy: URIRef holds: URIRef identifier: URIRef linkedTo: URIRef location: URIRef member: URIRef memberDuring: URIRef memberOf: URIRef organization: URIRef originalOrganization: URIRef postIn: URIRef purpose: URIRef remuneration: URIRef reportsTo: URIRef resultedFrom: URIRef resultingOrganization: URIRef role: URIRef roleProperty: URIRef siteAddress: URIRef siteOf: URIRef subOrganizationOf: URIRef transitiveSubOrganizationOf: URIRef unitOf: URIRef ChangeEvent: URIRef FormalOrganization: URIRef Membership: URIRef Organization: URIRef OrganizationalCollaboration: URIRef OrganizationalUnit: URIRef Post: URIRef Role: URIRef Site: URIRef Head: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_OWL.pyi0000644000175000017500000000432414555736633023160 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class OWL(DefinedNamespace): allValuesFrom: URIRef annotatedProperty: URIRef annotatedSource: URIRef annotatedTarget: URIRef assertionProperty: URIRef cardinality: URIRef complementOf: URIRef datatypeComplementOf: URIRef differentFrom: URIRef disjointUnionOf: URIRef disjointWith: URIRef distinctMembers: URIRef equivalentClass: URIRef equivalentProperty: URIRef hasKey: URIRef hasSelf: URIRef hasValue: URIRef intersectionOf: URIRef inverseOf: URIRef maxCardinality: URIRef maxQualifiedCardinality: URIRef members: URIRef minCardinality: URIRef minQualifiedCardinality: URIRef onClass: URIRef onDataRange: URIRef onDatatype: URIRef onProperties: URIRef onProperty: URIRef oneOf: URIRef propertyChainAxiom: URIRef propertyDisjointWith: URIRef qualifiedCardinality: URIRef sameAs: URIRef someValuesFrom: URIRef sourceIndividual: URIRef targetIndividual: URIRef targetValue: URIRef unionOf: URIRef withRestrictions: URIRef AllDifferent: URIRef AllDisjointClasses: URIRef AllDisjointProperties: URIRef Annotation: URIRef AnnotationProperty: URIRef AsymmetricProperty: URIRef Axiom: URIRef Class: URIRef DataRange: URIRef DatatypeProperty: URIRef DeprecatedClass: URIRef DeprecatedProperty: URIRef FunctionalProperty: URIRef InverseFunctionalProperty: URIRef IrreflexiveProperty: URIRef NamedIndividual: URIRef NegativePropertyAssertion: URIRef ObjectProperty: URIRef Ontology: URIRef OntologyProperty: URIRef ReflexiveProperty: URIRef Restriction: URIRef SymmetricProperty: URIRef TransitiveProperty: URIRef backwardCompatibleWith: URIRef deprecated: URIRef incompatibleWith: URIRef priorVersion: URIRef versionInfo: URIRef Nothing: URIRef Thing: URIRef bottomDataProperty: URIRef topDataProperty: URIRef bottomObjectProperty: URIRef topObjectProperty: URIRef imports: URIRef versionIRI: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_PROF.pyi0000644000175000017500000000067114555736633023266 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class PROF(DefinedNamespace): Profile: URIRef ResourceDescriptor: URIRef ResourceRole: URIRef hasToken: URIRef hasArtifact: URIRef hasResource: URIRef hasRole: URIRef isInheritedFrom: URIRef isProfileOf: URIRef isTransitiveProfileOf: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_PROV.pyi0000644000175000017500000001065014555736633023304 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class PROV(DefinedNamespace): activityOfInfluence: URIRef agentOfInfluence: URIRef contributed: URIRef ended: URIRef entityOfInfluence: URIRef generalizationOf: URIRef generatedAsDerivation: URIRef hadDelegate: URIRef hadDerivation: URIRef hadInfluence: URIRef hadRevision: URIRef informed: URIRef locationOf: URIRef qualifiedAssociationOf: URIRef qualifiedAttributionOf: URIRef qualifiedCommunicationOf: URIRef qualifiedDelegationOf: URIRef qualifiedDerivationOf: URIRef qualifiedEndOf: URIRef qualifiedGenerationOf: URIRef qualifiedInfluenceOf: URIRef qualifiedInvalidationOf: URIRef qualifiedQuotationOf: URIRef qualifiedSourceOf: URIRef qualifiedStartOf: URIRef qualifiedUsingActivity: URIRef quotedAs: URIRef revisedEntity: URIRef started: URIRef wasActivityOfInfluence: URIRef wasAssociateFor: URIRef wasMemberOf: URIRef wasPlanOf: URIRef wasPrimarySourceOf: URIRef wasRoleIn: URIRef wasUsedBy: URIRef wasUsedInDerivation: URIRef aq: URIRef category: URIRef component: URIRef constraints: URIRef definition: URIRef dm: URIRef editorialNote: URIRef editorsDefinition: URIRef inverse: URIRef n: URIRef order: URIRef qualifiedForm: URIRef sharesDefinitionWith: URIRef specializationOf: URIRef todo: URIRef unqualifiedForm: URIRef wasRevisionOf: URIRef Accept: URIRef Activity: URIRef ActivityInfluence: URIRef Agent: URIRef AgentInfluence: URIRef Association: URIRef Attribution: URIRef Bundle: URIRef Collection: URIRef Communication: URIRef Contribute: URIRef Contributor: URIRef Copyright: URIRef Create: URIRef Creator: URIRef Delegation: URIRef Derivation: URIRef Dictionary: URIRef DirectQueryService: URIRef EmptyDictionary: URIRef End: URIRef Entity: URIRef EntityInfluence: URIRef Generation: URIRef Influence: URIRef Insertion: URIRef InstantaneousEvent: URIRef Invalidation: URIRef KeyEntityPair: URIRef Location: URIRef Modify: URIRef Organization: URIRef Person: URIRef Plan: URIRef PrimarySource: URIRef Publish: URIRef Publisher: URIRef Quotation: URIRef Removal: URIRef Replace: URIRef Revision: URIRef RightsAssignment: URIRef RightsHolder: URIRef Role: URIRef ServiceDescription: URIRef SoftwareAgent: URIRef Start: URIRef Submit: URIRef Usage: URIRef atTime: URIRef endedAtTime: URIRef generatedAtTime: URIRef invalidatedAtTime: URIRef provenanceUriTemplate: URIRef removedKey: URIRef startedAtTime: URIRef value: URIRef pairEntity: URIRef pairKey: URIRef EmptyCollection: URIRef actedOnBehalfOf: URIRef activity: URIRef agent: URIRef alternateOf: URIRef asInBundle: URIRef atLocation: URIRef derivedByInsertionFrom: URIRef derivedByRemovalFrom: URIRef describesService: URIRef dictionary: URIRef entity: URIRef generated: URIRef hadActivity: URIRef hadDictionaryMember: URIRef hadGeneration: URIRef hadMember: URIRef hadPlan: URIRef hadPrimarySource: URIRef hadRole: URIRef hadUsage: URIRef has_anchor: URIRef has_provenance: URIRef has_query_service: URIRef influenced: URIRef influencer: URIRef insertedKeyEntityPair: URIRef invalidated: URIRef mentionOf: URIRef pingback: URIRef qualifiedAssociation: URIRef qualifiedAttribution: URIRef qualifiedCommunication: URIRef qualifiedDelegation: URIRef qualifiedDerivation: URIRef qualifiedEnd: URIRef qualifiedGeneration: URIRef qualifiedInfluence: URIRef qualifiedInsertion: URIRef qualifiedInvalidation: URIRef qualifiedPrimarySource: URIRef qualifiedQuotation: URIRef qualifiedRemoval: URIRef qualifiedRevision: URIRef qualifiedStart: URIRef qualifiedUsage: URIRef used: URIRef wasAssociatedWith: URIRef wasAttributedTo: URIRef wasDerivedFrom: URIRef wasEndedBy: URIRef wasGeneratedBy: URIRef wasInfluencedBy: URIRef wasInformedBy: URIRef wasInvalidatedBy: URIRef wasQuotedFrom: URIRef wasStartedBy: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_QB.pyi0000644000175000017500000000212114555736633023012 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class QB(DefinedNamespace): attribute: URIRef codeList: URIRef component: URIRef componentAttachment: URIRef componentProperty: URIRef componentRequired: URIRef concept: URIRef dataSet: URIRef dimension: URIRef hierarchyRoot: URIRef measure: URIRef measureDimension: URIRef measureType: URIRef observation: URIRef observationGroup: URIRef order: URIRef parentChildProperty: URIRef slice: URIRef sliceKey: URIRef sliceStructure: URIRef structure: URIRef Attachable: URIRef AttributeProperty: URIRef CodedProperty: URIRef ComponentProperty: URIRef ComponentSet: URIRef ComponentSpecification: URIRef DataSet: URIRef DataStructureDefinition: URIRef DimensionProperty: URIRef HierarchicalCodeList: URIRef MeasureProperty: URIRef Observation: URIRef ObservationGroup: URIRef Slice: URIRef SliceKey: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_RDF.pyi0000644000175000017500000000115414555736633023130 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class RDF(DefinedNamespace): nil: URIRef direction: URIRef first: URIRef language: URIRef object: URIRef predicate: URIRef rest: URIRef subject: URIRef type: URIRef value: URIRef Alt: URIRef Bag: URIRef CompoundLiteral: URIRef List: URIRef Property: URIRef Seq: URIRef Statement: URIRef HTML: URIRef JSON: URIRef PlainLiteral: URIRef XMLLiteral: URIRef langString: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_RDFS.pyi0000644000175000017500000000100714555736633023250 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class RDFS(DefinedNamespace): comment: URIRef domain: URIRef isDefinedBy: URIRef label: URIRef member: URIRef range: URIRef seeAlso: URIRef subClassOf: URIRef subPropertyOf: URIRef Class: URIRef Container: URIRef ContainerMembershipProperty: URIRef Datatype: URIRef Literal: URIRef Resource: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_SDO.pyi0000644000175000017500000012067114555736633023150 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class SDO(DefinedNamespace): ActiveActionStatus: URIRef CompletedActionStatus: URIRef FailedActionStatus: URIRef PotentialActionStatus: URIRef Researcher: URIRef GroupBoardingPolicy: URIRef ZoneBoardingPolicy: URIRef AudiobookFormat: URIRef EBook: URIRef Hardcover: URIRef Paperback: URIRef HearingImpairedSupported: URIRef TollFree: URIRef Friday: URIRef Monday: URIRef PublicHolidays: URIRef Saturday: URIRef Sunday: URIRef Thursday: URIRef Tuesday: URIRef Wednesday: URIRef OnSitePickup: URIRef CommentPermission: URIRef ReadPermission: URIRef WritePermission: URIRef AllWheelDriveConfiguration: URIRef FourWheelDriveConfiguration: URIRef FrontWheelDriveConfiguration: URIRef RearWheelDriveConfiguration: URIRef EventCancelled: URIRef EventMovedOnline: URIRef EventPostponed: URIRef EventRescheduled: URIRef EventScheduled: URIRef CoOp: URIRef MultiPlayer: URIRef SinglePlayer: URIRef OfflinePermanently: URIRef OfflineTemporarily: URIRef Online: URIRef OnlineFull: URIRef Female: URIRef Male: URIRef Discontinued: URIRef InStock: URIRef InStoreOnly: URIRef LimitedAvailability: URIRef OnlineOnly: URIRef OutOfStock: URIRef PreOrder: URIRef PreSale: URIRef SoldOut: URIRef ItemListOrderAscending: URIRef ItemListOrderDescending: URIRef ItemListUnordered: URIRef ParkingMap: URIRef SeatingMap: URIRef TransitMap: URIRef VenueMap: URIRef CompilationAlbum: URIRef DJMixAlbum: URIRef DemoAlbum: URIRef LiveAlbum: URIRef MixtapeAlbum: URIRef RemixAlbum: URIRef SoundtrackAlbum: URIRef SpokenWordAlbum: URIRef StudioAlbum: URIRef AlbumRelease: URIRef BroadcastRelease: URIRef EPRelease: URIRef SingleRelease: URIRef CDFormat: URIRef CassetteFormat: URIRef DVDFormat: URIRef DigitalAudioTapeFormat: URIRef DigitalFormat: URIRef LaserDiscFormat: URIRef VinylFormat: URIRef DamagedCondition: URIRef NewCondition: URIRef RefurbishedCondition: URIRef UsedCondition: URIRef OrderCancelled: URIRef OrderDelivered: URIRef OrderInTransit: URIRef OrderPaymentDue: URIRef OrderPickupAvailable: URIRef OrderProblem: URIRef OrderProcessing: URIRef OrderReturned: URIRef PaymentAutomaticallyApplied: URIRef PaymentComplete: URIRef PaymentDeclined: URIRef PaymentDue: URIRef PaymentPastDue: URIRef ReservationCancelled: URIRef ReservationConfirmed: URIRef ReservationHold: URIRef ReservationPending: URIRef DiabeticDiet: URIRef GlutenFreeDiet: URIRef HalalDiet: URIRef HinduDiet: URIRef KosherDiet: URIRef LowCalorieDiet: URIRef LowFatDiet: URIRef LowLactoseDiet: URIRef LowSaltDiet: URIRef VeganDiet: URIRef VegetarianDiet: URIRef RsvpResponseMaybe: URIRef RsvpResponseNo: URIRef RsvpResponseYes: URIRef LeftHandDriving: URIRef RightHandDriving: URIRef about: URIRef acceptedAnswer: URIRef acceptedOffer: URIRef acceptedPaymentMethod: URIRef acceptsReservations: URIRef accessCode: URIRef accessMode: URIRef accessModeSufficient: URIRef accessibilityAPI: URIRef accessibilityControl: URIRef accessibilityFeature: URIRef accessibilityHazard: URIRef accessibilitySummary: URIRef accountId: URIRef accountablePerson: URIRef acquiredFrom: URIRef actionAccessibilityRequirement: URIRef actionApplication: URIRef actionOption: URIRef actionPlatform: URIRef actionStatus: URIRef actor: URIRef actors: URIRef addOn: URIRef additionalName: URIRef additionalNumberOfGuests: URIRef additionalProperty: URIRef additionalType: URIRef address: URIRef addressCountry: URIRef addressLocality: URIRef addressRegion: URIRef advanceBookingRequirement: URIRef affiliation: URIRef afterMedia: URIRef agent: URIRef aggregateRating: URIRef aircraft: URIRef album: URIRef albumProductionType: URIRef albumRelease: URIRef albumReleaseType: URIRef albums: URIRef alignmentType: URIRef alternateName: URIRef alternativeHeadline: URIRef alumni: URIRef alumniOf: URIRef amenityFeature: URIRef amount: URIRef amountOfThisGood: URIRef annualPercentageRate: URIRef answerCount: URIRef application: URIRef applicationCategory: URIRef applicationSubCategory: URIRef applicationSuite: URIRef appliesToDeliveryMethod: URIRef appliesToPaymentMethod: URIRef area: URIRef areaServed: URIRef arrivalAirport: URIRef arrivalBusStop: URIRef arrivalGate: URIRef arrivalPlatform: URIRef arrivalStation: URIRef arrivalTerminal: URIRef arrivalTime: URIRef artEdition: URIRef artMedium: URIRef artform: URIRef articleBody: URIRef articleSection: URIRef artworkSurface: URIRef assembly: URIRef assemblyVersion: URIRef associatedArticle: URIRef associatedMedia: URIRef athlete: URIRef attendee: URIRef attendees: URIRef audience: URIRef audienceType: URIRef audio: URIRef authenticator: URIRef author: URIRef availability: URIRef availabilityEnds: URIRef availabilityStarts: URIRef availableAtOrFrom: URIRef availableChannel: URIRef availableDeliveryMethod: URIRef availableFrom: URIRef availableLanguage: URIRef availableOnDevice: URIRef availableThrough: URIRef award: URIRef awards: URIRef awayTeam: URIRef baseSalary: URIRef bccRecipient: URIRef bed: URIRef beforeMedia: URIRef benefits: URIRef bestRating: URIRef billingAddress: URIRef billingIncrement: URIRef billingPeriod: URIRef birthDate: URIRef birthPlace: URIRef bitrate: URIRef blogPost: URIRef blogPosts: URIRef boardingGroup: URIRef boardingPolicy: URIRef bookEdition: URIRef bookFormat: URIRef bookingAgent: URIRef bookingTime: URIRef borrower: URIRef box: URIRef branchCode: URIRef branchOf: URIRef brand: URIRef breadcrumb: URIRef broadcastAffiliateOf: URIRef broadcastChannelId: URIRef broadcastDisplayName: URIRef broadcastFrequency: URIRef broadcastFrequencyValue: URIRef broadcastOfEvent: URIRef broadcastServiceTier: URIRef broadcastTimezone: URIRef broadcaster: URIRef broker: URIRef browserRequirements: URIRef busName: URIRef busNumber: URIRef businessFunction: URIRef buyer: URIRef byArtist: URIRef calories: URIRef candidate: URIRef caption: URIRef carbohydrateContent: URIRef cargoVolume: URIRef carrier: URIRef carrierRequirements: URIRef catalog: URIRef catalogNumber: URIRef category: URIRef ccRecipient: URIRef character: URIRef characterAttribute: URIRef characterName: URIRef cheatCode: URIRef checkinTime: URIRef checkoutTime: URIRef childMaxAge: URIRef childMinAge: URIRef children: URIRef cholesterolContent: URIRef circle: URIRef citation: URIRef claimReviewed: URIRef clipNumber: URIRef closes: URIRef coach: URIRef codeRepository: URIRef codeSampleType: URIRef colleague: URIRef colleagues: URIRef collection: URIRef color: URIRef comment: URIRef commentCount: URIRef commentText: URIRef commentTime: URIRef competitor: URIRef composer: URIRef confirmationNumber: URIRef contactOption: URIRef contactPoint: URIRef contactPoints: URIRef contactType: URIRef containedIn: URIRef containedInPlace: URIRef containsPlace: URIRef containsSeason: URIRef contentLocation: URIRef contentRating: URIRef contentSize: URIRef contentType: URIRef contentUrl: URIRef contributor: URIRef cookTime: URIRef cookingMethod: URIRef copyrightHolder: URIRef copyrightYear: URIRef countriesNotSupported: URIRef countriesSupported: URIRef countryOfOrigin: URIRef course: URIRef courseCode: URIRef courseMode: URIRef coursePrerequisites: URIRef coverageEndTime: URIRef coverageStartTime: URIRef creator: URIRef creditedTo: URIRef cssSelector: URIRef currenciesAccepted: URIRef currency: URIRef customer: URIRef dataFeedElement: URIRef dataset: URIRef datasetTimeInterval: URIRef dateCreated: URIRef dateDeleted: URIRef dateIssued: URIRef dateModified: URIRef datePosted: URIRef datePublished: URIRef dateRead: URIRef dateReceived: URIRef dateSent: URIRef dateVehicleFirstRegistered: URIRef dateline: URIRef dayOfWeek: URIRef deathDate: URIRef deathPlace: URIRef defaultValue: URIRef deliveryAddress: URIRef deliveryLeadTime: URIRef deliveryMethod: URIRef deliveryStatus: URIRef department: URIRef departureAirport: URIRef departureBusStop: URIRef departureGate: URIRef departurePlatform: URIRef departureStation: URIRef departureTerminal: URIRef departureTime: URIRef dependencies: URIRef depth: URIRef description: URIRef device: URIRef director: URIRef directors: URIRef disambiguatingDescription: URIRef discount: URIRef discountCode: URIRef discountCurrency: URIRef discusses: URIRef discussionUrl: URIRef dissolutionDate: URIRef distance: URIRef distribution: URIRef doorTime: URIRef downloadUrl: URIRef downvoteCount: URIRef driveWheelConfiguration: URIRef dropoffLocation: URIRef dropoffTime: URIRef duns: URIRef duration: URIRef durationOfWarranty: URIRef duringMedia: URIRef editor: URIRef educationalAlignment: URIRef educationalCredentialAwarded: URIRef educationalFramework: URIRef educationalRole: URIRef educationalUse: URIRef elevation: URIRef eligibleCustomerType: URIRef eligibleDuration: URIRef eligibleQuantity: URIRef eligibleRegion: URIRef eligibleTransactionVolume: URIRef email: URIRef embedUrl: URIRef employee: URIRef employees: URIRef employmentType: URIRef encodesCreativeWork: URIRef encoding: URIRef encodingFormat: URIRef encodingType: URIRef encodings: URIRef endDate: URIRef endTime: URIRef endorsee: URIRef entertainmentBusiness: URIRef episode: URIRef episodeNumber: URIRef episodes: URIRef equal: URIRef error: URIRef estimatedCost: URIRef estimatedFlightDuration: URIRef estimatedSalary: URIRef event: URIRef eventStatus: URIRef events: URIRef exampleOfWork: URIRef executableLibraryName: URIRef exerciseCourse: URIRef exifData: URIRef expectedArrivalFrom: URIRef expectedArrivalUntil: URIRef expectsAcceptanceOf: URIRef experienceRequirements: URIRef expires: URIRef familyName: URIRef fatContent: URIRef faxNumber: URIRef featureList: URIRef feesAndCommissionsSpecification: URIRef fiberContent: URIRef fileFormat: URIRef fileSize: URIRef firstPerformance: URIRef flightDistance: URIRef flightNumber: URIRef floorSize: URIRef followee: URIRef follows: URIRef foodEstablishment: URIRef foodEvent: URIRef founder: URIRef founders: URIRef foundingDate: URIRef foundingLocation: URIRef free: URIRef fromLocation: URIRef fuelConsumption: URIRef fuelEfficiency: URIRef fuelType: URIRef funder: URIRef game: URIRef gameItem: URIRef gameLocation: URIRef gamePlatform: URIRef gameServer: URIRef gameTip: URIRef genre: URIRef geo: URIRef geoContains: URIRef geoCoveredBy: URIRef geoCovers: URIRef geoCrosses: URIRef geoDisjoint: URIRef geoEquals: URIRef geoIntersects: URIRef geoMidpoint: URIRef geoOverlaps: URIRef geoRadius: URIRef geoTouches: URIRef geoWithin: URIRef geographicArea: URIRef givenName: URIRef globalLocationNumber: URIRef grantee: URIRef greater: URIRef greaterOrEqual: URIRef gtin12: URIRef gtin13: URIRef gtin14: URIRef gtin8: URIRef hasBroadcastChannel: URIRef hasCourseInstance: URIRef hasDeliveryMethod: URIRef hasDigitalDocumentPermission: URIRef hasMap: URIRef hasMenu: URIRef hasMenuItem: URIRef hasMenuSection: URIRef hasOccupation: URIRef hasOfferCatalog: URIRef hasPOS: URIRef hasPart: URIRef headline: URIRef height: URIRef highPrice: URIRef hiringOrganization: URIRef homeLocation: URIRef homeTeam: URIRef honorificPrefix: URIRef honorificSuffix: URIRef hostingOrganization: URIRef hoursAvailable: URIRef httpMethod: URIRef iataCode: URIRef icaoCode: URIRef identifier: URIRef illustrator: URIRef image: URIRef inAlbum: URIRef inBroadcastLineup: URIRef inLanguage: URIRef inPlaylist: URIRef incentiveCompensation: URIRef incentives: URIRef includedComposition: URIRef includedDataCatalog: URIRef includedInDataCatalog: URIRef includesObject: URIRef industry: URIRef ingredients: URIRef installUrl: URIRef instructor: URIRef instrument: URIRef interactionCount: URIRef interactionService: URIRef interactionStatistic: URIRef interactionType: URIRef interactivityType: URIRef interestRate: URIRef inventoryLevel: URIRef isAccessibleForFree: URIRef isAccessoryOrSparePartFor: URIRef isBasedOn: URIRef isBasedOnUrl: URIRef isConsumableFor: URIRef isFamilyFriendly: URIRef isGift: URIRef isLiveBroadcast: URIRef isPartOf: URIRef isRelatedTo: URIRef isSimilarTo: URIRef isVariantOf: URIRef isbn: URIRef isicV4: URIRef isrcCode: URIRef issn: URIRef issueNumber: URIRef issuedBy: URIRef issuedThrough: URIRef iswcCode: URIRef item: URIRef itemCondition: URIRef itemListElement: URIRef itemListOrder: URIRef itemOffered: URIRef itemReviewed: URIRef itemShipped: URIRef jobBenefits: URIRef jobLocation: URIRef keywords: URIRef knownVehicleDamages: URIRef knows: URIRef landlord: URIRef language: URIRef lastReviewed: URIRef latitude: URIRef learningResourceType: URIRef legalName: URIRef leiCode: URIRef lender: URIRef lesser: URIRef lesserOrEqual: URIRef license: URIRef line: URIRef liveBlogUpdate: URIRef loanTerm: URIRef location: URIRef locationCreated: URIRef lodgingUnitDescription: URIRef lodgingUnitType: URIRef logo: URIRef longitude: URIRef loser: URIRef lowPrice: URIRef lyricist: URIRef lyrics: URIRef mainContentOfPage: URIRef mainEntity: URIRef mainEntityOfPage: URIRef makesOffer: URIRef manufacturer: URIRef map: URIRef mapType: URIRef maps: URIRef material: URIRef maxPrice: URIRef maxValue: URIRef maximumAttendeeCapacity: URIRef mealService: URIRef median: URIRef member: URIRef memberOf: URIRef members: URIRef membershipNumber: URIRef memoryRequirements: URIRef mentions: URIRef menu: URIRef menuAddOn: URIRef merchant: URIRef messageAttachment: URIRef mileageFromOdometer: URIRef minPrice: URIRef minValue: URIRef minimumPaymentDue: URIRef model: URIRef modifiedTime: URIRef mpn: URIRef multipleValues: URIRef musicArrangement: URIRef musicBy: URIRef musicCompositionForm: URIRef musicGroupMember: URIRef musicReleaseFormat: URIRef musicalKey: URIRef naics: URIRef name: URIRef namedPosition: URIRef nationality: URIRef netWorth: URIRef nextItem: URIRef nonEqual: URIRef numAdults: URIRef numChildren: URIRef numTracks: URIRef numberOfAirbags: URIRef numberOfAxles: URIRef numberOfBeds: URIRef numberOfDoors: URIRef numberOfEmployees: URIRef numberOfEpisodes: URIRef numberOfForwardGears: URIRef numberOfItems: URIRef numberOfPages: URIRef numberOfPlayers: URIRef numberOfPreviousOwners: URIRef numberOfRooms: URIRef numberOfSeasons: URIRef numberedPosition: URIRef nutrition: URIRef object: URIRef occupancy: URIRef occupationLocation: URIRef offerCount: URIRef offeredBy: URIRef offers: URIRef openingHours: URIRef openingHoursSpecification: URIRef opens: URIRef operatingSystem: URIRef opponent: URIRef option: URIRef orderDate: URIRef orderDelivery: URIRef orderItemNumber: URIRef orderItemStatus: URIRef orderNumber: URIRef orderQuantity: URIRef orderStatus: URIRef orderedItem: URIRef organizer: URIRef originAddress: URIRef ownedFrom: URIRef ownedThrough: URIRef owns: URIRef pageEnd: URIRef pageStart: URIRef pagination: URIRef parent: URIRef parentItem: URIRef parentOrganization: URIRef parentService: URIRef parents: URIRef partOfEpisode: URIRef partOfInvoice: URIRef partOfOrder: URIRef partOfSeason: URIRef partOfSeries: URIRef partOfTVSeries: URIRef participant: URIRef partySize: URIRef passengerPriorityStatus: URIRef passengerSequenceNumber: URIRef paymentAccepted: URIRef paymentDue: URIRef paymentDueDate: URIRef paymentMethod: URIRef paymentMethodId: URIRef paymentStatus: URIRef paymentUrl: URIRef percentile10: URIRef percentile25: URIRef percentile75: URIRef percentile90: URIRef performTime: URIRef performer: URIRef performerIn: URIRef performers: URIRef permissionType: URIRef permissions: URIRef permitAudience: URIRef permittedUsage: URIRef petsAllowed: URIRef photo: URIRef photos: URIRef pickupLocation: URIRef pickupTime: URIRef playMode: URIRef playerType: URIRef playersOnline: URIRef polygon: URIRef position: URIRef postOfficeBoxNumber: URIRef postalCode: URIRef potentialAction: URIRef predecessorOf: URIRef prepTime: URIRef previousItem: URIRef previousStartDate: URIRef price: URIRef priceComponent: URIRef priceCurrency: URIRef priceRange: URIRef priceSpecification: URIRef priceType: URIRef priceValidUntil: URIRef primaryImageOfPage: URIRef printColumn: URIRef printEdition: URIRef printPage: URIRef printSection: URIRef processingTime: URIRef processorRequirements: URIRef producer: URIRef produces: URIRef productID: URIRef productSupported: URIRef productionCompany: URIRef productionDate: URIRef proficiencyLevel: URIRef programMembershipUsed: URIRef programName: URIRef programmingLanguage: URIRef programmingModel: URIRef propertyID: URIRef proteinContent: URIRef provider: URIRef providerMobility: URIRef providesBroadcastService: URIRef providesService: URIRef publicAccess: URIRef publication: URIRef publishedOn: URIRef publisher: URIRef publishingPrinciples: URIRef purchaseDate: URIRef query: URIRef quest: URIRef question: URIRef ratingCount: URIRef ratingValue: URIRef readonlyValue: URIRef realEstateAgent: URIRef recipe: URIRef recipeCategory: URIRef recipeCuisine: URIRef recipeIngredient: URIRef recipeInstructions: URIRef recipeYield: URIRef recipient: URIRef recordLabel: URIRef recordedAs: URIRef recordedAt: URIRef recordedIn: URIRef recordingOf: URIRef referenceQuantity: URIRef referencesOrder: URIRef regionsAllowed: URIRef relatedLink: URIRef relatedTo: URIRef releaseDate: URIRef releaseNotes: URIRef releaseOf: URIRef releasedEvent: URIRef relevantOccupation: URIRef remainingAttendeeCapacity: URIRef replacee: URIRef replacer: URIRef replyToUrl: URIRef reportNumber: URIRef representativeOfPage: URIRef requiredCollateral: URIRef requiredGender: URIRef requiredMaxAge: URIRef requiredMinAge: URIRef requiredQuantity: URIRef requirements: URIRef requiresSubscription: URIRef reservationFor: URIRef reservationId: URIRef reservationStatus: URIRef reservedTicket: URIRef responsibilities: URIRef result: URIRef resultComment: URIRef resultReview: URIRef review: URIRef reviewAspect: URIRef reviewBody: URIRef reviewCount: URIRef reviewRating: URIRef reviewedBy: URIRef reviews: URIRef roleName: URIRef rsvpResponse: URIRef runtime: URIRef runtimePlatform: URIRef salaryCurrency: URIRef sameAs: URIRef sampleType: URIRef saturatedFatContent: URIRef scheduledPaymentDate: URIRef scheduledTime: URIRef schemaVersion: URIRef screenCount: URIRef screenshot: URIRef season: URIRef seasonNumber: URIRef seasons: URIRef seatNumber: URIRef seatRow: URIRef seatSection: URIRef seatingType: URIRef securityScreening: URIRef seeks: URIRef seller: URIRef sender: URIRef serialNumber: URIRef serverStatus: URIRef servesCuisine: URIRef serviceArea: URIRef serviceAudience: URIRef serviceLocation: URIRef serviceOperator: URIRef serviceOutput: URIRef servicePhone: URIRef servicePostalAddress: URIRef serviceSmsNumber: URIRef serviceType: URIRef serviceUrl: URIRef servingSize: URIRef sharedContent: URIRef sibling: URIRef siblings: URIRef significantLink: URIRef significantLinks: URIRef skills: URIRef sku: URIRef slogan: URIRef smokingAllowed: URIRef sodiumContent: URIRef softwareAddOn: URIRef softwareHelp: URIRef softwareRequirements: URIRef softwareVersion: URIRef sourceOrganization: URIRef spatial: URIRef spatialCoverage: URIRef speakable: URIRef specialCommitments: URIRef specialOpeningHoursSpecification: URIRef specialty: URIRef sponsor: URIRef sportsActivityLocation: URIRef sportsEvent: URIRef sportsTeam: URIRef spouse: URIRef starRating: URIRef startDate: URIRef startTime: URIRef steeringPosition: URIRef step: URIRef stepValue: URIRef steps: URIRef storageRequirements: URIRef streetAddress: URIRef subEvent: URIRef subEvents: URIRef subOrganization: URIRef subReservation: URIRef subjectOf: URIRef successorOf: URIRef sugarContent: URIRef suggestedAnswer: URIRef suggestedGender: URIRef suggestedMaxAge: URIRef suggestedMinAge: URIRef suitableForDiet: URIRef superEvent: URIRef supply: URIRef supportingData: URIRef surface: URIRef target: URIRef targetCollection: URIRef targetDescription: URIRef targetName: URIRef targetPlatform: URIRef targetProduct: URIRef targetUrl: URIRef taxID: URIRef telephone: URIRef temporal: URIRef temporalCoverage: URIRef text: URIRef thumbnail: URIRef thumbnailUrl: URIRef tickerSymbol: URIRef ticketNumber: URIRef ticketToken: URIRef ticketedSeat: URIRef timeRequired: URIRef title: URIRef toLocation: URIRef toRecipient: URIRef tool: URIRef totalPaymentDue: URIRef totalPrice: URIRef totalTime: URIRef touristType: URIRef track: URIRef trackingNumber: URIRef trackingUrl: URIRef tracks: URIRef trailer: URIRef trainName: URIRef trainNumber: URIRef transFatContent: URIRef transcript: URIRef translator: URIRef typeOfBed: URIRef typeOfGood: URIRef typicalAgeRange: URIRef underName: URIRef unitCode: URIRef unitText: URIRef unsaturatedFatContent: URIRef uploadDate: URIRef upvoteCount: URIRef url: URIRef urlTemplate: URIRef userInteractionCount: URIRef validFor: URIRef validFrom: URIRef validIn: URIRef validThrough: URIRef validUntil: URIRef value: URIRef valueAddedTaxIncluded: URIRef valueMaxLength: URIRef valueMinLength: URIRef valueName: URIRef valuePattern: URIRef valueReference: URIRef valueRequired: URIRef vatID: URIRef vehicleConfiguration: URIRef vehicleEngine: URIRef vehicleIdentificationNumber: URIRef vehicleInteriorColor: URIRef vehicleInteriorType: URIRef vehicleModelDate: URIRef vehicleSeatingCapacity: URIRef vehicleTransmission: URIRef vendor: URIRef version: URIRef video: URIRef videoFormat: URIRef videoFrameSize: URIRef videoQuality: URIRef volumeNumber: URIRef warranty: URIRef warrantyPromise: URIRef warrantyScope: URIRef webCheckinTime: URIRef weight: URIRef width: URIRef winner: URIRef wordCount: URIRef workExample: URIRef workFeatured: URIRef workHours: URIRef workLocation: URIRef workPerformed: URIRef workPresented: URIRef worksFor: URIRef worstRating: URIRef xpath: URIRef yearlyRevenue: URIRef yearsInOperation: URIRef AMRadioChannel: URIRef APIReference: URIRef AboutPage: URIRef AcceptAction: URIRef Accommodation: URIRef AccountingService: URIRef AchieveAction: URIRef Action: URIRef ActionAccessSpecification: URIRef ActionStatusType: URIRef ActivateAction: URIRef AddAction: URIRef AdministrativeArea: URIRef AdultEntertainment: URIRef AggregateOffer: URIRef AggregateRating: URIRef AgreeAction: URIRef Airline: URIRef Airport: URIRef AlignmentObject: URIRef AllocateAction: URIRef AmusementPark: URIRef AnimalShelter: URIRef Answer: URIRef Apartment: URIRef ApartmentComplex: URIRef AppendAction: URIRef ApplyAction: URIRef Aquarium: URIRef ArriveAction: URIRef ArtGallery: URIRef Article: URIRef AskAction: URIRef AssessAction: URIRef AssignAction: URIRef Attorney: URIRef Audience: URIRef AudioObject: URIRef AuthorizeAction: URIRef AutoBodyShop: URIRef AutoDealer: URIRef AutoPartsStore: URIRef AutoRental: URIRef AutoRepair: URIRef AutoWash: URIRef AutomatedTeller: URIRef AutomotiveBusiness: URIRef Bakery: URIRef BankAccount: URIRef BankOrCreditUnion: URIRef BarOrPub: URIRef Barcode: URIRef Beach: URIRef BeautySalon: URIRef BedAndBreakfast: URIRef BedDetails: URIRef BedType: URIRef BefriendAction: URIRef BikeStore: URIRef Blog: URIRef BlogPosting: URIRef BoardingPolicyType: URIRef BodyOfWater: URIRef Book: URIRef BookFormatType: URIRef BookSeries: URIRef BookStore: URIRef BookmarkAction: URIRef Boolean: URIRef BorrowAction: URIRef BowlingAlley: URIRef Brand: URIRef BreadcrumbList: URIRef Brewery: URIRef Bridge: URIRef BroadcastChannel: URIRef BroadcastEvent: URIRef BroadcastFrequencySpecification: URIRef BroadcastService: URIRef BuddhistTemple: URIRef BusReservation: URIRef BusStation: URIRef BusStop: URIRef BusTrip: URIRef BusinessAudience: URIRef BusinessEntityType: URIRef BusinessEvent: URIRef BusinessFunction: URIRef BuyAction: URIRef CableOrSatelliteService: URIRef CafeOrCoffeeShop: URIRef Campground: URIRef CampingPitch: URIRef Canal: URIRef CancelAction: URIRef Car: URIRef Casino: URIRef CatholicChurch: URIRef Cemetery: URIRef CheckAction: URIRef CheckInAction: URIRef CheckOutAction: URIRef CheckoutPage: URIRef ChildCare: URIRef ChildrensEvent: URIRef ChooseAction: URIRef Church: URIRef City: URIRef CityHall: URIRef CivicStructure: URIRef ClaimReview: URIRef Clip: URIRef ClothingStore: URIRef Code: URIRef CollectionPage: URIRef CollegeOrUniversity: URIRef ComedyClub: URIRef ComedyEvent: URIRef Comment: URIRef CommentAction: URIRef CommunicateAction: URIRef CompoundPriceSpecification: URIRef ComputerLanguage: URIRef ComputerStore: URIRef ConfirmAction: URIRef ConsumeAction: URIRef ContactPage: URIRef ContactPoint: URIRef ContactPointOption: URIRef Continent: URIRef ControlAction: URIRef ConvenienceStore: URIRef Conversation: URIRef CookAction: URIRef Corporation: URIRef Country: URIRef Course: URIRef CourseInstance: URIRef Courthouse: URIRef CreateAction: URIRef CreativeWork: URIRef CreativeWorkSeason: URIRef CreativeWorkSeries: URIRef CreditCard: URIRef Crematorium: URIRef CurrencyConversionService: URIRef DanceEvent: URIRef DanceGroup: URIRef DataCatalog: URIRef DataDownload: URIRef DataFeed: URIRef DataFeedItem: URIRef DataType: URIRef Dataset: URIRef Date: URIRef DateTime: URIRef DatedMoneySpecification: URIRef DayOfWeek: URIRef DaySpa: URIRef DeactivateAction: URIRef DefenceEstablishment: URIRef DeleteAction: URIRef DeliveryChargeSpecification: URIRef DeliveryEvent: URIRef DeliveryMethod: URIRef Demand: URIRef Dentist: URIRef DepartAction: URIRef DepartmentStore: URIRef DepositAccount: URIRef DigitalDocument: URIRef DigitalDocumentPermission: URIRef DigitalDocumentPermissionType: URIRef DisagreeAction: URIRef DiscoverAction: URIRef DiscussionForumPosting: URIRef DislikeAction: URIRef Distance: URIRef Distillery: URIRef DonateAction: URIRef DownloadAction: URIRef DrawAction: URIRef DrinkAction: URIRef DriveWheelConfigurationValue: URIRef DryCleaningOrLaundry: URIRef Duration: URIRef EatAction: URIRef EducationEvent: URIRef EducationalAudience: URIRef EducationalOrganization: URIRef Electrician: URIRef ElectronicsStore: URIRef ElementarySchool: URIRef EmailMessage: URIRef Embassy: URIRef EmergencyService: URIRef EmployeeRole: URIRef EmployerAggregateRating: URIRef EmploymentAgency: URIRef EndorseAction: URIRef EndorsementRating: URIRef Energy: URIRef EngineSpecification: URIRef EntertainmentBusiness: URIRef EntryPoint: URIRef Enumeration: URIRef Episode: URIRef Event: URIRef EventReservation: URIRef EventStatusType: URIRef EventVenue: URIRef ExerciseAction: URIRef ExerciseGym: URIRef ExhibitionEvent: URIRef FAQPage: URIRef FMRadioChannel: URIRef FastFoodRestaurant: URIRef Festival: URIRef FilmAction: URIRef FinancialProduct: URIRef FinancialService: URIRef FindAction: URIRef FireStation: URIRef Flight: URIRef FlightReservation: URIRef Float: URIRef Florist: URIRef FollowAction: URIRef FoodEstablishment: URIRef FoodEstablishmentReservation: URIRef FoodEvent: URIRef FoodService: URIRef FurnitureStore: URIRef Game: URIRef GamePlayMode: URIRef GameServer: URIRef GameServerStatus: URIRef GardenStore: URIRef GasStation: URIRef GatedResidenceCommunity: URIRef GenderType: URIRef GeneralContractor: URIRef GeoCircle: URIRef GeoCoordinates: URIRef GeoShape: URIRef GiveAction: URIRef GolfCourse: URIRef GovernmentBuilding: URIRef GovernmentOffice: URIRef GovernmentOrganization: URIRef GovernmentPermit: URIRef GovernmentService: URIRef GroceryStore: URIRef HVACBusiness: URIRef HairSalon: URIRef HardwareStore: URIRef HealthAndBeautyBusiness: URIRef HealthClub: URIRef HighSchool: URIRef HinduTemple: URIRef HobbyShop: URIRef HomeAndConstructionBusiness: URIRef HomeGoodsStore: URIRef Hospital: URIRef Hostel: URIRef Hotel: URIRef HotelRoom: URIRef House: URIRef HousePainter: URIRef HowTo: URIRef HowToDirection: URIRef HowToItem: URIRef HowToSection: URIRef HowToStep: URIRef HowToSupply: URIRef HowToTip: URIRef HowToTool: URIRef IceCreamShop: URIRef IgnoreAction: URIRef ImageGallery: URIRef ImageObject: URIRef IndividualProduct: URIRef InformAction: URIRef InsertAction: URIRef InstallAction: URIRef InsuranceAgency: URIRef Intangible: URIRef Integer: URIRef InteractAction: URIRef InteractionCounter: URIRef InternetCafe: URIRef InvestmentOrDeposit: URIRef InviteAction: URIRef Invoice: URIRef ItemAvailability: URIRef ItemList: URIRef ItemListOrderType: URIRef ItemPage: URIRef JewelryStore: URIRef JobPosting: URIRef JoinAction: URIRef LakeBodyOfWater: URIRef Landform: URIRef LandmarksOrHistoricalBuildings: URIRef Language: URIRef LeaveAction: URIRef LegalService: URIRef LegislativeBuilding: URIRef LendAction: URIRef Library: URIRef LikeAction: URIRef LiquorStore: URIRef ListItem: URIRef ListenAction: URIRef LiteraryEvent: URIRef LiveBlogPosting: URIRef LoanOrCredit: URIRef LocalBusiness: URIRef LocationFeatureSpecification: URIRef LockerDelivery: URIRef Locksmith: URIRef LodgingBusiness: URIRef LodgingReservation: URIRef LoseAction: URIRef Map: URIRef MapCategoryType: URIRef MarryAction: URIRef Mass: URIRef MediaGallery: URIRef MediaObject: URIRef MediaSubscription: URIRef MedicalOrganization: URIRef MeetingRoom: URIRef MensClothingStore: URIRef Menu: URIRef MenuItem: URIRef MenuSection: URIRef Message: URIRef MiddleSchool: URIRef MobileApplication: URIRef MobilePhoneStore: URIRef MonetaryAmount: URIRef MonetaryAmountDistribution: URIRef Mosque: URIRef Motel: URIRef MotorcycleDealer: URIRef MotorcycleRepair: URIRef Mountain: URIRef MoveAction: URIRef Movie: URIRef MovieClip: URIRef MovieRentalStore: URIRef MovieSeries: URIRef MovieTheater: URIRef MovingCompany: URIRef Museum: URIRef MusicAlbum: URIRef MusicAlbumProductionType: URIRef MusicAlbumReleaseType: URIRef MusicComposition: URIRef MusicEvent: URIRef MusicGroup: URIRef MusicPlaylist: URIRef MusicRecording: URIRef MusicRelease: URIRef MusicReleaseFormatType: URIRef MusicStore: URIRef MusicVenue: URIRef MusicVideoObject: URIRef NGO: URIRef NailSalon: URIRef NewsArticle: URIRef NightClub: URIRef Notary: URIRef NoteDigitalDocument: URIRef Number: URIRef NutritionInformation: URIRef Occupation: URIRef OceanBodyOfWater: URIRef Offer: URIRef OfferCatalog: URIRef OfferItemCondition: URIRef OfficeEquipmentStore: URIRef OnDemandEvent: URIRef OpeningHoursSpecification: URIRef Order: URIRef OrderAction: URIRef OrderItem: URIRef OrderStatus: URIRef Organization: URIRef OrganizationRole: URIRef OrganizeAction: URIRef OutletStore: URIRef OwnershipInfo: URIRef PaintAction: URIRef Painting: URIRef ParcelDelivery: URIRef ParcelService: URIRef ParentAudience: URIRef Park: URIRef ParkingFacility: URIRef PawnShop: URIRef PayAction: URIRef PaymentCard: URIRef PaymentChargeSpecification: URIRef PaymentMethod: URIRef PaymentService: URIRef PaymentStatusType: URIRef PeopleAudience: URIRef PerformAction: URIRef PerformanceRole: URIRef PerformingArtsTheater: URIRef PerformingGroup: URIRef Periodical: URIRef Permit: URIRef Person: URIRef PetStore: URIRef Pharmacy: URIRef Photograph: URIRef PhotographAction: URIRef Physician: URIRef Place: URIRef PlaceOfWorship: URIRef PlanAction: URIRef PlayAction: URIRef Playground: URIRef Plumber: URIRef PoliceStation: URIRef Pond: URIRef PostOffice: URIRef PostalAddress: URIRef PreOrderAction: URIRef PrependAction: URIRef Preschool: URIRef PresentationDigitalDocument: URIRef PriceSpecification: URIRef Product: URIRef ProductModel: URIRef ProfessionalService: URIRef ProfilePage: URIRef ProgramMembership: URIRef PropertyValue: URIRef PropertyValueSpecification: URIRef PublicSwimmingPool: URIRef PublicationEvent: URIRef PublicationIssue: URIRef PublicationVolume: URIRef QAPage: URIRef QualitativeValue: URIRef QuantitativeValue: URIRef QuantitativeValueDistribution: URIRef Quantity: URIRef Question: URIRef QuoteAction: URIRef RVPark: URIRef RadioChannel: URIRef RadioClip: URIRef RadioEpisode: URIRef RadioSeason: URIRef RadioSeries: URIRef RadioStation: URIRef Rating: URIRef ReactAction: URIRef ReadAction: URIRef RealEstateAgent: URIRef ReceiveAction: URIRef Recipe: URIRef RecyclingCenter: URIRef RegisterAction: URIRef RejectAction: URIRef RentAction: URIRef RentalCarReservation: URIRef ReplaceAction: URIRef ReplyAction: URIRef Report: URIRef Reservation: URIRef ReservationPackage: URIRef ReservationStatusType: URIRef ReserveAction: URIRef Reservoir: URIRef Residence: URIRef Resort: URIRef Restaurant: URIRef RestrictedDiet: URIRef ResumeAction: URIRef ReturnAction: URIRef Review: URIRef ReviewAction: URIRef RiverBodyOfWater: URIRef Role: URIRef RoofingContractor: URIRef Room: URIRef RsvpAction: URIRef RsvpResponseType: URIRef SaleEvent: URIRef ScheduleAction: URIRef ScholarlyArticle: URIRef School: URIRef ScreeningEvent: URIRef Sculpture: URIRef SeaBodyOfWater: URIRef SearchAction: URIRef SearchResultsPage: URIRef Season: URIRef Seat: URIRef SelfStorage: URIRef SellAction: URIRef SendAction: URIRef Series: URIRef Service: URIRef ServiceChannel: URIRef ShareAction: URIRef ShoeStore: URIRef ShoppingCenter: URIRef SingleFamilyResidence: URIRef SiteNavigationElement: URIRef SkiResort: URIRef SocialEvent: URIRef SocialMediaPosting: URIRef SoftwareApplication: URIRef SoftwareSourceCode: URIRef SomeProducts: URIRef SpeakableSpecification: URIRef Specialty: URIRef SportingGoodsStore: URIRef SportsActivityLocation: URIRef SportsClub: URIRef SportsEvent: URIRef SportsOrganization: URIRef SportsTeam: URIRef SpreadsheetDigitalDocument: URIRef StadiumOrArena: URIRef State: URIRef SteeringPositionValue: URIRef Store: URIRef StructuredValue: URIRef SubscribeAction: URIRef SubwayStation: URIRef Suite: URIRef SuspendAction: URIRef Synagogue: URIRef TVClip: URIRef TVEpisode: URIRef TVSeason: URIRef TVSeries: URIRef Table: URIRef TakeAction: URIRef TattooParlor: URIRef Taxi: URIRef TaxiReservation: URIRef TaxiService: URIRef TaxiStand: URIRef TechArticle: URIRef TelevisionChannel: URIRef TelevisionStation: URIRef TennisComplex: URIRef Text: URIRef TextDigitalDocument: URIRef TheaterEvent: URIRef TheaterGroup: URIRef Thing: URIRef Ticket: URIRef TieAction: URIRef Time: URIRef TipAction: URIRef TireShop: URIRef TouristAttraction: URIRef TouristInformationCenter: URIRef ToyStore: URIRef TrackAction: URIRef TradeAction: URIRef TrainReservation: URIRef TrainStation: URIRef TrainTrip: URIRef TransferAction: URIRef TravelAction: URIRef TravelAgency: URIRef Trip: URIRef TypeAndQuantityNode: URIRef URL: URIRef UnRegisterAction: URIRef UnitPriceSpecification: URIRef UpdateAction: URIRef UseAction: URIRef UserBlocks: URIRef UserCheckins: URIRef UserComments: URIRef UserDownloads: URIRef UserInteraction: URIRef UserLikes: URIRef UserPageVisits: URIRef UserPlays: URIRef UserPlusOnes: URIRef UserTweets: URIRef Vehicle: URIRef VideoGallery: URIRef VideoGame: URIRef VideoGameClip: URIRef VideoGameSeries: URIRef VideoObject: URIRef ViewAction: URIRef VisualArtsEvent: URIRef VisualArtwork: URIRef Volcano: URIRef VoteAction: URIRef WPAdBlock: URIRef WPFooter: URIRef WPHeader: URIRef WPSideBar: URIRef WantAction: URIRef WarrantyPromise: URIRef WarrantyScope: URIRef WatchAction: URIRef Waterfall: URIRef WearAction: URIRef WebApplication: URIRef WebPage: URIRef WebPageElement: URIRef WebSite: URIRef WholesaleStore: URIRef WinAction: URIRef Winery: URIRef WorkersUnion: URIRef WriteAction: URIRef Zoo: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_SH.pyi0000644000175000017500000001154514555736633023034 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class SH(DefinedNamespace): alternativePath: URIRef annotationProperty: URIRef annotationValue: URIRef annotationVarName: URIRef ask: URIRef closed: URIRef condition: URIRef conforms: URIRef construct: URIRef datatype: URIRef deactivated: URIRef declare: URIRef defaultValue: URIRef description: URIRef detail: URIRef disjoint: URIRef entailment: URIRef equals: URIRef expression: URIRef filterShape: URIRef flags: URIRef focusNode: URIRef group: URIRef hasValue: URIRef ignoredProperties: URIRef intersection: URIRef inversePath: URIRef js: URIRef jsFunctionName: URIRef jsLibrary: URIRef jsLibraryURL: URIRef labelTemplate: URIRef languageIn: URIRef lessThan: URIRef lessThanOrEquals: URIRef maxCount: URIRef maxExclusive: URIRef maxInclusive: URIRef maxLength: URIRef message: URIRef minCount: URIRef minExclusive: URIRef minInclusive: URIRef minLength: URIRef name: URIRef namespace: URIRef node: URIRef nodeKind: URIRef nodeValidator: URIRef nodes: URIRef object: URIRef oneOrMorePath: URIRef optional: URIRef order: URIRef parameter: URIRef path: URIRef pattern: URIRef predicate: URIRef prefix: URIRef prefixes: URIRef property: URIRef propertyValidator: URIRef qualifiedMaxCount: URIRef qualifiedMinCount: URIRef qualifiedValueShape: URIRef qualifiedValueShapesDisjoint: URIRef result: URIRef resultAnnotation: URIRef resultMessage: URIRef resultPath: URIRef resultSeverity: URIRef returnType: URIRef rule: URIRef select: URIRef severity: URIRef shapesGraph: URIRef shapesGraphWellFormed: URIRef sourceConstraint: URIRef sourceConstraintComponent: URIRef sourceShape: URIRef sparql: URIRef subject: URIRef suggestedShapesGraph: URIRef target: URIRef targetClass: URIRef targetNode: URIRef targetObjectsOf: URIRef targetSubjectsOf: URIRef union: URIRef uniqueLang: URIRef update: URIRef validator: URIRef value: URIRef xone: URIRef zeroOrMorePath: URIRef zeroOrOnePath: URIRef AbstractResult: URIRef ConstraintComponent: URIRef Function: URIRef JSConstraint: URIRef JSExecutable: URIRef JSFunction: URIRef JSLibrary: URIRef JSRule: URIRef JSTarget: URIRef JSTargetType: URIRef JSValidator: URIRef NodeKind: URIRef NodeShape: URIRef Parameter: URIRef Parameterizable: URIRef PrefixDeclaration: URIRef PropertyGroup: URIRef PropertyShape: URIRef ResultAnnotation: URIRef Rule: URIRef SPARQLAskExecutable: URIRef SPARQLAskValidator: URIRef SPARQLConstraint: URIRef SPARQLConstructExecutable: URIRef SPARQLExecutable: URIRef SPARQLFunction: URIRef SPARQLRule: URIRef SPARQLSelectExecutable: URIRef SPARQLSelectValidator: URIRef SPARQLTarget: URIRef SPARQLTargetType: URIRef SPARQLUpdateExecutable: URIRef Severity: URIRef Shape: URIRef Target: URIRef TargetType: URIRef TripleRule: URIRef ValidationReport: URIRef ValidationResult: URIRef Validator: URIRef this: URIRef AndConstraintComponent: URIRef ClassConstraintComponent: URIRef ClosedConstraintComponent: URIRef DatatypeConstraintComponent: URIRef DisjointConstraintComponent: URIRef EqualsConstraintComponent: URIRef ExpressionConstraintComponent: URIRef HasValueConstraintComponent: URIRef InConstraintComponent: URIRef JSConstraintComponent: URIRef LanguageInConstraintComponent: URIRef LessThanConstraintComponent: URIRef LessThanOrEqualsConstraintComponent: URIRef MaxCountConstraintComponent: URIRef MaxExclusiveConstraintComponent: URIRef MaxInclusiveConstraintComponent: URIRef MaxLengthConstraintComponent: URIRef MinCountConstraintComponent: URIRef MinExclusiveConstraintComponent: URIRef MinInclusiveConstraintComponent: URIRef MinLengthConstraintComponent: URIRef NodeConstraintComponent: URIRef NodeKindConstraintComponent: URIRef NotConstraintComponent: URIRef OrConstraintComponent: URIRef PatternConstraintComponent: URIRef PropertyConstraintComponent: URIRef QualifiedMaxCountConstraintComponent: URIRef QualifiedMinCountConstraintComponent: URIRef SPARQLConstraintComponent: URIRef UniqueLangConstraintComponent: URIRef XoneConstraintComponent: URIRef BlankNode: URIRef BlankNodeOrIRI: URIRef BlankNodeOrLiteral: URIRef IRI: URIRef IRIOrLiteral: URIRef Literal: URIRef Info: URIRef Violation: URIRef Warning: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_SKOS.pyi0000644000175000017500000000165714555736633023304 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class SKOS(DefinedNamespace): altLabel: URIRef broadMatch: URIRef broader: URIRef broaderTransitive: URIRef changeNote: URIRef closeMatch: URIRef definition: URIRef editorialNote: URIRef exactMatch: URIRef example: URIRef hasTopConcept: URIRef hiddenLabel: URIRef historyNote: URIRef inScheme: URIRef mappingRelation: URIRef member: URIRef memberList: URIRef narrowMatch: URIRef narrower: URIRef narrowerTransitive: URIRef notation: URIRef note: URIRef prefLabel: URIRef related: URIRef relatedMatch: URIRef scopeNote: URIRef semanticRelation: URIRef topConceptOf: URIRef Collection: URIRef Concept: URIRef ConceptScheme: URIRef OrderedCollection: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_SOSA.pyi0000644000175000017500000000206314555736633023262 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class SOSA(DefinedNamespace): ActuatableProperty: URIRef Actuation: URIRef Actuator: URIRef FeatureOfInterest: URIRef ObservableProperty: URIRef Observation: URIRef Platform: URIRef Procedure: URIRef Result: URIRef Sample: URIRef Sampler: URIRef Sampling: URIRef Sensor: URIRef hasSimpleResult: URIRef resultTime: URIRef actsOnProperty: URIRef hasFeatureOfInterest: URIRef hasResult: URIRef hasSample: URIRef hosts: URIRef isActedOnBy: URIRef isFeatureOfInterestOf: URIRef isHostedBy: URIRef isObservedBy: URIRef isResultOf: URIRef isSampleOf: URIRef madeActuation: URIRef madeByActuator: URIRef madeBySampler: URIRef madeBySensor: URIRef madeObservation: URIRef madeSampling: URIRef observedProperty: URIRef observes: URIRef phenomenonTime: URIRef usedProcedure: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_SSN.pyi0000644000175000017500000000125014555736633023155 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class SSN(DefinedNamespace): Deployment: URIRef Input: URIRef Output: URIRef Property: URIRef Stimulus: URIRef System: URIRef wasOriginatedBy: URIRef deployedOnPlatform: URIRef deployedSystem: URIRef detects: URIRef forProperty: URIRef hasDeployment: URIRef hasInput: URIRef hasOutput: URIRef hasProperty: URIRef hasSubSystem: URIRef implementedBy: URIRef implements: URIRef inDeployment: URIRef isPropertyOf: URIRef isProxyFor: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_TIME.pyi0000644000175000017500000000463614555736633023263 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class TIME(DefinedNamespace): generalDay: URIRef generalMonth: URIRef generalYear: URIRef DateTimeDescription: URIRef DateTimeInterval: URIRef DayOfWeek: URIRef Duration: URIRef DurationDescription: URIRef GeneralDateTimeDescription: URIRef GeneralDurationDescription: URIRef Instant: URIRef Interval: URIRef MonthOfYear: URIRef ProperInterval: URIRef TRS: URIRef TemporalDuration: URIRef TemporalEntity: URIRef TemporalPosition: URIRef TemporalUnit: URIRef TimePosition: URIRef TimeZone: URIRef day: URIRef dayOfYear: URIRef days: URIRef hasXSDDuration: URIRef hour: URIRef hours: URIRef inXSDDate: URIRef inXSDDateTimeStamp: URIRef inXSDgYear: URIRef inXSDgYearMonth: URIRef minute: URIRef minutes: URIRef month: URIRef months: URIRef nominalPosition: URIRef numericDuration: URIRef numericPosition: URIRef second: URIRef seconds: URIRef week: URIRef weeks: URIRef year: URIRef years: URIRef January: URIRef Year: URIRef inXSDDateTime: URIRef xsdDateTime: URIRef hasTRS: URIRef after: URIRef dayOfWeek: URIRef hasBeginning: URIRef hasDateTimeDescription: URIRef hasDuration: URIRef hasDurationDescription: URIRef hasEnd: URIRef hasTemporalDuration: URIRef hasTime: URIRef inDateTime: URIRef inTemporalPosition: URIRef inTimePosition: URIRef inside: URIRef intervalAfter: URIRef intervalBefore: URIRef intervalContains: URIRef intervalDisjoint: URIRef intervalDuring: URIRef intervalEquals: URIRef intervalFinishedBy: URIRef intervalFinishes: URIRef intervalIn: URIRef intervalMeets: URIRef intervalMetBy: URIRef intervalOverlappedBy: URIRef intervalOverlaps: URIRef intervalStartedBy: URIRef intervalStarts: URIRef monthOfYear: URIRef timeZone: URIRef unitType: URIRef before: URIRef Friday: URIRef Monday: URIRef Saturday: URIRef Sunday: URIRef Thursday: URIRef Tuesday: URIRef Wednesday: URIRef unitDay: URIRef unitHour: URIRef unitMinute: URIRef unitMonth: URIRef unitSecond: URIRef unitWeek: URIRef unitYear: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_VOID.pyi0000644000175000017500000000163714555736633023264 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class VOID(DefinedNamespace): classPartition: URIRef classes: URIRef dataDump: URIRef distinctObjects: URIRef distinctSubjects: URIRef documents: URIRef entities: URIRef exampleResource: URIRef feature: URIRef inDataset: URIRef linkPredicate: URIRef objectsTarget: URIRef openSearchDescription: URIRef properties: URIRef property: URIRef propertyPartition: URIRef rootResource: URIRef sparqlEndpoint: URIRef subjectsTarget: URIRef subset: URIRef target: URIRef triples: URIRef uriLookupEndpoint: URIRef uriRegexPattern: URIRef uriSpace: URIRef vocabulary: URIRef Dataset: URIRef DatasetDescription: URIRef Linkset: URIRef TechnicalFeature: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/_XSD.pyi0000644000175000017500000000331614555736633023155 0ustar00michaelmichaelfrom rdflib.namespace import DefinedNamespace as DefinedNamespace from rdflib.namespace import Namespace as Namespace from rdflib.term import URIRef as URIRef class XSD(DefinedNamespace): ENTITIES: URIRef ENTITY: URIRef ID: URIRef IDREF: URIRef IDREFS: URIRef NCName: URIRef NMTOKEN: URIRef NMTOKENS: URIRef NOTATION: URIRef Name: URIRef QName: URIRef anyURI: URIRef base64Binary: URIRef boolean: URIRef byte: URIRef date: URIRef dateTime: URIRef dateTimeStamp: URIRef dayTimeDuration: URIRef decimal: URIRef double: URIRef duration: URIRef float: URIRef gDay: URIRef gMonth: URIRef gMonthDay: URIRef gYear: URIRef gYearMonth: URIRef hexBinary: URIRef int: URIRef integer: URIRef language: URIRef long: URIRef negativeInteger: URIRef nonNegativeInteger: URIRef nonPositiveInteger: URIRef normalizedString: URIRef positiveInteger: URIRef short: URIRef string: URIRef time: URIRef token: URIRef unsignedByte: URIRef unsignedInt: URIRef unsignedLong: URIRef unsignedShort: URIRef yearMonthDuration: URIRef ordered: URIRef bounded: URIRef cardinality: URIRef numeric: URIRef length: URIRef minLength: URIRef maxLength: URIRef pattern: URIRef enumeration: URIRef whiteSpace: URIRef maxExclusive: URIRef maxInclusive: URIRef minExclusive: URIRef minInclusive: URIRef totalDigits: URIRef fractionDigits: URIRef Assertions: URIRef explicitTimezone: URIRef year: URIRef month: URIRef day: URIRef hour: URIRef minute: URIRef second: URIRef timezoneOffset: URIRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/namespace/__init__.pyi0000644000175000017500000000435214555736633024120 0ustar00michaelmichaelfrom typing import Any, Tuple from rdflib.term import URIRef __all__ = [ "split_uri", "Namespace", "ClosedNamespace", "RDF", "RDFS", "CSVW", "DC", "DCAT", "DCTERMS", "DOAP", "FOAF", "ODRL2", "ORG", "OWL", "PROF", "PROV", "QB", "SDO", "SH", "SKOS", "SOSA", "SSN", "TIME", "VOID", "XSD", "OWL", ] class Namespace(str): @property def title(self) -> URIRef: ... # type: ignore[override] def term(self, name: Any) -> URIRef: ... def __getitem__(self, key: Any) -> URIRef: ... def __getattr__(self, name: str) -> URIRef: ... class URIPattern(str): def format(self, *args: Any, **kwargs: Any) -> str: ... class DefinedNamespaceMeta(type): def __getitem__(cls, name: Any, default: Any | None = ...) -> URIRef: ... def __getattr__(cls, name: Any) -> URIRef: ... def __contains__(cls, item: Any) -> bool: ... class DefinedNamespace(metaclass=DefinedNamespaceMeta): def __init__(self) -> None: ... class ClosedNamespace(Namespace): def __new__(cls, uri: Any, terms: Any) -> ClosedNamespace: ... @property def uri(self) -> str: ... NAME_START_CATEGORIES = ["Ll", "Lu", "Lo", "Lt", "Nl"] SPLIT_START_CATEGORIES = NAME_START_CATEGORIES + ["Nd"] XMLNS = "http://www.w3.org/XML/1998/namespace" def split_uri(uri: Any, split_start: Any = ...) -> Tuple[str, str]: ... from rdflib.namespace._CSVW import CSVW from rdflib.namespace._DC import DC from rdflib.namespace._DCAT import DCAT from rdflib.namespace._DCTERMS import DCTERMS from rdflib.namespace._DOAP import DOAP from rdflib.namespace._FOAF import FOAF from rdflib.namespace._ODRL2 import ODRL2 from rdflib.namespace._ORG import ORG from rdflib.namespace._OWL import OWL from rdflib.namespace._PROF import PROF from rdflib.namespace._PROV import PROV from rdflib.namespace._QB import QB from rdflib.namespace._RDF import RDF from rdflib.namespace._RDFS import RDFS from rdflib.namespace._SDO import SDO from rdflib.namespace._SH import SH from rdflib.namespace._SKOS import SKOS from rdflib.namespace._SOSA import SOSA from rdflib.namespace._SSN import SSN from rdflib.namespace._TIME import TIME from rdflib.namespace._VOID import VOID from rdflib.namespace._XSD import XSD ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/parser.pyi0000644000175000017500000000020314555736633021710 0ustar00michaelmichaelfrom typing import Any class Parser: def __init__(self) -> None: ... def parse(self, source: Any, sink: Any) -> None: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/paths.pyi0000644000175000017500000000132414555736633021540 0ustar00michaelmichaelfrom collections.abc import Generator from typing import Any, Callable, Union from rdflib.term import Node as Node from rdflib.term import URIRef as URIRef ZeroOrMore: str OneOrMore: str ZeroOrOne: str class Path: __or__: Callable[[Path, Union["URIRef", "Path"]], "AlternativePath"] __invert__: Callable[[Path], "InvPath"] __neg__: Callable[[Path], "NegatedPath"] __truediv__: Callable[[Path, Union["URIRef", "Path"]], "SequencePath"] __mul__: Callable[[Path, str], "MulPath"] def __hash__(self) -> int: ... def __lt__(self, other: Any) -> bool: ... class InvPath(Path): ... class SequencePath(Path): ... class AlternativePath(Path): ... class MulPath(Path): ... class NegatedPath(Path): ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/plugin.pyi0000644000175000017500000000044014555736633021715 0ustar00michaelmichaelfrom typing import Any, Type, TypeVar def register(name: str, kind: Any, module_path: str, class_name: str) -> None: ... PluginT = TypeVar("PluginT") def get(name: str, kind: Type[PluginT]) -> Type[PluginT]: ... def plugins(name: Any | None = ..., kind: Any | None = ...) -> None: ... ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1706540611.685288 cwltest-2.4.20240129145612/mypy-stubs/rdflib/plugins/0000755000175000017500000000000014555737104021351 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/plugins/__init__.pyi0000644000175000017500000000016614555736633023644 0ustar00michaelmichael# Stubs for rdflib.plugins (Python 3.5) # # NOTE: This dynamically typed stub was automatically generated by stubgen. ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1706540611.685288 cwltest-2.4.20240129145612/mypy-stubs/rdflib/plugins/parsers/0000755000175000017500000000000014555737104023030 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/plugins/parsers/__init__.pyi0000644000175000017500000000017614555736633025324 0ustar00michaelmichael# Stubs for rdflib.plugins.parsers (Python 3.5) # # NOTE: This dynamically typed stub was automatically generated by stubgen. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/plugins/parsers/notation3.pyi0000644000175000017500000000004214555736633025473 0ustar00michaelmichaelclass BadSyntax(SyntaxError): ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/query.pyi0000644000175000017500000000251214555736633021566 0ustar00michaelmichaelfrom typing import IO, Any, Dict, Iterator, List, Mapping, Optional, Tuple, overload from rdflib import URIRef, Variable from rdflib.term import Identifier from typing_extensions import SupportsIndex class ResultRow(Tuple["Identifier", ...]): def __new__( cls, values: Mapping[Variable, Identifier], labels: List[Variable] ) -> ResultRow: ... def __getattr__(self, name: str) -> Identifier: ... @overload def __getitem__(self, name: str) -> Identifier: ... @overload def __getitem__(self, __x: SupportsIndex) -> Identifier: ... @overload def __getitem__(self, __x: slice) -> Tuple[Identifier, ...]: ... def get(self, name: str, default: Any | None = ...) -> Identifier: ... def asdict(self) -> Dict[str, Identifier]: ... class Result: type: Any vars: Any askAnswer: Any graph: Any def __init__(self, type_: str) -> None: ... bindings: Any def __iter__(self) -> Iterator[bool | ResultRow]: ... @staticmethod def parse( source: IO[Any] | None = ..., format: str | None = ..., content_type: str | None = ..., **kwargs: Any, ) -> Result: ... def serialize( self, destination: str | IO[Any] | None = ..., encoding: str = ..., format: str = ..., **args: Any, ) -> Optional[bytes]: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/resource.pyi0000644000175000017500000000256614555736633022261 0ustar00michaelmichaelfrom typing import Any, Iterable, Iterator, Tuple from _typeshed import Incomplete from rdflib.graph import Graph, Seq from rdflib.term import Node class Resource: def __init__(self, graph: Graph, subject: Node) -> None: ... graph: Incomplete identifier: Incomplete def add(self, p: Node, o: Node) -> None: ... def remove(self, p: Node, o: Node | None = ...) -> None: ... def set(self, p: Node, o: Node) -> None: ... def subjects(self, predicate: Any | None = ...) -> Iterable[Node]: ... def predicates(self, o: Incomplete | None = ...) -> Iterable[Node]: ... def objects(self, predicate: Any | None = ...) -> Iterable[Node]: ... def subject_predicates(self) -> Iterator[Tuple[Node, Node]]: ... def subject_objects(self) -> Iterator[Tuple[Node, Node]]: ... def predicate_objects(self) -> Iterator[Tuple[Node, Node]]: ... def value( self, p: Node, o: Node | None = ..., default: Any | None = ..., any: bool = ... ) -> Any: ... def label(self) -> Any: ... def comment(self) -> Any: ... def items(self) -> Iterator[Any]: ... def transitive_objects( self, predicate: Node, remember: Any | None = ... ) -> Iterator[Any]: ... def transitive_subjects( self, predicate: Node, remember: Any | None = ... ) -> Iterator[Any]: ... def seq(self) -> Seq | None: ... def qname(self) -> Any: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/rdflib/term.pyi0000644000175000017500000000247114555736633021374 0ustar00michaelmichaelfrom typing import Any, Callable, Union class Node: ... class Identifier(Node, str): def __new__(cls, value: Union[Any, str, None]) -> "Identifier": ... def eq(self, other: Any) -> bool: ... def neq(self, other: Any) -> bool: ... class IdentifiedNode(Identifier): ... class URIRef(IdentifiedNode): def toPython(self) -> str: ... def n3(self, namespace_manager: Any | None = ...) -> str: ... def defrag(self) -> "URIRef": ... def de_skolemize(self) -> "BNode": ... class Genid(URIRef): ... class RDFLibGenid(Genid): ... class BNode(IdentifiedNode): def toPython(self) -> str: ... def n3(self, namespace_manager: Any | None = ...) -> str: ... def skolemize( self, authority: Any | None = ..., basepath: Any | None = ... ) -> "RDFLibGenid": ... class Literal(Identifier): def normalize(self) -> "Literal": ... @property def value(self) -> Any: ... @property def language(self) -> str | None: ... @property def datatype(self) -> Any: ... def eq(self, other: Any) -> bool: ... def neq(self, other: Any) -> bool: ... def n3(self, namespace_manager: Any | None = ...) -> str: ... def toPython(self) -> str: ... class Variable(Identifier): def toPython(self) -> str: ... def n3(self, namespace_manager: Any | None = ...) -> str: ... ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1706540611.685288 cwltest-2.4.20240129145612/mypy-stubs/ruamel/0000755000175000017500000000000014555737104017713 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy-stubs/ruamel/__init__.pyi0000644000175000017500000000000014555736633022171 0ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/mypy.ini0000644000175000017500000000107014555736633015775 0ustar00michaelmichael[mypy] show_error_context = true show_column_numbers = true show_error_codes = true pretty = true # --strict options as of mypy 0.910 warn_unused_configs = True disallow_any_generics = True disallow_subclassing_any = True disallow_untyped_calls = True disallow_untyped_defs = True disallow_incomplete_defs = True check_untyped_defs = True disallow_untyped_decorators = True no_implicit_optional = True warn_redundant_casts = True warn_unused_ignores = True warn_return_any = True implicit_reexport = False strict_equality = True [mypy-ruamel.*] ignore_errors = True ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/pyproject.toml0000644000175000017500000000345714555736633017225 0ustar00michaelmichael[build-system] requires = [ "setuptools>=61.2", "setuptools_scm>=8.0.4,<9", ] build-backend = "setuptools.build_meta" [project] name = "cwltest" authors = [{name = "Common workflow language working group", email = "common-workflow-language@googlegroups.com"}] license = {text = "Apache 2.0"} description = "Common Workflow Language testing framework" classifiers = [ "Environment :: Console", "Framework :: Pytest", "License :: OSI Approved :: Apache Software License", "Operating System :: POSIX", "Operating System :: MacOS :: MacOS X", "Development Status :: 5 - Production/Stable", "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", "Typing :: Typed", ] requires-python = ">=3.8,<3.13" dynamic = ["version", "dependencies"] [project.readme] file = "README.rst" content-type = "text/x-rst" [project.urls] Homepage = "https://github.com/common-workflow-language/cwltest" Download = "https://github.com/common-workflow-language/cwltest" [project.entry-points.pytest11] cwl = "cwltest.plugin" [project.optional-dependencies] pytest-plugin = ["pytest"] [project.scripts] cwltest = "cwltest.main:main" [tool.aliases] test = "pytest" [tool.setuptools] package-dir = {"cwltest.tests" = "tests"} packages = ["cwltest", "cwltest.tests"] zip-safe = true include-package-data = true [tool.setuptools.package-data] cwltest = ["py.typed"] tests = ["test-data/*"] [tool.setuptools.dynamic] dependencies = {file = ["requirements.txt"]} [tool.isort] multi_line_output = "3" include_trailing_comma = "True" force_grid_wrap = "0" use_parentheses = "True" line_length = "88" [tool.setuptools_scm] write_to = "cwltest/_version.py" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/release-test.sh0000755000175000017500000000665014555736633017243 0ustar00michaelmichael#!/bin/bash set -e set -x export LC_ALL=C package=cwltest module=cwltest extras="" if [ "$GITHUB_ACTIONS" = "true" ]; then # We are running as a GH Action repo=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git HEAD=${GITHUB_REF} else repo=https://github.com/common-workflow-language/cwltest.git HEAD=$(git rev-parse HEAD) fi run_tests="bin/py.test -p pytester --pyargs ${module}" pipver=23.1 # minimum required version of pip for Python 3.12 setuptoolsver=67.6.1 # required for Python 3.12 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" rm -Rf testenv? || /bin/true if [ "${RELEASE_SKIP}" != "head" ] then python3 -m venv testenv1 # First we test the head # shellcheck source=/dev/null source testenv1/bin/activate rm -Rf testenv1/local rm -f testenv1/lib/python-wheels/setuptools* \ && pip install --force-reinstall -U pip==${pipver} \ && pip install setuptools==${setuptoolsver} wheel pip install -rtest-requirements.txt ".${extras}" make test pip uninstall -y ${package} || true; pip uninstall -y ${package} || true; make install mkdir testenv1/not-${module} # if there is a subdir named '${module}' py.test will execute tests # there instead of the installed module's tests pushd testenv1/not-${module} # shellcheck disable=SC2086 ../${run_tests}; popd fi python3 -m venv testenv2 python3 -m venv testenv3 python3 -m venv testenv4 python3 -m venv testenv5 rm -Rf testenv[2345]/local # Secondly we test via pip pushd testenv2 # shellcheck source=/dev/null source bin/activate rm -f lib/python-wheels/setuptools* \ && pip install --force-reinstall -U pip==${pipver} \ && pip install setuptools==${setuptoolsver} wheel # The following can fail if you haven't pushed your commits to ${repo} pip install -e "git+${repo}@${HEAD}#egg=${package}${extras}" pushd src/${package} pip install -rtest-requirements.txt build make dist make test cp dist/${package}*tar.gz ../../../testenv3/ cp dist/${module}*whl ../../../testenv4/ pip uninstall -y ${package} || true; pip uninstall -y ${package} || true; make install popd # ../.. no subdir named ${proj} here, safe for py.testing the installed module # shellcheck disable=SC2086 ${run_tests} popd # Is the source distribution in testenv2 complete enough to build # another functional distribution? pushd testenv3/ # shellcheck source=/dev/null source bin/activate rm -f lib/python-wheels/setuptools* \ && pip install --force-reinstall -U pip==${pipver} \ && pip install setuptools==${setuptoolsver} wheel package_tar=$(find . -name "${package}*tar.gz") pip install "-r${DIR}/test-requirements.txt" build pip install "${package_tar}${extras}" mkdir out tar --extract --directory=out -z -f ${package}*.tar.gz pushd out/${package}* make dist make test pip install "-r${DIR}/mypy-requirements.txt" make mypy pip uninstall -y ${package} || true; pip uninstall -y ${package} || true; make install mkdir ../not-${module} pushd ../not-${module} # shellcheck disable=SC2086 ../../${run_tests}; popd popd popd # Is the wheel in testenv2 installable and will it pass the tests pushd testenv4/ # shellcheck source=/dev/null source bin/activate rm -f lib/python-wheels/setuptools* \ && pip install --force-reinstall -U pip==${pipver} \ && pip install setuptools==${setuptoolsver} wheel pip install "$(ls ${module}*.whl)${extras}" pip install "-r${DIR}/test-requirements.txt" mkdir not-${module} pushd not-${module} # shellcheck disable=SC2086 ../${run_tests}; popd popd ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/requirements.txt0000644000175000017500000000020314555736633017557 0ustar00michaelmichaelschema-salad >= 5.0.20200220195218, < 9 junit-xml >= 1.8 pytest >= 7, < 9 defusedxml importlib_resources>=1.4;python_version<'3.9' ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6892881 cwltest-2.4.20240129145612/setup.cfg0000644000175000017500000000004614555737104016113 0ustar00michaelmichael[egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/test-requirements.txt0000644000175000017500000000007714555736633020545 0ustar00michaelmichaelcwlref-runner cwltool pytest >= 7, < 9 pytest-cov pytest-xdist ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1706540611.685288 cwltest-2.4.20240129145612/tests/0000755000175000017500000000000014555737104015434 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/__init__.py0000644000175000017500000000003114555736633017545 0ustar00michaelmichael"""Tests for cwltest.""" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6892881 cwltest-2.4.20240129145612/tests/test-data/0000755000175000017500000000000014555737104017322 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/conformance_test_v1.0.cwltest.yml0000644000175000017500000000071614555736633025640 0ustar00michaelmichael- output: args: [cat, hello.txt] job: v1.0/cat-job.json tool: v1.0/cat1-testcli.cwl label: cl_optional_inputs_missing id: 4 doc: Test command line with optional input (missing) tags: [ required, command_line_tool ] - output: args: [cat, -n, hello.txt] job: v1.0/cat-n-job.json tool: v1.0/cat1-testcli.cwl label: cl_optional_bindings_provided id: 5 doc: Test command line with optional input (provided) tags: [ command_line_tool ]././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/conformance_test_v1.2.cwltest.yaml0000644000175000017500000000067014555736633026002 0ustar00michaelmichael- output: args: [cat, hello.txt] job: v1.0/cat-job.json tool: v1.0/cat1-testcli.cwl id: cl_optional_inputs_missing doc: Test command line with optional input (missing) tags: [ required, command_line_tool ] - output: args: [cat, -n, hello.txt] job: v1.0/cat-n-job.json tool: v1.0/cat1-testcli.cwl id: cl_optional_bindings_provided doc: Test command line with optional input (provided) tags: [ command_line_tool ]././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/cores.txt0000644000175000017500000000000214555736633021174 0ustar00michaelmichael2 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/cwltool-conftest.py0000644000175000017500000000206514555736633023213 0ustar00michaelmichael""" Example configuration for pytest-cwl plugin using cwltool directly. Calls cwltool via Python, instead of a subprocess via `--cwl-runner cwltool`. """ import json from io import StringIO from typing import Any, Dict, List, Optional, Tuple from cwltest import utils def pytest_cwl_execute_test( config: utils.CWLTestConfig, processfile: str, jobfile: Optional[str] ) -> Tuple[int, Optional[Dict[str, Any]]]: """Use the CWL reference runner (cwltool) to execute tests.""" from cwltool import main from cwltool.errors import WorkflowException stdout = StringIO() argsl: List[str] = [f"--outdir={config.outdir}"] if config.runner_quiet: argsl.append("--quiet") elif config.verbose: argsl.append("--debug") argsl.extend(config.args) argsl.append(processfile) if jobfile: argsl.append(jobfile) try: result = main.main(argsl=argsl, stdout=stdout) except WorkflowException: return 1, {} out = stdout.getvalue() return result, json.loads(out) if out else {} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/exclude-tags.yml0000644000175000017500000000065014555736633022441 0ustar00michaelmichael- job: v1.0/cat-job.json output: {} tool: return-0.cwl doc: | Test with label id: opt-error1 tags: [ command_line_tool ] - job: v1.0/cat-job.json id: opt-error2 output: {} tool: return-0.cwl doc: | Test without label tags: [ command_line_tool, workflow ] - job: v1.0/cat-job.json id: opt-error3 output: {} tool: return-0.cwl doc: | Test without label tags: [ workflow ] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/integer-id.yml0000644000175000017500000000014314555736633022100 0ustar00michaelmichael- job: v1.0/cat1-job.json output: {} tool: return-0.cwl doc: Test with an integer id id: 1 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/mock_cwl_runner.py0000755000175000017500000000174714555736633023105 0ustar00michaelmichael#!/usr/bin/env python3 """Mock implementation of the cwlref-runner command line.""" import argparse import sys from time import sleep from cwltest import UNSUPPORTED_FEATURE UNSUPPORTED_FEATURE_TOOL = "return-unsupported.cwl" ERROR_TOOL = "return-1.cwl" TIMEOUT_TOOL = "timeout.cwl" def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("processfile") parser.add_argument("jobfile") parser.add_argument("--version", action="version", version="%(prog)s 1.0") parser.add_argument("--outdir") parser.add_argument("--quiet", action="store_true") args = parser.parse_args() if args.processfile.endswith(UNSUPPORTED_FEATURE_TOOL): exit(UNSUPPORTED_FEATURE) elif args.processfile.endswith(ERROR_TOOL): exit(1) elif args.processfile.endswith(TIMEOUT_TOOL): print("timeout stderr", file=sys.stderr) sys.stderr.flush() sleep(100000) exit(1) exit(0) if __name__ == "__main__": main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/multi-lined-doc.yml0000644000175000017500000000041214555736633023036 0ustar00michaelmichael- job: v1.0/cat-job.json output: {} tool: return-0.cwl doc: | Test with label label: opt-error tags: [ js, init_work_dir ] - job: v1.0/cat-job.json output: {} tool: return-0.cwl doc: | Test without label tags: [ js, init_work_dir ] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/optional-error.yml0000644000175000017500000000044414555736633023031 0ustar00michaelmichael- job: v1.0/cat-job.json output: output_txt: class: File checksum: sha1$47a013e660d408619d894b20806b1d5086aab03b location: output.txt size: 13 tool: return-1.cwl doc: Optional test that returns error code other than unsupported tags: [ js, init_work_dir ] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/optional-unsupported.yml0000644000175000017500000000041214555736633024263 0ustar00michaelmichael- job: v1.0/cat-job.json output: output_txt: class: File checksum: sha1$47a013e660d408619d894b20806b1d5086aab03b location: output.txt size: 13 tool: return-unsupported.cwl doc: Optional test that is unsupported tags: [ optional ] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/required-unsupported.yml0000644000175000017500000000103114555736633024254 0ustar00michaelmichael- job: v1.0/cat-job.json output: output_txt: class: File checksum: sha1$47a013e660d408619d894b20806b1d5086aab03b location: output.txt size: 13 tool: return-unsupported.cwl doc: Required test that is unsupported (without tags) - job: v1.0/cat-job.json output: output_txt: class: File checksum: sha1$47a013e660d408619d894b20806b1d5086aab03b location: output.txt size: 13 tool: return-unsupported.cwl doc: Required test that is unsupported (with tags) tags: [ required ]././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/return-0.cwl0000644000175000017500000000000014555736633021501 0ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/return-1.cwl0000644000175000017500000000000014555736633021502 0ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/return-unsupported.cwl0000644000175000017500000000000014555736633023732 0ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/short-names.yml0000644000175000017500000000021214555736633022306 0ustar00michaelmichael- job: v1.0/cat-job.json output: {} tool: return-0.cwl doc: Test with a short name label: opt-error tags: [ js, init_work_dir ] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/string-id.yml0000644000175000017500000000016114555736633021751 0ustar00michaelmichael- job: v1.0/cat1-job.json output: {} tool: return-0.cwl doc: Test with a string label id: test-string-id ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/timeout.cwl0000644000175000017500000000013214555736633021521 0ustar00michaelmichaelclass: CommandLineTool cwlVersion: v1.0 inputs: [] outputs: [] baseCommand: [sleep, "15"] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/timeout.yml0000644000175000017500000000036014555736633021540 0ustar00michaelmichael- job: v1.0/empty.json output: output_txt: class: File checksum: sha1$47a013e660d408619d894b20806b1d5086aab03b location: output.txt size: 13 tool: timeout.cwl doc: Test of timeout stdout and stderr capture ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1706540611.6892881 cwltest-2.4.20240129145612/tests/test-data/v1.0/0000755000175000017500000000000014555737104020006 5ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/v1.0/args.py0000644000175000017500000000026214555736633021322 0ustar00michaelmichael#!/usr/bin/env python import sys import json import os args = [os.path.basename(a) for a in sys.argv[1:]] with open("cwl.output.json", "w") as f: json.dump({"args": args}, f)././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/v1.0/cat-job.json0000644000175000017500000000012114555736633022220 0ustar00michaelmichael{ "file1": { "class": "File", "location": "hello.txt" } }././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/v1.0/cat-n-job.json0000644000175000017500000000015014555736633022455 0ustar00michaelmichael{ "file1": { "class": "File", "location": "hello.txt" }, "numbering": true }././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/v1.0/cat1-job.json0000644000175000017500000000000014555736633022275 0ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/v1.0/cat1-testcli.cwl0000644000175000017500000000203014555736633023013 0ustar00michaelmichael#!/usr/bin/env cwl-runner { "class": "CommandLineTool", "cwlVersion": "v1.0", "doc": "Print the contents of a file to stdout using 'cat' running in a docker container.", "hints": [ { "class": "DockerRequirement", "dockerPull": "python:2-slim" }, { "class": "ResourceRequirement", "ramMin": 128 } ], "inputs": [ { "id": "file1", "type": "File", "inputBinding": {"position": 1} }, { "id": "numbering", "type": ["null", "boolean"], "inputBinding": { "position": 0, "prefix": "-n" } }, { id: "args.py", type: File, default: { class: File, location: args.py }, inputBinding: { position: -1 } } ], "outputs": [{"id": "args", "type": "string[]"}], "baseCommand": "python", "arguments": ["cat"] }././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/v1.0/cat2-job.json0000644000175000017500000000000014555736633022276 0ustar00michaelmichael././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/v1.0/empty.json0000644000175000017500000000000314555736633022036 0ustar00michaelmichael{} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/v1.0/hello.txt0000644000175000017500000000001414555736633021653 0ustar00michaelmichaelHello world!././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test-data/with-and-without-short-names.yml0000644000175000017500000000031714555736633025526 0ustar00michaelmichael- job: v1.0/cat1-job.json output: {} tool: return-0.cwl doc: Test without a short name - job: v1.0/cat2-job.json output: {} tool: return-0.cwl doc: Test with a short name short_name: opt-error ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test_argparse.py0000644000175000017500000000056414555736633020664 0ustar00michaelmichaelfrom cwltest.argparser import arg_parser def test_arg() -> None: """Basic test of the argparse.""" parser = arg_parser() parsed = parser.parse_args( ["--test", "test_name", "-n", "52", "--tool", "cwltool", "-j", "4"] ) assert parsed.test == "test_name" assert parsed.n == "52" assert parsed.tool == "cwltool" assert parsed.j == 4 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test_categories.py0000644000175000017500000000571714555736633021212 0ustar00michaelmichaelimport os import re from os import linesep as n from os import sep as p from pathlib import Path from typing import cast from xml.etree.ElementTree import Element import defusedxml.ElementTree as ET import schema_salad.ref_resolver from .util import get_data, run_with_mock_cwl_runner def test_unsupported_with_required_tests() -> None: cwl_runner = get_data("tests/test-data/mock_cwl_runner.py") cwd = os.getcwd() os.chdir(get_data("tests/test-data/")) args = ["--test", "required-unsupported.yml"] try: error_code, stdout, stderr = run_with_mock_cwl_runner(args) finally: os.chdir(cwd) assert error_code == 1 print(stderr) stderr = re.sub(r" '?--outdir=[^ ]*", "", stderr) if os.name == "nt": q = "'" else: q = "" assert ( f"The `id` field is missing.{n}" f"The `id` field is missing.{n}" f"Test [1/2] Required test that is unsupported (without tags){n}" f"{n}" f"Test 1 failed: {cwl_runner} --quiet return-unsupported.cwl {q}v1.0{p}cat-job.json{q}{n}" f"Required test that is unsupported (without tags){n}" f"Does not support required feature{n}" f"Test [2/2] Required test that is unsupported (with tags){n}" f"{n}" f"Test 2 failed: {cwl_runner} --quiet return-unsupported.cwl {q}v1.0{p}cat-job.json{q}{n}" f"Required test that is unsupported (with tags){n}" f"Does not support required feature{n}" f"0 tests passed, 2 failures, 0 unsupported features{n}" ) == stderr def test_unsupported_with_optional_tests() -> None: args = [ "--test", schema_salad.ref_resolver.file_uri( get_data("tests/test-data/optional-unsupported.yml") ), ] error_code, stdout, stderr = run_with_mock_cwl_runner(args) stderr = re.sub(r" '?--outdir=[^ ]*", "", stderr) assert error_code == 0 assert ( "The `id` field is missing.{n}" "Test [1/1] Optional test that is unsupported{n}{n}" "0 tests passed, 1 unsupported " "features{n}".format(n=n) ) == stderr def test_error_with_optional_tests() -> None: args = [ "--test", schema_salad.ref_resolver.file_uri( get_data("tests/test-data/optional-error.yml") ), ] error_code, stdout, stderr = run_with_mock_cwl_runner(args) assert error_code == 1 assert "1 failures" in stderr def test_category_in_junit_xml(tmp_path: Path) -> None: junit_xml_report = tmp_path / "junit-report.xml" args = [ "--test", schema_salad.ref_resolver.file_uri( get_data("tests/test-data/optional-error.yml") ), "--junit-xml", str(junit_xml_report), ] run_with_mock_cwl_runner(args) tree = ET.parse(junit_xml_report) root = tree.getroot() category = cast( Element, cast(Element, root.find("testsuite")).find("testcase") ).attrib["class"] assert category == "js, init_work_dir" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test_compare.py0000644000175000017500000004041314555736633020503 0ustar00michaelmichaelimport os from pathlib import Path from typing import Any, Dict import pytest from cwltest.compare import CompareFail, _compare_directory, _compare_file, compare from .util import get_data def test_compare_any_success() -> None: expected = "Any" actual: Dict[str, Any] = {} compare(expected, actual) def test_compare_contents_failure() -> None: expected = { "location": "cores.txt", "size": 2, "class": "File", "contents": "2", } actual = { "basename": "cores.txt", "checksum": "sha1$7448d8798a4380162d4b56f9b452e2f6f9e24e7a", "class": "File", "location": "file:///var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/cores.txt", "path": get_data("tests/test-data/cores.txt"), "size": 2, } with pytest.raises(CompareFail): compare(expected, actual) def test_compare_contents_success() -> None: expected = { "location": "cores.txt", "size": 2, "class": "File", "contents": "2\n", "checksum": "sha1$7448d8798a4380162d4b56f9b452e2f6f9e24e7a", } actual = { "basename": "cores.txt", "checksum": "sha1$7448d8798a4380162d4b56f9b452e2f6f9e24e7a", "class": "File", "location": "file:///var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/cores.txt", "path": get_data("tests/test-data/cores.txt"), "size": 2, } compare(expected, actual) def test_compare_contents_not_exist() -> None: expected = { "location": "cores.txt", "class": "File", } actual = { "basename": "cores.txt", "class": "File", "location": "file:///var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/cores.txt", "path": "/none/exist/path/to/cores.txt", "size": 2, } with pytest.raises(CompareFail): _compare_file(expected, actual, False) def test_compare_file_different_size(tmp_path: Path) -> None: expected = { "location": "cores.txt", "size": 2, "class": "File", } path = tmp_path / "cores.txt" with open(path, "w") as f: f.write("hello") actual = { "basename": "cores.txt", "class": "File", "location": path.as_uri(), } with pytest.raises(CompareFail): _compare_file(expected, actual, False) def test_compare_file_different_checksum(tmp_path: Path) -> None: expected = { "location": "cores.txt", "class": "File", "checksum": "sha1$7448d8798a4380162d4b56f9b452e2f6f9e24e7a", } path = tmp_path / "cores.txt" with open(path, "w") as f: f.write("hello") actual = { "basename": "cores.txt", "class": "File", "location": path.as_uri(), } with pytest.raises(CompareFail): _compare_file(expected, actual, False) def test_compare_file_inconsistent_size(tmp_path: Path) -> None: expected = { "location": "cores.txt", "class": "File", } path = tmp_path / "cores.txt" with open(path, "w") as f: f.write("hello") actual = { "basename": "cores.txt", "class": "File", "location": path.as_uri(), "size": 65535, } with pytest.raises(CompareFail): _compare_file(expected, actual, False) def test_compare_file_inconsistent_checksum(tmp_path: Path) -> None: expected = { "location": "cores.txt", "class": "File", } path = tmp_path / "cores.txt" with open(path, "w") as f: f.write("hello") actual = { "basename": "cores.txt", "checksum": "inconsistent-checksum", "class": "File", "location": path.as_uri(), } with pytest.raises(CompareFail): _compare_file(expected, actual, False) def test_compare_directory(tmp_path: Path) -> None: expected = { "location": "dir", "class": "Directory", "listing": [], } path = tmp_path / "dir" os.makedirs(path) actual = { "class": "Directory", "location": path.as_uri(), "listing": [], } _compare_directory(expected, actual, False) def test_compare_directory_path(tmp_path: Path) -> None: expected = { "location": "dir", "class": "Directory", "listing": [], } path = tmp_path / "dir" os.makedirs(path) actual = { "class": "Directory", "path": str(path), "listing": [], } _compare_directory(expected, actual, False) def test_compare_directory_success() -> None: expected = { "stuff": { "class": "Directory", "listing": [ { "basename": "baz.txt", "checksum": "sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709", "class": "File", "size": 0, }, { "basename": "foo", "class": "Directory", "listing": [ { "basename": "bar.txt", "checksum": "sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709", "class": "File", "size": 0, } ], }, ], } } actual = { "stuff": { "class": "Directory", "listing": [ { "basename": "baz.txt", "checksum": "sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709", "class": "File", "size": 0, }, { "basename": "foo", "class": "Directory", "listing": [ { "basename": "bar.txt", "checksum": "sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709", "class": "File", "size": 0, } ], }, ], } } compare(expected, actual, skip_details=True) def test_compare_directory_failure_different_listing() -> None: expected = { "stuff": { "class": "Directory", "listing": [ { "basename": "baz.txt", "checksum": "sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709", "class": "File", "size": 0, }, { "basename": "foo", "class": "Directory", "listing": [ { "basename": "bar.txt", "checksum": "sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709", "class": "File", "size": 0, } ], }, ], } } actual = { "stuff": { "class": "Directory", "location": "file:///var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff", "path": "/var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff", "listing": [ { "basename": "baz.txt", "checksum": "sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709", "class": "File", "location": "file:///var/folders/8x/" "2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff/baz.txt", "path": "/var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff/baz.txt", "size": 0, }, { "basename": "foo", "class": "Directory", "location": "file:///var/folders/8x/" "2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff/foo", "path": "/var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff/foo", "listing": [ { "basename": "bar.txt", "checksum": "sha1$da39a3ee5e6b4b0d3255bfef95601890afd80775", "class": "File", "location": "file:///var/folders/8x/" "2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff/foo/bar.txt", "path": "/var/folders/8x/" "2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff/foo/bar.txt", "size": 0, } ], }, ], } } with pytest.raises(CompareFail): compare(expected, actual) def test_compare_directory_failure_no_listing() -> None: expected = { "stuff": { "class": "Directory", "listing": [ { "basename": "baz.txt", "checksum": "sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709", "class": "File", "size": 0, }, { "basename": "foo", "class": "Directory", "listing": [ { "basename": "bar.txt", "checksum": "sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709", "class": "File", "size": 0, } ], }, ], } } actual = { "stuff": { "class": "Directory", "location": "file:///var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff", "path": "/var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff", "listing": [ { "basename": "baz.txt", "checksum": "sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709", "class": "File", "location": "file:///var/folders/8x/" "2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff/baz.txt", "path": "/var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff/baz.txt", "size": 0, }, { "basename": "foo", "class": "Directory", "location": "file:///var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff/foo", "path": "/var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/stuff/foo", }, ], } } with pytest.raises(CompareFail): compare(expected, actual) def test_compare_file_failure_different() -> None: expected = { "location": "cores.txt", "size": 2, "class": "File", "checksum": "sha1$7448d8798a4380162d4b56f9b452e2f6f9e24e7b", } actual = { "basename": "cores.txt", "checksum": "sha1$7448d8798a4380162d4b56f9b452e2f6f9e24e7a", "class": "File", "location": "file:///var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/cores.txt", "path": "/var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/cores.txt", "size": 2, } with pytest.raises(CompareFail): compare(expected, actual) def test_compare_file_failure_none() -> None: expected = { "location": "cores.txt", "size": 2, "class": "File", "checksum": "sha1$7448d8798a4380162d4b56f9b452e2f6f9e24e7b", } actual: Dict[str, Any] = {} with pytest.raises(CompareFail): compare(expected, actual) def test_compare_file_success() -> None: expected = { "location": "cores.txt", "size": 2, "class": "File", "checksum": "sha1$7448d8798a4380162d4b56f9b452e2f6f9e24e7a", } actual = { "basename": "cores.txt", "checksum": "sha1$7448d8798a4380162d4b56f9b452e2f6f9e24e7a", "class": "File", "location": "file:///var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/cores.txt", "path": "/var/folders/8x/2df05_7j20j6r8y81w4qf43r0000gn/T/tmpG0EkrS/cores.txt", "size": 2, } compare(expected, actual, skip_details=True) def test_compare_list_failure_missing() -> None: expected = { "args": [ "tmap", "mapall", "stage1", "map1", "--min-seq-length", "20", "map2", "--min-seq-length", "20", "stage2", "map1", "--max-seq-length", "20", "--min-seq-length", "10", "--seed-length", "16", "map2", "--max-seed-hits", "-1", "--max-seq-length", "20", "--min-seq-length", "10", ] } actual = { "args": [ "tmap", "mapall", "stage1", "map1", "stage2", "map1", "--max-seq-length", "20", "--min-seq-length", "10", "--seed-length", "16", "map2", "--max-seed-hits", "-1", "--max-seq-length", "20", "--min-seq-length", "10", ] } with pytest.raises(CompareFail): compare(expected, actual) def test_compare_list_failure_order() -> None: expected = { "args": [ "tmap", "mapall", "stage1", "map1", "--min-seq-length", "20", "map2", "--min-seq-length", "20", "stage2", "map1", "--max-seq-length", "20", "--min-seq-length", "10", "--seed-length", "16", "map2", "--max-seed-hits", "-1", "--max-seq-length", "20", "--min-seq-length", "10", ] } actual = { "args": [ "tmap", "mapall", "stage1", "map1", "--min-seq-length", "20", "map2", "--min-seq-length", "20", "stage2", "map2", "--max-seed-hits", "-1", "--max-seq-length", "20", "--min-seq-length", "10", "map1", "--max-seq-length", "20", "--min-seq-length", "10", "--seed-length", "16", ] } with pytest.raises(CompareFail): compare(expected, actual) def test_compare_list_failure_type() -> None: expected = { "args": [ "tmap", "mapall", "stage1", "map1", "--min-seq-length", "20", "map2", "--min-seq-length", "20", "stage2", "map1", "--max-seq-length", "20", "--min-seq-length", "10", "--seed-length", "16", "map2", "--max-seed-hits", "-1", "--max-seq-length", "20", "--min-seq-length", "10", ] } actual: Dict[str, Any] = {"args": {}} with pytest.raises(CompareFail): compare(expected, actual) def test_compare_list_success() -> None: expected = { "args": [ "tmap", "mapall", "stage1", "map1", "--min-seq-length", "20", "map2", "--min-seq-length", "20", "stage2", "map1", "--max-seq-length", "20", "--min-seq-length", "10", "--seed-length", "16", "map2", "--max-seed-hits", "-1", "--max-seq-length", "20", "--min-seq-length", "10", ] } compare(expected, expected) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test_exclude_tags.py0000644000175000017500000000156314555736633021527 0ustar00michaelmichaelfrom os import linesep as n from .util import get_data, run_with_mock_cwl_runner def test_list_only_exclude() -> None: args = [ "--test", get_data("tests/test-data/exclude-tags.yml"), "-l", "--exclude-tags=workflow", ] error_code, stdout, stderr = run_with_mock_cwl_runner(args) assert f"[1] opt-error1: Test with label{n}" in stdout assert "opt-error2" not in stdout assert "opt-error3" not in stdout def test_list_include_and_exclude() -> None: args = [ "--test", get_data("tests/test-data/exclude-tags.yml"), "-l", "--tags=command_line_tool", "--exclude-tags=workflow", ] error_code, stdout, stderr = run_with_mock_cwl_runner(args) assert f"[1] opt-error1: Test with label{n}" in stdout assert "opt-error2" not in stdout assert "opt-error3" not in stdout ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test_integer_id.py0000644000175000017500000000060314555736633021163 0ustar00michaelmichaelfrom .util import get_data, run_with_mock_cwl_runner def test_warning_with_integer_id() -> None: args = [ "--test", get_data("tests/test-data/integer-id.yml"), "-l", ] error_code, stdout, stderr = run_with_mock_cwl_runner(args) assert ( "The `id` field with integer is deprecated. Use string identifier instead." in stderr ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test_multi_lined_doc.py0000644000175000017500000000132114555736633022202 0ustar00michaelmichaelfrom os import linesep as n from .util import get_data, run_with_mock_cwl_runner def test_run() -> None: args = ["--test", get_data("tests/test-data/multi-lined-doc.yml")] error_code, stdout, stderr = run_with_mock_cwl_runner(args) assert "The `label` field is deprecated. Use `id` field instead." in stderr assert f"Test [1/2] opt-error: Test with label{n}" in stderr assert f"Test [2/2] Test without label{n}" in stderr def test_list() -> None: args = ["--test", get_data("tests/test-data/multi-lined-doc.yml"), "-l"] error_code, stdout, stderr = run_with_mock_cwl_runner(args) assert f"[1] opt-error: Test with label{n}" in stdout assert f"[2] Test without label{n}" in stdout ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test_plugin.py0000644000175000017500000001063714555736633020360 0ustar00michaelmichaelimport os import shutil from pathlib import Path from typing import TYPE_CHECKING from .util import get_data if TYPE_CHECKING: from _pytest.pytester import Pytester def _load_v1_0_dir(path: Path) -> None: inner_dir = os.path.join(path.parent, "v1.0") os.mkdir(inner_dir) shutil.copy(get_data("tests/test-data/v1.0/cat1-testcli.cwl"), inner_dir) shutil.copy(get_data("tests/test-data/v1.0/cat-job.json"), inner_dir) shutil.copy(get_data("tests/test-data/v1.0/cat-n-job.json"), inner_dir) shutil.copy(get_data("tests/test-data/v1.0/hello.txt"), inner_dir) shutil.copy(get_data("tests/test-data/v1.0/args.py"), inner_dir) def test_include(pytester: "Pytester") -> None: """Test the pytest plugin using cwltool as cwl-runner.""" path = pytester.copy_example("conformance_test_v1.0.cwltest.yml") shutil.copy( get_data("tests/test-data/cwltool-conftest.py"), path.parent / "conftest.py" ) _load_v1_0_dir(path) result = pytester.runpytest( "-k", "conformance_test_v1.0.cwltest.yml", "--cwl-include", "cl_optional_inputs_missing", ) result.assert_outcomes(passed=1, skipped=1) def test_exclude(pytester: "Pytester") -> None: """Test the pytest plugin using cwltool as cwl-runner.""" path = pytester.copy_example("conformance_test_v1.0.cwltest.yml") shutil.copy( get_data("tests/test-data/cwltool-conftest.py"), path.parent / "conftest.py" ) _load_v1_0_dir(path) result = pytester.runpytest( "-k", "conformance_test_v1.0.cwltest.yml", "--cwl-exclude", "cl_optional_inputs_missing,cl_optional_bindings_provided", ) result.assert_outcomes(passed=0, skipped=2) def test_tags(pytester: "Pytester") -> None: """Test the pytest plugin using cwltool as cwl-runner.""" path = pytester.copy_example("conformance_test_v1.0.cwltest.yml") shutil.copy( get_data("tests/test-data/cwltool-conftest.py"), path.parent / "conftest.py" ) _load_v1_0_dir(path) result = pytester.runpytest( "-k", "conformance_test_v1.0.cwltest.yml", "--cwl-tags", "required" ) result.assert_outcomes(passed=1, skipped=1) def test_exclude_tags(pytester: "Pytester") -> None: """Test the pytest plugin using cwltool as cwl-runner.""" path = pytester.copy_example("conformance_test_v1.0.cwltest.yml") shutil.copy( get_data("tests/test-data/cwltool-conftest.py"), path.parent / "conftest.py" ) _load_v1_0_dir(path) result = pytester.runpytest( "-k", "conformance_test_v1.0.cwltest.yml", "--cwl-exclude-tags", "command_line_tool", ) result.assert_outcomes(skipped=2) def test_badgedir(pytester: "Pytester") -> None: """Test the pytest plugin creates the badges directory.""" path = pytester.copy_example("conformance_test_v1.0.cwltest.yml") shutil.copy( get_data("tests/test-data/cwltool-conftest.py"), path.parent / "conftest.py" ) _load_v1_0_dir(path) assert not os.path.exists("cwl-badges") pytester.runpytest( "-k", "conformance_test_v1.0.cwltest.yml", "--cwl-badgedir", "cwl-badges" ) assert os.path.exists("cwl-badges") def test_no_label(pytester: "Pytester") -> None: """Test the pytest plugin correctly extracts test names from the id field when label is missing.""" path = pytester.copy_example("conformance_test_v1.2.cwltest.yaml") shutil.copy( get_data("tests/test-data/cwltool-conftest.py"), path.parent / "conftest.py" ) _load_v1_0_dir(path) result = pytester.runpytest( "-k", "conformance_test_v1.2.cwltest.yaml", "--cwl-tags", "required" ) result.assert_outcomes(passed=1, skipped=1) def test_cwltool_hook(pytester: "Pytester") -> None: """Test the pytest plugin using cwltool as cwl-runner.""" path = pytester.copy_example("conformance_test_v1.0.cwltest.yml") shutil.copy( get_data("tests/test-data/cwltool-conftest.py"), path.parent / "conftest.py" ) _load_v1_0_dir(path) result = pytester.runpytest("-k", "conformance_test_v1.0.cwltest.yml") result.assert_outcomes(passed=2) def test_no_hook(pytester: "Pytester") -> None: """Test the pytest plugin using the default cwl-runner.""" path = pytester.copy_example("conformance_test_v1.0.cwltest.yml") _load_v1_0_dir(path) result = pytester.runpytest("-k", "conformance_test_v1.0.cwltest.yml") result.assert_outcomes(passed=2) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test_prepare.py0000644000175000017500000000146114555736633020513 0ustar00michaelmichael"""Test prepare_test_command()""" import os from cwltest import utils def test_unix_relative_path() -> None: """Confirm unix style to windows style path corrections.""" command = utils.prepare_test_command( tool="cwl-runner", args=[], testargs=None, test={ "doc": "General test of command line generation", "output": {"args": ["echo"]}, "tool": "v1.0/bwa-mem-tool.cwl", "job": "v1.0/bwa-mem-job.json", "tags": ["required"], }, cwd=os.getcwd(), ) if os.name == "nt": assert command[3] == "v1.0\\bwa-mem-tool.cwl" assert command[4] == "v1.0\\bwa-mem-job.json" else: assert command[3] == "v1.0/bwa-mem-tool.cwl" assert command[4] == "v1.0/bwa-mem-job.json" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test_short_names.py0000644000175000017500000000320514555736633021375 0ustar00michaelmichaelfrom os import linesep as n from pathlib import Path from typing import cast from xml.etree.ElementTree import Element import defusedxml.ElementTree as ET from .util import get_data, run_with_mock_cwl_runner def test_stderr_output() -> None: args = ["--test", get_data("tests/test-data/short-names.yml")] error_code, stdout, stderr = run_with_mock_cwl_runner(args) assert f"Test [1/1] opt-error: Test with a short name{n}" in stderr def test_run_by_short_name() -> None: short_name = "opt-error" args = [ "--test", get_data("tests/test-data/with-and-without-short-names.yml"), "-s", short_name, ] error_code, stdout, stderr = run_with_mock_cwl_runner(args) assert "Test [2/2] opt-error: Test with a short name" in stderr assert "Test [1/2]" not in stderr def test_list_tests() -> None: args = [ "--test", get_data("tests/test-data/with-and-without-short-names.yml"), "-l", ] error_code, stdout, stderr = run_with_mock_cwl_runner(args) assert ( f"[1] Test without a short name{n}" f"[2] opt-error: Test with a short name{n}" ) in stdout def test_short_name_in_junit_xml(tmp_path: Path) -> None: junit_xml_report = tmp_path / "junit-report.xml" args = [ "--test", get_data("tests/test-data/short-names.yml"), "--junit-xml", str(junit_xml_report), ] run_with_mock_cwl_runner(args) tree = ET.parse(junit_xml_report) root = tree.getroot() category = cast( Element, cast(Element, root.find("testsuite")).find("testcase") ).attrib["file"] assert category == "opt-error" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test_string_id.py0000644000175000017500000000047414555736633021042 0ustar00michaelmichaelfrom os import linesep as n from .util import get_data, run_with_mock_cwl_runner def test_list() -> None: args = ["--test", get_data("tests/test-data/string-id.yml"), "-l"] error_code, stdout, stderr = run_with_mock_cwl_runner(args) assert f"[1] test-string-id: Test with a string label{n}" in stdout ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/test_timeout.py0000644000175000017500000000275414555736633020551 0ustar00michaelmichaelimport os from pathlib import Path from typing import cast from xml.etree.ElementTree import Element import defusedxml.ElementTree as ET import schema_salad.ref_resolver from .util import get_data, run_with_mock_cwl_runner def test_timeout_stderr_stdout(tmp_path: Path) -> None: junit_xml_report = tmp_path / "junit-report.xml" args = [ "--test", schema_salad.ref_resolver.file_uri(get_data("tests/test-data/timeout.yml")), "--timeout", "5", "--junit-xml", str(junit_xml_report), ] cwd = os.getcwd() try: os.chdir(get_data("tests/test-data/")) error_code, stdout, stderr = run_with_mock_cwl_runner(args) finally: os.chdir(cwd) assert error_code == 1 assert "Test 1 timed out" in stderr tree = ET.parse(junit_xml_report) try: root = tree.getroot() timeout_text = cast( Element, cast(Element, cast(Element, root.find("testsuite")).find("testcase")).find( "failure" ), ).text timeout_stderr = cast( Element, cast(Element, cast(Element, root.find("testsuite")).find("testcase")).find( "system-err" ), ).text assert timeout_text is not None and "Test timed out" in timeout_text assert timeout_stderr is not None and "timeout stderr" in timeout_stderr except AttributeError as e: print(junit_xml_report.read_text()) raise e ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tests/util.py0000644000175000017500000000247014555736633016774 0ustar00michaelmichael"""Test functions.""" import atexit import os import subprocess # nosec from contextlib import ExitStack from pathlib import Path from typing import List, Tuple from cwltest.utils import as_file, files def get_data(filename: str) -> str: """Return the absolute path starting from a file name.""" filename = os.path.normpath(filename) # normalizing path depending on OS or else it will cause problem when # joining path filepath = None try: file_manager = ExitStack() atexit.register(file_manager.close) traversable = files("cwltest") / filename filepath = file_manager.enter_context(as_file(traversable)) except ModuleNotFoundError: pass if not filepath or not os.path.isfile(filepath): filepath = Path(os.path.dirname(__file__)) / ".." / filename return str(filepath.resolve()) def run_with_mock_cwl_runner(args: List[str]) -> Tuple[int, str, str]: """Bind a mock cwlref-runner implementation to cwltest.""" cwl_runner = get_data("tests/test-data/mock_cwl_runner.py") process = subprocess.Popen( # nosec ["cwltest", "--tool", cwl_runner] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) stdout, stderr = process.communicate() return process.returncode, stdout.decode(), stderr.decode() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1706540443.0 cwltest-2.4.20240129145612/tox.ini0000644000175000017500000000434314555736633015617 0ustar00michaelmichael[tox] envlist = py3{8,9,10,11,12}-lint, py3{8,9,10,11,12}-unit, py3{8,9,10,11,12}-bandit, py3{8,9,10,11,12}-mypy, py312-lintreadme, py312-pydocstyle skip_missing_interpreters = True isolated_build = True [pytest] addopts = -p pytester -n auto pytester_example_dir = tests/test-data testpaths = tests [gh-actions] python = 3.8: py38 3.9: py39 3.10: py310 3.11: py311 3.12: py312 [testenv] skipsdist = py3{8,9,10,11,12}-!{unit,mypy,lintreadme} = True description = py3{8,9,10,11,12}-unit: Run the unit tests py3{8,9,10,11,12}-lint: Lint the Python code py3{8,9,10,11,12}-bandit: Search for common security issues py3{8,9,10,11,12}-mypy: Check for type safety py312-pydocstyle: docstring style checker py312-lintreadme: Lint the README.rst->.md conversion passenv = CI GITHUB_* deps = py3{8,9,10,11,12}-{unit,mypy}: -rrequirements.txt py3{8,9,10,11,12}-{unit,mypy}: -rtest-requirements.txt py3{8,9,10,11,12}-lint: flake8-bugbear py3{8,9,10,11,12}-lint: black~=23.1 py3{8,9,10,11,12}-bandit: bandit py3{8,9,10,11,12}-mypy: -rmypy-requirements.txt set_env = py3{8,3,10,11,12}-unit: LC_ALL = C.UTF-8 COV_CORE_SOURCE=cwltest COV_CORE_CONFIG={toxinidir}/.coveragerc COV_CORE_DATAFILE={toxinidir}/.coverage.eager commands = py3{8,9,10,11,12}-unit: python -m pip install -U pip setuptools wheel py3{8,9,10,11,12}-unit: python -m pytest --cov --cov-config={toxinidir}/.coveragerc --cov-append {posargs} py3{8,9,10,11,12}-unit: coverage xml py3{8,9,10,11,12}-bandit: bandit --recursive cwltest py3{8,9,10,11,12}-lint: make flake8 py3{8,9,10,11,12}-lint: make format-check py3{8,9,10,11,12}-mypy: make mypy allowlist_externals = py3{8,9,10,11,12}-lint: flake8 py3{8,9,10,11,12}-lint: black py3{8,9,10,11,12}-{mypy,shellcheck,lint,unit}: make skip_install = py3{8,9,10,11,12}-lint: true py3{8,9,10,11,12}-bandit: true [testenv:py312-pydocstyle] allowlist_externals = make commands = make diff_pydocstyle_report deps = pydocstyle diff-cover skip_install = true [testenv:py312-lintreadme] description = Lint the README.rst->.md conversion commands = python -m build --outdir {distdir} twine check {distdir}/* deps = twine build readme_renderer[rst] skip_install = true