Skip to content

Commit

Permalink
add: add pyright as a static type checker (#1)
Browse files Browse the repository at this point in the history
* update: upgrade python version

* add: langchain

* add: ignore .env file

* add: .env.sample

* documentation

* add: recommend to use tamasfe.even-better-toml

* add: add pyright

* add: add pyright

* add: how to lauch .py

* update: exclude .devcontainer and __pycached__ dir when ruff check

* documentation

* add: pylance setting

* update: add pyright setting

* add: sample source

* add: pyright workflow for static type checking

* update: Test codes should be more relaxed

* add: add a simple unit test case.

* update: allow __init__.py to be empty

* refactor: move lint.per-file-ignores section next to lint one.

* add: define markers

* update: add type check in function

* ignore PT023

* Add Pyright on uv hook for static type checking in pre-commit config

* update: update pre-commit config

* remove: remove defineConstant

* update: this repository uses only python 3.12

* documentation

* update: add typeCheckingMode="standard"

* update: add some strict rules of pyright
  • Loading branch information
arrowkato authored Oct 6, 2024
1 parent 1590944 commit bd2479c
Show file tree
Hide file tree
Showing 18 changed files with 1,500 additions and 17 deletions.
4 changes: 3 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"pkief.material-icon-theme",
"shardulm94.trailing-spaces",
"usernamehw.errorlens",
"yzhang.markdown-all-in-one"
"yzhang.markdown-all-in-one",
"tamasfe.even-better-toml",
"ms-python.vscode-pylance"
],
"settings": {
"python.defaultInterpreterPath": "/root/.local/share/uv/python",
Expand Down
4 changes: 4 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Usage: Copy this file to .env and replace the values with your own

# if you use OpenAI API with langchain
OPENAI_API_KEY=<your_api_key>
27 changes: 27 additions & 0 deletions .github/workflows/pyright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Pyright

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
static_type_check:
runs-on: ubuntu-latest

strategy:
matrix:
python-version: ['3.12']

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Python ${{ matrix.python-version }} with uv
uses: ./.github/actions/setup-python-with-uv
with:
python-version: ${{ matrix.python-version }}

- name: static type check
run: uv run pyright
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,6 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

# This file includes secret info.
.env
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,13 @@ repos:
language: system
types: ["dockerfile"]
entry: hadolint

- repo: local
hooks:
- id: pyright
name: Pyright
description: "Run Pyright for static type checking"
entry: pyright
language: python
types: [python, jupyter]
additional_dependencies: ['pyright>=1.1']
2 changes: 1 addition & 1 deletion .python-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.12.3
3.12.6
1 change: 1 addition & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
"shardulm94.trailing-spaces",
"usernamehw.errorlens",
"yzhang.markdown-all-in-one",
"ms-python.vscode-pylance",
]
}
11 changes: 11 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"configurations": [
{
"name": "Python デバッガー: 現在のファイル",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
},
],
}
12 changes: 10 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
{
"[python]": {
"editor.codeActionsOnSave": {
//ファイル保存時に自動で指摘箇所を修正する
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
// Ruffでformat
"source.fixAll.ruff": "explicit",
// Ruffでimportの整列
"source.organizeImports.ruff": "explicit",
},
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
},
"files.insertFinalNewline": true,
"files.trimTrailingWhitespace": true
"files.trimTrailingWhitespace": true,
// pylance. 主に可読性向上のために利用
"python.analysis.inlayHints.functionReturnTypes": true,
"python.analysis.inlayHints.callArgumentNames": "all",
}
71 changes: 63 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,75 @@
name = "default"
version = "0.1.0"
description = "This repository contains configurations to set up a Python development environment using VSCode's Dev Container feature. The environment includes uv and Ruff."
authors = [
{name = "a5chin", email = "[email protected]"}
]
maintainers = [
{name = "a5chin", email = "[email protected]"}
]
authors = [{ name = "a5chin", email = "[email protected]" }]
maintainers = [{ name = "a5chin", email = "[email protected]" }]
requires-python = ">=3.9"
readme = "README.md"
license = {file = "LICENSE"}
dependencies = []
license = { file = "LICENSE" }
dependencies = [
"langchain-openai>=0.2.2",
"langchain>=0.3.2",
"python-dotenv>=1.0.1",
]

[tool.uv]
dev-dependencies = [
"pytest>=8.3.2",
"pre-commit>=3.8.0",
"ruff>=0.6.3",
"pyright>=1.1.383",
]


[tool.pyright]
# ref https://microsoft.github.io/pyright/#/configuration
## Environment Options ##
include = ["python_uv", "tests"]
exclude = [
"**/__pycache__",
"python_uv/sample*.py",
".mypy_cache",
".pytest_cache",
".ruff_cache",
]
ignore = []
pythonVersion = "3.12"
pythonPlatform = "Linux"

