[Git][debian-gis-team/netcdf4-python][experimental] 6 commits: New upstream version 1.6.4

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Tue Jun 6 11:58:44 BST 2023



Bas Couwenberg pushed to branch experimental at Debian GIS Project / netcdf4-python


Commits:
d5fdc039 by Bas Couwenberg at 2023-06-06T12:43:09+02:00
New upstream version 1.6.4
- - - - -
e0634edc by Bas Couwenberg at 2023-06-06T12:43:13+02:00
Update upstream source from tag 'upstream/1.6.4'

Update to upstream version '1.6.4'
with Debian dir 50a383bf9124cda4cc331d5caab78815fadf73d6
- - - - -
b79905c0 by Bas Couwenberg at 2023-06-06T12:43:26+02:00
New upstream release.

- - - - -
6e0dd179 by Bas Couwenberg at 2023-06-06T12:44:53+02:00
Add python3-certifi to build dependencies.

- - - - -
f41e22f8 by Bas Couwenberg at 2023-06-06T12:45:27+02:00
Refresh patches.

- - - - -
8d780804 by Bas Couwenberg at 2023-06-06T12:45:53+02:00
Set distribution to experimental.

- - - - -


19 changed files:

- + .github/dependabot.yml
- .github/workflows/build_latest.yml
- .github/workflows/build_master.yml
- .github/workflows/build_old.yml
- .github/workflows/miniconda.yml
- Changelog
- README.md
- debian/changelog
- debian/control
- debian/patches/rpath.patch
- examples/reading_netCDF.ipynb
- include/netCDF4.pxi
- pyproject.toml
- setup.py
- src/netCDF4/_netCDF4.pyx
- test/run_all.py
- test/tst_dap.py
- test/tst_multifile.py
- + test/tst_multiple_open_close.py


Changes:

=====================================
.github/dependabot.yml
=====================================
@@ -0,0 +1,11 @@
+# See https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/keeping-your-actions-up-to-date-with-dependabot
+
+version: 2
+updates:
+
+  - package-ecosystem: "github-actions"
+    directory: "/"
+    schedule:
+      interval: "daily"
+    labels:
+      - "Bot"


=====================================
.github/workflows/build_latest.yml
=====================================
@@ -6,7 +6,7 @@ jobs:
     runs-on: ubuntu-latest
     env:
       PNETCDF_VERSION: 1.12.1
-      NETCDF_VERSION: 4.9.1
+      NETCDF_VERSION: 4.9.2
       NETCDF_DIR: ${{ github.workspace }}/..
       NETCDF_EXTRA_CONFIG: --enable-pnetcdf
       CC: mpicc.mpich
@@ -16,10 +16,10 @@ jobs:
         python-version: ["3.11"]
     steps:
 
-    - uses: actions/checkout at v2
+    - uses: actions/checkout at v3
 
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python at v2
+      uses: actions/setup-python at v4
       with:
         python-version: ${{ matrix.python-version }}
 


=====================================
.github/workflows/build_master.yml
=====================================
@@ -13,10 +13,10 @@ jobs:
         python-version: ["3.11"]
     steps:
 
-    - uses: actions/checkout at v2
+    - uses: actions/checkout at v3
 
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python at v2
+      uses: actions/setup-python at v4
       with:
         python-version: ${{ matrix.python-version }}
 


=====================================
.github/workflows/build_old.yml
=====================================
@@ -16,10 +16,10 @@ jobs:
         python-version: ["3.11"]
     steps:
 
-    - uses: actions/checkout at v2
+    - uses: actions/checkout at v3
 
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python at v2
+      uses: actions/setup-python at v4
       with:
         python-version: ${{ matrix.python-version }}
 


=====================================
.github/workflows/miniconda.yml
=====================================
@@ -24,29 +24,24 @@ jobs:
     - uses: actions/checkout at v3
 
     - name: Setup Micromamba
-      uses: mamba-org/provision-with-micromamba at v13
+      uses: mamba-org/setup-micromamba at v1
       with:
-        environment-file: false
+        environment-name: TEST
+        init-shell: bash
+        create-args: >-
+          python=${{ matrix.python-version }}
+          numpy cython pip pytest hdf5 libnetcdf cftime zlib certifi
+          --channel conda-forge
 
-    - name: Python ${{ matrix.python-version }}
+    - name: Install netcdf4-python
       shell: bash -l {0}
       run: |
-        micromamba create --name TEST python=${{ matrix.python-version }} numpy cython pip pytest hdf5 libnetcdf cftime zlib --channel conda-forge
-        micromamba activate TEST
         export PATH="${CONDA_PREFIX}/bin:${CONDA_PREFIX}/Library/bin:$PATH" # so setup.py finds nc-config
-        pip install -v -e . --no-deps --force-reinstall
-
-    - name: Debug conda
-      shell: bash -l {0}
-      run: |
-        micromamba activate TEST
-        micromamba info --all
-        micromamba list
+        python -m pip install -v -e . --no-deps --force-reinstall
 
     - name: Tests
       shell: bash -l {0}
       run: |
-        micromamba activate TEST
         cd test && python run_all.py
 
   run-mpi:
@@ -57,33 +52,28 @@ jobs:
         os: [ubuntu-latest]
         platform: [x64]
     steps:
-    - uses: actions/checkout at v2
+    - uses: actions/checkout at v3
 
     - name: Setup Micromamba
-      uses: mamba-org/provision-with-micromamba at main
+      uses: mamba-org/setup-micromamba at v1
       with:
-        environment-file: false
+        environment-name: TEST
+        init-shell: bash
+        create-args: >-
+          python=${{ matrix.python-version }}
+          numpy cython pip pytest mpi4py hdf5=*=mpi* libnetcdf=*=mpi* cftime zlib certifi
+          --channel conda-forge
 
-    - name: Python ${{ matrix.python-version }}
+    - name: Install netcdf4-python with mpi
       shell: bash -l {0}
       run: |
-        micromamba create --name TEST python=${{ matrix.python-version }} numpy cython pip pytest mpi4py hdf5=*=mpi* libnetcdf=*=mpi* cftime zlib --channel conda-forge
-        micromamba activate TEST
         export PATH="${CONDA_PREFIX}/bin:${CONDA_PREFIX}/Library/bin:$PATH" # so setup.py finds nc-config
         nc-config --all
-        pip install -v -e . --no-build-isolation --no-deps --force-reinstall
-
-    - name: Debug conda
-      shell: bash -l {0}
-      run: |
-        micromamba activate TEST
-        micromamba info --all
-        micromamba list
+        python -m pip install -v -e . --no-build-isolation --no-deps --force-reinstall
 
     - name: Tests
       shell: bash -l {0}
       run: |
-        micromamba activate TEST
         cd test && python run_all.py
         cd ../examples
         export PATH="${CONDA_PREFIX}/bin:${CONDA_PREFIX}/Library/bin:$PATH" 


