diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 7beca4f..2141e36 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -18,7 +18,7 @@ jobs: fail-fast: false matrix: os: [ubuntu] - python-version: ['3.8', '3.9', '3.10'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] requirements: [latest] include: # Test on macos and windows (first and last version of python only) @@ -26,13 +26,13 @@ jobs: python-version: '3.8' requirements: latest - os: macos - python-version: '3.10' + python-version: '3.12' requirements: latest - os: windows python-version: '3.8' requirements: latest - os: windows - python-version: '3.10' + python-version: '3.12' requirements: latest # Test on minimal requirements - os: ubuntu diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7374eda..2c6d7e2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -34,6 +34,6 @@ repos: additional_dependencies: # Typed libraries - numpy - - pandas==1.4 + - pandas - pshell - - xarray==2022.3.0 + - xarray diff --git a/ci/requirements-docs.yml b/ci/requirements-docs.yml index 1ddbc86..eba53fd 100644 --- a/ci/requirements-docs.yml +++ b/ci/requirements-docs.yml @@ -2,10 +2,10 @@ name: ndcsv-docs channels: - conda-forge dependencies: - - python=3.10 + - python=3.12 - sphinx - sphinx_rtd_theme - numpy - - pandas=1.4 + - pandas - pshell - - xarray=2022.3.0 + - xarray diff --git a/ci/requirements-latest.yml b/ci/requirements-latest.yml index 057f2f5..bb6c753 100644 --- a/ci/requirements-latest.yml +++ b/ci/requirements-latest.yml @@ -5,6 +5,6 @@ dependencies: - pytest - pytest-cov - numpy - - pandas=1.4 + - pandas - pshell - - xarray=2022.3.0 + - xarray diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 9f4b14b..364cace 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -7,6 +7,9 @@ What's New v1.2.0 (unreleased) ------------------- +- Added support for Python 3.11 and 3.12 +- Added support for xarray >=2022.6.0 +- Added support for pandas >=1.5 .. _whats-new.1.1.0: diff --git a/ndcsv/proper_unstack.py b/ndcsv/proper_unstack.py index 9464747..8d4ec73 100644 --- a/ndcsv/proper_unstack.py +++ b/ndcsv/proper_unstack.py @@ -51,7 +51,7 @@ def proper_unstack(array: T, dim: Hashable) -> T: array.coords[dim] = mindex # Invoke builtin unstack - array = array.unstack(dim) + array = array.unstack(dim) # type: ignore[arg-type] # Convert numpy arrays of Python objects to numpy arrays of C floats, ints, # strings, etc. diff --git a/ndcsv/tests/test_read.py b/ndcsv/tests/test_read.py index 6e38d99..ddf43ad 100644 --- a/ndcsv/tests/test_read.py +++ b/ndcsv/tests/test_read.py @@ -10,6 +10,8 @@ from ndcsv import read_csv +PANDAS_GE_150 = [int(x) for x in pandas.__version__.split(".")] >= [1, 5] + def test_malformed_input(): buf = io.StringIO("foo,bar,baz") @@ -32,17 +34,16 @@ def test_coords_dtypes(unstack): if not unstack: # Manually unstack a = a.unstack("dim_1") - print("==================") - print(a) + assert a.x1.dtype.kind == "i" # int assert a.x2.dtype.kind == "M" # numpy.datetime64 assert a.y1.dtype.kind == "f" # float - if unstack: - assert a.x3.dtype.kind == "b" # bool - assert a.y2.dtype.kind == "U" # unicode string - else: + if not PANDAS_GE_150 and not unstack: assert a.x3.dtype.kind == "O" # bool assert a.y2.dtype.kind == "O" # unicode string + else: + assert a.x3.dtype.kind == "b" # bool + assert a.y2.dtype.kind == "U" # unicode string def test_coords_bool(): @@ -56,11 +57,20 @@ def test_coords_bool(): assert a.y.values.tolist() == [True, False] * 10 -def test_coords_date(): - buf = io.StringIO("y,10/11/2017,2017-11-10\nx,,\nx0,1,2\n") +@pytest.mark.parametrize( + "s", + [ + "2017-11-13,2017-11-14", + "13/11/2017,14/11/2017", + "11/13/2017,11/14/2017", + "13 Nov 2017,14 Nov 2017", + ], +) +def test_coords_date(s): + buf = io.StringIO(f"y,{s}\nx,,\nx0,1,2\n") a = read_csv(buf) np.testing.assert_equal( - pandas.to_datetime(["10 Nov 2017", "10 Nov 2017"]).values, a.coords["y"].values + pandas.to_datetime(["13 Nov 2017", "14 Nov 2017"]).values, a.coords["y"].values ) diff --git a/ndcsv/write.py b/ndcsv/write.py index af714a6..683df09 100644 --- a/ndcsv/write.py +++ b/ndcsv/write.py @@ -84,7 +84,9 @@ def _write_csv_dataarray(array: xarray.DataArray, buf: IO) -> None: f"Multi-dimensional coord '{k}' is not supported by the NDCSV format" ) if len(v.dims) == 1 and v.dims[0] != k: - coord_renames[k] = f"{k} ({v.dims[0]})" + idx = array.indexes[v.dims[0]] + if idx is not None and not isinstance(idx, pandas.MultiIndex): + coord_renames[k] = f"{k} ({v.dims[0]})" array = array.rename(coord_renames) if array.ndim > 2: diff --git a/setup.cfg b/setup.cfg index 2f9caf1..e61c62f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,9 +29,9 @@ include_package_data = True python_requires = >=3.8 install_requires = numpy >=1.14 - pandas >=0.24,<1.5 + pandas >=0.24 pshell >=1.0 - xarray >=0.14,<2022.6.0 + xarray >=0.14 setup_requires = setuptools_scm [options.package_data]