Skip to content
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

Corrections and enchancements to type stubs #1349

Merged
merged 83 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from 78 commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
851d453
Reformat type stubs with ruff to 130 chars
RandallPittmanOrSt Jul 11, 2024
5098b5e
Import typing.TYPE_CHECKING, import Self and TypeAlias from typing_ex…
RandallPittmanOrSt Jul 11, 2024
c45529d
Add missing comma to strings in CalendarOptions
RandallPittmanOrSt Jul 11, 2024
361ead0
dtype_is_complex is publicly available under the netCDF4 module due t…
RandallPittmanOrSt Jul 11, 2024
147337d
minor whitespace
RandallPittmanOrSt Jul 11, 2024
03e57b1
Use cls instead of self in __new__
RandallPittmanOrSt Jul 11, 2024
4badee2
Fix '__dealloc' >> '__dealloc__'
RandallPittmanOrSt Jul 11, 2024
d91bc54
Rename type aliases to singular names
RandallPittmanOrSt Jul 11, 2024
94fc229
Move TypedDicts to be adjacent to TypeAliases as they serve a simlar …
RandallPittmanOrSt Jul 11, 2024
4ec1558
minor - spelling in comment
RandallPittmanOrSt Jul 11, 2024
559429b
Rework all possible type arguments and overloads for createVariable. …
RandallPittmanOrSt Jul 12, 2024
516c644
Add docstring and notes section to top of file
RandallPittmanOrSt Jul 12, 2024
2268909
np.float64 is a possible type
RandallPittmanOrSt Jul 13, 2024
d5baab3
datatype specifier can be an arbitrary string
RandallPittmanOrSt Jul 13, 2024
229d6ae
Add float and str for GetSetItemKey
RandallPittmanOrSt Jul 13, 2024
06f7238
integral float can be specified for dimension size
RandallPittmanOrSt Jul 13, 2024
bc3bd3f
arbitrary strings can be used intead of literals, and truthy values i…
RandallPittmanOrSt Jul 13, 2024
ea0297f
enum_dict for createEnum can have int or np.integer values
RandallPittmanOrSt Jul 13, 2024
0ba830d
Return Any from Variable.__getitem__
RandallPittmanOrSt Jul 13, 2024
0c5524d
Simplify Variable.dtype to be Any
RandallPittmanOrSt Jul 13, 2024
290e671
minor fixes to enum type tests
RandallPittmanOrSt Jul 13, 2024
e5d88d0
use np.ma.masked_array in tests for numpy version compatibility
RandallPittmanOrSt Jul 13, 2024
8806f10
Add some assertions for static typing
RandallPittmanOrSt Jul 13, 2024
bb330c6
minor static typing additions
RandallPittmanOrSt Jul 13, 2024
513e4d6
use np.ndarray.tobytes instead of deprecated tostring
RandallPittmanOrSt Jul 13, 2024
c81f60d
__dealloc__ seems to be a cython-only member of Dataset
RandallPittmanOrSt Jul 14, 2024
62d97f3
Update stubtest-allowlist
RandallPittmanOrSt Jul 14, 2024
77bec6b
Restore some missing needed entires
RandallPittmanOrSt Jul 14, 2024
13d625a
Return Any rather than Union from datatype for now
RandallPittmanOrSt Jul 16, 2024
e086579
All arguments that take literals should allow arbitrary strings also.…
RandallPittmanOrSt Jul 16, 2024
4bad04f
Minor test fixes based on mypy/pyright checking
RandallPittmanOrSt Jul 16, 2024
84d5b41
Use descriptor stubs to overload datatype and dtype properties
RandallPittmanOrSt Jul 16, 2024
75dab94
explain type: ignore
RandallPittmanOrSt Jul 17, 2024
577a437
Fix from mypy - don't use the same name for different meanings in a fn
RandallPittmanOrSt Jul 17, 2024
2fcf116
Add some type: ignore for redefitions mypy doesn't like
RandallPittmanOrSt Jul 17, 2024
d5f87da
Make mypy more thorough by checking contents of untyped functions
RandallPittmanOrSt Jul 17, 2024
aee46f8
Add faux __iter__ method to Variable so type-checkers believe that it…
RandallPittmanOrSt Jul 17, 2024
d41ea15
Actually test for expected warning
RandallPittmanOrSt Jul 17, 2024
19c736f
Updated allowlist with faux __iter__ method
RandallPittmanOrSt Jul 17, 2024
cfb5fcb
Allow specifying more verbosity in test/run_all.py
RandallPittmanOrSt Jul 17, 2024
fbcb79f
Fix EnumDictTestCase not called due to bad indentation
RandallPittmanOrSt Jul 17, 2024
ac98550
Allow str as key for variable
RandallPittmanOrSt Jul 17, 2024
866ae47
minor comment update
RandallPittmanOrSt Jul 17, 2024
252deab
Moved mypy flags to pyproject.toml
RandallPittmanOrSt Jul 24, 2024
63c73ed
Merge remote-tracking branch 'upstream/master' into rwp_typing
RandallPittmanOrSt Jul 24, 2024
620faf7
Rename variables rather than mypy ignore to avoid redefinition errors
RandallPittmanOrSt Jul 24, 2024
31513ee
Restore bool type on truthy inputs, related fix on Variable.__init__
RandallPittmanOrSt Jul 24, 2024
15151d2
Fix type for shuffle argument in test
RandallPittmanOrSt Jul 24, 2024
d982b4c
Make sure rc_get and rc_set are exported
RandallPittmanOrSt Jul 24, 2024
f85bbfd
Make sure mypy and stubtest exclude utils
RandallPittmanOrSt Jul 24, 2024
40000e2
Add missing bzip2 to CompressionType
RandallPittmanOrSt Jul 25, 2024
f24edef
Restore limiting types to literals when creating datasets and variables
RandallPittmanOrSt Jul 25, 2024
7eebd5a
Add np.number as valid type for fill_value
RandallPittmanOrSt Jul 25, 2024
97273dd
Test updates to deal with only allowing Literals for some parameters
RandallPittmanOrSt Jul 25, 2024
13a79a1
Revamp GetSetItemKey
RandallPittmanOrSt Jul 25, 2024
a33f631
Fix runtime behavior of examples
RandallPittmanOrSt Jul 25, 2024
6442074
add typing-extensions so tests can pass
RandallPittmanOrSt Jul 25, 2024
c4e6e72
tests and examples are py311, don't need typing_extensions
RandallPittmanOrSt Jul 30, 2024
7c9eb60
disable some cicd
RandallPittmanOrSt Jul 30, 2024
ea84857
Always get and use typing-extensions in cast py<3.10
RandallPittmanOrSt Jul 30, 2024
303e8b1
Remove None union from typeguards
RandallPittmanOrSt Jul 30, 2024
111d347
Revamp type_guards a bit
RandallPittmanOrSt Jul 30, 2024
fab4050
Revert "disable some cicd"
RandallPittmanOrSt Jul 30, 2024
e0719da
(minor) restore whitespace to clean diff
RandallPittmanOrSt Jul 30, 2024
d42667d
(minor) restore whitespace again to clean diff
RandallPittmanOrSt Jul 30, 2024
3b1de4b
update examples and tests type_guards
RandallPittmanOrSt Jul 30, 2024
9f7698d
disallow lists of floats or strings in GetSetItemKey
RandallPittmanOrSt Jul 31, 2024
1975e12
disallow float dimension size
RandallPittmanOrSt Jul 31, 2024
cd002c8
Add TypeGuard for variable type
RandallPittmanOrSt Jul 31, 2024
3f2e8aa
Update type stub notes
RandallPittmanOrSt Jul 31, 2024
4400567
Revert "Add TypeGuard for variable type"
RandallPittmanOrSt Jul 31, 2024
50ed873
Revert erroneous change in chunksizes type
RandallPittmanOrSt Aug 23, 2024
0cf4d6d
Fix incorrect type of datatype for Real types
RandallPittmanOrSt Aug 23, 2024
55e88e7
Fixed inconsistent naming of DimensionsSpecifier >> DimensionsType
RandallPittmanOrSt Aug 23, 2024
00d3c61
Also rename DatatypeSpecifier >> DatatypeType
RandallPittmanOrSt Aug 23, 2024
29fd359
Don't need the type_guards module
RandallPittmanOrSt Aug 23, 2024
ac8c6fa
Don't bother with TypeGuard
RandallPittmanOrSt Aug 23, 2024
ba2e99a
Removed GetSetItemKey and replaced with typing.Any
RandallPittmanOrSt Sep 5, 2024
b26da50
Remove accidentally-commited nc files.
RandallPittmanOrSt Oct 21, 2024
d81d4fa
Update stubtest-allowlist for changes in recent commits
RandallPittmanOrSt Oct 21, 2024
9cd78c9
Merge remote-tracking branch 'upstream/master' into rwp_typing
RandallPittmanOrSt Oct 22, 2024
6a31be4
post-merge mypy/stubtest fixes. Allow any numpy generic or array in f…
RandallPittmanOrSt Oct 22, 2024
1004467
Revert stubtest change -- mypy v1.12 differs from 1.11
RandallPittmanOrSt Oct 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 26 additions & 15 deletions .github/stubtest-allowlist
Original file line number Diff line number Diff line change
@@ -1,33 +1,44 @@
netCDF4.AccessModeOptions
netCDF4.CompressionLevelOptions
netCDF4.CompressionOptions
netCDF4.DatatypeOptions
netCDF4.DimensionsOptions
netCDF4.DiskFormatOptions
netCDF4.EndianOptions
netCDF4.FormatOptions
netCDF4.QuantizeOptions
netCDF4.CalendarOptions
netCDF4.RealTypeLiteral
netCDF4.ComplexTypeLiteral
netCDF4.NumericTypeLiteral
netCDF4.CharTypeLiteral
netCDF4.TypeLiteral
netCDF4.NumPyRealType
netCDF4.NumPyComplexType
netCDF4.NumPyNumericType
netCDF4.NetCDFUDTClass
netCDF4.AccessMode
netCDF4.CompressionLevel
netCDF4.CompressionType
netCDF4.DatatypeSpecifier
netCDF4.DimensionsSpecifier
netCDF4.DiskFormat
netCDF4.EndianType
netCDF4.Format
netCDF4.QuantizeMode
netCDF4.CalendarType
netCDF4.ellipsis
netCDF4.DateTimeArray
netCDF4.FiltersDict
netCDF4.SzipInfo
netCDF4.BloscInfo
netCDF4.BoolInt
netCDF4.GetSetItemKey
netCDF4.T_Datatype
netCDF4.T_DatatypeNC
netCDF4.Dataset.__dealloc
netCDF4.VarT
netCDF4.RealVarT
netCDF4.ComplexVarT
netCDF4.NumericVarT
netCDF4.Dimension.__reduce_cython__
netCDF4.Dimension.__setstate_cython__
netCDF4.Variable.auto_complex
netCDF4._netCDF4.Dataset.__dealloc
netCDF4.Variable.__iter__
netCDF4._netCDF4.Dimension.__reduce_cython__
netCDF4._netCDF4.Dimension.__setstate_cython__
netCDF4._netCDF4.NC_DISKLESS
netCDF4._netCDF4.NC_PERSIST
netCDF4._netCDF4.Variable.auto_complex
netCDF4._netCDF4.Variable.__iter__
netCDF4._netCDF4.__reduce_cython__
netCDF4._netCDF4.__setstate_cython__
netCDF4._netCDF4.__test__
netCDF4.utils.bytes
netCDF4.utils
2 changes: 1 addition & 1 deletion .github/workflows/build_latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
- name: Install python dependencies via pip
run: |
python -m pip install --upgrade pip
pip install numpy cython cftime pytest twine wheel check-manifest mpi4py
pip install numpy cython cftime pytest twine wheel check-manifest mpi4py typing-extensions