## Type Evaluation Settings ##
strictListInference = true
strictDictionaryInference = true
strictSetInference = true
deprecateTypingAliases = true

## Type Check Diagnostics Settings ##
typeCheckingMode = "standard"

## Type Check Rule Overrides ##
# Settings that are closer to "strict" than "standard"
reportMissingImports = "error"
reportUnknownParameterType = "error"
reportWildcardImportFromLibrary = "error"
reportConstantRedefinition = "error"
reportDuplicateImport = "error"
reportMatchNotExhaustive = "warning"
reportMissingParameterType = "warning"
reportMissingTypeArgument = "error"
reportPrivateUsage = "error"
reportUnknownMemberType = "warning"
reportUnnecessaryCast = "warning"
reportUnnecessaryComparison = "warning"
reportUnnecessaryContains = "warning"
reportUnusedImport = "error"
reportUnusedFunction = "warning"
reportUnusedVariable = "warning"

## Execution Environment Options ##
# There is no setting, because the settings listed in the "Environment Options" section
# will be used in all environments.

# [tool.ruff]
# [tool.ruff.lint]
# [tool.ruff.format]
# etc
# see ruff.toml file
6 changes: 6 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[pytest]
markers =
slow: The marked tests should be excluded from the normal test suite because they take a long time.
unit_test: Test cases that do not require external dependencies.
integration: Test cases that require external dependencies. e.g. database, network, external API etc.

Empty file added python_uv/__init__.py
Empty file.
21 changes: 21 additions & 0 deletions python_uv/calc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
def add(a: int, b: int) -> int:
"""Add two numbers.
Args:
----
a (int): First number.
b (int): Second number.
Raises:
------
TypeError: Both a and b must be integers.
Returns:
-------
int: sum of a and b.
"""
if not isinstance(a, int) or not isinstance(b, int):
err_msg = "Both a and b must be integers."
raise TypeError(err_msg)
return a + b
22 changes: 22 additions & 0 deletions python_uv/chat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import logging
from logging import getLogger

from dotenv import load_dotenv
from langchain_openai import ChatOpenAI

load_dotenv()

logger = getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())


def chat() -> None:
"""Chat with gpt-4o chat."""
llm = ChatOpenAI(model="gpt-4o-mini")
response = llm.invoke("こんにちは。私は元気です。")
logger.debug(response.content)


if __name__ == "__main__":
chat()
30 changes: 25 additions & 5 deletions ruff.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Exclude a variety of commonly ignored directories.
exclude = [
# default setting: https://docs.astral.sh/ruff/configuration/
".bzr",
".direnv",
".eggs",
Expand All @@ -26,6 +27,9 @@ exclude = [
"node_modules",
"site-packages",
"venv",
# add this project's setting
".devcontainer",
"__pycache__",
]

# Same as Black.
Expand All @@ -39,11 +43,21 @@ target-version = "py312"
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
select = ["ALL"]
ignore = [
"COM812", "COM819",
"D100", "D203", "D213", "D300",
"E111", "E114", "E117",
"ISC001", "ISC002",
"Q000", "Q001", "Q002", "Q003",
"COM812",
"COM819",
"D100",
"D203",
"D213",
"D300",
"E111",
"E114",
"E117",
"ISC001",
"ISC002",
"Q000",
"Q001",
"Q002",
"Q003",
"W191",
]

Expand All @@ -54,6 +68,12 @@ unfixable = []
# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[lint.per-file-ignores]
# allow __init__.py to be empty
"__init__.py" = ["D104"]
# Test codes should be more relaxed
"tests/**.py" = ["D103", "S101", "PLR2004", "PT023"]

[format]
# Like Black, use double quotes for strings.
quote-style = "double"
Expand Down
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Includes test files. The test file's name should start with test_."""
35 changes: 35 additions & 0 deletions tests/test_calc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import pytest

from python_uv.calc import add


@pytest.mark.unit_test
@pytest.mark.parametrize(
("a", "b", "expected"),
[
(1, 2, 3),
(2, 3, 5),
(0, 0, 0),
(-1, 1, 0),
(-1, -1, -2),
],
)
def test_add_correct(a: int, b: int, expected: int) -> None:
assert add(a, b) == expected


@pytest.mark.unit_test
@pytest.mark.parametrize(
("a", "b"),
[
(1, "2"),
("1", 2),
("1", "2"),
(1, 2.1),
(1.1, 2),
(1.1, 2.1),
],
)
def test_add_incorrect(a: int, b: int) -> None:
with pytest.raises(TypeError):
add(a, b)
Loading

0 comments on commit bd2479c

Please sign in to comment.