diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2ccff517..150a361b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,7 +32,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install -e .[dev,torch,statsmodels,xgboost] + python -m pip install -e ".[all]" - name: Run Tests run: | pytest -m 'not rsc_test and not docker' --cov --cov-report xml @@ -109,3 +109,32 @@ jobs: - name: Run tests run: | pytest vetiver/tests/test_sklearn.py + + typecheck: + runs-on: ubuntu-latest + + # We want to run on external PRs, but not on our own internal PRs as they'll be run + # by the push to the branch. + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + strategy: + matrix: + python-version: [3.11] + + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install Packages + shell: bash + run: | + pip install ".[dev,all_models]" + + - name: Run Tests + shell: bash + run: make typecheck diff --git a/Makefile b/Makefile index b6448cfc..05ba060f 100644 --- a/Makefile +++ b/Makefile @@ -91,5 +91,8 @@ dev-stop: docker-compose down rm -f $(RSC_API_KEYS) +typecheck: + pyright + $(RSC_API_KEYS): dev-start python script/setup-rsconnect/dump_api_keys.py $@ diff --git a/pyproject.toml b/pyproject.toml index e50bb2ee..0cc88beb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,3 +18,65 @@ markers = [ [tool.setuptools_scm] fallback_version = "999" version_scheme = 'post-release' + +########## Tool - Pyright ########## +[tool.pyright] +# Paths of directories or files that should be included. If no paths +# are specified, pyright defaults to the directory that contains the +# config file. Paths may contain wildcard characters ** (a directory or +# multiple levels of directories), * (a sequence of zero or more +# characters), or ? (a single character). If no include paths are +# specified, the root path for the workspace is assumed. +include = [ + "vetiver/" + ] + +# Paths of directories or files whose diagnostic output (errors and +# warnings) should be suppressed even if they are an included file or +# within the transitive closure of an included file. Paths may contain +# wildcard characters ** (a directory or multiple levels of +# directories), * (a sequence of zero or more characters), or ? (a +# single character). +ignore = [ + #"vetiver/__init__.py", + #"vetiver/attach_pkgs.py", + "vetiver/helpers.py", + "vetiver/meta.py", + "vetiver/mock.py", + "vetiver/model_card.py", + "vetiver/monitor.py", + "vetiver/pin_read_write.py", + "vetiver/prototype.py", + "vetiver/rsconnect.py", + "vetiver/server.py", + "vetiver/types.py", + "vetiver/utils.py", + "vetiver/vetiver_model.py", + "vetiver/write_docker.py", + "vetiver/write_fastapi.py", + "vetiver/handlers/", + "vetiver/data/", + "vetiver/tests" +] + +# Set of identifiers that should be assumed to contain a constant +# value wherever used within this program. For example, { "DEBUG": true +# } indicates that pyright should assume that the identifier DEBUG will +# always be equal to True. If this identifier is used within a +# conditional expression (such as if not DEBUG:) pyright will use the +# indicated value to determine whether the guarded block is reachable +# or not. Member expressions that reference one of these constants +# (e.g. my_module.DEBUG) are also supported. +defineConstant = { DEBUG = true } + +# typeCheckingMode = "strict" +useLibraryCodeForTypes = true +reportUnnecessaryTypeIgnoreComment = true + +# Specifies a list of execution environments (see below). Execution +# environments are searched from start to finish by comparing the path +# of a source file with the root path specified in the execution +# environment. +executionEnvironments = [] + +stubPath = "" diff --git a/setup.cfg b/setup.cfg index c65e4a08..78eecad0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -41,6 +41,10 @@ install_requires = [options.extras_require] all = vetiver[dev] + vetiver[all_models] + vetiver[docs] + +all_models = vetiver[torch] vetiver[statsmodels] vetiver[xgboost] @@ -49,15 +53,20 @@ dev = pytest pytest-cov pytest-snapshot + vetiver[typecheck] docs = quartodoc -torch = - torch - statsmodels = statsmodels +torch = + torch + xgboost = xgboost + +typecheck = + pyright + pandas-stubs diff --git a/vetiver/attach_pkgs.py b/vetiver/attach_pkgs.py index 2b589322..19a9802b 100644 --- a/vetiver/attach_pkgs.py +++ b/vetiver/attach_pkgs.py @@ -1,12 +1,20 @@ +from __future__ import annotations +import typing + import tempfile import os import warnings -from typing import List from .vetiver_model import VetiverModel from .meta import VetiverMeta +if typing.TYPE_CHECKING: + from typing import Optional + from pathlib import Path + -def load_pkgs(model: VetiverModel = None, packages: list = None, path=""): +def load_pkgs( + model: VetiverModel, packages: Optional[list] = None, path: str | Path = "" +): """Load packages necessary for predictions Parameters @@ -40,7 +48,7 @@ def load_pkgs(model: VetiverModel = None, packages: list = None, path=""): os.remove(tmp.name) -def get_board_pkgs(board) -> List[str]: +def get_board_pkgs(board) -> list[str]: """ Extract packages required for pin board authorization