- name: Install netcdf4-python
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build_master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
- name: Install python dependencies via pip
run: |
python -m pip install --upgrade pip
pip install numpy cython cftime pytest twine wheel check-manifest mpi4py mypy types-setuptools
pip install numpy cython cftime pytest twine wheel check-manifest mpi4py mypy types-setuptools typing-extensions

- name: Install netcdf4-python
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build_old.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
- name: Install python dependencies via pip
run: |
python -m pip install --upgrade pip
pip install numpy cython cftime pytest twine wheel check-manifest mpi4py
pip install numpy cython cftime pytest twine wheel check-manifest mpi4py typing-extensions

- name: Install netcdf4-python
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/cibuildwheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ jobs:
CIBW_TEST_SKIP: "cp38-*_aarch64 cp39-*_aarch64 cp310-*_aarch64 cp311-*_aarch64"
CIBW_ENVIRONMENT: ${{ matrix.CIBW_ENVIRONMENT }}
CIBW_BEFORE_BUILD_MACOS: brew install hdf5 netcdf
CIBW_TEST_REQUIRES: pytest cython packaging
CIBW_TEST_REQUIRES: pytest cython packaging typing-extensions
CIBW_TEST_COMMAND: >
python -c "import netCDF4; print(f'netCDF4 v{netCDF4.__version__}')"
&& pytest -s -rxs -v {project}/test
Expand Down Expand Up @@ -157,7 +157,7 @@ jobs:
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: >
delvewheel show {wheel}
&& delvewheel repair -w {dest_dir} {wheel}
CIBW_TEST_REQUIRES: pytest cython packaging
CIBW_TEST_REQUIRES: pytest cython packaging typing-extensions
CIBW_TEST_COMMAND: >
python -c "import netCDF4; print(f'netCDF4 v{netCDF4.__version__}')"
&& pytest -s -rxs -v {project}\\test
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/miniconda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
init-shell: bash
create-args: >-
python=${{ matrix.python-version }}
numpy cython pip pytest hdf5 libnetcdf cftime zlib certifi
numpy cython pip pytest hdf5 libnetcdf cftime zlib certifi typing-extensions
--channel conda-forge

