pytest-revealtype-injector


Namepytest-revealtype-injector JSON
Version 0.2.3 PyPI version JSON
download
home_pageNone
SummaryPytest plugin for replacing reveal_type() calls inside test functions with static and runtime type checking result comparison, for confirming type annotation validity.
upload_time2024-12-19 01:58:01
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseNone
keywords annotation dynamic-typing pytest reveal_type static-typing stub stubs type-checking types typing
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ![PyPI - Version](https://img.shields.io/pypi/v/pytest-revealtype-injector)
![GitHub Release Date](https://img.shields.io/github/release-date/abelcheung/pytest-revealtype-injector)
![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fgithub.com%2Fabelcheung%2Fpytest-revealtype-injector%2Fraw%2Frefs%2Fheads%2Fmain%2Fpyproject.toml)
![PyPI - Wheel](https://img.shields.io/pypi/wheel/pytest-revealtype-injector)

`pytest-revealtype-injector` is a `pytest` plugin for replacing [`reveal_type()`](https://docs.python.org/3/library/typing.html#typing.reveal_type) calls inside test functions as something more sophisticated. It does the following tasks in parallel:

- Launch external static type checkers (`pyright` and `mypy`) and store `reveal_type` results.
- Use [`typeguard`](https://github.com/agronholm/typeguard) to verify the aforementioned static type checker result _really_ matches runtime code result.

## Usage

In short: install this plugin, create test functions which calls `reveal_type()` with variable or function return result, done.

### The longer story

This plugin would be automatically enabled when launching `pytest`.

For using `reveal_type()` inside tests, there is no boiler plate code involved. Import `reveal_type` normally, like:

```python
from typing import reveal_type
```

Just importing `typing` module is fine too (or import `typing_extensions` for Python 3.10, because `reveal_type()` is only available officially since 3.11):

```python
import typing

def test_something():
    x: str = 1  # type: ignore  # pyright: ignore
    typing.reveal_type(x)  # typeguard fails here
```

Since this plugin scans for `reveal_type()` for replacement under carpet, even `import ... as ...` syntax works too:

```python
import typing as typ  # or...
from typing import reveal_type as rt
```

### Limitations

But there are 2 caveats.

1. This plugin only searches for global import in test files, so local import inside test function doesn't work. That means following code doesn't utilize this plugin at all:

```python
def test_something():
    from typing import reveal_type
    x = 1
    reveal_type(x)  # calls vanilla reveal_type()
```

2. `reveal_type()` calls have to stay in a single line, without anything else. This limitation comes from using [`eval` mode in AST parsing](https://docs.python.org/3/library/ast.html#ast.Expression).

## Logging

This plugin uses standard [`logging`](https://docs.python.org/3/library/logging.html) internally. `pytest -v` can be used to reveal `INFO` and `DEBUG` logs. Given following example:

```python
def test_superfluous(self) -> None:
    x: list[str] = ['a', 'b', 'c', 1]  # type: ignore  # pyright: ignore
    reveal_type(x)
```

Something like this will be shown as test result:

```
...
    raise TypeCheckError(f"is not an instance of {qualified_name(origin_type)}")
E   typeguard.TypeCheckError: item 3 is not an instance of str (from pyright)
------------------------------------------------------------- Captured log call -------------------------------------------------------------
INFO     revealtype-injector:hooks.py:26 Replaced reveal_type() from global import with <function revealtype_injector at 0x00000238DB923D00>
DEBUG    revealtype-injector:main.py:60 Extraction OK: code='reveal_type(x)', result='x'
========================================================== short test summary info ==========================================================
FAILED tests/runtime/test_attrib.py::TestAttrib::test_superfluous - typeguard.TypeCheckError: item 3 is not an instance of str (from pyright)
============================================================= 1 failed in 3.38s =============================================================
```


## History

This pytest plugin starts its life as part of testsuite related utilities within [`types-lxml`](https://github.com/abelcheung/types-lxml). As `lxml` is a `cython` project and probably never incorporate inline python annotation in future, there is need to compare runtime result to static type checker output for discrepancy. As time goes by, it starts to make sense to manage as an independent project.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "pytest-revealtype-injector",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "annotation, dynamic-typing, pytest, reveal_type, static-typing, stub, stubs, type-checking, types, typing",
    "author": null,
    "author_email": "Abel Cheung <abelcheung@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/0d/b3/ec201676194bdb41f0ce856f88ebf73a71981952d1fb28ae9f7941b5da1d/pytest_revealtype_injector-0.2.3.tar.gz",
    "platform": null,
    "description": "![PyPI - Version](https://img.shields.io/pypi/v/pytest-revealtype-injector)\n![GitHub Release Date](https://img.shields.io/github/release-date/abelcheung/pytest-revealtype-injector)\n![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fgithub.com%2Fabelcheung%2Fpytest-revealtype-injector%2Fraw%2Frefs%2Fheads%2Fmain%2Fpyproject.toml)\n![PyPI - Wheel](https://img.shields.io/pypi/wheel/pytest-revealtype-injector)\n\n`pytest-revealtype-injector` is a `pytest` plugin for replacing [`reveal_type()`](https://docs.python.org/3/library/typing.html#typing.reveal_type) calls inside test functions as something more sophisticated. It does the following tasks in parallel:\n\n- Launch external static type checkers (`pyright` and `mypy`) and store `reveal_type` results.\n- Use [`typeguard`](https://github.com/agronholm/typeguard) to verify the aforementioned static type checker result _really_ matches runtime code result.\n\n## Usage\n\nIn short: install this plugin, create test functions which calls `reveal_type()` with variable or function return result, done.\n\n### The longer story\n\nThis plugin would be automatically enabled when launching `pytest`.\n\nFor using `reveal_type()` inside tests, there is no boiler plate code involved. Import `reveal_type` normally, like:\n\n```python\nfrom typing import reveal_type\n```\n\nJust importing `typing` module is fine too (or import `typing_extensions` for Python 3.10, because `reveal_type()` is only available officially since 3.11):\n\n```python\nimport typing\n\ndef test_something():\n    x: str = 1  # type: ignore  # pyright: ignore\n    typing.reveal_type(x)  # typeguard fails here\n```\n\nSince this plugin scans for `reveal_type()` for replacement under carpet, even `import ... as ...` syntax works too:\n\n```python\nimport typing as typ  # or...\nfrom typing import reveal_type as rt\n```\n\n### Limitations\n\nBut there are 2 caveats.\n\n1. This plugin only searches for global import in test files, so local import inside test function doesn't work. That means following code doesn't utilize this plugin at all:\n\n```python\ndef test_something():\n    from typing import reveal_type\n    x = 1\n    reveal_type(x)  # calls vanilla reveal_type()\n```\n\n2. `reveal_type()` calls have to stay in a single line, without anything else. This limitation comes from using [`eval` mode in AST parsing](https://docs.python.org/3/library/ast.html#ast.Expression).\n\n## Logging\n\nThis plugin uses standard [`logging`](https://docs.python.org/3/library/logging.html) internally. `pytest -v` can be used to reveal `INFO` and `DEBUG` logs. Given following example:\n\n```python\ndef test_superfluous(self) -> None:\n    x: list[str] = ['a', 'b', 'c', 1]  # type: ignore  # pyright: ignore\n    reveal_type(x)\n```\n\nSomething like this will be shown as test result:\n\n```\n...\n    raise TypeCheckError(f\"is not an instance of {qualified_name(origin_type)}\")\nE   typeguard.TypeCheckError: item 3 is not an instance of str (from pyright)\n------------------------------------------------------------- Captured log call -------------------------------------------------------------\nINFO     revealtype-injector:hooks.py:26 Replaced reveal_type() from global import with <function revealtype_injector at 0x00000238DB923D00>\nDEBUG    revealtype-injector:main.py:60 Extraction OK: code='reveal_type(x)', result='x'\n========================================================== short test summary info ==========================================================\nFAILED tests/runtime/test_attrib.py::TestAttrib::test_superfluous - typeguard.TypeCheckError: item 3 is not an instance of str (from pyright)\n============================================================= 1 failed in 3.38s =============================================================\n```\n\n\n## History\n\nThis pytest plugin starts its life as part of testsuite related utilities within [`types-lxml`](https://github.com/abelcheung/types-lxml). As `lxml` is a `cython` project and probably never incorporate inline python annotation in future, there is need to compare runtime result to static type checker output for discrepancy. As time goes by, it starts to make sense to manage as an independent project.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Pytest plugin for replacing reveal_type() calls inside test functions with static and runtime type checking result comparison, for confirming type annotation validity.",
    "version": "0.2.3",
    "project_urls": {
        "homepage": "https://github.com/abelcheung/pytest-revealtype-injector"
    },
    "split_keywords": [
        "annotation",
        " dynamic-typing",
        " pytest",
        " reveal_type",
        " static-typing",
        " stub",
        " stubs",
        " type-checking",
        " types",
        " typing"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "904c9155eeea4d24258a5763377f4897e0569fdb97454397d27248a7778b5165",
                "md5": "7c784a445de0e9c485f170262dec18dc",
                "sha256": "53e1a4ee773844899900b1e70325dd1a91ded6669592159b4a4419f5d2644413"
            },
            "downloads": -1,
            "filename": "pytest_revealtype_injector-0.2.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7c784a445de0e9c485f170262dec18dc",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 16131,
            "upload_time": "2024-12-19T01:58:00",
            "upload_time_iso_8601": "2024-12-19T01:58:00.236793Z",
            "url": "https://files.pythonhosted.org/packages/90/4c/9155eeea4d24258a5763377f4897e0569fdb97454397d27248a7778b5165/pytest_revealtype_injector-0.2.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0db3ec201676194bdb41f0ce856f88ebf73a71981952d1fb28ae9f7941b5da1d",
                "md5": "afaa071104c5b4c04f42eb8f5b39738d",
                "sha256": "18caa82595091211d9515e3e83231d74e26c0ecb07332841f0414ea6d88d5f82"
            },
            "downloads": -1,
            "filename": "pytest_revealtype_injector-0.2.3.tar.gz",
            "has_sig": false,
            "md5_digest": "afaa071104c5b4c04f42eb8f5b39738d",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 12653,
            "upload_time": "2024-12-19T01:58:01",
            "upload_time_iso_8601": "2024-12-19T01:58:01.693667Z",
            "url": "https://files.pythonhosted.org/packages/0d/b3/ec201676194bdb41f0ce856f88ebf73a71981952d1fb28ae9f7941b5da1d/pytest_revealtype_injector-0.2.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-12-19 01:58:01",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "abelcheung",
    "github_project": "pytest-revealtype-injector",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "pytest-revealtype-injector"
}
        
Elapsed time: 0.41995s