=====================================
Changelog
=====================================
@@ -1,9 +1,18 @@
+ version 1.6.4 (tag v1.6.4rel)
+===============================
+ * set path to SSL certificates internally, so https DAP URLs work with wheels
+   (issue #1246, requires nc_rc_set function available starting with netcdf-c
+   4.9.1, plus bugfix in netcdf-c PR #2690).
+   Added certifi as a dependency.
+ * Added `isopen` method to `MFDataset` object to check if underlying files are open.
+
  version 1.6.3 (tag v1.6.3rel)
 ==============================
  * Use ``nc_put_vars`` for strided writes for netcdf-c >= 4.6.2 (issue #1222).
- * _Unsigned="false" should be same as not having _Unsigned set (issue #1232). 
+ * _Unsigned="false" should be same as not having _Unsigned set (issue #1232).
    _Unsigned now must be set to "true" or "True" for variable to be interpreted
    as unsigned, instead of just having _Unsigned be set (to anything).
+ * pypi wheels built with netcdf-c 4.9.1.
 
  version 1.6.2 (tag v1.6.2rel)
 ==============================
@@ -13,6 +22,7 @@
    now returns an empty numpy array (instead of raising an exception - issue #1197).
    Behavior now consistent with numpy slicing.
  * fix problem with compiling using netcdf-c < 4.9.0 (issue #1209)
+ * pypi wheels build with netcdf-c 4.9.0.
 
  version 1.6.1 (tag v1.6.1rel)
 ==============================
@@ -49,15 +59,15 @@
    options.
  * MFDataset did not aggregate 'name' variable attribute (issue #1153).
  * issue warning instead of raising an exception if missing_value or
-   _FillValue can't be cast to the variable type when creating a 
-   masked array (issue #1152).  
+   _FillValue can't be cast to the variable type when creating a
+   masked array (issue #1152).
  * Define MPI_Session for compatibility with current mpi4py (PR #1156).
 
  version 1.5.8 (tag v1.5.8rel)
 ==============================
  * Fix Enum bug (issue #1128): the enum_dict member of an EnumType read from a file
    contains invalid values when the enum is large enough (more than 127 or 255
-   members). 
+   members).
  * Binary wheels for aarch64 and python 3.10.
 
  version 1.5.7 (tag v1.5.7rel)
@@ -112,7 +122,7 @@
 
  version 1.5.3 (tag v1.5.3rel)
 ==============================
- * make sure arrays are masked that are not filled when auto_fill is off 
+ * make sure arrays are masked that are not filled when auto_fill is off
    (issue #972).
  * python 3.8 binary wheels.
 
@@ -154,7 +164,7 @@
  version 1.5.0.1 (tag v1.5.0.1rel)
 ==================================
  * binary wheels for linux and macosx rebuilt against netcdf-c 4.6.3 (instead
-   of 4.4.1.1).  
+   of 4.4.1.1).
  * add read-shared mode (mode='rs'). Significantly speeds up reads of NETCDF3
    files (pull request #902).
 


=====================================
README.md
=====================================
@@ -2,7 +2,7 @@
 [Python](http://python.org)/[numpy](http://numpy.org) interface to the netCDF [C library](https://github.com/Unidata/netcdf-c).
 
 [![Build status](https://github.com/Unidata/netcdf4-python/workflows/Build%20and%20Test/badge.svg)](https://github.com/Unidata/netcdf4-python/actions)
-[![PyPI package](https://badge.fury.io/py/netCDF4.svg)](http://python.org/pypi/netCDF4)
+[![PyPI package](https://img.shields.io/pypi/v/netCDF4.svg)](http://python.org/pypi/netCDF4)
 [![Anaconda-Server Badge](https://anaconda.org/conda-forge/netCDF4/badges/version.svg)](https://anaconda.org/conda-forge/netCDF4)
 [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.2592291.svg)](https://doi.org/10.5281/zenodo.2592290)
 
@@ -10,6 +10,10 @@
 ## News
 For details on the latest updates, see the [Changelog](https://github.com/Unidata/netcdf4-python/blob/master/Changelog).
 
+6/4/2023:  Version [1.6.4](https://pypi.python.org/pypi/netCDF4/1.6.4) released.  Now requires 
+[certifi](https://github.com/certifi/python-certifi) to locate SSL certificates - this allows 
+OpenDAP https URLs to work with linux wheels (issue [#1246](https://github.com/Unidata/netcdf4-python/issues/1246).
+
 3/3/2023:  Version [1.6.3](https://pypi.python.org/pypi/netCDF4/1.6.3) released.
 
 11/15/2022:  Version [1.6.2](https://pypi.python.org/pypi/netCDF4/1.6.2) released. Fix for


=====================================
debian/changelog
=====================================
@@ -1,3 +1,11 @@
+netcdf4-python (1.6.4-1~exp1) experimental; urgency=medium
+
+  * New upstream release.
+  * Add python3-certifi to build dependencies.
+  * Refresh patches.
+
+ -- Bas Couwenberg <sebastic at debian.org>  Tue, 06 Jun 2023 12:45:39 +0200
+
 netcdf4-python (1.6.3-1~exp1) experimental; urgency=medium
 
   * New upstream release.


=====================================
debian/control
=====================================
@@ -7,6 +7,7 @@ Build-Depends: debhelper-compat (= 12),
                dh-python,
                pybuild-plugin-pyproject,
                python3-all-dev,
+               python3-certifi,
                python3-cftime,
                python3-setuptools,
                python3-numpy,


=====================================
debian/patches/rpath.patch
=====================================
@@ -4,7 +4,7 @@ Forwarded: not-needed
 
 --- a/setup.py
 +++ b/setup.py
-@@ -524,11 +524,6 @@ NETCDF4_DIR environment variable not set
+@@ -528,11 +528,6 @@ NETCDF4_DIR environment variable not set
          lib_dirs.append(curl_libdir)
          inc_dirs.append(curl_incdir)
  
@@ -16,7 +16,7 @@ Forwarded: not-needed
  # Do not require numpy for just querying the package
  # Taken from the h5py setup file.
  if any('--' + opt in sys.argv for opt in Distribution.display_option_names +
-@@ -700,8 +695,7 @@ if 'sdist' not in sys.argv[1:] and 'clea
+@@ -711,8 +706,7 @@ if 'sdist' not in sys.argv[1:] and 'clea
                               define_macros=DEFINE_MACROS,
                               libraries=libs,
                               library_dirs=lib_dirs,


=====================================
examples/reading_netCDF.ipynb
=====================================
@@ -41,9 +41,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 1,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_number": 2,
      "slide_helper": "subslide_end"
@@ -79,9 +78,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 2,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 4,
@@ -97,7 +95,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "<type 'netCDF4._netCDF4.Dataset'>\n",
+      "<class 'netCDF4._netCDF4.Dataset'>\n",
       "root group (NETCDF4_CLASSIC data model, file format HDF5):\n",
       "    Conventions: CF-1.0\n",
       "    title: HYCOM ATLb2.00\n",
@@ -106,9 +104,8 @@
       "    experiment: 90.9\n",
       "    history: archv2ncdf3z\n",
       "    dimensions(sizes): MT(1), Y(850), X(712), Depth(10)\n",
-      "    variables(dimensions): float64 \u001b[4mMT\u001b[0m(MT), float64 \u001b[4mDate\u001b[0m(MT), float32 \u001b[4mDepth\u001b[0m(Depth), int32 \u001b[4mY\u001b[0m(Y), int32 \u001b[4mX\u001b[0m(X), float32 \u001b[4mLatitude\u001b[0m(Y,X), float32 \u001b[4mLongitude\u001b[0m(Y,X), float32 \u001b[4mu\u001b[0m(MT,Depth,Y,X), float32 \u001b[4mv\u001b[0m(MT,Depth,Y,X), float32 \u001b[4mtemperature\u001b[0m(MT,Depth,Y,X), float32 \u001b[4msalinity\u001b[0m(MT,Depth,Y,X)\n",
-      "    groups: \n",
-      "\n"
+      "    variables(dimensions): float64 MT(MT), float64 Date(MT), float32 Depth(Depth), int32 Y(Y), int32 X(X), float32 Latitude(Y, X), float32 Longitude(Y, X), float32 u(MT, Depth, Y, X), float32 v(MT, Depth, Y, X), float32 temperature(MT, Depth, Y, X), float32 salinity(MT, Depth, Y, X)\n",
+      "    groups: \n"
      ]
     }
    ],
@@ -138,9 +135,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 3,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 6,
@@ -156,14 +152,14 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "[u'MT', u'Date', u'Depth', u'Y', u'X', u'Latitude', u'Longitude', u'u', u'v', u'temperature', u'salinity']\n",
-      "<type 'netCDF4._netCDF4.Variable'>\n",
+      "dict_keys(['MT', 'Date', 'Depth', 'Y', 'X', 'Latitude', 'Longitude', 'u', 'v', 'temperature', 'salinity'])\n",
+      "<class 'netCDF4._netCDF4.Variable'>\n",
       "float32 temperature(MT, Depth, Y, X)\n",
       "    coordinates: Longitude Latitude Date\n",
       "    standard_name: sea_water_potential_temperature\n",
       "    units: degC\n",
-      "    _FillValue: 1.26765e+30\n",
-      "    valid_range: [ -5.07860279  11.14989948]\n",
+      "    _FillValue: 1.2676506e+30\n",
+      "    valid_range: [-5.078603  11.1498995]\n",
       "    long_name:   temp [90.9H]\n",
       "unlimited dimensions: MT\n",
       "current shape = (1, 10, 850, 712)\n",
@@ -199,9 +195,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 4,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 8
@@ -215,14 +210,10 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "(u'MT', <type 'netCDF4._netCDF4.Dimension'> (unlimited): name = 'MT', size = 1\n",
-      ")\n",
-      "(u'Y', <type 'netCDF4._netCDF4.Dimension'>: name = 'Y', size = 850\n",
-      ")\n",
-      "(u'X', <type 'netCDF4._netCDF4.Dimension'>: name = 'X', size = 712\n",
-      ")\n",
-      "(u'Depth', <type 'netCDF4._netCDF4.Dimension'>: name = 'Depth', size = 10\n",
-      ")\n"
+      "('MT', <class 'netCDF4._netCDF4.Dimension'> (unlimited): name = 'MT', size = 1)\n",
+      "('Y', <class 'netCDF4._netCDF4.Dimension'>: name = 'Y', size = 850)\n",
+      "('X', <class 'netCDF4._netCDF4.Dimension'>: name = 'X', size = 712)\n",
+      "('Depth', <class 'netCDF4._netCDF4.Dimension'>: name = 'Depth', size = 10)\n"
      ]
     }
    ],
@@ -248,9 +239,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 5,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 10
@@ -263,10 +253,10 @@
     {
      "data": {
       "text/plain": [
-       "(u'MT', u'Depth', u'Y', u'X')"
+       "('MT', 'Depth', 'Y', 'X')"
       ]
      },
-     "execution_count": 9,
+     "execution_count": 5,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -277,9 +267,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": 6,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 11,
@@ -297,7 +286,7 @@
        "(1, 10, 850, 712)"
       ]
      },
-     "execution_count": 10,
+     "execution_count": 6,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -326,9 +315,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 7,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 13,
@@ -344,7 +332,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "<type 'netCDF4._netCDF4.Variable'>\n",
+      "<class 'netCDF4._netCDF4.Variable'>\n",
       "float64 MT(MT)\n",
       "    long_name: time\n",
       "    units: days since 1900-12-31 00:00:00\n",
@@ -352,16 +340,14 @@
       "    axis: T\n",
       "unlimited dimensions: MT\n",
       "current shape = (1,)\n",
-      "filling on, default _FillValue of 9.96920996839e+36 used\n",
-      "\n",
-      "<type 'netCDF4._netCDF4.Variable'>\n",
+      "filling on, default _FillValue of 9.969209968386869e+36 used\n",
+      "<class 'netCDF4._netCDF4.Variable'>\n",
       "int32 X(X)\n",
       "    point_spacing: even\n",
       "    axis: X\n",
       "unlimited dimensions: \n",
       "current shape = (712,)\n",
-      "filling on, default _FillValue of -2147483647 used\n",
-      "\n"
+      "filling on, default _FillValue of -2147483647 used\n"
      ]
     }
    ],
@@ -395,9 +381,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": 8,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 15
@@ -411,7 +396,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "[ 41023.25]\n"
+      "[41023.25]\n"
      ]
     }
    ],
@@ -422,9 +407,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 9,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 16
@@ -438,7 +422,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "[    0.   100.   200.   400.   700.  1000.  2000.  3000.  4000.  5000.]\n"
+      "[   0.  100.  200.  400.  700. 1000. 2000. 3000. 4000. 5000.]\n"
      ]
     }
    ],
@@ -449,9 +433,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 10,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 17,
@@ -501,9 +484,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
+   "execution_count": 11,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 19
@@ -517,14 +499,13 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "<type 'netCDF4._netCDF4.Variable'>\n",
+      "<class 'netCDF4._netCDF4.Variable'>\n",
       "float32 Latitude(Y, X)\n",
       "    standard_name: latitude\n",
       "    units: degrees_north\n",
       "unlimited dimensions: \n",
       "current shape = (850, 712)\n",
-      "filling on, default _FillValue of 9.96920996839e+36 used\n",
-      "\n"
+      "filling on, default _FillValue of 9.969209968386869e+36 used\n"
      ]
     }
    ],
@@ -552,9 +533,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 16,
+   "execution_count": 12,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 20,
@@ -636,9 +616,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
+   "execution_count": 13,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 25,
@@ -707,9 +686,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": 14,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 28,
@@ -725,7 +703,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "http://thredds.ucar.edu/thredds/dodsC/grib/NCEP/GFS/Global_0p5deg/GFS_Global_0p5deg_20150711_0600.grib2/GC\n"
+      "https://thredds.ucar.edu/thredds/dodsC/grib/NCEP/GFS/Global_0p5deg/GFS_Global_0p5deg_20230525_1200.grib2/GC\n"
      ]
     }
    ],
@@ -733,7 +711,7 @@
     "import datetime\n",
     "date = datetime.datetime.now()\n",
     "# build URL for latest synoptic analysis time\n",
-    "URL = 'http://thredds.ucar.edu/thredds/dodsC/grib/NCEP/GFS/Global_0p5deg/GFS_Global_0p5deg_%04i%02i%02i_%02i%02i.grib2/GC' %\\\n",
+    "URL = 'https://thredds.ucar.edu/thredds/dodsC/grib/NCEP/GFS/Global_0p5deg/GFS_Global_0p5deg_%04i%02i%02i_%02i%02i.grib2/GC' %\\\n",
     "(date.year,date.month,date.day,6*(date.hour//6),0)\n",
     "# keep moving back 6 hours until a valid URL found\n",
     "validURL = False; ncount = 0\n",
@@ -749,9 +727,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 15,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 28,
@@ -768,52 +745,50 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "<type 'netCDF4._netCDF4.Variable'>\n",
-      "float32 Temperature_surface(time2, lat, lon)\n",
+      "<class 'netCDF4._netCDF4.Variable'>\n",
+      "float32 Temperature_surface(time1, lat, lon)\n",
       "    long_name: Temperature @ Ground or water surface\n",
       "    units: K\n",
       "    abbreviation: TMP\n",
       "    missing_value: nan\n",
       "    grid_mapping: LatLon_Projection\n",
-      "    coordinates: reftime time2 lat lon \n",
+      "    coordinates: reftime time1 lat lon \n",
       "    Grib_Variable_Id: VAR_0-0-0_L1\n",
       "    Grib2_Parameter: [0 0 0]\n",
       "    Grib2_Parameter_Discipline: Meteorological products\n",
       "    Grib2_Parameter_Category: Temperature\n",
       "    Grib2_Parameter_Name: Temperature\n",
-      "    Grib2_Level_Type: Ground or water surface\n",
+      "    Grib2_Level_Type: 1\n",
+      "    Grib2_Level_Desc: Ground or water surface\n",
       "    Grib2_Generating_Process_Type: Forecast\n",
+      "    Grib2_Statistical_Process_Type: UnknownStatType--1\n",
       "unlimited dimensions: \n",
-      "current shape = (93, 361, 720)\n",
+      "current shape = (129, 361, 720)\n",
       "filling off\n",
-      "\n",
-      "<type 'netCDF4._netCDF4.Variable'>\n",
-      "float64 time2(time2)\n",
-      "    units: Hour since 2015-07-11T06:00:00Z\n",
+      "<class 'netCDF4._netCDF4.Variable'>\n",
+      "float64 time1(time1)\n",
+      "    units: Hour since 2023-05-25T12:00:00Z\n",
       "    standard_name: time\n",
       "    long_name: GRIB forecast or observation time\n",
       "    calendar: proleptic_gregorian\n",
       "    _CoordinateAxisType: Time\n",
       "unlimited dimensions: \n",
-      "current shape = (93,)\n",
+      "current shape = (129,)\n",
       "filling off\n",
-      "\n",
-      "<type 'netCDF4._netCDF4.Variable'>\n",
+      "<class 'netCDF4._netCDF4.Variable'>\n",
       "float32 lat(lat)\n",
       "    units: degrees_north\n",
       "    _CoordinateAxisType: Lat\n",
       "unlimited dimensions: \n",
       "current shape = (361,)\n",
       "filling off\n",
-      "\n",
-      "<type 'netCDF4._netCDF4.Variable'>\n",
+      "<class 'netCDF4._netCDF4.Variable'>\n",
       "float32 lon(lon)\n",
       "    units: degrees_east\n",
       "    _CoordinateAxisType: Lon\n",
       "unlimited dimensions: \n",
       "current shape = (720,)\n",
-      "filling off\n",
-      "\n"
+      "filling off\n"
      ]
     }
    ],
@@ -849,9 +824,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": 16,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 31
@@ -870,9 +844,9 @@
     },
     {
      "data": {
-      "image/png": "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\n",
+      "image/png": "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",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x1125c5a90>"
+       "<Figure size 640x480 with 1 Axes>"
       ]
      },
      "metadata": {},
@@ -931,9 +905,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 17,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 34
@@ -947,15 +920,17 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "name of time dimension = time2\n",
-      "units = Hour since 2015-07-11T06:00:00Z, values = [   0.    3.    6.    9.   12.   15.   18.   21.   24.   27.   30.   33.\n",
-      "   36.   39.   42.   45.   48.   51.   54.   57.   60.   63.   66.   69.\n",
-      "   72.   75.   78.   81.   84.   87.   90.   93.   96.   99.  102.  105.\n",
-      "  108.  111.  114.  117.  120.  123.  126.  129.  132.  135.  138.  141.\n",
-      "  144.  147.  150.  153.  156.  159.  162.  165.  168.  171.  174.  177.\n",
-      "  180.  183.  186.  189.  192.  195.  198.  201.  204.  207.  210.  213.\n",
-      "  216.  219.  222.  225.  228.  231.  234.  237.  240.  252.  264.  276.\n",
-      "  288.  300.  312.  324.  336.  348.  360.  372.  384.]\n"
+      "name of time dimension = time1\n",
+      "units = Hour since 2023-05-25T12:00:00Z, values = [  0.   3.   6.   9.  12.  15.  18.  21.  24.  27.  30.  33.  36.  39.\n",
+      "  42.  45.  48.  51.  54.  57.  60.  63.  66.  69.  72.  75.  78.  81.\n",
+      "  84.  87.  90.  93.  96.  99. 102. 105. 108. 111. 114. 117. 120. 123.\n",
+      " 126. 129. 132. 135. 138. 141. 144. 147. 150. 153. 156. 159. 162. 165.\n",
+      " 168. 171. 174. 177. 180. 183. 186. 189. 192. 195. 198. 201. 204. 207.\n",
+      " 210. 213. 216. 219. 222. 225. 228. 231. 234. 237. 240. 243. 246. 249.\n",
+      " 252. 255. 258. 261. 264. 267. 270. 273. 276. 279. 282. 285. 288. 291.\n",
+      " 294. 297. 300. 303. 306. 309. 312. 315. 318. 321. 324. 327. 330. 333.\n",
+      " 336. 339. 342. 345. 348. 351. 354. 357. 360. 363. 366. 369. 372. 375.\n",
+      " 378. 381. 384.]\n"
      ]
     }
    ],