- name: Install netcdf4-python
Expand Down Expand Up @@ -69,7 +69,7 @@ jobs:
init-shell: bash
create-args: >-
python=${{ matrix.python-version }}
numpy cython pip pytest mpi4py hdf5=*=mpi* libnetcdf=*=mpi* cftime zlib certifi
numpy cython pip pytest mpi4py hdf5=*=mpi* libnetcdf=*=mpi* cftime zlib certifi typing-extensions
--channel conda-forge

- name: Install netcdf4-python with mpi
Expand Down
7 changes: 6 additions & 1 deletion examples/bench.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# benchmark reads and writes, with and without compression.
# tests all four supported file formats.
from typing import TYPE_CHECKING, Any
from numpy.random.mtrand import uniform
import netCDF4
from timeit import Timer
import os, sys
if TYPE_CHECKING:
from netCDF4 import Format as NCFormat
else:
NCFormat = Any

# create an n1dim by n2dim by n3dim random array.
n1dim = 30
Expand All @@ -14,7 +19,7 @@
sys.stdout.write('reading and writing a %s by %s by %s by %s random array ..\n'%(n1dim,n2dim,n3dim,n4dim))
array = uniform(size=(n1dim,n2dim,n3dim,n4dim))

def write_netcdf(filename,zlib=False,least_significant_digit=None,format='NETCDF4'):
def write_netcdf(filename,zlib=False,least_significant_digit=None,format: NCFormat='NETCDF4'):
file = netCDF4.Dataset(filename,'w',format=format)
file.createDimension('n1', n1dim)
file.createDimension('n2', n2dim)
Expand Down
11 changes: 8 additions & 3 deletions examples/bench_compress.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# benchmark reads and writes, with and without compression.
# tests all four supported file formats.
from typing import TYPE_CHECKING, Any
from numpy.random.mtrand import uniform
import netCDF4
import netCDF4.utils
from timeit import Timer
import os, sys
if TYPE_CHECKING:
from netCDF4 import CompressionLevel
else:
CompressionLevel = Any

