{"id":14989176,"url":"https://github.com/barakkatzir/types-scipy-sparse","last_synced_at":"2026-02-02T22:37:05.200Z","repository":{"id":252051445,"uuid":"837952756","full_name":"BarakKatzir/types-scipy-sparse","owner":"BarakKatzir","description":"Type hints for scipy sparse module","archived":false,"fork":false,"pushed_at":"2024-08-12T11:00:02.000Z","size":185,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-29T01:19:41.078Z","etag":null,"topics":["mypy-stubs","python","python3","scipy","scipy-sparse","type-annotation","type-annotations","type-package","type-stubs"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BarakKatzir.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-04T14:31:53.000Z","updated_at":"2024-12-14T22:45:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"8607b510-ddf9-4363-bb6e-283c06dada78","html_url":"https://github.com/BarakKatzir/types-scipy-sparse","commit_stats":{"total_commits":9,"total_committers":2,"mean_commits":4.5,"dds":0.2222222222222222,"last_synced_commit":"6b7fc9a69a1c203bc103ca8c914c80564e574f87"},"previous_names":["barakkatzir/types-scipy-sparse"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/BarakKatzir/types-scipy-sparse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BarakKatzir%2Ftypes-scipy-sparse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BarakKatzir%2Ftypes-scipy-sparse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BarakKatzir%2Ftypes-scipy-sparse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BarakKatzir%2Ftypes-scipy-sparse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BarakKatzir","download_url":"https://codeload.github.com/BarakKatzir/types-scipy-sparse/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BarakKatzir%2Ftypes-scipy-sparse/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263099439,"owners_count":23413622,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mypy-stubs","python","python3","scipy","scipy-sparse","type-annotation","type-annotations","type-package","type-stubs"],"created_at":"2024-09-24T14:17:48.614Z","updated_at":"2026-02-02T22:37:05.138Z","avatar_url":"https://github.com/BarakKatzir.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Type annotations types-package for `scipy.sparse`\n\nThis is a [PEP-561](https://peps.python.org/pep-0561/) compilant type information package for the `sparse` module of the [`SciPy`](https://scipy.org/) package.\nInstalling this package will allow [`mypy`](https://mypy.readthedocs.io/en/latest/installed_packages.html) and possibly other static type checkers (e.g., pyright) to recognize type annotations for `scipy.sparse` classes and functions.\n\n\n\u003e [!CAUTION]\n\u003e This package is a work in progress, and while it is tests the test coverage is still lacking (see this issue https://github.com/BarakKatzir/types-scipy-sparse/issues/6 ).\n\u003e \n\u003e Currently the `csgraph` and `linalg` submodules are not type annotated (see issue https://github.com/BarakKatzir/types-scipy-sparse/issues/5).\n\u003e \n\u003e This package only supports `\"numpy \u003c2.0.0\"` for now (see issue https://github.com/BarakKatzir/types-scipy-sparse/issues/7).\n\n## Installation\n\nIn your python environment run\n\n```bash\npip install types-scipy-sparse\n```\n\n## Annotations\n\nThe basic annotations work fine. For example, if we have the file `important_func.py`\n\n```python\n# content of important_func.py\nfrom scipy.sparse import coo_array\n\ndef make_sparse(\n    x: list[int], y: list[int], vals: list[float]\n) -\u003e csr_array:\n    return coo_array((vals, (x, y))).tocsr()\n\n```\n\nit will pass a mypy check\n\n```console\n$ mypy important_func.py\nSuccess: no issues found in 1 source file\n```\n\n### `numpy`-flavored generics\n\nThe different sparse array and sparse matrix classes are type annotated similarly to `numpy.ndarray`s, with two `TypeVar`s: `\u003csparse_class\u003e[ShapeType, DType]`, for example `csc_array[Any, numpy.float32]`. As for `numpy.ndarray`, the `DType` is bound by `numpy.dtype[Any]` and the `ShapeType` can be anything.\n\nFor example,\n\n```python\n# content of important_script.py\nimport numpy\nfrom scipy.sparse import csr_array, lil_array\n\nx = csr_array([[0, 1], [2, 0]], dtype=numpy.float64)\ny = lil_array(numpy.array([[0, 1], [2, 0]], dtype=numpy.float32))\nreveal_locals()\n\n```\n\npasses mypy with the revealed types of the `x` and `y` arrays\n\n```console\n$ mypy important_script.py\nimportant_script.py:6: note: Revealed local types are:\nimportant_script.py:6: note:     x: scipy.sparse._csr.csr_array[Any, numpy.dtype[numpy.floating[numpy._typing._64Bit]]]\nimportant_script.py:6: note:     y: scipy.sparse._lil.lil_array[Any, numpy.dtype[numpy.floating[numpy._typing._32Bit]]]\nSuccess: no issues found in 1 source file\n```\n\nAs in numpy, the first type variable, `ShapeType`, is left for user customization.\n\nNote that for compatibility with any other type packages, The `ShapeType` and `DType` type variables default to `Any`, using the [PEP-696](https://peps.python.org/pep-0696/) feature. This means that type annotatin `x: dok_array` will implicitly insert these `Any`s:\n\n```console\n$ mypy -c \"import scipy.sparse as sp; x: sp.dok_array; reveal_type(x)\"\n\u003cstring\u003e:1: note: Revealed type is \"scipy.sparse._dok.dok_array[Any, numpy.dtype[Any]]\"\nSuccess: no issues found in 1 source file\n```\n\n\u003e [!NOTE]\n\u003e Since these generics are only introduced in the type stubs, they will raise an error at runtime. Thus, `x: coo_array[Any, numpy.dtype[numpy.uint8]]` will raise an error.\n\u003e If you desire to use this feature when annotating `.py` files then there are two easy solutions:\n\u003e \n\u003e * Use implicit forward references by adding `from __future__ import annotations` at the top of your script\n\u003e \n\u003e * Use explicit forward references by putting troublesome annotations in quotation marks, e.g., `x: \"coo_array[Any, numpy.dtype[numpy.uint8]]\"`\n\n\n### Type narrowing functions\n\nThere are several convenience type-narrowing functions in the `sparse` module, e.g., `issparse`, `isspmatrix` and `isdense`. These are annotated with the `TypeIs` introduced in [PEP-742](https://peps.python.org/pep-0742/). This conveniently narrows the type (and not casts to it, like `typing.TypeGuard`) and allows type narrowing in both `if` and `else` branches of a conditional.\n\nFor example the python file\n\n```python\n# content of my_script.py\nfrom typing import Any\n\nimport numpy\nfrom scipy.sparse import csr_array, issparse\n\nx: numpy.ndarray[Any, Any] | csr_array\nif issparse(x):\n    reveal_type(x)\n    # attribute of csr_array\n    x.indptr\nelif isinstance(x, numpy.ndarray):\n    # attribute of ndarray\n    reveal_type(x)\n    x.strides\nelse:\n    # This branch is inferred to be unreachable\n    # so mypy ignores the following\n    reveal_type(x)\n    x.mystery_attribute\n\n```\n\nwill pass mypy with the correct revealed types\n\n```console\n$ mypy my_script.py\nmy_script.py:8: note: Revealed type is \"scipy.sparse._csr.csr_array[Any, numpy.dtype[Any]]\"\nmy_script.py:12: note: Revealed type is \"numpy.ndarray[Any, Any]\"\nSuccess: no issues found in 1 source file\n```\n\n### The `sparray` and `spmatrix` namespace classes\n\nThe classes `sparray` and `spmatrix` have empty bodies and are used for mainly for namespacing and `isinstance` checks, while the many sparse array/matrix class' methods are implemented via private mixin classes. While the private classes are not type annotated by this types package, the sparray and spmatrix are conveniantly type annotated as `Protocol[ShapeType, DType]`, this way it is conveyed to the type-checker that any methods they carry (such as `sum` and `asformat`) is not implemented, while still stating what method theri subclasses do implement.\n\n\n### New `scipy.sparse.typing`\n\nThis type package introduces a new `scipy.sparse.typing` module for convenience. This new module is used internally for common type aliases and it exposes the `SparseArray` type alias which can specify a sparse array or sparse matrix by its scalar type similarly to `numpy`'s `numpy.typing.NDArray` (a scalar type is the subtype of the `numpy.generic`, e.g., `numpy.int8` and `numpy.complex128`),\n\n```python\n_SCT_co = TypeVar(\"_SCT_co\", covariant=True, bound=numpy.generic)\nSparseArray: TypeAlias = (\n    sparray[Any, numpy.dtype[_SCT_co]] | spmatrix[Any, numpy.dtype[_SCT_co]]\n)\n```\n\nFor example, the following passes mypy\n\n```python\nfrom __future__ import annotations\n\nfrom typing import TYPE_CHECKING\nimport numpy\n\nif TYPE_CHECKING:\n    from scipy.sparse.typing import SparseArray\n\ndef foo(x: SparseArray[numpy.float64]) -\u003e None:\n    print(f\"doing serious calculations with {x}\")\n\n```\n\n\u003e [!NOTE]\n\u003e `SparseArray` cannot be used in runtime so it's best to use it in forward references (see above explanation for more)\n\n### What is and what isn't annotated?\n\nI aim to annotate all the public object of `scipy.sparse`, see https://github.com/BarakKatzir/types-scipy-sparse/issues/5 for track of missing types. However, most of the private objects are left untyped (the private functions/classes/methods are those whose name begin with `'_'` and do not end with `'_'`, or that they reside in a private module and are not re-exported in a public module). There are a few exceptions to this that I keep track of here.\n\nCurrently, there are only two expections to the above rule: the function `_todata` and function `_ravel_coords` that seems useful and well docstringed.\n\nAnother thing to point out is that the whole *private* module `scipy.sparse._sparsetools` is not exposed in `sparse`'s `__init__.py`, but some of its functions are re-exposed by some deprecated modules such as `bsr.py`, `compressed.py`, `construct.py` and some others. As such, the `_sparsetools` module is typed in this package, but it would be prudent to not rely on these stubs.\n\n## Development\n\n### Development environment setup\n\nThe current development environment uses the experimental `uv` package.\n\nHere are a few steps for anyone to set up the development environment quickly:\n\n1) clone that package\n\n2) [install uv](https://docs.astral.sh/uv/installation/) (consider fixing the version of `uv` to that of this repo)\n\nIn workspace root, create virtual environment\n\n  ```bash\n  uv venv -p 3.10 --python-preference managed\n  ```\n\n  and activate the venv (e.g., run `source .venv/bin/activate` if in a linux terminal).\n\n3) To install dependencies run\n\n  ```bash\n  uv sync --frozen\n  ```\n\n4) to make sure the type package is correctly installed, install in **non-editable** mode\n\n  ```bash\n  uv pip install . --no-deps\n  ```\n\n\u003e [!NOTE]\n\u003e If you plan to change the version of `uv`, know that it is fixed separately in different places as the `uv` command is run separately in different environments: the dev venv, tox venvs, when building wheels, and in github workflows\n\n### Type stub generation\n\nA big portion of the stub files are generated by code from common templates, since the scipy sparse module has a lot of similar classes with common functionality and common inheritance.\nThe repository includes the stub generating CLI tool named `make-scipy-sparse-stubs`. The tool can be installed as a package in editable mode (with the `uv sync` command or with `uv pip install -e make-scipy-sparse-stubs@tools/make-scipy-sparse-stubs`). It contains the python module `make_scipy_sparse_stubs` which can be run to either generate the type stubs or to check that the present / installed type stubs are in sync.\n\nTo check that the stubs are in sync with the generated stubs run\n\n```console\n$ python -m make_scipy_sparse_stubs --check\nFinished without any changes 🎉\n```\n\nor to overwrite the current stubs by specifying their location in the workspace\n\n```console\n$ python -m make_scipy_sparse_stubs -sp src/scipy-stubs\nFinished without any changes 🎉\n```\n\nFor more on the tool, see it's help:\n\n```bash\npython -m make_scipy_sparse_stubs --help\n```\n\n\u003e [!WARNING]\n\u003e The tool's functionality and interface can change between different revisions of the repository.\n\n### Tests\n\nPull requests to `main` are automatically run through tests, so you can develop locally and push to main and see if it passes. You can run the tests locally by running `tox` before pushing\n\n```bash\nuv run tox\n```\n\nor if you activated the venv, then simply run `tox`.\n\nThe stubs are tested for:\n\n* type stubs match the generated `make_scipy_sparse_stubs` tool\n\n* `ruff` formatters and checkers\n\n* `mypy` and mypy's `stubtest`\n\n* `pytest` examines mypy failure / pass / reveal on example code (the template for these tests was adapted from the now archived `numpy-stubs` repo (see https://github.com/numpy/numpy-stubs)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarakkatzir%2Ftypes-scipy-sparse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbarakkatzir%2Ftypes-scipy-sparse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarakkatzir%2Ftypes-scipy-sparse/lists"}