All Projects → antonagestam → phantom-types

antonagestam / phantom-types

Licence: BSD-3-Clause license
Phantom types for Python.

Programming Languages

python
139335 projects - #7 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to phantom-types

vim-mypy
Vim plugin for executing Python's optional static type checker MyPy (http://mypy-lang.org/)
Stars: ✭ 89 (-25.83%)
Mutual labels:  static-analysis, mypy
flake8-mypy
A plugin for flake8 integrating Mypy.
Stars: ✭ 103 (-14.17%)
Mutual labels:  typing, mypy
pybind11-stubgen
Generates stubs for python modules (targeted to C++ extensions compiled with pybind11)
Stars: ✭ 103 (-14.17%)
Mutual labels:  typing, mypy
Pytype
A static type analyzer for Python code
Stars: ✭ 3,545 (+2854.17%)
Mutual labels:  static-analysis, typing
Vehicle-Security-Toolkit
汽车/安卓/固件/代码安全测试工具集
Stars: ✭ 367 (+205.83%)
Mutual labels:  static-analysis
phpcs-psr4-sniff
[READ-ONLY] PHP_CodeSniffer sniff that checks class name matches PSR-4 project structure.
Stars: ✭ 23 (-80.83%)
Mutual labels:  static-analysis
facts
Refined types
Stars: ✭ 58 (-51.67%)
Mutual labels:  refinement-types
gospal
Go static program analyser
Stars: ✭ 56 (-53.33%)
Mutual labels:  static-analysis
cmake-init
The missing CMake project initializer
Stars: ✭ 1,071 (+792.5%)
Mutual labels:  static-analysis
inline-plz
Inline your lint messages
Stars: ✭ 32 (-73.33%)
Mutual labels:  static-analysis
klever
Read-only mirror of the Klever Git repository
Stars: ✭ 18 (-85%)
Mutual labels:  static-analysis
subpy
Python subsets
Stars: ✭ 41 (-65.83%)
Mutual labels:  static-analysis
tt
Practicing touch typing, and monitor your typing speed using your own text files
Stars: ✭ 68 (-43.33%)
Mutual labels:  typing
Lyra
No description or website provided.
Stars: ✭ 23 (-80.83%)
Mutual labels:  static-analysis
dlint
Dlint is a tool for encouraging best coding practices and helping ensure Python code is secure.
Stars: ✭ 130 (+8.33%)
Mutual labels:  static-analysis
firebase-rxjs
Firebase with Observables, Type Checking of Schema, Zone.js aware and Angular ready.
Stars: ✭ 17 (-85.83%)
Mutual labels:  static-typing
swap-detector
A library for detecting swapped arguments in function calls, and a Clang Static Analyzer plugin used to demonstrate the library.
Stars: ✭ 19 (-84.17%)
Mutual labels:  static-analysis
aparoid
Static and dynamic Android application security analysis
Stars: ✭ 62 (-48.33%)
Mutual labels:  static-analysis
typing.js
Js library for creating typing effect on webpage.
Stars: ✭ 22 (-81.67%)
Mutual labels:  typing
localhost-sonarqube
Analysing source code locally with SonarQube in a Docker environment.
Stars: ✭ 17 (-85.83%)
Mutual labels:  static-analysis

phantom-types

CI Build Status Documentation Build Status Test coverage report
PyPI Package Python versions

Phantom types for Python will help you make illegal states unrepresentable and avoid shotgun parsing by enabling you to practice "Parse, don't validate".

Checkout the complete documentation on Read the Docs →

Installation

$  python3 -m pip install phantom-types

Extras

$  python3 -m pip install phantom-types[all]

Examples

By introducing a phantom type we can define a pre-condition for a function argument.

from phantom import Phantom
from phantom.predicates.collection import contained


class Name(str, Phantom, predicate=contained({"Jane", "Joe"})):
    ...


def greet(name: Name):
    print(f"Hello {name}!")

Now this will be a valid call.

greet(Name.parse("Jane"))

... and so will this.

joe = "Joe"
assert isinstance(joe, Name)
greet(joe)

But this will yield a static type checking error.

greet("bird")

Runtime type checking

By combining phantom types with a runtime type-checker like beartype or typeguard, we can achieve the same level of security as you'd gain from using contracts.

import datetime
from beartype import beartype
from phantom.datetime import TZAware


@beartype
def soon(dt: TZAware) -> TZAware:
    return dt + datetime.timedelta(seconds=10)

The soon function will now validate that both its argument and return value is timezone aware, e.g. pre- and post conditions.

Pydantic support

Phantom types are ready to use with pydantic and have integrated support out-of-the-box. Subclasses of Phantom work with both pydantic's validation and its schema generation.

class Name(str, Phantom, predicate=contained({"Jane", "Joe"})):
    @classmethod
    def __schema__(cls) -> Schema:
        return super().__schema__() | {
            "description": "Either Jane or Joe",
            "format": "custom-name",
        }


class Person(BaseModel):
    name: Name
    created: TZAware


print(json.dumps(Person.schema(), indent=2))

The code above outputs the following JSONSchema.

{
  "title": "Person",
  "type": "object",
  "properties": {
    "name": {
      "title": "Name",
      "description": "Either Jane or Joe",
      "format": "custom-name",
      "type": "string"
    },
    "created": {
      "title": "TZAware",
      "description": "A date-time with timezone data.",
      "type": "string",
      "format": "date-time"
    }
  },
  "required": ["name", "created"]
}

Development

Install development requirements, preferably in a virtualenv:

$ python3 -m pip install .[all,test]

Run tests:

$ pytest
# or
$ make test

Linting and static type checking is setup with pre-commit, after installing it you can setup hooks with the following command, so that checks run before you push changes.

# configure hooks to run when pushing
$ pre-commit install -t pre-push
# or when committing
$ pre-commit install -t pre-commit
# run all checks
$ pre-commit run --all-files
# or just a single hook
$ pre-commit run mypy --all-files

In addition to static type checking, the project is setup with pytest-mypy-plugins to test that exposed mypy types work as expected, these checks will run together with the rest of the test suite, but you can single them out with the following command.

$ make test-typing
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].