# create an n1dim by n2dim by n3dim random array.
n1dim = 30
Expand All @@ -13,10 +19,9 @@
ntrials = 10
sys.stdout.write('reading and writing a %s by %s by %s by %s random array ..\n'%(n1dim,n2dim,n3dim,n4dim))
sys.stdout.write('(average of %s trials)\n' % ntrials)
array = netCDF4.utils._quantize(uniform(size=(n1dim,n2dim,n3dim,n4dim)),4) # type: ignore
array = netCDF4.utils._quantize(uniform(size=(n1dim,n2dim,n3dim,n4dim)),4)


def write_netcdf(filename,zlib=False,shuffle=False,complevel=6):
def write_netcdf(filename,zlib=False,shuffle=False,complevel: CompressionLevel = 6):
file = netCDF4.Dataset(filename,'w',format='NETCDF4')
file.createDimension('n1', n1dim)
file.createDimension('n2', n2dim)
Expand Down
7 changes: 6 additions & 1 deletion examples/bench_compress4.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# benchmark reads and writes, with and without compression.
# tests all four supported file formats.
from typing import Literal
from numpy.random.mtrand import uniform
import netCDF4
from timeit import Timer
Expand All @@ -19,7 +20,11 @@
array = nc.variables['hgt'][0:n1dim,5,:,:]


