{ "info": { "author": "Cooper Lees", "author_email": "me@cooperlees.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10" ], "description": "# \ud83c\udfc3\u200d\u2640\ufe0f `ptr` - Python Test Runner \ud83c\udfc3\u200d\u2642\ufe0f\n\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![Actions Status](https://github.com/facebookincubator/ptr/workflows/ptr_ci/badge.svg)](https://github.com/facebookincubator/ptr/actions)\n[![PyPI](https://img.shields.io/pypi/v/ptr)](https://pypi.org/project/ptr/)\n[![Downloads](https://pepy.tech/badge/ptr/week)](https://pepy.tech/project/ptr/week)\n\nPython Test Runner (ptr) was born to run tests in an opinionated way, within arbitrary code repositories.\n`ptr` supports many Python projects with unit tests defined in their `setup.(cfg|py)` files per repository.\n`ptr` allows developers to test multiple projects/modules in one Python environment through the use of a single test virtual environment.\n\n- `ptr` requires `>=` **python 3.7**\n- `ptr` itself uses `ptr` to run its tests \ud83d\udc4c\ud83c\udffc\n- `ptr` is supported and tested on *Linux*, *MacOS* + *Windows* Operating Systems\n\nBy adding `ptr` configuration to your `setup.cfg` or `setup.py` you can have `ptr` perform the following, per test suite, in parallel:\n- run your test suite\n- check and enforce coverage requirements (via [coverage](https://pypi.org/project/coverage/)),\n- format code (via [black](https://pypi.org/project/black/))\n- perform static type analysis (via [mypy](http://mypy-lang.org/))\n\n\n## Quickstart\n- Install `ptr` into you virtualenv\n - `pip install ptr`\n- Ensure your tests have a base file that can be executed directly\n - i.e. `python3 test.py` (possibly using `unittest.main()`)\n- After adding `ptr_params` to setup.py (see example below), run:\n```\ncd repo\nptr\n```\n\n## How does `ptr` perform this magic? \ud83c\udfa9\n\nI'm glad you ask. Under the covers `ptr` performs:\n- Recursively searches for `setup.(cfg|py)` files from `BASE_DIR` (defaults to your \"current working directory\" (CWD))\n - [AST](https://docs.python.org/3/library/ast.html) parses out the config for each `setup.py` test requirements\n - If a `setup.cfg` exists, load via configparser and prefer if a `[ptr]` section exists\n- Creates a [Python Virtual Environment](https://docs.python.org/3/tutorial/venv.html) (*OPTIONALLY* pointed at an internal PyPI mirror)\n- Runs `ATONCE` tests suites in parallel (i.e. per setup.(cfg|ptr))\n- All steps will be run for each suite and ONLY *FAILED* runs will have output written to stdout\n\n## Usage \ud83e\udd13\n\nTo use `ptr` all you need to do is cd to your project or set the base dir via `-b` and execute:\n\n $ ptr [-dk] [-b some/path] [--venv /tmp/existing_venv]\n\nFor **faster runs** when testing, it is recommended to reuse a Virtual Environment:\n- `-k` - To keep the virtualenv created by `ptr`.\n- Use `--venv VENV_PATH` to reuse to an existing virtualenv created by the user.\n\n### Help Output \ud83d\ude4b\u200d\u2640\ufe0f \ud83d\ude4b\u200d\u2642\ufe0f\n\n```shell\nusage: ptr.py [-h] [-a ATONCE] [-b BASE_DIR] [-d] [-e] [-k] [-m MIRROR]\n [--print-cov] [--print-non-configured]\n [--progress-interval PROGRESS_INTERVAL] [--run-disabled]\n [--stats-file STATS_FILE] [--system-site-packages] [--venv VENV]\n [--venv-timeout VENV_TIMEOUT]\n\noptional arguments:\n -h, --help show this help message and exit\n -a ATONCE, --atonce ATONCE\n How many tests to run at once [Default: 6]\n -b BASE_DIR, --base-dir BASE_DIR\n Path to recursively look for setup.py files [Default:\n /Users/cooper/repos/ptr]\n -d, --debug Verbose debug output\n -e, --error-on-warnings\n Have Python warnings raise DeprecationWarning on tests\n run\n -k, --keep-venv Do not remove created venv\n -m MIRROR, --mirror MIRROR\n URL for pip to use for Simple API [Default:\n https://pypi.org/simple/]\n --print-cov Print modules coverage report\n --print-non-configured\n Print modules not configured to run ptr\n --progress-interval PROGRESS_INTERVAL\n Seconds between status update on test running\n [Default: Disabled]\n --run-disabled Force any disabled tests suites to run\n --stats-file STATS_FILE\n JSON statistics file [Default: /var/folders/tc/hbwxh76\n j1hn6gqjd2n2sjn4j9k1glp/T/ptr_stats_12510]\n --system-site-packages\n Give the virtual environment access to the system\n site-packages dir\n --venv VENV Path to venv to reuse\n --venv-timeout VENV_TIMEOUT\n Timeout in seconds for venv creation + deps install\n [Default: 120]\n```\n\n## Configuration \ud83e\uddf0\n\n`ptr` is configured by placing directives in one or more of the following files. `.ptrconfig` provides\nbase configuration and default values for all projects in the repository, while each `setup.(cfg|py)`\noverrides the base configuration for the respective packages they define.\n\n### `.ptrconfig`\n\n`ptr` supports a general config in `ini` ([ConfigParser](https://docs.python.org/3/library/configparser.html)) format.\nA `.ptrconfig` file can be placed at the root of any repository or in any directory within your repository.\nThe first `.ptrconfig` file found via a recursive walk to the root (\"/\" in POSIX systems) will be used.\n\nPlease refer to [`ptrconfig.sample`](http://github.com/facebookincubator/ptr/blob/master/ptrconfig.sample) for the options available.\n\n### `setup.py`\n\nThis is per project in your repository. A simple example, based on `ptr` itself:\n\n```python\n# Specific Python Test Runner (ptr) params for Unit Testing Enforcement\nptr_params = {\n # Where mypy will run to type check your program\n \"entry_point_module\": \"ptr\",\n # Base Unittest file\n \"test_suite\": \"ptr_tests\",\n \"test_suite_timeout\": 300,\n # Relative path from setup.py to module (e.g. ptr == ptr.py)\n \"required_coverage\": {\"ptr.py\": 99, \"TOTAL\": 99},\n # Run `black --check` or not\n \"run_black\": False,\n # Run mypy or not\n \"run_mypy\": True,\n}\n```\n\n### `setup.cfg`\n\nThis is per project in your repository and if exists is preferred over `setup.py`.\n\nPlease refer to [`setup.cfg.sample`](http://github.com/facebookincubator/ptr/blob/master/setup.cfg.sample) for the options available + format.\n\n### mypy Specifics\n\nWhen enabled, (in `setup.(cfg|py)`) **mypy** can support using a custom `mypy.ini` for each setup.py (module) defined.\n\nTo have `ptr` run mypy using you config:\n- create a `mypy.ini` in the same directory as your `setup.py`\n- OR add **[mypy]** section to your `setup.cfg`\n\n`mypy` Configuration Documentation can be found [here](https://mypy.readthedocs.io/en/stable/config_file.html)\n- An example `setup.cfg` can be seen [here](http://github.com/facebookincubator/ptr/blob/master/mypy.ini).\n\n# Example Output \ud83d\udcdd\n\nHere are some example runs.\n\n## Successful `ptr` Run:\n\nHere is what you want to see in your CI logs!\n```\n[2019-02-06 21:51:45,442] INFO: Starting ptr.py (ptr.py:782)\n[2019-02-06 21:51:59,471] INFO: Successfully created venv @ /var/folders/tc/hbwxh76j1hn6gqjd2n2sjn4j9k1glp/T/ptr_venv_24397 to run tests (14s) (ptr.py:547)\n[2019-02-06 21:51:59,472] INFO: Installing /Users/cooper/repos/ptr/setup.py + deps (ptr.py:417)\n[2019-02-06 21:52:00,726] INFO: Running /Users/cooper/repos/ptr/ptr_tests.py tests via coverage (ptr.py:417)\n[2019-02-06 21:52:04,153] INFO: Analyzing coverage report for /Users/cooper/repos/ptr/setup.py (ptr.py:417)\n[2019-02-06 21:52:04,368] INFO: Running mypy for /Users/cooper/repos/ptr/setup.py (ptr.py:417)\n[2019-05-03 14:54:09,915] INFO: Running flake8 for /Users/cooper/repos/ptr/setup.py (ptr.py:417)\n[2019-05-03 14:54:10,422] INFO: Running pylint for /Users/cooper/repos/ptr/setup.py (ptr.py:417)\n[2019-05-03 14:54:14,020] INFO: Running pyre for /Users/cooper/repos/ptr/setup.py (ptr.py:417)\n[2019-02-06 21:52:07,733] INFO: /Users/cooper/repos/ptr/setup.py has passed all configured tests (ptr.py:509)\n-- Summary (total time 22s):\n\n\u2705 PASS: 1\n\u274c FAIL: 0\n\u231b\ufe0f TIMEOUT: 0\n\ud83d\udca9 TOTAL: 1\n\n-- 1 / 1 (100%) `setup.py`'s have `ptr` tests running\n```\n## Unsuccessful `ptr` Run Examples:\n\nHere are some examples of runs failing. Any \"step\" can fail. All output is predominately the underlying tool.\n\n### Unit Test Failure\n\n```\n[2019-02-06 21:53:58,121] INFO: Starting ptr.py (ptr.py:782)\n[2019-02-06 21:53:58,143] INFO: Installing /Users/cooper/repos/ptr/setup.py + deps (ptr.py:417)\n[2019-02-06 21:53:59,698] INFO: Running /Users/cooper/repos/ptr/ptr_tests.py tests via coverage (ptr.py:417)\n-- Summary (total time 5s):\n\n\u2705 PASS: 0\n\u274c FAIL: 1\n\u231b\ufe0f TIMEOUT: 0\n\ud83d\udca9 TOTAL: 1\n\n-- 1 / 1 (100%) `setup.py`'s have `ptr` tests running\n\n-- Failure Output --\n\n/Users/cooper/repos/ptr/setup.py (failed 'tests_run' step):\n...F....................\n======================================================================\nFAIL: test_config (__main__.TestPtr)\n----------------------------------------------------------------------\nTraceback (most recent call last):\n File \"/Users/cooper/repos/ptr/ptr_tests.py\", line 125, in test_config\n self.assertEqual(len(sc[\"ptr\"][\"venv_pkgs\"].split()), 4)\nAssertionError: 5 != 4\n\n----------------------------------------------------------------------\nRan 24 tests in 3.221s\n\nFAILED (failures=1)\n```\n\n### coverage\n\n```\n[2019-02-06 21:55:42,947] INFO: Starting ptr.py (ptr.py:782)\n[2019-02-06 21:55:42,969] INFO: Installing /Users/cooper/repos/ptr/setup.py + deps (ptr.py:417)\n[2019-02-06 21:55:44,920] INFO: Running /Users/cooper/repos/ptr/ptr_tests.py tests via coverage (ptr.py:417)\n[2019-02-06 21:55:49,628] INFO: Analyzing coverage report for /Users/cooper/repos/ptr/setup.py (ptr.py:417)\n-- Summary (total time 7s):\n\n\u2705 PASS: 0\n\u274c FAIL: 1\n\u231b\ufe0f TIMEOUT: 0\n\ud83d\udca9 TOTAL: 1\n\n-- 1 / 1 (100%) `setup.py`'s have `ptr` tests running\n\n-- Failure Output --\n\n/Users/cooper/repos/ptr/setup.py (failed 'analyze_coverage' step):\nThe following files did not meet coverage requirements:\n ptr.py: 84 < 99 - Missing: 146-147, 175, 209, 245, 269, 288-291, 334-336, 414-415, 425-446, 466, 497, 506, 541-543, 562, 611-614, 639-688\n```\n\n### black\n\n```\n[2019-02-06 22:34:20,029] INFO: Starting ptr.py (ptr.py:804)\n[2019-02-06 22:34:20,060] INFO: Installing /Users/cooper/repos/ptr/setup.py + deps (ptr.py:430)\n[2019-02-06 22:34:21,614] INFO: Running /Users/cooper/repos/ptr/ptr_tests.py tests via coverage (ptr.py:430)\n[2019-02-06 22:34:25,208] INFO: Analyzing coverage report for /Users/cooper/repos/ptr/setup.py (ptr.py:430)\n[2019-02-06 22:34:25,450] INFO: Running mypy for /Users/cooper/repos/ptr/setup.py (ptr.py:430)\n[2019-02-06 22:34:26,422] INFO: Running black for /Users/cooper/repos/ptr/setup.py (ptr.py:430)\n-- Summary (total time 7s):\n\n\u2705 PASS: 0\n\u274c FAIL: 1\n\u231b\ufe0f TIMEOUT: 0\n\ud83d\udca9 TOTAL: 1\n\n-- 1 / 1 (100%) `setup.py`'s have `ptr` tests running\n\n-- Failure Output --\n\n/Users/cooper/repos/ptr/setup.py (failed 'black_run' step):\nwould reformat /Users/cooper/repos/ptr/ptr.py\nAll done! \ud83d\udca5 \ud83d\udc94 \ud83d\udca5\n1 file would be reformatted, 4 files would be left unchanged.\n```\n\n### mypy\n\n```\n[2019-02-06 22:35:39,480] INFO: Starting ptr.py (ptr.py:802)\n[2019-02-06 22:35:39,531] INFO: Installing /Users/cooper/repos/ptr/setup.py + deps (ptr.py:428)\n[2019-02-06 22:35:41,203] INFO: Running /Users/cooper/repos/ptr/ptr_tests.py tests via coverage (ptr.py:428)\n[2019-02-06 22:35:45,156] INFO: Analyzing coverage report for /Users/cooper/repos/ptr/setup.py (ptr.py:428)\n[2019-02-06 22:35:45,413] INFO: Running mypy for /Users/cooper/repos/ptr/setup.py (ptr.py:428)\n-- Summary (total time 6s):\n\n\u2705 PASS: 0\n\u274c FAIL: 1\n\u231b\ufe0f TIMEOUT: 0\n\ud83d\udca9 TOTAL: 1\n\n-- 1 / 1 (100%) `setup.py`'s have `ptr` tests running\n\n-- Failure Output --\n\n/Users/cooper/repos/ptr/setup.py (failed 'mypy_run' step):\n/Users/cooper/repos/ptr/ptr.py: note: In function \"_write_stats_file\":\n/Users/cooper/repos/ptr/ptr.py:179: error: Argument 1 to \"open\" has incompatible type \"Path\"; expected \"Union[str, bytes, int]\"\n/Users/cooper/repos/ptr/ptr.py: note: In function \"run_tests\":\n/Users/cooper/repos/ptr/ptr.py:700: error: Argument 1 to \"_write_stats_file\" has incompatible type \"str\"; expected \"Path\"\n```\n\n### pyre\n\n```\ncooper-mbp1:ptr cooper$ /tmp/tp/bin/ptr --venv /var/folders/tc/hbwxh76j1hn6gqjd2n2sjn4j9k1glp/T/ptr_venv_49117\n[2019-05-03 14:51:43,623] INFO: Starting /tmp/tp/bin/ptr (ptr.py:1023)\n[2019-05-03 14:51:43,657] INFO: Installing /Users/cooper/repos/ptr/setup.py + deps (ptr.py:565)\n[2019-05-03 14:51:44,840] INFO: Running ptr_tests tests via coverage (ptr.py:565)\n[2019-05-03 14:51:47,361] INFO: Analyzing coverage report for /Users/cooper/repos/ptr/setup.py (ptr.py:565)\n[2019-05-03 14:51:47,559] INFO: Running mypy for /Users/cooper/repos/ptr/setup.py (ptr.py:565)\n[2019-05-03 14:51:47,827] INFO: Running black for /Users/cooper/repos/ptr/setup.py (ptr.py:565)\n[2019-05-03 14:51:47,996] INFO: Running flake8 for /Users/cooper/repos/ptr/setup.py (ptr.py:565)\n[2019-05-03 14:51:48,566] INFO: Running pylint for /Users/cooper/repos/ptr/setup.py (ptr.py:565)\n[2019-05-03 14:51:52,301] INFO: Running pyre for /Users/cooper/repos/ptr/setup.py (ptr.py:565)\n[2019-05-03 14:51:54,983] INFO: /Users/cooper/repos/ptr/setup.py has passed all configured tests (ptr.py:668)\n-- Summary (total time 11s):\n\n\u2705 PASS: 1\n\u274c FAIL: 0\n\u231b\ufe0f TIMEOUT: 0\n\ud83d\udca9 TOTAL: 1\n\n-- 1 / 1 (100%) `setup.py`'s have `ptr` tests running\n\n-- Failure Output --\n\n/Users/cooper/repos/ptr/setup.py (failed 'pyre_run' step):\n2019-05-03 14:54:14,173 INFO No binary specified, looking for `pyre.bin` in PATH\n2019-05-03 14:54:14,174 INFO Found: `/var/folders/tc/hbwxh76j1hn6gqjd2n2sjn4j9k1glp/T/ptr_venv_49117/bin/pyre.bin`\n... *(truncated)* ...\nptr.py:602:25 Undefined name [18]: Global name `stdout` is not defined, or there is at least one control flow path that doesn't define `stdout`.\n```\n\n### usort\n\nIf your imports are not making `usort` happy it would look like this:\n\n```\n[2021-05-29 09:30:56,044] INFO: Starting /tmp/tp/bin/ptr (ptr.py:1129)\n[2021-05-29 09:30:56,051] INFO: Installing /Users/cooper/repos/ptr/setup.py + deps (ptr.py:637)\n[2021-05-29 09:30:56,587] INFO: Running ptr_tests tests via coverage (ptr.py:637)\n[2021-05-29 09:30:58,238] INFO: Analyzing coverage report for /Users/cooper/repos/ptr/setup.py (ptr.py:637)\n[2021-05-29 09:30:58,341] INFO: Running mypy for /Users/cooper/repos/ptr/setup.py (ptr.py:637)\n[2021-05-29 09:30:58,436] INFO: Running usort for /Users/cooper/repos/ptr/setup.py (ptr.py:637)\n-- Summary (total time 2s):\n\n\u2705 PASS: 0\n\u274c FAIL: 1\n \ufe0f\u231b TIMEOUT: 0\n\ud83d\udd12 DISABLED: 0\n\ud83d\udca9 TOTAL: 1\n\n-- 1 / 1 (100%) `setup.py`'s have `ptr` tests running\n\n-- Failure Output --\n\n/Users/cooper/repos/ptr/setup.py (failed 'usort_run' step):\nWould sort /Users/cooper/repos/ptr/setup.py\n```\n\n# FAQ \u2049\ufe0f\n\n### Q. How do I debug? I need output!\n\n- `ptr` developers recommend that if you want output, please cause a test to fail\n - e.g. `raise ZeroDivisionError`\n- Another recommended way is to run your tests with the default `setup.py test` using a `ptr` created venv:\n - `cd to/my/code`\n - `/tmp/venv/bin/python setup.py test`\n\n### Q. How do I get specific version of black, coverage, mypy etc.?\n\n- Just simply hard set the version in the .ptrconfig in your repo or use `requirements.txt` to pre-install before running `ptr`\n- All `pip` [PEP 440 version specifiers](https://www.python.org/dev/peps/pep-0440/) are supported\n\n### Q. Why is the venv creation so slow?\n\n- `ptr` attempts to update from a PyPI compatible mirror (PEP 381) or PyPI itself\n- Running a package cache or local mirror can greatly increase speed. Example software to do this:\n - [bandersnatch](https://pypi.org/project/bandersnatch): Can do selected or FULL PyPI mirrors. The maintainer is also devilishly good looking.\n - [devpi](https://pypi.org/project/devpi/): Can be ran and used to *proxy* packages locally when pip goes out to grab your dependencies.\n- Please ensure you're using the `-k` or `--venv` option to no recreate a virtualenv each run when debugging your tests!\n\n### Q. Why is ptr not able to run `pyre` on Windows?\n\n- `pyre` (pyre-check on PyPI) does not ship a Windows wheel with the ocaml pyre.bin\n\n\n### Q. Why do you depend on >= coverage 5.0.1\n\n- `coverage` 5.0 introduced using sqlite and we don't want to have a mix of 4.x and 5.x for ptr\n- < 5.0 could possibly still work as we now ensure to run each projects tests from setup_py.parent CWD with subprocess\n\n\n# Contact or join the ptr community \ud83d\udcac\n\nTo chat in real time, hit us up on IRC. Otherwise, GitHub issues are always welcome!\nIRC: `#pythontestrunner` on *FreeNode*\n\nSee the [CONTRIBUTING](CONTRIBUTING.md) file for how to help out.\n\n## License\n`ptr` is MIT licensed, as found in the [LICENSE file](LICENSE).\n\n## Terms of Use + Privacy Policy\n\n- [Terms of Use](https://opensource.facebook.com/legal/terms)\n- [Privacy Policy](https://opensource.facebook.com/legal/privacy)\n\nCopyright \u00a9 Meta Platforms, Inc. and affiliates\n\n\n## `ptr` Change History\n\nEach release to PyPI I'm going to give a codename as to where I am or was in the world \ud83c\udf0f.\n\n### 2022.2.2\n\nCodename: **Richie 2 for 22 \ud83c\udfcf**\n\n*Release named in honoUr of the Late Great [Richie Benaud](https://en.wikipedia.org/wiki/Richie_Benaud)*\n\n- This will be the last 3.7 supported version\n - Why? Want a less buggy `asyncio.run` for starting asyncio\n- Reactivate `pylint` in CI \n - f-string all ptr strings\n- Drop python 3.6 CI + support\n- We're Meta now - Update copyrights due to comapny change name\n\n3.11 CI is failing due to depedencies. Will watch and fix asap.\n\n### 2021.11.23\n\nCodename: **A \ud83c\udd70\ufe0f**\n\n*Release to support 'Three dot Ten' and A == 10 in hexidecimal*\n\n- Add Official Support and CI for Python 3.10\n - This will be the last release *(if no bugs present themselves)* for 3.6\n- Also start ci_latest running 3.11\n\n### 2021.5.28\n\nCodename: **Memorial Day \ud83c\uddfa**\n\n*Release on Memorial Day long weekend*\n\n- Add usort to the family of CI options\n - https://pypi.org/project/usort/\n\n### 2021.3.16\n\nCodename: **Wildwood \ud83e\udeb5**\n\n*First release from my South Lake Tahoe residence*\n\n- Support floats for coverage comparisions in `required_coverage` - PR #108\n- Change `--print-cov` to work when `required_coverage` does not exist in ptr config - PR #109\n- Move tests out of install but include in sdist - PR #99 - Thanks @jayvdb\n- Test with 3.10 alphas via deadsnakes - PR #110\n- Misc f-string + lint/typing fixes\n\n### 2020.2.26\n\nCodename: **Month after Straya Day \ud83c\udde6\ud83c\uddfa**\ud83c\uddfa\n\n*1 month since @cooperlees was in AU for Australia day!*\n\n- Enable pyre for Python 3.8 now it's fully supported\n\n### 2019.12.25\n\nCodename: **Vernon Hills, IL \ud83c\udf85**\n\n*@cooperlees visiting girlfriend's family in IL*\n\n- Fix documentation for some new arguments - Thanks @omikader\n- Windows now defaults to updating pip + setuptools\n- Rely on setting current working directory with subprocess and remove coverage file environment setting\n- f-string everything via [flynt](https://pypi.org/project/flynt/) now we're >= 3.6\n\n### 2019.12.13\n\nCodename: **College Park, MD \ud83d\udc22**\n\n*@omikader studied at the University of Maryland, College Park*\n\n- Add ability to create partial `.ptrconfig` files - PR: #83\n- Use native recursive file search for black and flake8 - PR: #81\n\n### 2019.12.12\n\nCodename: **Sapporo, Japan \ud83c\uddef\ud83c\uddf5**\n\n*@omikader is going skiing there in February*\n\n- Add support for passing `--system-site-packages` during venv creation - PR: #80\n\n### 2019.11.21\n\nCodename: **Santa Clara, CA**\n\n*@thatch lives there!**\n\n- Add license file for @thatch - PR: #77 - *Thanks @thatch*\n\n### 2019.11.15\n\nCodename: **Russian River, CA \ud83c\uddfa\ud83c\uddf8**\n\n*@cooperlees is going to the Russian River tomorrow*\n\n- Run ptr even when test_suite is not provided - PR: #73 - *Thanks @spurav*\n- Remove use of deprecated setuptools `test` option\n- Move to GitHub Actions for CI + Releases\n\n### 2019.11.2\n\nCodename: **Mumbai, India \ud83c\uddee\ud83c\uddf3**\n\n*@spurav is from Mumbai, India*\n\n- Fix math error dividing 1 / 2 for os.cpu_count - PR: #69 - *Thanks @spurav*\n- Get GitHub Actions CI Running - PR: #68 + #70 - *Thanks @adhaamehab*\n\n### 2019.10.22\n\nCodename: **Cairo, Egypt \ud83c\uddea\ud83c\uddec**\n\n*@adhaamehab who first time contributed is from there! Thanks!*\n\n- Print more helpful error when file does not exist for coverage check - PR: #51\n- Officially Support Python 3.8 and enforce tests passing\n- Disable pyre-check for >=3.8 due to no support\n - Issue to Track: https://github.com/facebook/pyre-check/issues/213\n\n### 2019.10.6\n\nCodename: **Stanford, CA**\n\n*@cooperlees tailgated there yesterday \ud83d\ude90\ud83c\udfc8*\n\n- Handle OSX /private in coverage report - PR: #60\n\n### 2019.9.14\n\nCodename: **Clowntown \ud83e\udd21**\n\n- Fix bad bool passing for `--print-cov` + `--error-on-warnings`\n\n### 2019.9.11\n\nCodename: **Rathbone Square**\n\n*@cooperlees is releasing this release from FB London Office*\n\n- Add CLI option to enable erroring on all [warnings](https://docs.python.org/3/library/warnings.html) - Issue: #57\n\n### 2019.8.7\n\nCodename: **Ellicott City**\n\n*@omikader who reported and tested the fix for AST parsing is from there.*\n*Ellicott City is also home to one of the oldest surviving train stations in the US!*\n\n- Fix AST parsing to ignore AST targets that do not have an `id` attribute - Issue: #54\n- Renable `black` by default on 3.7 now that it runs on > 3.7.2 - Issue: #41\n- Fix --venv-timeout to store ints\n- Refactor _get_test_modules function to remove lint error - PR: #53 - *Thanks @TomasFeeney*\n\n### 2019.7.16\n\nCodename: **California City**\n\n*An over developed desert with infrastructure and little [people](https://en.wikipedia.org/wiki/California_City,_California)*\n\n- Add `--print-non-configured` to find non `ptr` modules in repos - Issue: #50\n\n### 2019.6.15\n\nCodename: **Concord**\n\n*\ud83d\udeeb @cooperlees is playing Aussie Football @ Concord, CA today \ud83c\udfc8*\n\n- Add ability to `disable` test suites and add a `--run-disabled` option to force the run - Issue: #46\n- Azure CI now runs on Mac and Windows again\n\n### 2019.5.3\n\nCodename: **Cleveland**\n\n*\ud83c\uddfa\ud83c\uddf8 @cooperlees + @jreese are at PyCon US in Cleveland, OH \ud83e\udd85*\n\n- Print step name in failure output - Issue: #31\n- Add in `pyre` Type Checking step support - Issue: #38 + #40\n\n**Known Bug:** `black.exe` does not run in Windows 3.7 - **disabled** by *default* on Python 3.7 on Windows\n\n### 2019.3.5\n\nCodename: **Jaipur**\n\n*\ud83c\uddee\ud83c\uddf3 @cooperlees releasing whilst in Jaipur, India for a wedding \ud83d\udc92*\n\n- Preliminary Windows support now ready for testing - Issue: #2\n- Run tests/mypy/flake8 etc. in CWD of setup.py path - Issue #23 - Thanks @jreese\n- Add support for linting with flake8 and pylint - Issue #20 - Thanks @jreese\n- Ignore dotted directories when running black - PR #19 - Thanks @jreese\n\n**Known Bug:** `black.exe` does not run in Windows 3.7 - **disabled** by *default* on Python 3.7 on Windows\n\n### 2019.2.12\n\nCodename: **Forbes**\n\n*[Forbes, NSW, Australia](https://en.wikipedia.org/wiki/Forbes,_New_South_Wales) is the home of @aijayadams \ud83d\udc68\ud83c\udffb\u200d\ud83e\uddb0\ud83c\udde6\ud83c\uddfa*\n\n- Added suite file coverage % to statistics JSON file - Issue: #16 - *Thanks @aijayadams*\n- Ignore hidden '.' (dot) directories when running black - PR: #19 - *Thanks @jreese*\n\n### 2019.2.10\n\nCodename: **Carnival**\n\n*\ud83c\udde7\ud83c\uddf7 @cooperlees was in Rio de Janeiro, Brazil for Carnival 3 years ago today \ud83c\udde7\ud83c\uddf7*\n\n- Added ptr `setup.cfg` support for ptr_params - Issue: #1\n- Added JSON stats validation to `ci.py` - Issue: #7\n- Fixed bug that allowed a step to run by default - Issue: #11\n\n### 2019.2.8.post1/2\n\n- Fix `setup.py` URL to ptr GitHub\n- Other various `setup.py` fixes - e.g. Classifiers + License information\n\n### 2019.2.8\n\nCodename: **Snowbird**\n\n*Recent shredding of Snowbird, UT, USA took place \ud83c\udfc2 \ud83c\uddfa\ud83c\uddf8*\n\n- Initial Release to the world!\n\n\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/facebookincubator/ptr", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "ptr", "package_url": "https://pypi.org/project/ptr/", "platform": "", "project_url": "https://pypi.org/project/ptr/", "project_urls": { "Homepage": "http://github.com/facebookincubator/ptr" }, "release_url": "https://pypi.org/project/ptr/22.2.2/", "requires_dist": null, "requires_python": ">=3.7", "summary": "Parallel asyncio Python setup.(cfg|py) Test Runner", "version": "22.2.2", "yanked": false, "yanked_reason": null }, "last_serial": 12768553, "releases": { "19.10.22": [ { "comment_text": "", "digests": { "md5": "29415ce266c90e018932f1b3cf4ef410", "sha256": "420fed8a81a8f55dd6c62ac01444d9e427306abdf42053466b8756645c8a3fdc" }, "downloads": -1, "filename": "ptr-19.10.22-py3-none-any.whl", "has_sig": false, "md5_digest": "29415ce266c90e018932f1b3cf4ef410", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 27684, "upload_time": "2019-10-22T19:18:08", "upload_time_iso_8601": "2019-10-22T19:18:08.255749Z", "url": "https://files.pythonhosted.org/packages/4c/9e/8bce5bc2512b1a5ffe1498c7489afded46dd962cb35e5b60a46e8fdb6ca9/ptr-19.10.22-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "31eff6589ea409aa48821b5f28cad79b", "sha256": "62d683bb0271d2ffe3e1f628f251b51615b99daa681c135a14a4e32f97443724" }, "downloads": -1, "filename": "ptr-19.10.22.tar.gz", "has_sig": false, "md5_digest": "31eff6589ea409aa48821b5f28cad79b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 34138, "upload_time": "2019-10-22T19:18:10", "upload_time_iso_8601": "2019-10-22T19:18:10.628143Z", "url": "https://files.pythonhosted.org/packages/de/ec/be61590670c3d6658afff4b89f8020fa69f1b88e2770230a6fca31f609b8/ptr-19.10.22.tar.gz", "yanked": false, "yanked_reason": null } ], "19.10.6": [ { "comment_text": "", "digests": { "md5": "9ff23a75a33ea79619ff40b12e0d3ac9", "sha256": "e30b0919a0299ab06e17cde21c4bceff8674788e28aa9365435ffe379c1a2bea" }, "downloads": -1, "filename": "ptr-19.10.6-py3-none-any.whl", "has_sig": false, "md5_digest": "9ff23a75a33ea79619ff40b12e0d3ac9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 27096, "upload_time": "2019-10-07T00:52:52", "upload_time_iso_8601": "2019-10-07T00:52:52.993392Z", "url": "https://files.pythonhosted.org/packages/47/d4/ab77107ec87e26e7cee001258452d0fd617aea7a0a26b0c48efb90294b15/ptr-19.10.6-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "8589be056a6780016a6d671676323fd4", "sha256": "400e20c597c84ddc4e1363ad1a172ac82fd691516039205783b3a2121d4b4f1e" }, "downloads": -1, "filename": "ptr-19.10.6.tar.gz", "has_sig": false, "md5_digest": "8589be056a6780016a6d671676323fd4", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 29098, "upload_time": "2019-10-07T00:53:04", "upload_time_iso_8601": "2019-10-07T00:53:04.284850Z", "url": "https://files.pythonhosted.org/packages/14/78/a8bfa8e7123ad77786469b4e74420b94f85ef91d6cdc674d3f0fc404d22c/ptr-19.10.6.tar.gz", "yanked": false, "yanked_reason": null } ], "19.11.15": [ { "comment_text": "", "digests": { "md5": "b5c447de574b2d1c94b85a9f195ea7f4", "sha256": "c9702ec594a351fd4ef8f5b1106b9806fc4fe01e4b97156f42a02db76858a215" }, "downloads": -1, "filename": "ptr-19.11.15-py3-none-any.whl", "has_sig": false, "md5_digest": "b5c447de574b2d1c94b85a9f195ea7f4", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 27984, "upload_time": "2019-11-16T00:31:58", "upload_time_iso_8601": "2019-11-16T00:31:58.462971Z", "url": "https://files.pythonhosted.org/packages/27/40/4808c8fdb0a2cd1dd5f01c9a4357024a414b998d4324f5684876c0f34de4/ptr-19.11.15-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "95dafc24b224a003dfa1bbf29467f937", "sha256": "44771ef3f7123fbbe2e3d1f2af0cd9a6964ca6e466926a0b4c4b240efafe4d60" }, "downloads": -1, "filename": "ptr-19.11.15.tar.gz", "has_sig": false, "md5_digest": "95dafc24b224a003dfa1bbf29467f937", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 30336, "upload_time": "2019-11-16T00:32:00", "upload_time_iso_8601": "2019-11-16T00:32:00.216025Z", "url": "https://files.pythonhosted.org/packages/4c/17/96a23b7d432015c4122ad5befe24fb21c99475bb2d56d2f79fecc790e18a/ptr-19.11.15.tar.gz", "yanked": false, "yanked_reason": null } ], "19.11.2": [ { "comment_text": "", "digests": { "md5": "b9a34d79985d8aeff802a87a549caf9f", "sha256": "e10a24736b040748bb68f5bfba7f26152d48680462fe3eade0571926dbd42027" }, "downloads": -1, "filename": "ptr-19.11.2-py3-none-any.whl", "has_sig": false, "md5_digest": "b9a34d79985d8aeff802a87a549caf9f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 27774, "upload_time": "2019-11-02T23:55:33", "upload_time_iso_8601": "2019-11-02T23:55:33.220457Z", "url": "https://files.pythonhosted.org/packages/6a/95/13916adf1cf0bc6484a6e363a4256481eacd2aa2cb21e9f1c024374dce06/ptr-19.11.2-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "3368f874a5a212780943900ed727fe33", "sha256": "6799be8342508663e5e9678bd857dfd8c1e4a32ac2ae23e853412bc624aecf53" }, "downloads": -1, "filename": "ptr-19.11.2.tar.gz", "has_sig": false, "md5_digest": "3368f874a5a212780943900ed727fe33", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 30101, "upload_time": "2019-11-02T23:55:35", "upload_time_iso_8601": "2019-11-02T23:55:35.622801Z", "url": "https://files.pythonhosted.org/packages/77/9a/468c8a56577b8dd1ca95795a324b4f9459258520ff8f1dc78ab8af1e076f/ptr-19.11.2.tar.gz", "yanked": false, "yanked_reason": null } ], "19.11.21": [ { "comment_text": "", "digests": { "md5": "1b733ca5b3269767547411f6b72634f5", "sha256": "fc4904cb4428cccad7e88e28dcc0b8227f267900890915f915137b15cb4885e9" }, "downloads": -1, "filename": "ptr-19.11.21-py3-none-any.whl", "has_sig": false, "md5_digest": "1b733ca5b3269767547411f6b72634f5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 28027, "upload_time": "2019-11-22T03:51:15", "upload_time_iso_8601": "2019-11-22T03:51:15.967322Z", "url": "https://files.pythonhosted.org/packages/98/6a/309677f3b3cf74ba329a04e8e08fa3027f7b6a5c61f00c7824b5404a788f/ptr-19.11.21-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "09000a2cdaf36963d48576ddcd2d99e9", "sha256": "94a7aeb0e6a083c767a7c11b9275314a0424c8bb0158fcb207b244120ba8fe17" }, "downloads": -1, "filename": "ptr-19.11.21.tar.gz", "has_sig": false, "md5_digest": "09000a2cdaf36963d48576ddcd2d99e9", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 31048, "upload_time": "2019-11-22T03:51:17", "upload_time_iso_8601": "2019-11-22T03:51:17.248446Z", "url": "https://files.pythonhosted.org/packages/96/ba/02ab7f72b280d63b841b1e2fdde063cb52594d653d56ee3daffca9947d97/ptr-19.11.21.tar.gz", "yanked": false, "yanked_reason": null } ], "19.12.12": [ { "comment_text": "", "digests": { "md5": "cb467824c26a5927f96d0343dc1693cd", "sha256": "4b40fa7175c838c93230b58e9269b5ffa449a452e6c463283226c1e2cf4a6026" }, "downloads": -1, "filename": "ptr-19.12.12-py3-none-any.whl", "has_sig": false, "md5_digest": "cb467824c26a5927f96d0343dc1693cd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 28292, "upload_time": "2019-12-12T23:05:38", "upload_time_iso_8601": "2019-12-12T23:05:38.383019Z", "url": "https://files.pythonhosted.org/packages/64/a9/c90b7db52fb8447914efbdbd0ba0270acc9076c5609a984969d47e9f8c6d/ptr-19.12.12-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "f9426d8423c30e95ed4b34a5e1247ec5", "sha256": "e5e782206914e071a01fdb15f75705b4925db75bdbecdcf47edff1aa9dac9f1a" }, "downloads": -1, "filename": "ptr-19.12.12.tar.gz", "has_sig": false, "md5_digest": "f9426d8423c30e95ed4b34a5e1247ec5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 31356, "upload_time": "2019-12-12T23:05:39", "upload_time_iso_8601": "2019-12-12T23:05:39.901315Z", "url": "https://files.pythonhosted.org/packages/cd/2c/101c2f82978c105cc3fdaff80377d2f3a25cc8c35782405059411fc4e31b/ptr-19.12.12.tar.gz", "yanked": false, "yanked_reason": null } ], "19.12.13": [ { "comment_text": "", "digests": { "md5": "3250707161d0cf078c9ec72a4b7f47c3", "sha256": "c8cb98e6cbef9c20fecd4cb3e68fa7b8488a762369a81be025c3520a14cf924c" }, "downloads": -1, "filename": "ptr-19.12.13-py3-none-any.whl", "has_sig": false, "md5_digest": "3250707161d0cf078c9ec72a4b7f47c3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 28384, "upload_time": "2019-12-13T22:50:33", "upload_time_iso_8601": "2019-12-13T22:50:33.805474Z", "url": "https://files.pythonhosted.org/packages/d3/bc/c4a1af17901455fd7cbd0aa56d6e86a7f06b70c8a5cb3675f21a75cf9e19/ptr-19.12.13-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "6d98aa25e9800ce2cac439590fcd93e7", "sha256": "034da3edc93158f037812cb9cf1ef11604c6e8d0db412615f3c5e1d1236ff093" }, "downloads": -1, "filename": "ptr-19.12.13.tar.gz", "has_sig": false, "md5_digest": "6d98aa25e9800ce2cac439590fcd93e7", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 31554, "upload_time": "2019-12-13T22:50:35", "upload_time_iso_8601": "2019-12-13T22:50:35.401206Z", "url": "https://files.pythonhosted.org/packages/28/7e/d55acb27b411bd87b9a5f3c6bde2e08df1ba65298e66ef7713cd9e1748b8/ptr-19.12.13.tar.gz", "yanked": false, "yanked_reason": null } ], "19.12.25": [ { "comment_text": "", "digests": { "md5": "6f11e532eb70552c98172cbf997d6c95", "sha256": "ab98be93f885e2a6ba2983e726d85ed1e244fa0b8335d742e824733b6de1cd0b" }, "downloads": -1, "filename": "ptr-19.12.25-py3-none-any.whl", "has_sig": false, "md5_digest": "6f11e532eb70552c98172cbf997d6c95", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 28513, "upload_time": "2019-12-25T19:45:45", "upload_time_iso_8601": "2019-12-25T19:45:45.191283Z", "url": "https://files.pythonhosted.org/packages/56/39/077a41c2fb41639b8e29ffa330f3ea6b81d51f833ea4b69bde1ca867df49/ptr-19.12.25-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "6082efd284ef0d1e8dd52b95c6f46add", "sha256": "4740a6d8172f982bb555a5d1bc95cad33c4a464fcde0fe84259ddb26dd13c9ae" }, "downloads": -1, "filename": "ptr-19.12.25.tar.gz", "has_sig": false, "md5_digest": "6082efd284ef0d1e8dd52b95c6f46add", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 31986, "upload_time": "2019-12-25T19:45:46", "upload_time_iso_8601": "2019-12-25T19:45:46.396204Z", "url": "https://files.pythonhosted.org/packages/49/1e/a88bbb3575e95d489dac4063413a18b677d0e2a6496fb241a3c92ecb3852/ptr-19.12.25.tar.gz", "yanked": false, "yanked_reason": null } ], "19.2.10": [ { "comment_text": "", "digests": { "md5": "d2d95b93b1eec8d7efe176a50665629f", "sha256": "bd2bc2a491803aa9bce2b4bdac3d13736b1fdfaa1e681dbd57cad3f686ef8515" }, "downloads": -1, "filename": "ptr-19.2.10-py3-none-any.whl", "has_sig": false, "md5_digest": "d2d95b93b1eec8d7efe176a50665629f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 22128, "upload_time": "2019-02-10T20:27:51", "upload_time_iso_8601": "2019-02-10T20:27:51.992676Z", "url": "https://files.pythonhosted.org/packages/48/08/e78091efe4f4358cbdb68e19e11852e53eed5b8e6fd1f0dc414e27ee097a/ptr-19.2.10-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "badbf50c0df69aca2a228ffa37a2f799", "sha256": "ab6aeff731b7476e6be375a182f1e47fba0be8482dc730c4522d76f746eec956" }, "downloads": -1, "filename": "ptr-19.2.10.tar.gz", "has_sig": false, "md5_digest": "badbf50c0df69aca2a228ffa37a2f799", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 20639, "upload_time": "2019-02-10T20:28:00", "upload_time_iso_8601": "2019-02-10T20:28:00.043460Z", "url": "https://files.pythonhosted.org/packages/e3/a2/09b2fce350fa7f9654f35d1ee167d5e7696aa09b719118615d437c1f8f46/ptr-19.2.10.tar.gz", "yanked": false, "yanked_reason": null } ], "19.2.12": [ { "comment_text": "", "digests": { "md5": "cc1d6f8435b560d2f39b3c1cc7c09c2c", "sha256": "b612318cefc6163583f36c8c8ab8c9bc01711cef0c240272562ada866aaea5d3" }, "downloads": -1, "filename": "ptr-19.2.12-py3-none-any.whl", "has_sig": false, "md5_digest": "cc1d6f8435b560d2f39b3c1cc7c09c2c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 22586, "upload_time": "2019-02-13T04:09:57", "upload_time_iso_8601": "2019-02-13T04:09:57.462561Z", "url": "https://files.pythonhosted.org/packages/ce/27/9c6098161f6c41bdc708a1cb43acbbf080c866c3aeb1c52ea83081ba4aac/ptr-19.2.12-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "4ac076463aff3a9df6e2cffab8ae7e66", "sha256": "4f02096859f7e154d372269cdb64ab41691663de0f4475a25d99cb9d63c2b007" }, "downloads": -1, "filename": "ptr-19.2.12.tar.gz", "has_sig": false, "md5_digest": "4ac076463aff3a9df6e2cffab8ae7e66", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 21096, "upload_time": "2019-02-13T04:11:11", "upload_time_iso_8601": "2019-02-13T04:11:11.661458Z", "url": "https://files.pythonhosted.org/packages/31/6d/c2131b974c3e88b53e3a1f25bcefdf987811dbbc00126859710957d50b6b/ptr-19.2.12.tar.gz", "yanked": false, "yanked_reason": null } ], "19.2.8.post2": [ { "comment_text": "", "digests": { "md5": "92780d8df2b1c1e3604461c2ef3e0138", "sha256": "64ae73c8df7e5c7c629c452f11995073204719f1035248df2ceb8eea5a6a8d29" }, "downloads": -1, "filename": "ptr-19.2.8.post2-py3-none-any.whl", "has_sig": false, "md5_digest": "92780d8df2b1c1e3604461c2ef3e0138", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 21470, "upload_time": "2019-02-08T23:25:45", "upload_time_iso_8601": "2019-02-08T23:25:45.313057Z", "url": "https://files.pythonhosted.org/packages/8f/34/e7bdee8db3f6bf9924964c57b6a7448e476b324b40b3c94cb0a991fe4d4c/ptr-19.2.8.post2-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "0bcac8fed31a2d5f61568b684d13844e", "sha256": "47de9aa28f415f7313e6cafb14dd2bb1764c12aad3cca290adc3136d58c5a3c2" }, "downloads": -1, "filename": "ptr-19.2.8.post2.tar.gz", "has_sig": false, "md5_digest": "0bcac8fed31a2d5f61568b684d13844e", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 19880, "upload_time": "2019-02-08T23:25:53", "upload_time_iso_8601": "2019-02-08T23:25:53.369100Z", "url": "https://files.pythonhosted.org/packages/9f/c5/9ea390c301f940bc28d7db88846bd877ecbe5e9d2c70b77b1b390e8c1faf/ptr-19.2.8.post2.tar.gz", "yanked": false, "yanked_reason": null } ], "19.3.5": [ { "comment_text": "", "digests": { "md5": "cd4b6eb290d7afac46cf510aa0c8f248", "sha256": "47cdd5667da53da39f6dd1d60b4c013894e6eb286bc2a20b27e3da244fc6190a" }, "downloads": -1, "filename": "ptr-19.3.5-py3-none-any.whl", "has_sig": false, "md5_digest": "cd4b6eb290d7afac46cf510aa0c8f248", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 24636, "upload_time": "2019-03-05T13:28:31", "upload_time_iso_8601": "2019-03-05T13:28:31.924360Z", "url": "https://files.pythonhosted.org/packages/56/7f/6af0618e51cc2e952bbfeb2d93826424bce6618e1aba7dace7e93d44011f/ptr-19.3.5-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "ca45714d4189e1ddea8cedd9b40ac761", "sha256": "279c225b70c0055afd82dec629bc5d2f07fe94451bfa967b50c5503f1fc786ad" }, "downloads": -1, "filename": "ptr-19.3.5.tar.gz", "has_sig": false, "md5_digest": "ca45714d4189e1ddea8cedd9b40ac761", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 23560, "upload_time": "2019-03-05T13:28:35", "upload_time_iso_8601": "2019-03-05T13:28:35.472507Z", "url": "https://files.pythonhosted.org/packages/bb/09/980ec17a2a271f94064db8f2b45c4a82bc2f2503d2de44c6f298a82880f1/ptr-19.3.5.tar.gz", "yanked": false, "yanked_reason": null } ], "19.5.3": [ { "comment_text": "", "digests": { "md5": "7c8399b4926e3997c846af36da048fa2", "sha256": "6829d63f10846a3d5b12de2aebaed4df9bf62353da3db7ed884132f7bcacf6c2" }, "downloads": -1, "filename": "ptr-19.5.3-py3-none-any.whl", "has_sig": false, "md5_digest": "7c8399b4926e3997c846af36da048fa2", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 25423, "upload_time": "2019-05-03T19:46:36", "upload_time_iso_8601": "2019-05-03T19:46:36.857937Z", "url": "https://files.pythonhosted.org/packages/41/fc/b4ec155ca8b84e00c0d3c71cbe85141f2abb3904fb4c4ff2cb48ae691825/ptr-19.5.3-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "72434232e28a576e03b6bf2f14b22a3d", "sha256": "3b1693297de03872e752a6b965f2c744e03e50dc26a3ace83a262d2f5465bd84" }, "downloads": -1, "filename": "ptr-19.5.3.tar.gz", "has_sig": false, "md5_digest": "72434232e28a576e03b6bf2f14b22a3d", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 30097, "upload_time": "2019-05-03T19:46:39", "upload_time_iso_8601": "2019-05-03T19:46:39.724659Z", "url": "https://files.pythonhosted.org/packages/02/7d/cd68bd3bf79d953034677dc56b156aef3b90b0eec93f20a35f6cce280b41/ptr-19.5.3.tar.gz", "yanked": false, "yanked_reason": null } ], "19.6.15": [ { "comment_text": "", "digests": { "md5": "04ce6a9085d7e709367664c4a28eae36", "sha256": "22d89e6fcd3468704e67ff6da8a419f393581f7254d80a32108a783de0af885f" }, "downloads": -1, "filename": "ptr-19.6.15-py3-none-any.whl", "has_sig": false, "md5_digest": "04ce6a9085d7e709367664c4a28eae36", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 25781, "upload_time": "2019-06-15T15:09:31", "upload_time_iso_8601": "2019-06-15T15:09:31.066417Z", "url": "https://files.pythonhosted.org/packages/53/79/5224005131991a0b03360679db6d8c3138a658d50308c8450ae0e903ae8c/ptr-19.6.15-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "50a215f6f11800aae7a5b9d6ab3542d0", "sha256": "e84d46fef677d716468af89f932006726a536d72b22ca47188aaaee7ed5c5092" }, "downloads": -1, "filename": "ptr-19.6.15.tar.gz", "has_sig": false, "md5_digest": "50a215f6f11800aae7a5b9d6ab3542d0", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 27043, "upload_time": "2019-06-15T15:09:40", "upload_time_iso_8601": "2019-06-15T15:09:40.971631Z", "url": "https://files.pythonhosted.org/packages/c3/c5/e57c723e52aa7297aded03278c79eae63be8b2a8a58d147aaf70315f3b2f/ptr-19.6.15.tar.gz", "yanked": false, "yanked_reason": null } ], "19.7.16": [ { "comment_text": "", "digests": { "md5": "d5ddc971273c24be4969954564fb2908", "sha256": "16087d6a6eda80f7ca515f3b9adcb0d265c2750192ccea11a6ddb7cbea09cb97" }, "downloads": -1, "filename": "ptr-19.7.16-py3-none-any.whl", "has_sig": false, "md5_digest": "d5ddc971273c24be4969954564fb2908", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 26372, "upload_time": "2019-07-16T17:14:24", "upload_time_iso_8601": "2019-07-16T17:14:24.310869Z", "url": "https://files.pythonhosted.org/packages/9c/31/622321011df0fa339f44992cd58f76ccaf3872205a2286ebe9e982e0feb4/ptr-19.7.16-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "05495810a67738651b1da5f91c95c21f", "sha256": "8482a3a7585e1d8b2d180899fa48d584b547d528eef9950a5565bcc3c2a75a03" }, "downloads": -1, "filename": "ptr-19.7.16.tar.gz", "has_sig": false, "md5_digest": "05495810a67738651b1da5f91c95c21f", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 31686, "upload_time": "2019-07-16T17:14:27", "upload_time_iso_8601": "2019-07-16T17:14:27.000125Z", "url": "https://files.pythonhosted.org/packages/e0/88/d08c74fc3d9175c31e8adcee251b1433027648648eaf24d0de2db926fbf6/ptr-19.7.16.tar.gz", "yanked": false, "yanked_reason": null } ], "19.8.7": [ { "comment_text": "", "digests": { "md5": "1b17bc672a8d3cfb6f4e7e153bccded9", "sha256": "79a72b1b530070f9842435227fabb2c3610e168ca0ee2a7ab74de6ea78fb3a5c" }, "downloads": -1, "filename": "ptr-19.8.7-py3-none-any.whl", "has_sig": false, "md5_digest": "1b17bc672a8d3cfb6f4e7e153bccded9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 26175, "upload_time": "2019-08-07T16:53:19", "upload_time_iso_8601": "2019-08-07T16:53:19.627792Z", "url": "https://files.pythonhosted.org/packages/6c/69/a752523ece014510b5164ac0c6f14d87f13ff0104d45a7118c5126c724c8/ptr-19.8.7-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "3ddf292330b1472cc522829ed475880c", "sha256": "5c10f38744bc175ce8f22c03bf2bfadd1c4cd695cbe6106b478f621d7ba82806" }, "downloads": -1, "filename": "ptr-19.8.7.tar.gz", "has_sig": false, "md5_digest": "3ddf292330b1472cc522829ed475880c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 31965, "upload_time": "2019-08-07T16:53:22", "upload_time_iso_8601": "2019-08-07T16:53:22.003089Z", "url": "https://files.pythonhosted.org/packages/9e/b9/7c98e50c8b758c1f44d660a2422c5ac104cb7914a2d5be27a9d4effd1d93/ptr-19.8.7.tar.gz", "yanked": false, "yanked_reason": null } ], "19.9.11": [ { "comment_text": "", "digests": { "md5": "b44d2517cf057a48d8bff047f28ea7a2", "sha256": "3e89356b0d0ca045cafac6c2d6afba3488780198a81f78e94b0cd8862f037845" }, "downloads": -1, "filename": "ptr-19.9.11-py3-none-any.whl", "has_sig": false, "md5_digest": "b44d2517cf057a48d8bff047f28ea7a2", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 26442, "upload_time": "2019-09-11T12:18:06", "upload_time_iso_8601": "2019-09-11T12:18:06.801504Z", "url": "https://files.pythonhosted.org/packages/7e/8b/92ab0334333060f26064d31d49810f77c3e460354f7043e8d108adf9941f/ptr-19.9.11-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "d8b966cafd9105ebf9abd8262d917982", "sha256": "1d4c78b642c442a2e5f7a788d37172985f992bbb3f032461d759a761e7675614" }, "downloads": -1, "filename": "ptr-19.9.11.tar.gz", "has_sig": false, "md5_digest": "d8b966cafd9105ebf9abd8262d917982", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 28396, "upload_time": "2019-09-11T12:18:25", "upload_time_iso_8601": "2019-09-11T12:18:25.296603Z", "url": "https://files.pythonhosted.org/packages/36/e7/10988fc933512b3a41ce60ebcebc50395da060d2742c6d1185c5e2f8b1fc/ptr-19.9.11.tar.gz", "yanked": false, "yanked_reason": null } ], "19.9.14": [ { "comment_text": "", "digests": { "md5": "05174433e32e1b05be9cf2fc43fba77d", "sha256": "cec6ed69c40af41e330fa6d1e27789595b9e5be8db1da186aa32f69d6f1cb8df" }, "downloads": -1, "filename": "ptr-19.9.14-py3-none-any.whl", "has_sig": false, "md5_digest": "05174433e32e1b05be9cf2fc43fba77d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 26563, "upload_time": "2019-09-14T21:08:26", "upload_time_iso_8601": "2019-09-14T21:08:26.686165Z", "url": "https://files.pythonhosted.org/packages/2a/eb/885d658d2c7e4ce8fdbcdcc23c789a58ab6bb0041fbc6816e270bca566c8/ptr-19.9.14-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "20efc0e3cbefad7f17ce729ec0427f3a", "sha256": "73af6176b570203299e89a1427969f6af5cf6ae40e41df9322ec11fc1c320041" }, "downloads": -1, "filename": "ptr-19.9.14.tar.gz", "has_sig": false, "md5_digest": "20efc0e3cbefad7f17ce729ec0427f3a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 32616, "upload_time": "2019-09-14T21:08:29", "upload_time_iso_8601": "2019-09-14T21:08:29.176403Z", "url": "https://files.pythonhosted.org/packages/dd/41/6ddbc7fff4c42a431e4208069ab88d6d006b65aef07c8cb392b0a06815ff/ptr-19.9.14.tar.gz", "yanked": false, "yanked_reason": null } ], "20.2.26": [ { "comment_text": "", "digests": { "md5": "8032d1064eeb3562908769513eca8940", "sha256": "a6113989d47d6e8bf4db0987561235c5fd8e2b317fc7a1480ee2f3bcd0f02f94" }, "downloads": -1, "filename": "ptr-20.2.26-py3-none-any.whl", "has_sig": false, "md5_digest": "8032d1064eeb3562908769513eca8940", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 28446, "upload_time": "2020-02-27T00:05:59", "upload_time_iso_8601": "2020-02-27T00:05:59.245954Z", "url": "https://files.pythonhosted.org/packages/ce/39/94f68c58ce8271a91dd72db9611a7d1f9d562f73fc4aae25bf166078e47b/ptr-20.2.26-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "4fc97f46138cea4006110c5ccd4f493c", "sha256": "ee3e5888e74c29b5ce2abb77fd281173d9d11a31aa5adc069dc9d3f1716d1ddc" }, "downloads": -1, "filename": "ptr-20.2.26.tar.gz", "has_sig": false, "md5_digest": "4fc97f46138cea4006110c5ccd4f493c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 32049, "upload_time": "2020-02-27T00:06:00", "upload_time_iso_8601": "2020-02-27T00:06:00.790781Z", "url": "https://files.pythonhosted.org/packages/dd/a5/6d2411064cfe1cbb929278c260f5e649dd247eec16ff10486b0ab153ae71/ptr-20.2.26.tar.gz", "yanked": false, "yanked_reason": null } ], "21.11.23": [ { "comment_text": "", "digests": { "md5": "be6b022d0a55905a818628a03edbdf5a", "sha256": "94f9ac16062798850043a31af2d4092e49121d6948007919baf1797652a1bf39" }, "downloads": -1, "filename": "ptr-21.11.23-py3-none-any.whl", "has_sig": false, "md5_digest": "be6b022d0a55905a818628a03edbdf5a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 20395, "upload_time": "2021-11-23T23:53:06", "upload_time_iso_8601": "2021-11-23T23:53:06.651384Z", "url": "https://files.pythonhosted.org/packages/59/f3/d2f09d90b5e329b2fcff04da70cc9916d3a9bd9a1ab974f0f27c803e511b/ptr-21.11.23-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "59bd1263114fd47ca8225e76d9cf1ff6", "sha256": "efbcf564127ea6b7f87506f0d5a1d65e90e0f39ffe68ece5f60713a6f9a05858" }, "downloads": -1, "filename": "ptr-21.11.23.tar.gz", "has_sig": false, "md5_digest": "59bd1263114fd47ca8225e76d9cf1ff6", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 31205, "upload_time": "2021-11-23T23:53:08", "upload_time_iso_8601": "2021-11-23T23:53:08.185337Z", "url": "https://files.pythonhosted.org/packages/0b/14/aba3fcdafd12282ec83d51e6a22351937439cd18711efd63cbf43f601682/ptr-21.11.23.tar.gz", "yanked": false, "yanked_reason": null } ], "21.3.16": [ { "comment_text": "", "digests": { "md5": "ed6d99d94b8b33dac23eea0f52b37a40", "sha256": "2fd48ad9ffc2734661faa1a2017f86b0ebffccf538762e15df673970aeef9dcc" }, "downloads": -1, "filename": "ptr-21.3.16-py3-none-any.whl", "has_sig": false, "md5_digest": "ed6d99d94b8b33dac23eea0f52b37a40", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 19639, "upload_time": "2021-03-16T16:40:25", "upload_time_iso_8601": "2021-03-16T16:40:25.435835Z", "url": "https://files.pythonhosted.org/packages/93/27/b4d2f21fbc8983b456b6074939b677a11eb6f6660d8a35216dd258f9c4c9/ptr-21.3.16-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "6f5ae8efbca0a34a989584e68a59a99a", "sha256": "b42f5efb6366a799518cd5a7f02ea9fad89c686c40f1162c4bf779fe3421052d" }, "downloads": -1, "filename": "ptr-21.3.16.tar.gz", "has_sig": false, "md5_digest": "6f5ae8efbca0a34a989584e68a59a99a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 32817, "upload_time": "2021-03-16T16:40:26", "upload_time_iso_8601": "2021-03-16T16:40:26.563604Z", "url": "https://files.pythonhosted.org/packages/5b/44/17e8b6a772adc8b0030c2ab228344e3c1a6c792c352e1c1a86561810b884/ptr-21.3.16.tar.gz", "yanked": false, "yanked_reason": null } ], "21.5.28": [ { "comment_text": "", "digests": { "md5": "b747327fc1596d10e5c8a2ed0c0d3a43", "sha256": "124bfdf7473ac3668d4686aace034fc3042994e7ab1f77841e6316da32d8c98e" }, "downloads": -1, "filename": "ptr-21.5.28-py3-none-any.whl", "has_sig": false, "md5_digest": "b747327fc1596d10e5c8a2ed0c0d3a43", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 19780, "upload_time": "2021-05-28T23:30:41", "upload_time_iso_8601": "2021-05-28T23:30:41.089183Z", "url": "https://files.pythonhosted.org/packages/7c/cc/57e1f7c2325089276f757d3510b003ec10a18d1371ba73a78d0d8203878e/ptr-21.5.28-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "b4a1f1231bb2e3bba3253ebf502c9670", "sha256": "7292dc65bf448b2456bc432edf02c37b0f6ef5a5c6df88a068c5512759de7e85" }, "downloads": -1, "filename": "ptr-21.5.28.tar.gz", "has_sig": false, "md5_digest": "b4a1f1231bb2e3bba3253ebf502c9670", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 30412, "upload_time": "2021-05-28T23:30:42", "upload_time_iso_8601": "2021-05-28T23:30:42.439783Z", "url": "https://files.pythonhosted.org/packages/e2/b3/2b2aa01ccfe957ca8d9f4094b46e6e8ca01dedc42b2606feba7d9f6531ec/ptr-21.5.28.tar.gz", "yanked": false, "yanked_reason": null } ], "22.2.2": [ { "comment_text": "", "digests": { "md5": "71b87862f0da61199960aca6aa36ade8", "sha256": "9a59f1c2b9b50475ecc9ad922f6939a3e329d7b256f9c51d09a2f1b382485037" }, "downloads": -1, "filename": "ptr-22.2.2-py3-none-any.whl", "has_sig": false, "md5_digest": "71b87862f0da61199960aca6aa36ade8", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.7", "size": 20572, "upload_time": "2022-02-02T18:50:10", "upload_time_iso_8601": "2022-02-02T18:50:10.641845Z", "url": "https://files.pythonhosted.org/packages/ac/da/5986b837b890c6ebc0801be3c1296a104cf648330ab11db2e0c2757f51ad/ptr-22.2.2-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "51493345f9785832b395b7c6ba01e11c", "sha256": "163fd748e0a4079459bf5ed4b3ac5bd07ea33a261c74b79eb41105e749316c3b" }, "downloads": -1, "filename": "ptr-22.2.2.tar.gz", "has_sig": false, "md5_digest": "51493345f9785832b395b7c6ba01e11c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.7", "size": 32111, "upload_time": "2022-02-02T18:50:12", "upload_time_iso_8601": "2022-02-02T18:50:12.083372Z", "url": "https://files.pythonhosted.org/packages/e0/9b/489d5887c2d7d05fb17434f5eeebe586537a1a2b0596b30a1d0a690f24dc/ptr-22.2.2.tar.gz", "yanked": false, "yanked_reason": null } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "71b87862f0da61199960aca6aa36ade8", "sha256": "9a59f1c2b9b50475ecc9ad922f6939a3e329d7b256f9c51d09a2f1b382485037" }, "downloads": -1, "filename": "ptr-22.2.2-py3-none-any.whl", "has_sig": false, "md5_digest": "71b87862f0da61199960aca6aa36ade8", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.7", "size": 20572, "upload_time": "2022-02-02T18:50:10", "upload_time_iso_8601": "2022-02-02T18:50:10.641845Z", "url": "https://files.pythonhosted.org/packages/ac/da/5986b837b890c6ebc0801be3c1296a104cf648330ab11db2e0c2757f51ad/ptr-22.2.2-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "51493345f9785832b395b7c6ba01e11c", "sha256": "163fd748e0a4079459bf5ed4b3ac5bd07ea33a261c74b79eb41105e749316c3b" }, "downloads": -1, "filename": "ptr-22.2.2.tar.gz", "has_sig": false, "md5_digest": "51493345f9785832b395b7c6ba01e11c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.7", "size": 32111, "upload_time": "2022-02-02T18:50:12", "upload_time_iso_8601": "2022-02-02T18:50:12.083372Z", "url": "https://files.pythonhosted.org/packages/e0/9b/489d5887c2d7d05fb17434f5eeebe586537a1a2b0596b30a1d0a690f24dc/ptr-22.2.2.tar.gz", "yanked": false, "yanked_reason": null } ], "vulnerabilities": [] }