@@ -969,9 +944,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": 18,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 35,
@@ -987,7 +961,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "['2015-07-11 06:00:00', '2015-07-11 09:00:00', '2015-07-11 12:00:00', '2015-07-11 15:00:00', '2015-07-11 18:00:00', '2015-07-11 21:00:00', '2015-07-12 00:00:00', '2015-07-12 03:00:00', '2015-07-12 06:00:00', '2015-07-12 09:00:00']\n"
+      "['2023-05-25 12:00:00', '2023-05-25 15:00:00', '2023-05-25 18:00:00', '2023-05-25 21:00:00', '2023-05-26 00:00:00', '2023-05-26 03:00:00', '2023-05-26 06:00:00', '2023-05-26 09:00:00', '2023-05-26 12:00:00', '2023-05-26 15:00:00']\n"
      ]
     }
    ],
@@ -1014,9 +988,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 24,
+   "execution_count": 19,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 37
@@ -1030,8 +1003,8 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "2015-07-14 07:22:39.579246\n",
-      "index = 24, date = 2015-07-14 06:00:00\n"
+      "2023-05-28 15:57:27.760935\n",
+      "index = 25, date = 2023-05-28 15:00:00\n"
      ]
     }
    ],
@@ -1061,9 +1034,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": 20,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 39,
@@ -1079,7 +1051,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Boulder forecast valid at 2015-07-14 06:00:00 UTC = 296.8 K\n"
+      "Boulder forecast valid at 2023-05-28 15:00:00 UTC = 297.6 K\n"
      ]
     }
    ],