def write_netcdf(filename,nsd,quantize_mode='BitGroom'):
def write_netcdf(
filename,
nsd,
quantize_mode: Literal["BitGroom", "BitRound", "GranularBitRound"] = "BitGroom"
):
file = netCDF4.Dataset(filename,'w',format='NETCDF4')
file.createDimension('n1', None)
file.createDimension('n3', n3dim)
Expand Down
11 changes: 8 additions & 3 deletions examples/bench_diskless.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# benchmark reads and writes, with and without compression.
# tests all four supported file formats.
from typing import TYPE_CHECKING, Any, Literal
from numpy.random.mtrand import uniform
import netCDF4
from timeit import Timer
import os, sys
if TYPE_CHECKING:
from netCDF4 import Format as NCFormat
else:
NCFormat = Any

# create an n1dim by n2dim by n3dim random array.
n1dim = 30
Expand All @@ -14,7 +19,7 @@
sys.stdout.write('reading and writing a %s by %s by %s by %s random array ..\n'%(n1dim,n2dim,n3dim,n4dim))
array = uniform(size=(n1dim,n2dim,n3dim,n4dim))

def write_netcdf(filename,zlib=False,least_significant_digit=None,format='NETCDF4',closeit=False):
def write_netcdf(filename, zlib=False, least_significant_digit=None, format: NCFormat='NETCDF4',closeit=False):
file = netCDF4.Dataset(filename,'w',format=format,diskless=True,persist=True)
file.createDimension('n1', n1dim)
file.createDimension('n2', n2dim)
Expand Down Expand Up @@ -42,13 +47,13 @@ def read_netcdf(ncfile):
sys.stdout.write('writing took %s seconds\n' %\
repr(sum(t.repeat(ntrials,1))/ntrials))
# test reading.
ncfile = write_netcdf('test1.nc',format=format)
ncfile = write_netcdf('test1.nc',format=format) # type: ignore
t = Timer("read_netcdf(ncfile)","from __main__ import read_netcdf,ncfile")
sys.stdout.write('reading took %s seconds\n' %
repr(sum(t.repeat(ntrials,1))/ntrials))

# test diskless=True in nc_open
format='NETCDF3_CLASSIC'
format: Literal["NETCDF3_CLASSIC"] = 'NETCDF3_CLASSIC' # mypy should know this but it needs help...
trials=50
sys.stdout.write('test caching of file in memory on open for %s\n' % format)
sys.stdout.write('testing file format %s ...\n' % format)
Expand Down
26 changes: 11 additions & 15 deletions examples/mpi_example.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
# to run: mpirun -np 4 python mpi_example.py
import sys
from typing import Literal
from mpi4py import MPI
import numpy as np
from netCDF4 import Dataset

format: Literal[
'NETCDF4',
'NETCDF4_CLASSIC',
'NETCDF3_CLASSIC',
'NETCDF3_64BIT_OFFSET',
'NETCDF3_64BIT_DATA'
]
if len(sys.argv) == 2:
format = sys.argv[1] # type: ignore
else:
format = 'NETCDF4_CLASSIC'

nc_format = 'NETCDF4_CLASSIC' if len(sys.argv) < 2 else sys.argv[1]

rank = MPI.COMM_WORLD.rank # The process ID (integer 0-3 for 4-process run)
if rank == 0:
print('Creating file with format {}'.format(format))
nc = Dataset('parallel_test.nc', 'w', parallel=True, comm=MPI.COMM_WORLD,
info=MPI.Info(), format=format)
print('Creating file with format {}'.format(nc_format))
nc = Dataset(
"parallel_test.nc",
"w",
parallel=True,
comm=MPI.COMM_WORLD,
info=MPI.Info(),
format=nc_format, # type: ignore # we'll assume it's OK
)
# below should work also - MPI_COMM_WORLD and MPI_INFO_NULL will be used.
#nc = Dataset('parallel_test.nc', 'w', parallel=True)
d = nc.createDimension('dim',4)
Expand Down
Binary file added examples/parallel_test.nc
RandallPittmanOrSt marked this conversation as resolved.
Show resolved Hide resolved
Binary file not shown.
Binary file added examples/parallel_test_compressed.nc
Binary file not shown.
6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ filterwarnings = [

[tool.mypy]
files = ["src/netCDF4"]
exclude = "utils.py"
check_untyped_defs = true
allow_redefinition = true
# next 2 lines workarounds for mypy dealing with type_guards.py
mypy_path = "test"
explicit_package_bases = true

[[tool.mypy.overrides]]
ignore_missing_imports = true
Expand Down
Loading
Loading