Repository navigation
Conversation
Co-authored-by: Dan Redding <[email protected]>
Co-authored-by: Dan Redding <[email protected]>
Co-authored-by: Dan Redding <[email protected]>
Co-authored-by: Dan Redding <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Add type annotation stubs for array, table, tensor, builder, memory, device, config, and types modules. Includes type-ignore annotations in related tests.
Drop the TypeVar/Generic parameters from the DataType subclasses, Field, Array, ChunkedArray and the tabular classes. Where a property can only return one of a few types (dictionary index type, run end type, time units) it now returns a union or Literal instead. Most of these parameters weren't buying much yet: scalar.pyi and lib.pyi are still placeholders, so e.g. Array[Scalar[...]] collapsed to Any anyway, and several annotations were being flagged by mypy and pyright (TypeVars used only once, type arguments on subclasses that weren't actually generic). Plain classes are a lot easier to read and review, and we can bring parameters back later where they clearly pay off. This also removes the stub-only _BasicDataType and _HasPrecisionScale helpers, which have no runtime counterpart, plus the IntoArray and SingleOrList aliases.
Add pyarrow-stubs/tests with pandas-stubs style checks:
check(assert_type(lib.list_(lib.int32()), lib.ListType), lib.ListType)
assert_type is verified by mypy, pyright and ty, which already include
pyarrow-stubs/ in their runs, and check() verifies the runtime class when
the tests run under pytest, so the stubs can't silently drift from what
pyarrow returns. Usage that should be rejected goes under
`if TYPE_CHECKING_INVALID_USAGE:` with a `# type: ignore[...]`; unused
ignores are errors in these tests, so those fail if the usage starts
type checking.
To have something to test, lib.pyi now re-exports the stub modules that
are annotated so far, still falling back to Any for everything else.
The CI type annotation script runs the tests with pytest after the type
checkers.
|
|
table.pyi imports RecordBatchReader from ._ipc, which had no stub, so pyright and ty failed to resolve the import. Add a placeholder in the same style as io.pyi and scalar.pyi until _ipc gets fully annotated.
|
I have run I have also run mypy's stubtest with Besides the reports mentioned above which will be fixed in subsequent PRs, stubtest did found one bug in pyarrow: Note missing "L" in "Decimal". I will work on the fix for this now and would suggest to add it as part of this PR. Can commit directly, if that is ok. |
|
I've run Running on editable dev build 27, with pyright==1.1.414 in my conda env, I also hit errors |
That makes sense and please go for it. I think we should aim for
Huh. I've never noticed these were missing. Given we're not really using them as types I'd skip them if we can.
Huh. Let's do the fix as separate PR, but also include a fix here? (And we'll just rebase over the actual fix on main)
I'm not sure we want (can) bring in ruff as a CI dependency. However we should autoformat before we merge, so we don't do it later and change history for no good reason. So I propose one of you runs the ruff formatter and commits the change into this branch. |
I think
Sounds good. Will open an issue and a PR and add a fix here also. |
Yeah, they are internal and exposed through |
Ok, I'll do that reformatting in a bit. |
|
I have started with reviewing pyarrow tests with running click for output$ mypy --check-untyped-defs --warn-unused-ignores pyarrow/tests/test_array.py
pyarrow/tests/test_array.py:21: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:22: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:25: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:80: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:790: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:986: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:1300: error: List item 3 has incompatible type "None"; expected "int" [list-item]
pyarrow/tests/test_array.py:1302: error: List item 1 has incompatible type "None"; expected "list[tuple[bytes, int]]" [list-item]
pyarrow/tests/test_array.py:1313: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:1320: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:1324: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:1348: error: List item 0 has incompatible type "None"; expected "list[tuple[bytes, int]]" [list-item]
pyarrow/tests/test_array.py:1348: error: List item 1 has incompatible type "None"; expected "list[tuple[bytes, int]]" [list-item]
pyarrow/tests/test_array.py:1362: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:2513: error: Need type annotation for "buffers" (hint: "buffers: list[<type>] = ...") [var-annotated]
pyarrow/tests/test_array.py:2539: error: "object" has no attribute "dtype" [attr-defined]
pyarrow/tests/test_array.py:2541: error: Value of type "object" is not indexable [index]
pyarrow/tests/test_array.py:2542: error: Value of type "object" is not indexable [index]
pyarrow/tests/test_array.py:2543: error: Value of type "object" is not indexable [index]
pyarrow/tests/test_array.py:2885: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:2917: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:2938: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:2939: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:3183: error: Value of type "object" is not indexable [index]
pyarrow/tests/test_array.py:3299: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:3720: error: Incompatible types in assignment (expression has type "None", variable has type "ndarray[tuple[Any, ...], dtype[Any]]") [assignment]
pyarrow/tests/test_array.py:3729: error: Value of type "object" is not indexable [index]
pyarrow/tests/test_array.py:3740: error: Value of type "object" is not indexable [index]
pyarrow/tests/test_array.py:3817: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:4004: error: Incompatible types in assignment (expression has type "MyArrayInvalid", variable has type "MyArray") [assignment]
pyarrow/tests/test_array.py:4017: error: Incompatible types in assignment (expression has type "MyArray2", variable has type "MyArray") [assignment]
pyarrow/tests/test_array.py:4031: error: Incompatible types in assignment (expression has type "MyArray3", variable has type "MyArray") [assignment]
pyarrow/tests/test_array.py:4095: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:4099: error: Unused "type: ignore" comment [unused-ignore]
pyarrow/tests/test_array.py:4315: error: List item 3 has incompatible type "None"; expected "int" [list-item]
pyarrow/tests/test_array.py:4319: error: List item 5 has incompatible type "None"; expected "int" [list-item]
pyarrow/tests/test_array.py:4324: error: List item 2 has incompatible type "None"; expected "int" [list-item]
pyarrow/tests/test_array.py:4324: error: List item 4 has incompatible type "None"; expected "int" [list-item]
pyarrow/tests/test_array.py:4395: error: List item 1 has incompatible type "None"; expected "int" [list-item]
pyarrow/tests/test_array.py:4407: error: List item 0 has incompatible type "None"; expected "int" [list-item]
Found 40 errors in 1 file (checked 1 source file)Type checkers are currently configured to skip I propose to temporarily add the |
|
Another thing: I can't run |
|
Oh, I was too fast here. Unfortunately Would it make sense to remove I will leave this for discussion and start with reading the stubs and comparing them with the APIs, starting with |
|
Ignore statements not being needed is more likely due to changes to typecheckers than due to changes in stubs. Or they might be needed once we import other parts of the library. Also note camel cased (e.g. reportArgumentType) ignores are likely coming from pyright. So if mypy thinks it's a redundant ignore you might want to check pyright too. |
Let's rather remove |
|
OK, agree, when reviewing I plan to do that later and am focusing on reading the stubs currently. |
|
Ehhh... I've fallen into this interesting rabbit hole - There are over 1.5k mypy errors % mypy --check-untyped-defs --warn-unused-ignores pyarrow/tests/test_convert_builtin.py
pyarrow/tests/test_convert_builtin.py:78: error: Module not callable [operator]
pyarrow/tests/test_convert_builtin.py:79: error: Module not callable [operator]
...
pyarrow/tests/test_convert_builtin.py:168: error: Module not callable [operator]
...
Found 321 errors in 1 file (checked 1 source file)
% mypy --check-untyped-defs --warn-unused-ignores pyarrow/tests/test_*.py
Found 1866 errors in 35 files (checked 44 source files)
% ... | grep -c "Module not callable"
1562test_convert_builtin.py:168 : pa.array(... A stub So I propose we reintroduce subfolder |
|
Just to note: with commit eda3425 stubs |
|
@tadeja I suppose the |
|
@jorisvandenbossche oh, yes, I think |
| values: NullableCollection | ||
| | Iterable[Any] |
There was a problem hiding this comment.
What is the point of having both the NullableCollection and Iterable? (the collection seems a strict subset of Iterable)
Rationale for this change
This is the next step in adding type annotations to PyArrow (#32609). It merges #49103 (internal type system stubs) and #49193 (core data structures) because the two depend on each other and can't be type checked separately.
What changes are included in this PR?
Are these changes tested?
Are there any user-facing changes?
Was AI used for this PR?
In accordance to the AI generation guidelines, please disclose below whether and how AI was used in this PR.
PR code and description written by:
Reviewed before submission by: