Repository navigation
GH-55263: [Python][Annotations] Add internal types and core data structures #55264
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
base: main
Are you sure you want to change the base?
Changes from all commits
ee419b0
b09050f
28a44c7
3d7a713
fb50721
fc48948
9b03d17
3874966
32e439d
93d807e
558321c
6a1d410
de68c89
e3105e3
de7a5b6
5d920e9
f7573ac
a0c8c7a
a05d894
821e914
3003457
8886730
5ee863c
4f6c101
9a1185c
168c7c4
c347f7f
0e55c81
b096b3b
147e021
67aeb33
440fbee
a72e35b
120659e
f93d912
1add31b
c570fa9
eda3425
fd19ff4
4b97c69
110511a
aee2040
4b70969
3ddf085
aac6c4b
d9f0adb
b896dd3
9ddb17a
5114af5
cbe5355
c593509
63bc6a1
132c92a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -136,15 +136,101 @@ repos: | |
| - id: flake8 | ||
| alias: python | ||
| name: Python Lint | ||
| additional_dependencies: | ||
| - flake8-pyi | ||
| args: | ||
| - "--config" | ||
| - "python/setup.cfg" | ||
| - "--extend-select" | ||
| - "Y" | ||
| - "--per-file-ignores" | ||
| - "python/pyarrow-stubs/pyarrow/*.pyi:E301,E302,E305,E701,F821" | ||
| files: >- | ||
| ^(c_glib|dev|python)/ | ||
| types: | ||
| - file | ||
| types_or: | ||
| - python | ||
| - pyi | ||
| exclude: >- | ||
| ( | ||
| ?^python/pyarrow/vendored/| | ||
| ) | ||
| # Linting, formatting and type checking of the type stubs. These hooks only | ||
| # run on request, not on commit or in the existing CI jobs: | ||
| # pre-commit run --hook-stage manual python-stubs --all-files | ||
| - repo: https://github.com/astral-sh/ruff-pre-commit | ||
| rev: v0.17.2 | ||
| hooks: | ||
| - id: ruff-check | ||
| alias: python-stubs | ||
| name: Python Stubs Lint (ruff) | ||
| stages: | ||
| - manual | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ruff does not have to be manual? (it is fast, installs easily isolated) |
||
| args: | ||
| - "--fix" | ||
| files: >- | ||
| ^python/pyarrow-stubs/ | ||
| types: | ||
| - pyi | ||
| - id: ruff-format | ||
| alias: python-stubs | ||
| name: Python Stubs Format (ruff) | ||
| stages: | ||
| - manual | ||
| files: >- | ||
| ^python/pyarrow-stubs/ | ||
| types: | ||
| - pyi | ||
| - repo: local | ||
| hooks: | ||
| - id: mypy | ||
| alias: python-stubs | ||
| name: Python Stubs Type Check (mypy) | ||
| stages: | ||
| - manual | ||
| language: python | ||
| entry: bash -c "cd python && exec mypy" | ||
| pass_filenames: false | ||
| files: >- | ||
| ^python/(pyarrow-stubs/|pyproject\.toml$) | ||
| additional_dependencies: &python-type-check-dependencies | ||
| - fsspec==2026.9.0 | ||
| - mypy==2.4.0 | ||
| - numpy==2.4.6 | ||
| - pandas-stubs==3.0.5.260914 | ||
| # Provides the modules that aren't annotated yet, e.g. pyarrow.compute. | ||
| - pyarrow==26.0.0 | ||
| - pyright==1.1.414 | ||
| - pytest==9.0.2 | ||
| - scipy-stubs==1.17.1.5 | ||
| - ty==0.0.99 | ||
| - types-cffi==2.1.0.20260827 | ||
| - types-psutil==7.2.2.20260906 | ||
| - types-python-dateutil==2.9.0.20261021 | ||
| - types-requests==2.33.0.20261006 | ||
| - id: pyright | ||
| alias: python-stubs | ||
| name: Python Stubs Type Check (pyright) | ||
| stages: | ||
| - manual | ||
| language: python | ||
| entry: pyright -p python/pyproject.toml | ||
| pass_filenames: false | ||
| files: >- | ||
| ^python/(pyarrow-stubs/|pyproject\.toml$) | ||
| additional_dependencies: *python-type-check-dependencies | ||
| - id: ty | ||
| alias: python-stubs | ||
| name: Python Stubs Type Check (ty) | ||
| stages: | ||
| - manual | ||
| language: python | ||
| entry: ty check --project python | ||
| pass_filenames: false | ||
| files: >- | ||
| ^python/(pyarrow-stubs/|pyproject\.toml$) | ||
| additional_dependencies: *python-type-check-dependencies | ||
| - repo: https://github.com/MarcoGorelli/cython-lint | ||
| rev: v0.21.1 | ||
| hooks: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -114,6 +114,18 @@ Running Type Checkers | |
| We support multiple type checkers. Their configurations are in | ||
| ``pyproject.toml``. | ||
|
|
||
| The easiest way to run all of them is with ``pre-commit``, which installs | ||
| the same versions of the type checkers and stub packages for everyone. This | ||
| also lints and formats the stubs with ruff: | ||
|
|
||
| .. code-block:: | ||
|
|
||
| $ pre-commit run --hook-stage manual python-stubs --all-files | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This currently fails for me with:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And should this manual stage also be run in the CI build that runs pre-commit? |
||
|
|
||
| These hooks only run on request, not on commit. | ||
|
|
||
| To run a type checker directly instead: | ||
|
|
||
| **mypy** | ||
|
|
||
| To run mypy on the PyArrow codebase: | ||
|
|
@@ -169,6 +181,48 @@ in downstream projects and for users' IDEs. | |
| Note: ``py.typed`` marker file in the ``pyarrow/`` directory indicates to type | ||
| checkers that PyArrow supports type checking according to :pep:`561`. | ||
|
|
||
| Testing Type Stubs | ||
| ------------------ | ||
|
|
||
| The tests in ``pyarrow-stubs/tests/`` pin down the annotated types of public | ||
| APIs. Each check pairs :func:`typing.assert_type`, which every type checker | ||
| verifies statically, with a runtime ``isinstance`` check: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| import pyarrow.lib as lib | ||
|
|
||
| from _check import TYPE_CHECKING_INVALID_USAGE, assert_type, check | ||
|
|
||
| def test_list_type() -> None: | ||
| lst = lib.list_(lib.int32()) | ||
| check(assert_type(lst, lib.ListType), lib.ListType) | ||
| check(assert_type(lst.value_type, lib.DataType), lib.DataType) | ||
|
|
||
| if TYPE_CHECKING_INVALID_USAGE: | ||
| lib.list_(1) # type: ignore[call-overload] | ||
|
|
||
| The type checkers check these files as part of the regular runs above, and | ||
| pytest runs them against the installed PyArrow to make sure the stubs agree | ||
| with what PyArrow actually returns: | ||
|
|
||
| .. code-block:: | ||
|
|
||
| $ cd arrow/python | ||
| $ pytest pyarrow-stubs/tests | ||
|
|
||
| Run ``pytest`` directly and pass it the directory: ``python -m pytest`` puts | ||
| ``arrow/python`` on ``sys.path``, so the source tree would be imported instead | ||
| of the installed PyArrow. | ||
|
Comment on lines
+214
to
+216
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know if this is hallucinated or because someone of you actually run into an issue with this, but using (in general this is just about running pytest, so that should generally work the same as running the normal pyarrow unit tests? And there we don't say anything like this: https://arrow.apache.org/docs/developers/python/development.html#unit-testing)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| Code under ``if TYPE_CHECKING_INVALID_USAGE:`` is never executed. It should | ||
| fail type checking, which is asserted with a ``# type: ignore[<mypy code>]`` | ||
| comment: unused ignores are reported as errors in these tests, so the test | ||
| fails once the usage is no longer rejected. Start new test files with a | ||
| ``# mypy: warn-unused-ignores`` comment to enable this for mypy (pyright is | ||
| configured in ``pyproject.toml``). ty doesn't honor mypy error codes, so it | ||
| doesn't check invalid usage. | ||
|
|
||
| Doctest | ||
| ======= | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # Licensed to the Apache Software Foundation (ASF) under one | ||
| # or more contributor license agreements. See the NOTICE file | ||
| # distributed with this work for additional information | ||
| # regarding copyright ownership. The ASF licenses this file | ||
| # to you under the Apache License, Version 2.0 (the | ||
| # "License"); you may not use this file except in compliance | ||
| # with the License. You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, | ||
| # software distributed under the License is distributed on an | ||
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| # KIND, either express or implied. See the License for the | ||
| # specific language governing permissions and limitations | ||
| # under the License. | ||
|
|
||
| # Separate subpackage so that e.g. array.pyi doesn't shadow pyarrow.array() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it needed to run flake8 on the pyi files if we already run ruff linting+formatting? (does flake8 at that point add any value?)