@@ -1113,9 +1085,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 26,
+   "execution_count": 21,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 41
@@ -1129,23 +1100,23 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "-rw-r--r--  1 jwhitaker  staff  8985332 Jul 10 06:43 data/prmsl.2000.nc\r\n",
-      "-rw-r--r--  1 jwhitaker  staff  8968789 Jul 10 06:43 data/prmsl.2001.nc\r\n",
-      "-rw-r--r--  1 jwhitaker  staff  8972796 Jul 10 06:43 data/prmsl.2002.nc\r\n",
-      "-rw-r--r--  1 jwhitaker  staff  8974435 Jul 10 06:43 data/prmsl.2003.nc\r\n",
-      "-rw-r--r--  1 jwhitaker  staff  8997438 Jul 10 06:43 data/prmsl.2004.nc\r\n",
-      "-rw-r--r--  1 jwhitaker  staff  8976678 Jul 10 06:43 data/prmsl.2005.nc\r\n",
-      "-rw-r--r--  1 jwhitaker  staff  8969714 Jul 10 06:43 data/prmsl.2006.nc\r\n",
-      "-rw-r--r--  1 jwhitaker  staff  8974360 Jul 10 06:43 data/prmsl.2007.nc\r\n",
-      "-rw-r--r--  1 jwhitaker  staff  8994260 Jul 10 06:43 data/prmsl.2008.nc\r\n",
-      "-rw-r--r--  1 jwhitaker  staff  8974678 Jul 10 06:43 data/prmsl.2009.nc\r\n",
-      "-rw-r--r--  1 jwhitaker  staff  8970732 Jul 10 06:43 data/prmsl.2010.nc\r\n",
-      "-rw-r--r--  1 jwhitaker  staff  8976285 Jul 10 06:43 data/prmsl.2011.nc\r\n"
+      "-rw-rw-r-- 1 8985332 May 17 15:27 data/prmsl.2000.nc\r\n",
+      "-rw-rw-r-- 1 8968789 May 17 15:27 data/prmsl.2001.nc\r\n",
+      "-rw-rw-r-- 1 8972796 May 17 15:27 data/prmsl.2002.nc\r\n",
+      "-rw-rw-r-- 1 8974435 May 17 15:27 data/prmsl.2003.nc\r\n",
+      "-rw-rw-r-- 1 8997438 May 17 15:27 data/prmsl.2004.nc\r\n",
+      "-rw-rw-r-- 1 8976678 May 17 15:27 data/prmsl.2005.nc\r\n",
+      "-rw-rw-r-- 1 8969714 May 17 15:27 data/prmsl.2006.nc\r\n",
+      "-rw-rw-r-- 1 8974360 May 17 15:27 data/prmsl.2007.nc\r\n",
+      "-rw-rw-r-- 1 8994260 May 17 15:27 data/prmsl.2008.nc\r\n",
+      "-rw-rw-r-- 1 8974678 May 17 15:27 data/prmsl.2009.nc\r\n",
+      "-rw-rw-r-- 1 8970732 May 17 15:27 data/prmsl.2010.nc\r\n",
+      "-rw-rw-r-- 1 8976285 May 17 15:27 data/prmsl.2011.nc\r\n"
      ]
     }
    ],
    "source": [
-    "!ls -l data/prmsl*nc"
+    "!ls -ldgG data/prmsl*nc"
    ]
   },
   {
@@ -1172,9 +1143,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 27,
+   "execution_count": 22,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 43,
@@ -1193,7 +1163,7 @@
       "starting date = 2000-01-01 00:00:00\n",
       "ending date = 2011-12-31 00:00:00\n",
       "times shape = 4383\n",
-      "prmsl dimensions = (u'time', u'lat', u'lon'), prmsl shape = (4383, 91, 180)\n"
+      "prmsl dimensions = ('time', 'lat', 'lon'), prmsl shape = (4383, 91, 180)\n"
      ]
     }
    ],
