ประเภท Phantom สำหรับ Python จะช่วยให้คุณทำให้รัฐที่ผิดกฎหมายไม่สามารถแสดงได้และหลีกเลี่ยงการแยกวิเคราะห์ปืนลูกซองโดยช่วยให้คุณฝึก "แยกวิเคราะห์อย่าตรวจสอบ"
$ 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]ด้วยการแนะนำประเภท Phantom เราสามารถกำหนดเงื่อนไขล่วงหน้าสำหรับอาร์กิวเมนต์ฟังก์ชั่น
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 จะตรวจสอบว่าทั้งการโต้แย้งและค่าส่งคืนคือการรับรู้ถึงเขตเวลาเช่นเงื่อนไขก่อนและโพสต์
ประเภท 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 testRun Type Checker:
$ mypyLinters และ Formatters ถูกตั้งค่าด้วย Goose หลังจากติดตั้งคุณสามารถเรียกใช้เป็น:
# run all checks
$ goose run --select=all
# or just a single hook
$ goose run mypy --select=allนอกเหนือจากการตรวจสอบประเภทคงที่โครงการยังได้รับการตั้งค่าด้วย pytest-mypy-plugins เพื่อทดสอบว่าประเภท MyPy ทำงานได้ตามที่คาดไว้การตรวจสอบเหล่านี้จะทำงานร่วมกับชุดทดสอบที่เหลือ แต่คุณสามารถออกคำสั่งต่อไปนี้ได้
$ make test-typing