PythonのPhantomタイプは、「解析、検証しない」練習を可能にすることで、違法な状態を代表しないものにし、ショットガンの解析を避けるのに役立ちます。
$ python3 -m pip install phantom-types機能を有効にするか、サードパーティライブラリの互換性のあるバージョンをインストールするために使用できるエクストラがいくつかあります。
| 余分な名前 | 特徴 |
|---|---|
[dateutil] | python-dateutilをインストールします。 TZAwareとTZNaiveで弦を解析するために必要です。 |
[phonenumbers] | PhoneNumbersをインストールします。 phantom.ext.phonenumbersを使用する必要があります。 |
[pydantic] | Pydanticをインストールします。 |
[hypothesis] | 仮説をインストールします。 |
[all] | 上記のすべてをインストールします。 |
$ python3 -m pip install phantom-types[all]ファントムタイプを導入することにより、関数引数の事前条件を定義できます。
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 } !" )今、これは有効な呼び出しになります。
greet ( Name . parse ( "Jane" ))...そしてこれもそうです。
joe = "Joe"
assert isinstance ( joe , Name )
greet ( joe )ただし、これにより、静的なタイプのチェックエラーが得られます。
greet ( "bird" )明確にするために、最初の例が合格する理由は、タイプチェッカーが何らかの形で私たちの述語について魔法のように知っているからではなく、タイプチェッカーにassertを通して証明を提供したからです。タイプチェッカーが気にするのは、変数がNameでない限り、ランタイムがアサーションを過ぎて実行を続けることができないということです。以下の例のように呼び出しを移動すると、タイプチェッカーはgreet()呼び出しのエラーが発生します。
joe = "Joe"
greet ( joe )
assert isinstance ( joe , Name )PhantomタイプをBearTypeやTypeguardなどのランタイムタイプチェッカーと組み合わせることで、契約の使用から得られる同じレベルのセキュリティを実現できます。
import datetime
from beartype import beartype
from phantom . datetime import TZAware
@ beartype
def soon ( dt : TZAware ) -> TZAware :
return dt + datetime . timedelta ( seconds = 10 ) soon関数は、その引数と返品値の両方がTimeZone認識であることを検証します。たとえば、事前およびポスト条件です。
PhantomタイプはPydanticで使用する準備ができており、すぐにサポートを統合しています。 Phantomのサブクラスは、Pydanticの検証とそのスキーマ生成の両方で機能します。
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 ))上記のコードは、次の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 " ]
}できればvirtualenvに開発要件をインストールしてください。
$ python3 -m pip install .[all,test,type-check]テストの実行:
$ pytest
# or
$ make testタイプチェッカーを実行:
$ mypyリナーとフォーマッタはガチョウでセットアップされます。インストールした後、次のように実行できます。
# run all checks
$ goose run --select=all
# or just a single hook
$ goose run mypy --select=all静的タイプのチェックに加えて、プロジェクトはPytest-Mypy-Pluginsを使用してセットアップされており、露出したMyPyタイプが期待どおりに機能することをテストします。これらのチェックは、残りのテストスイートと一緒に実行されますが、次のコマンドとともに単一にすることができます。
$ make test-typing