Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Pyright for Type-Checking #630

Merged
merged 4 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 0 additions & 62 deletions .github/workflows/mypy.yml

This file was deleted.

52 changes: 52 additions & 0 deletions .github/workflows/pyright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Pyright

on:
push:
pull_request:
branches: [ main ]

env:
WORKING_DIRECTORY: "."
PYRIGHT_OUTPUT_FILENAME: "pyright.log"

jobs:
Pyright:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
python-version: ["3.9", "3.10", "3.11"]

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Cache Poetry virtualenv
uses: actions/cache@v2
with:
path: ~/.cache/pypoetry/virtualenvs
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
restore-keys: |
${{ runner.os }}-poetry-

- name: Install Poetry
uses: snok/install-poetry@v1.3.1

- name: Install dependencies
run: poetry install --with dev,anthropic

- name: Run Static Type Checking with Pyright
run: |
set -e -o pipefail
poetry run pyright > ${{ env.WORKING_DIRECTORY }}/${{ env.PYRIGHT_OUTPUT_FILENAME }}

- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: pyright-log
path: ${{ env.WORKING_DIRECTORY }}/${{ env.PYRIGHT_OUTPUT_FILENAME }}
29 changes: 0 additions & 29 deletions .mypy.ini

This file was deleted.

15 changes: 3 additions & 12 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,7 @@ repos:
files: ^(instructor|tests|examples)/
- id: ruff-format # Run the formatter.
name: Run Formatter (Ruff)
- repo: local
- repo: https://github.com/RobertCraigie/pyright-python
rev: v1.1.360
hooks:
- id: ci_type_mypy
name: Run Type Check (Mypy)
entry: >
bash -c 'set -o pipefail;
export CUSTOM_PACKAGES="instructor/_types/_alias.py instructor/cli/cli.py instructor/cli/files.py instructor/cli/usage.py instructor/exceptions.py" &&
export CUSTOM_FLAGS="--python-version=3.9 --color-output --no-pretty --follow-imports=skip" &&
curl -sSL https://raw.githubusercontent.com/gao-hongnan/omniverse/2fd5de1b8103e955cd5f022ab016b72fa901fa8f/scripts/devops/continuous-integration/type_mypy.sh |
bash'
language: system
types: [python]
pass_filenames: false
- id: pyright
2 changes: 2 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ select = [
"E722",
# unused arguments
"ARG",
# Enforce modern type-syntax
"UP006",
]
ignore = [
# mutable defaults
Expand Down
3 changes: 1 addition & 2 deletions examples/anthropic/run.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from pydantic import BaseModel
from typing import List
import anthropic
import instructor

Expand All @@ -15,7 +14,7 @@ class Properties(BaseModel):
class User(BaseModel):
name: str
age: int
properties: List[Properties]
properties: list[Properties]


user = client.messages.create(
Expand Down
10 changes: 5 additions & 5 deletions examples/auto-ticketer/run.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import instructor
from openai import OpenAI

from typing import List, Optional
from typing import Optional
from pydantic import BaseModel, Field
from enum import Enum

Expand Down Expand Up @@ -32,11 +32,11 @@ class Ticket(BaseModel):
name: str = Field(..., description="Title of the task")
description: str = Field(..., description="Detailed description of the task")
priority: PriorityEnum = Field(..., description="Priority level")
assignees: List[str] = Field(..., description="List of users assigned to the task")
subtasks: Optional[List[Subtask]] = Field(
assignees: list[str] = Field(..., description="List of users assigned to the task")
subtasks: Optional[list[Subtask]] = Field(
None, description="List of subtasks associated with the main task"
)
dependencies: Optional[List[int]] = Field(
dependencies: Optional[list[int]] = Field(
None, description="List of ticket IDs that this ticket depends on"
)

Expand All @@ -46,7 +46,7 @@ class ActionItems(BaseModel):
Correctly resolved set of action items from the given transcript
"""

items: List[Ticket]
items: list[Ticket]


def generate(data: str):
Expand Down
6 changes: 3 additions & 3 deletions examples/avail/run.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pydantic import BaseModel, Field
from typing import Iterable, List, Literal
from typing import Iterable, Literal
from datetime import datetime, timedelta

from openai import OpenAI
Expand All @@ -17,7 +17,7 @@ class DateRange(BaseModel):
default=None,
description="If the date range repeats, and how often, this way we can generalize the date range to the future., if its special, then we can assume it is a one time event.",
)
days_of_week: List[
days_of_week: list[
Literal[
"monday",
"tuesday",
Expand All @@ -41,7 +41,7 @@ class DateRange(BaseModel):


class AvailabilityResponse(BaseModel):
availability: List[DateRange]
availability: list[DateRange]


def prepare_dates(n=7) -> str:
Expand Down
6 changes: 3 additions & 3 deletions examples/avail/run_mixtral.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os
from pydantic import BaseModel, Field
from typing import List, Literal
from typing import Literal
from datetime import datetime, timedelta

from openai import OpenAI
Expand All @@ -25,7 +25,7 @@ class DateRange(BaseModel):
default=None,
description="If the date range repeats, and how often, this way we can generalize the date range to the future., if its special, then we can assume it is a one time event.",
)
days_of_week: List[
days_of_week: list[
jxnl marked this conversation as resolved.
Show resolved Hide resolved
Literal[
"monday",
"tuesday",
Expand All @@ -49,7 +49,7 @@ class DateRange(BaseModel):


class AvailabilityResponse(BaseModel):
availability: List[DateRange]
availability: list[DateRange]


def prepare_dates(n=7) -> str:
Expand Down
5 changes: 2 additions & 3 deletions examples/batch-classification/run-cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from openai import AsyncOpenAI
from pydantic import BaseModel, Field, field_validator
from typing import List
from enum import Enum

client = instructor.from_openai(AsyncOpenAI(), mode=instructor.Mode.TOOLS)
Expand Down Expand Up @@ -40,7 +39,7 @@ class QuestionClassification(BaseModel):
chain_of_thought: str = Field(
..., description="The chain of thought that led to the classification"
)
classification: List[QuestionType] = Field(
classification: list[QuestionType] = Field(
description=f"An accuracy and correct prediction predicted class of question. Only allowed types: {[t.value for t in QuestionType]}, should be used",
)

Expand Down Expand Up @@ -68,7 +67,7 @@ async def classify(data: str):
)


async def main(questions: List[str]):
async def main(questions: list[str]):
tasks = [classify(question) for question in questions]
resps = []
for task in asyncio.as_completed(tasks):
Expand Down
5 changes: 2 additions & 3 deletions examples/batch-classification/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from openai import AsyncOpenAI
from pydantic import BaseModel, Field, field_validator
from typing import List
from enum import Enum

client = AsyncOpenAI()
Expand Down Expand Up @@ -42,7 +41,7 @@ class QuestionClassification(BaseModel):
chain_of_thought: str = Field(
..., description="The chain of thought that led to the classification"
)
classification: List[QuestionType] = Field(
classification: list[QuestionType] = Field(
description=f"An accuracy and correct prediction predicted class of question. Only allowed types: {[t.value for t in QuestionType]}, should be used",
)

Expand All @@ -69,7 +68,7 @@ async def classify(data: str):
)


async def main(questions: List[str], *, path_to_jsonl: str = None):
async def main(questions: list[str], *, path_to_jsonl: str = None):
tasks = [classify(question) for question in questions]
for task in asyncio.as_completed(tasks):
question, label = await task
Expand Down
5 changes: 2 additions & 3 deletions examples/batch-classification/run_langsmith.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from openai import AsyncOpenAI
from pydantic import BaseModel, Field, field_validator
from typing import List
from enum import Enum

client = wrap_openai(AsyncOpenAI())
Expand Down Expand Up @@ -44,7 +43,7 @@ class QuestionClassification(BaseModel):
chain_of_thought: str = Field(
..., description="The chain of thought that led to the classification"
)
classification: List[QuestionType] = Field(
classification: list[QuestionType] = Field(
description=f"An accuracy and correct prediction predicted class of question. Only allowed types: {[t.value for t in QuestionType]}, should be used",
)

Expand Down Expand Up @@ -73,7 +72,7 @@ async def classify(data: str):
)


async def main(questions: List[str]):
async def main(questions: list[str]):
tasks = [classify(question) for question in questions]
resps = []
for task in asyncio.as_completed(tasks):
Expand Down
9 changes: 4 additions & 5 deletions examples/chain-of-density/chain_of_density.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from pydantic import BaseModel, Field, field_validator
from typing import List
import instructor
import nltk
from openai import OpenAI
Expand Down Expand Up @@ -38,12 +37,12 @@ class RewrittenSummary(BaseModel):
...,
description="This is a new, denser summary of identical length which covers every entity and detail from the previous summary plus the Missing Entities. It should have the same length ( ~ 80 words ) as the previous summary and should be easily understood without the Article",
)
absent: List[str] = Field(
absent: list[str] = Field(
...,
default_factory=list,
description="this is a list of Entities found absent from the new summary that were present in the previous summary",
)
missing: List[str] = Field(
missing: list[str] = Field(
default_factory=list,
description="This is a list of 1-3 informative Entities from the Article that are missing from the new summary which should be included in the next generated summary.",
)
Expand Down Expand Up @@ -77,15 +76,15 @@ def min_length(cls, v: str):
return v

@field_validator("missing")
def has_missing_entities(cls, missing_entities: List[str]):
def has_missing_entities(cls, missing_entities: list[str]):
if len(missing_entities) == 0:
raise ValueError(
"You must identify 1-3 informative Entities from the Article which are missing from the previously generated summary to be used in a new summary"
)
return missing_entities

@field_validator("absent")
def has_no_absent_entities(cls, absent_entities: List[str]):
def has_no_absent_entities(cls, absent_entities: list[str]):
absent_entity_string = ",".join(absent_entities)
if len(absent_entities) > 0:
print(f"Detected absent entities of {absent_entity_string}")
Expand Down
Loading
Loading