@@ -1229,9 +1199,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 28,
+   "execution_count": 23,
    "metadata": {
-    "collapsed": false,
     "internals": {
      "frag_helper": "fragment_end",
      "frag_number": 45
@@ -1271,23 +1240,23 @@
  "metadata": {
   "celltoolbar": "Raw Cell Format",
   "kernelspec": {
-   "display_name": "Python 2",
+   "display_name": "Python 3 (ipykernel)",
    "language": "python",
-   "name": "python2"
+   "name": "python3"
   },
   "language_info": {
    "codemirror_mode": {
     "name": "ipython",
-    "version": 2
+    "version": 3
    },
    "file_extension": ".py",
    "mimetype": "text/x-python",
    "name": "python",
    "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython2",
-   "version": "2.7.9"
+   "pygments_lexer": "ipython3",
+   "version": "3.9.16"
   }
  },
  "nbformat": 4,
- "nbformat_minor": 0
+ "nbformat_minor": 1
 }


=====================================
include/netCDF4.pxi
=====================================
@@ -366,6 +366,7 @@ cdef extern from "netcdf.h":
     int nc_inq_enum_member(int ncid, nc_type xtype, int idx, char *name, void *value) nogil
 
     int nc_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier) nogil
+    int nc_rc_set(char* key, char* value) nogil
 
 IF HAS_QUANTIZATION_SUPPORT:
     cdef extern from "netcdf.h":


=====================================
pyproject.toml
=====================================
@@ -42,6 +42,7 @@ classifiers = [
 ]
 dependencies = [
     "cftime",
+    "certifi",
     "numpy",
 ]
 dynamic = ["version"]


=====================================
setup.py
=====================================
@@ -60,6 +60,7 @@ def check_api(inc_dirs,netcdf_lib_version):
     has_blosc = False
     has_ncfilter = False
     has_set_alignment = False
+    has_nc_rc_set = False
 
     for d in inc_dirs:
         try:
@@ -83,6 +84,8 @@ def check_api(inc_dirs,netcdf_lib_version):
                 has_quantize = True
             if line.startswith('nc_set_alignment'):
                 has_set_alignment = True
+            if line.startswith('EXTERNL int nc_rc_set'):
+                has_nc_rc_set = True
 
         if has_nc_open_mem:
             try:
@@ -150,7 +153,8 @@ def check_api(inc_dirs,netcdf_lib_version):
     return has_rename_grp, has_nc_inq_path, has_nc_inq_format_extended, \
            has_cdf5_format, has_nc_open_mem, has_nc_create_mem, \
            has_parallel4_support, has_pnetcdf_support, has_szip_support, has_quantize, \
-           has_zstandard, has_bzip2, has_blosc, has_set_alignment, has_ncfilter
+           has_zstandard, has_bzip2, has_blosc, has_set_alignment, has_ncfilter, \
+           has_nc_rc_set
 
 
 def getnetcdfvers(libdirs):
@@ -564,7 +568,7 @@ if 'sdist' not in sys.argv[1:] and 'clean' not in sys.argv[1:] and '--version' n
     has_rename_grp, has_nc_inq_path, has_nc_inq_format_extended, \
     has_cdf5_format, has_nc_open_mem, has_nc_create_mem, \
     has_parallel4_support, has_pnetcdf_support, has_szip_support, has_quantize, \
-    has_zstandard, has_bzip2, has_blosc, has_set_alignment, has_ncfilter = \
+    has_zstandard, has_bzip2, has_blosc, has_set_alignment, has_ncfilter, has_nc_rc_set = \
     check_api(inc_dirs,netcdf_lib_version)
     # for netcdf 4.4.x CDF5 format is always enabled.
     if netcdf_lib_version is not None and\
@@ -686,6 +690,13 @@ if 'sdist' not in sys.argv[1:] and 'clean' not in sys.argv[1:] and '--version' n
         sys.stdout.write('netcdf lib does not have nc_inq_filter_avail function\n')
         f.write('DEF HAS_NCFILTER = 0\n')
 
+    if has_nc_rc_set:
+        sys.stdout.write('netcdf lib has nc_rc_set function\n')
+        f.write('DEF HAS_NCRCSET = 1\n')
+    else:
+        sys.stdout.write('netcdf lib does not have nc_rc_set function\n')
+        f.write('DEF HAS_NCRCSET = 0\n')
+
     f.close()
 
     if has_parallel4_support or has_pnetcdf_support:


