Giter VIP home page Giter VIP logo

phantom-types's Introduction

Depiction of phantom types in the wild

phantom-types

CI Build Status Documentation Build Status Test coverage report

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

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 .[test,pydantic,phonenumbers]

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

phantom-types's People

Contributors

antonagestam avatar sobolevn avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.