=====================================
src/netCDF4/_netCDF4.pyx
=====================================
@@ -1,5 +1,5 @@
 """
-Version 1.6.3
+Version 1.6.4
 -------------
 
 # Introduction
@@ -33,7 +33,7 @@ types) are not supported.
  - Clone the
    [github repository](http://github.com/Unidata/netcdf4-python).
  - Make sure the dependencies are satisfied (Python 3.7 or later,
-   [numpy](http://numpy.scipy.org), 
+   [numpy](http://numpy.scipy.org),
    [Cython](http://cython.org),
    [cftime](https://github.com/Unidata/cftime),
    [setuptools](https://pypi.python.org/pypi/setuptools),
@@ -155,12 +155,12 @@ in a netCDF 3 file you will get an error message.
 >>> print(rootgrp.groups)
 {'forecasts': <class 'netCDF4._netCDF4.Group'>
 group /forecasts:
-    dimensions(sizes): 
-    variables(dimensions): 
+    dimensions(sizes):
+    variables(dimensions):
     groups: , 'analyses': <class 'netCDF4._netCDF4.Group'>
 group /analyses:
-    dimensions(sizes): 
-    variables(dimensions): 
+    dimensions(sizes):
+    variables(dimensions):
     groups: }
 >>>
 ```
@@ -196,32 +196,32 @@ object yields summary information about it's contents.
 >>> print(rootgrp)
 <class 'netCDF4._netCDF4.Dataset'>
 root group (NETCDF4 data model, file format HDF5):
-    dimensions(sizes): 
-    variables(dimensions): 
+    dimensions(sizes):
+    variables(dimensions):
     groups: forecasts, analyses
 >>> for children in walktree(rootgrp):
 ...     for child in children:
 ...         print(child)
 <class 'netCDF4._netCDF4.Group'>
 group /forecasts:
-    dimensions(sizes): 
-    variables(dimensions): 
+    dimensions(sizes):
+    variables(dimensions):
     groups: model1, model2
 <class 'netCDF4._netCDF4.Group'>
 group /analyses:
-    dimensions(sizes): 
-    variables(dimensions): 
-    groups: 
+    dimensions(sizes):
+    variables(dimensions):
+    groups:
 <class 'netCDF4._netCDF4.Group'>
 group /forecasts/model1:
-    dimensions(sizes): 
-    variables(dimensions): 
-    groups: 
+    dimensions(sizes):
+    variables(dimensions):
+    groups:
 <class 'netCDF4._netCDF4.Group'>
 group /forecasts/model2:
-    dimensions(sizes): 
-    variables(dimensions): 
-    groups: 
+    dimensions(sizes):
+    variables(dimensions):
+    groups:
 ```
 
 ## Dimensions in a netCDF file
@@ -356,9 +356,9 @@ You can also query a `Dataset` or `Group` instance directly to obtain `Group` or
 >>> print(rootgrp["/forecasts/model1"])  # a Group instance
 <class 'netCDF4._netCDF4.Group'>
 group /forecasts/model1:
-    dimensions(sizes): 
+    dimensions(sizes):
     variables(dimensions): float32 temp(time,level,lat,lon)
-    groups: 
+    groups:
 >>> print(rootgrp["/forecasts/model1/temp"])  # a Variable instance
 <class 'netCDF4._netCDF4.Variable'>
 float32 temp(time, level, lat, lon)
@@ -384,11 +384,11 @@ unlimited dimensions: level
 current shape = (0,)
 filling on, default _FillValue of -2147483647 used, 'lat': <class 'netCDF4._netCDF4.Variable'>
 float32 lat(lat)
-unlimited dimensions: 
+unlimited dimensions:
 current shape = (73,)
 filling on, default _FillValue of 9.969209968386869e+36 used, 'lon': <class 'netCDF4._netCDF4.Variable'>
 float32 lon(lon)
-unlimited dimensions: 
+unlimited dimensions:
 current shape = (144,)
 filling on, default _FillValue of 9.969209968386869e+36 used, 'temp': <class 'netCDF4._netCDF4.Variable'>
 float32 temp(time, level, lat, lon)
@@ -672,7 +672,7 @@ underlying file format is HDF5) and are silently ignored if the file
 format is `NETCDF3_CLASSIC`, `NETCDF3_64BIT_OFFSET` or `NETCDF3_64BIT_DATA`.
 If the HDF5 library is built with szip support, compression=`szip` can also
 be used (in conjunction with the `szip_coding` and `szip_pixels_per_block` keyword
-arguments).  
+arguments).
 
 If your data only has a certain number of digits of precision (say for
 example, it is temperature data that was measured with a precision of
@@ -782,7 +782,7 @@ objects gives useful summary information in an interactive session:
 root group (NETCDF4 data model, file format HDF5):
     dimensions(sizes): x_dim(3)
     variables(dimensions): {'names':['real','imag'], 'formats':['<f8','<f8'], 'offsets':[0,8], 'itemsize':16, 'aligned':True} cmplx_var(x_dim)
-    groups: 
+    groups:
 >>> print(f.variables["cmplx_var"])
 <class 'netCDF4._netCDF4.Variable'>
 compound cmplx_var(x_dim)
@@ -851,12 +851,12 @@ vlen variable =
 root group (NETCDF4 data model, file format HDF5):
     dimensions(sizes): x(3), y(4)
     variables(dimensions): int32 phony_vlen_var(y,x)
-    groups: 
+    groups:
 >>> print(f.variables["phony_vlen_var"])
 <class 'netCDF4._netCDF4.Variable'>
 vlen phony_vlen_var(y, x)
 vlen data type: int32
-unlimited dimensions: 
+unlimited dimensions:
 current shape = (4, 3)
 >>> print(f.vltypes["phony_vlen"])
 <class 'netCDF4._netCDF4.VLType'>: name = 'phony_vlen', numpy dtype = int32
@@ -893,12 +893,12 @@ variable-length string variable:
 root group (NETCDF4 data model, file format HDF5):
     dimensions(sizes): x(3), y(4), z(10)
     variables(dimensions): int32 phony_vlen_var(y,x), <class 'str'> strvar(z)
-    groups: 
+    groups:
 >>> print(f.variables["strvar"])
 <class 'netCDF4._netCDF4.Variable'>
 vlen strvar(z)
 vlen data type: <class 'str'>
-unlimited dimensions: 
+unlimited dimensions:
 current shape = (10,)
 ```
 
@@ -967,7 +967,7 @@ current shape = (5,)
 
 If MPI parallel enabled versions of netcdf and hdf5 or pnetcdf are detected,
 and [mpi4py](https://mpi4py.scipy.org) is installed, netcdf4-python will
-be built with parallel IO capabilities enabled. Parallel IO of NETCDF4 or 
+be built with parallel IO capabilities enabled. Parallel IO of NETCDF4 or
 NETCDF4_CLASSIC formatted files is only available if the MPI parallel HDF5
 library is available. Parallel IO of classic netcdf-3 file formats is only
 available if the [PnetCDF](https://parallel-netcdf.github.io/) library is
@@ -1154,7 +1154,7 @@ approaches.
 root group (NETCDF4 data model, file format HDF5):
     dimensions(sizes): x(5)
     variables(dimensions): int32 v(x)
-    groups: 
+    groups:
 >>> print(nc['v'][:])
 [0 1 2 3 4]
 >>> nc.close() # file saved to disk
@@ -1171,7 +1171,7 @@ root group (NETCDF4 data model, file format HDF5):
 root group (NETCDF4 data model, file format HDF5):
     dimensions(sizes): x(5)
     variables(dimensions): int32 v(x)
-    groups: 
+    groups:
 >>> print(nc['v'][:])
 [0 1 2 3 4]
 >>> nc.close()
@@ -1226,8 +1226,9 @@ from cpython.bytes cimport PyBytes_FromStringAndSize
 from .utils import (_StartCountStride, _quantize, _find_dim, _walk_grps,
                     _out_array_shape, _sortbylist, _tostr, _safecast, _is_int)
 import sys
+import functools
 
-__version__ = "1.6.3"
+__version__ = "1.6.4"
 
 # Initialize numpy
 import posixpath
@@ -1258,6 +1259,20 @@ ELSE:
     ctypedef object Comm
     ctypedef object Info
 
+# set path to SSL certificates (issue #1246)
+IF HAS_NCRCSET: # available starting in version 4.9.1
+    import certifi
+    cdef _set_curl_certpath(certpath):
+        cdef char *cert_path
+        cdef char *key
+        cdef int ierr
+        bytestr = _strencode(certpath)
+        cert_path = bytestr
+        ierr = nc_rc_set("HTTP.SSL.CAINFO",cert_path)
+        if ierr != 0:
+            raise RuntimeError('error setting path to SSL certificates')
+    _set_curl_certpath(certifi.where())
+
 # check for required version of netcdf-4 and hdf5.
 
 def _gethdf5libversion():
@@ -1265,7 +1280,7 @@ def _gethdf5libversion():
     cdef herr_t ierr
     with nogil:
         ierr = H5get_libversion( &majorvers, &minorvers, &releasevers)
-    if ierr < 0:
+    if ierr != 0:
         raise RuntimeError('error getting HDF5 library version info')
     return '%d.%d.%d' % (majorvers,minorvers,releasevers)
 
@@ -1392,9 +1407,9 @@ _needsworkaround_issue485 = __netcdf4libversion__ < "4.4.0" or \
 if __netcdf4libversion__[0:5] < "4.4.1" and\
    __hdf5libversion__.startswith("1.10"):
     msg = """
-WARNING: Backwards incompatible files will be created with HDF5 1.10.x 
-and netCDF < 4.4.1. Upgrading to netCDF4 >= 4.4.1 or downgrading to 
-to HDF5 version 1.8.x is highly recommended 
+WARNING: Backwards incompatible files will be created with HDF5 1.10.x
+and netCDF < 4.4.1. Upgrading to netCDF4 >= 4.4.1 or downgrading to
+to HDF5 version 1.8.x is highly recommended
 (see https://github.com/Unidata/netcdf-c/issues/250)."""
     warnings.warn(msg)
 
@@ -2119,8 +2134,8 @@ strings.
         **`mode`**: access mode. `r` means read-only; no data can be
         modified. `w` means write; a new file is created, an existing file with
         the same name is deleted. `x` means write, but fail if an existing
-        file with the same name already exists. `a` and `r+` mean append; 
-        an existing file is opened for reading and writing, if 
+        file with the same name already exists. `a` and `r+` mean append;
+        an existing file is opened for reading and writing, if
         file does not exist already, one is created.
         Appending `s` to modes `r`, `w`, `r+` or `a` will enable unbuffered shared
         access to `NETCDF3_CLASSIC`, `NETCDF3_64BIT_OFFSET` or
@@ -2401,7 +2416,7 @@ strings.
                 if parallel:
                     # NC_SHARE ignored
                     IF HAS_PARALLEL4_SUPPORT or HAS_PNETCDF_SUPPORT:
-                        cmode = NC_CLOBBER | parmode 
+                        cmode = NC_CLOBBER | parmode
                         with nogil:
                             ierr = nc_create_par(path, NC_CLOBBER | cmode, \
                                    mpicomm, mpiinfo, &grpid)
@@ -2617,7 +2632,9 @@ Is the Dataset open or closed?
         return bool(self._isopen)
 
     def __dealloc__(self):
-        # close file when there are no references to object left
+        # close file when there are no references to object left and clear the cache.
+        if self.get_variables_by_attributes:
+            self.get_variables_by_attributes.cache_clear()
         if self._isopen:
            self._close(False)
 
@@ -2763,7 +2780,7 @@ datatype."""
                 enum_dict)
         return self.enumtypes[datatype_name]
 
-    def createVariable(self, varname, datatype, dimensions=(), 
+    def createVariable(self, varname, datatype, dimensions=(),
             compression=None, zlib=False,
             complevel=4, shuffle=True,
             szip_coding='nn',szip_pixels_per_block=8,
@@ -2815,7 +2832,7 @@ Default is `None` (no compression).  All of the compressors except
 `zlib` and `szip` use the HDF5 plugin architecture.
 
 If the optional keyword `zlib` is `True`, the data will be compressed in
-the netCDF file using zlib compression (default `False`).  The use of this option is 
+the netCDF file using zlib compression (default `False`).  The use of this option is
 deprecated in favor of `compression='zlib'`.
 
 The optional keyword `complevel` is an integer between 0 and 9 describing
@@ -3333,9 +3350,10 @@ of existing (sub-) groups and their variables.
             for group in groups:
                 group.set_ncstring_attrs(value) # recurse into subgroups...
 
+    @functools.lru_cache(maxsize=128)
     def get_variables_by_attributes(self, **kwargs):
         """
-**`get_variables_by_attribute(self, **kwargs)`**
+**`get_variables_by_attributes(self, **kwargs)`**
 
 Returns a list of variables that match specific conditions.
 
@@ -3422,15 +3440,15 @@ suffix replaced by `.nc` is used..
 **`format`**: underlying file format to use (one of `'NETCDF4',
 'NETCDF4_CLASSIC', 'NETCDF3_CLASSIC'`, `'NETCDF3_64BIT_OFFSET'` or
 `'NETCDF3_64BIT_DATA'`. Default `'NETCDF4'`.
-       
+
 Dataset instance for `ncfilename` is returned.
- 
+
 [ncgen]: https://www.unidata.ucar.edu/software/netcdf/docs/netcdf_utilities_guide.html#ncgen_guide
 [cdl]: https://www.unidata.ucar.edu/software/netcdf/docs/netcdf_utilities_guide.html#cdl_guide
         """
         if ncfilename is None:
             filepath = pathlib.Path(cdlfilename)
-            ncfilename = filepath.with_suffix('.nc') 
+            ncfilename = filepath.with_suffix('.nc')
         formatcodes = {'NETCDF4': 4,
                        'NETCDF4_CLASSIC': 7,
                        'NETCDF3_CLASSIC': 3,
@@ -3824,13 +3842,13 @@ truncated to retain this number of significant digits when it is assigned to the
 Only available with netcdf-c >= 4.9.0,
 and only works with `NETCDF4` or `NETCDF4_CLASSIC` formatted files.
 The number of significant digits used in the quantization of variable data can be
-obtained using the `Variable.significant_digits` method. Default `None` - 
+obtained using the `Variable.significant_digits` method. Default `None` -
 no quantization done.
 
 **`quantize_mode`**: New in version 1.6.0. Controls
 the quantization algorithm (default 'BitGroom', 'BitRound' and
 'GranularBitRound' also available).  The 'GranularBitRound'
-algorithm may result in better compression for typical geophysical datasets. 
+algorithm may result in better compression for typical geophysical datasets.
 Ignored if `significant_digits` not specified. If 'BitRound' is used, then
 `significant_digits` is interpreted as binary (not decimal) digits.
 
@@ -3854,7 +3872,7 @@ behavior is similar to Fortran or Matlab, but different than numpy.
     def __init__(self, grp, name, datatype, dimensions=(),
             compression=None, zlib=False,
             complevel=4, shuffle=True, szip_coding='nn', szip_pixels_per_block=8,
-            blosc_shuffle=1, 
+            blosc_shuffle=1,
             fletcher32=False, contiguous=False,
             chunksizes=None, endian='native', least_significant_digit=None,
             significant_digits=None,quantize_mode='BitGroom',fill_value=None, chunk_cache=None, **kwargs):
@@ -3894,7 +3912,7 @@ behavior is similar to Fortran or Matlab, but different than numpy.
         (defined previously with `createDimension`). Default is an empty tuple
         which means the variable is a scalar (and therefore has no dimensions).
 
-        **`compression`**: compression algorithm to use. 
+        **`compression`**: compression algorithm to use.
         Currently `zlib`,`szip`,`zstd`,`bzip2`,`blosc_lz`,`blosc_lz4`,`blosc_lz4hc`,
         `blosc_zlib` and `blosc_zstd` are supported.
         Default is `None` (no compression).  All of the compressors except
@@ -3920,7 +3938,7 @@ behavior is similar to Fortran or Matlab, but different than numpy.
         or `nn` (nearest neighbor coding). Default is `nn`.
         Ignored if szip compressor not used.
 
-        **`szip_pixels_per_block`**: Can be 4,8,16 or 32 (Default 8). 
+        **`szip_pixels_per_block`**: Can be 4,8,16 or 32 (Default 8).
         Ignored if szip compressor not used.
 
         **`fletcher32`**: if `True` (default `False`), the Fletcher32 checksum
@@ -4001,7 +4019,7 @@ behavior is similar to Fortran or Matlab, but different than numpy.
         cdef float preemptionp
         # flag to indicate that orthogonal indexing is supported
         self.__orthogonal_indexing__ = True
-        # For backwards compatibility, deprecated zlib kwarg takes 
+        # For backwards compatibility, deprecated zlib kwarg takes
         # precedence if compression kwarg not set.
         if zlib and not compression:
             compression = 'zlib'
@@ -4500,7 +4518,7 @@ kwarg for quantization."""
 
     property datatype:
         """numpy data type (for primitive data types) or
-        VLType/CompoundType/EnumType instance 
+        VLType/CompoundType/EnumType instance
         (for compound, vlen  or enum data types)"""
         def __get__(self):
             if self._iscompound:
@@ -4640,8 +4658,8 @@ return dictionary containing HDF5 filter parameters."""
         cdef int iszip=0
         cdef int iszip_coding=0
         cdef int iszip_pixels_per_block=0
-        cdef int icomplevel_zstd=0 
-        cdef int icomplevel_bzip2=0 
+        cdef int icomplevel_zstd=0
+        cdef int icomplevel_bzip2=0
         cdef unsigned int iblosc_shuffle=0
         cdef unsigned int iblosc_compressor=0
         cdef unsigned int iblosc_blocksize=0
@@ -5572,7 +5590,7 @@ When data is written to a variable, the masked
 array is converted back to a regular numpy array by replacing all the
 masked values by the missing_value attribute of the variable (if it
 exists).  If the variable has no missing_value attribute, the _FillValue
-is used instead. 
+is used instead.
 
 If `maskandscale` is set to `True`, and the variable has a
 `scale_factor` or an `add_offset` attribute, then data read
@@ -5662,7 +5680,7 @@ When data is written to a variable, the masked
 array is converted back to a regular numpy array by replacing all the
 masked values by the missing_value attribute of the variable (if it
 exists).  If the variable has no missing_value attribute, the _FillValue
-is used instead. 
+is used instead.
 
 The default value of `mask` is `True`
 (automatic conversions are performed).
@@ -6930,6 +6948,14 @@ Example usage (See `MFDataset.__init__` for more details):
         for dset in self._cdf:
             dset.close()
 
+    def isopen(self):
+        """
+        **`isopen(self)`**
+
+        True if all files are open, False otherwise.
+        """
+        return all(map(lambda dset: dset.isopen(), self._cdf))
+
     def __repr__(self):
         ncdump = [repr(type(self))]
         dimnames = tuple(str(dimname) for dimname in self.dimensions.keys())


=====================================
test/run_all.py
=====================================
@@ -57,6 +57,11 @@ if os.getenv('NO_CDL'):
     test_files.remove('tst_cdl.py');
     sys.stdout.write('not running tst_cdl.py ...\n')
 
+# Don't run computationally intensive test
+if not os.getenv('MEMORY_LEAK_TEST'):
+    test_files.remove('tst_multiple_open_close.py');
+    sys.stdout.write('not running tst_multiple_open_close.py ...\n')
+
 # Build the test suite from the tests found in the test files.
 testsuite = unittest.TestSuite()
 for f in test_files:


=====================================
test/tst_dap.py
=====================================
@@ -7,8 +7,8 @@ from numpy.testing import assert_array_almost_equal
 # test accessing data over http with opendap.
 
 yesterday = datetime.utcnow() - timedelta(days=1)
-URL = "http://nomads.ncep.noaa.gov/dods/gfs_1p00/gfs%s/gfs_1p00_00z" % yesterday.strftime('%Y%m%d')
-URL_https = 'https://podaac-opendap.jpl.nasa.gov/opendap/allData/modis/L3/aqua/11um/v2019.0/4km/daily/2017/365/AQUA_MODIS.20171231.L3m.DAY.NSST.sst.4km.nc'
+URL = f'http://nomads.ncep.noaa.gov/dods/gfs_1p00/gfs{yesterday:%Y%m%d}/gfs_1p00_00z'
+URL_https = 'https://www.neracoos.org/erddap/griddap/WW3_EastCoast_latest'
 varname = 'hgtsfc'
 data_min = -40; data_max = 5900
 varshape = (181, 360)
@@ -33,7 +33,7 @@ class DapTestCase(unittest.TestCase):
         ncfile.close()
         # test https support (linked curl lib must built with openssl support)
         ncfile = netCDF4.Dataset(URL_https)
-        assert(ncfile['sst'].long_name=='Sea Surface Temperature')    
+        assert(ncfile['hs'].long_name=='Significant Wave Height')
         ncfile.close()
 
 if __name__ == '__main__':


=====================================
test/tst_multifile.py
=====================================
@@ -74,7 +74,9 @@ class VariablesTestCase(unittest.TestCase):
         f = MFDataset(self.files,check=True)
         assert f.get_variables_by_attributes(axis='T') == []
         f.get_variables_by_attributes(units='zlotys')[0] == f['x']
+        assert f.isopen()
         f.close()
+        assert not f.isopen()
 
 class NonuniformTimeTestCase(unittest.TestCase):
     ninc = 365


=====================================
test/tst_multiple_open_close.py
=====================================
@@ -0,0 +1,50 @@
+import os
+import tracemalloc
+import unittest
+
+import netCDF4
+
+class MultipleVariablesByAttributesCallsTests(unittest.TestCase):
+
+
+    def test_multiple_calls(self):
+        netcdf_file = os.path.join(os.path.dirname(__file__), "netcdf_dummy_file.nc")
+        tracemalloc.start()
+        snapshot = tracemalloc.take_snapshot()
+
+        k_times = 10
+        for _k in range(k_times):
+            nc = netCDF4.Dataset(netcdf_file)
+            
+            vs = nc.get_variables_by_attributes(axis='Z')
+            self.assertEqual(len(vs), 1)
+            
+            vs = nc.get_variables_by_attributes(units='m/s')
+            self.assertEqual(len(vs), 4)
+
+            vs = nc.get_variables_by_attributes(axis='Z', units='m')
+            self.assertEqual(len(vs), 1)
+            
+            vs = nc.get_variables_by_attributes(axis=lambda v: v in ['X', 'Y', 'Z', 'T'])
+            self.assertEqual(len(vs), 1)
+
+            vs = nc.get_variables_by_attributes(grid_mapping=lambda v: v is not None)
+            self.assertEqual(len(vs), 12)
+
+            vs = nc.get_variables_by_attributes(grid_mapping=lambda v: v is not None, long_name=lambda v: v is not None and 'Upward (w) velocity' in v)
+            self.assertEqual(len(vs), 1)
+
+            vs = nc.get_variables_by_attributes(units='m/s', grid_mapping=lambda v: v is not None)
+            self.assertEqual(len(vs), 4)
+
+            vs = nc.get_variables_by_attributes(grid_mapping=lambda v: v is not None, long_name='Upward (w) velocity')
+            self.assertEqual(len(vs), 1)
+            nc.close()
+        stats = tracemalloc.take_snapshot().compare_to(snapshot, 'filename')
+        tracemalloc.stop()
+        print("[ Top 10 differences ]")
+        for stat in stats[:10]:
+            print(stat)
+
+if __name__ == '__main__':    
+    unittest.main()



View it on GitLab: https://salsa.debian.org/debian-gis-team/netcdf4-python/-/compare/72edf5468504e1172465ca0f7c0ee2348b977073...8d780804d90d1f6f67991471a6eef76b39d50dc0

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/netcdf4-python/-/compare/72edf5468504e1172465ca0f7c0ee2348b977073...8d780804d90d1f6f67991471a6eef76b39d50dc0
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20230606/f3490e54/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list