rabernat: Is anyone maintaining this package? Why haven't PR's like this one been merged?
diff --git a/setup.py b/setup.py
index 7471f20..79675e6 100644
--- a/setup.py
+++ b/setup.py
@@ -9,7 +9,8 @@ install_requires = [
     'Jinja2',
     'docopt',
     'six >= 1.4.0',
-    'beautifulsoup4'
+    'beautifulsoup4',
+    'requests'
 ]
 
 if sys.version_info < (3, 5):
@@ -32,14 +33,13 @@ docs_extras = [
 ]
 
 cas_extras = [
-    'requests',
     'lxml'
-    ]
+]
 
 hdl_netcdf_extras = [
     'netCDF4',
     'ordereddict'
-    ]
+]
 
 tests_require = (functions_extras + cas_extras + server_extras +
                  hdl_netcdf_extras +
diff --git a/src/pydap/handlers/csv/__init__.py b/src/pydap/handlers/csv/__init__.py
index 38ded4c..717079b 100644
--- a/src/pydap/handlers/csv/__init__.py
+++ b/src/pydap/handlers/csv/__init__.py
@@ -114,7 +114,7 @@ class CSVHandler(BaseHandler):
         BaseHandler.__init__(self)
 
         try:
-            with open(filepath, 'Ur') as fp:
+            with open(filepath, 'r') as fp:
                 reader = csv.reader(fp, quoting=csv.QUOTE_NONNUMERIC)
                 vars = next(reader)
         except Exception as exc:
@@ -257,7 +257,7 @@ class CSVData(IterData):
     def stream(self):
         """Generator that yield lines of the file."""
         try:
-            with open(self.filepath, 'Ur') as fp:
+            with open(self.filepath, 'r') as fp:
                 reader = csv.reader(fp, quoting=csv.QUOTE_NONNUMERIC)
                 next(reader)  # consume var names
                 for row in reader:
diff --git a/src/pydap/handlers/lib.py b/src/pydap/handlers/lib.py
index dca98b8..ffef4e8 100644
--- a/src/pydap/handlers/lib.py
+++ b/src/pydap/handlers/lib.py
@@ -120,7 +120,7 @@ class BaseHandler(object):
                     'Origin, X-Requested-With, Content-Type')
 
             return res(environ, start_response)
-        except:
+        except Exception:
             # should the exception be catched?
             if environ.get('x-wsgiorg.throw_errors'):
                 raise
@@ -456,7 +456,7 @@ def build_filter(expression, template):
             col = keys.index(token)
             target = target[token]
         a = operator.itemgetter(col)
-    except:
+    except Exception:
         raise ConstraintExpressionError(
             'Invalid constraint expression: "{expression}" '
             '("{id}" is not a valid variable)'.format(
@@ -474,7 +474,7 @@ def build_filter(expression, template):
 
             def b(row):
                 return value
-        except:
+        except Exception:
             raise ConstraintExpressionError(
                 'Invalid constraint expression: "{expression}" '
                 '("{id}" is not valid)'.format(
diff --git a/src/pydap/lib.py b/src/pydap/lib.py
index ed55eb9..7bfc7ea 100644
--- a/src/pydap/lib.py
+++ b/src/pydap/lib.py
@@ -125,7 +125,7 @@ def encode(obj):
     """Return an object encoded to its DAP representation."""
     try:
         return '%.6g' % obj
-    except:
+    except Exception:
         return '"{0}"'.format(obj)
 
 
diff --git a/src/pydap/model.py b/src/pydap/model.py
index 335f0c3..ee9b486 100644
--- a/src/pydap/model.py
+++ b/src/pydap/model.py
@@ -381,7 +381,7 @@ class StructureType(DapType, Mapping):
         """Lazy shortcut return children."""
         try:
             return self[attr]
-        except:
+        except Exception:
             return DapType.__getattr__(self, attr)
 
     def __contains__(self, key):
@@ -408,7 +408,7 @@ class StructureType(DapType, Mapping):
             if len(splitted) > 1:
                 try:
                     return self[splitted[0]]['.'.join(splitted[1:])]
-                except KeyError:
+                except (KeyError, IndexError):
                     return self['.'.join(splitted[1:])]
             else:
                 raise
diff --git a/src/pydap/parsers/__init__.py b/src/pydap/parsers/__init__.py
index 7068faa..aab33ed 100644
--- a/src/pydap/parsers/__init__.py
+++ b/src/pydap/parsers/__init__.py
@@ -74,12 +74,12 @@ def parse_selection(expression, dataset):
 
     try:
         id1 = get_var(dataset, id1)
-    except:
+    except Exception:
         id1 = ast.literal_eval(id1)
 
     try:
         id2 = get_var(dataset, id2)
-    except:
+    except Exception:
         id2 = ast.literal_eval(id2)
 
     return id1, op, id2
diff --git a/src/pydap/wsgi/app.py b/src/pydap/wsgi/app.py
index b735b10..578187e 100644
--- a/src/pydap/wsgi/app.py
+++ b/src/pydap/wsgi/app.py
@@ -155,7 +155,7 @@ def alphanum_key(s):
     def tryint(s):
         try:
             return int(s)
-        except:
+        except Exception:
             return s
     return [tryint(c) for c in re.split('([0-9]+)', s)]
 
diff --git a/src/pydap/wsgi/ssf.py b/src/pydap/wsgi/ssf.py
index e85eed4..785c7d4 100644
--- a/src/pydap/wsgi/ssf.py
+++ b/src/pydap/wsgi/ssf.py
@@ -183,10 +183,10 @@ def eval_function(dataset, function, functions):
             try:
                 names = re.sub(r'\[.*?\]', '', str(token)).split('.')
                 return reduce(operator.getitem, [dataset] + names)
-            except:
+            except Exception:
                 try:
                     return ast.literal_eval(token)
-                except:
+                except Exception:
                     return token
 
     args = map(parse, tokenize(args))

requests missing from requirements
It appears pydap uses the requests pacakge, but it's not listed in the setup.py:

```
install_requires = [
    'numpy',
    'Webob',
    'Jinja2',
    'docopt',
    'six >= 1.4.0',
    'beautifulsoup4'
]
```

diff --git a/src/pydap/tests/test_model.py b/src/pydap/tests/test_model.py
index c2e8fee..35e7e77 100644
--- a/src/pydap/tests/test_model.py
+++ b/src/pydap/tests/test_model.py
@@ -248,8 +248,10 @@ def test_StructureType_getitem():
     """Test item retrieval."""
     var = StructureType("var")
     child = BaseType("child")
+    child.data = np.array([[[0, 1]]])
     var["child"] = child
     assert var["child"] is child
+    assert var["child.child"] is child
     with pytest.raises(KeyError):
         var["unloved child"]
     with pytest.raises(KeyError):
diff --git a/src/pydap/tests/test_responses_error.py b/src/pydap/tests/test_responses_error.py
index 70e35ab..3c9f06e 100644
--- a/src/pydap/tests/test_responses_error.py
+++ b/src/pydap/tests/test_responses_error.py
@@ -11,7 +11,7 @@ class TestErrorResponse(unittest.TestCase):
         # create an exception that would happen in runtime
         try:
             1/0
-        except:
+        except Exception:
             error = ErrorResponse(sys.exc_info())
 
         req = Request.blank('/')

pip install -e .[server,handlers.netcdf,testing]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-attrib requests-mock requests
apt-get update apt-get install -y libhdf5-serial-dev netcdf-bin libnetcdf-dev
3.6
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
beautifulsoup4==4.12.3
certifi==2021.5.30
cftime==1.6.0
charset-normalizer==2.0.12
coards==1.0.5
coverage==6.2
docopt==0.6.2
flake8==5.0.4
gsw==3.0.6
gunicorn==21.2.0
idna==3.10
importlib-metadata==4.2.0
iniconfig==1.1.1
Jinja2==3.0.3
lxml==5.3.1
MarkupSafe==2.0.1
mccabe==0.7.0
netCDF4==1.6.2
numpy==1.19.5
ordereddict==1.1
packaging==21.3
PasteDeploy==2.1.1
pluggy==1.0.0
py==1.11.0
pycodestyle==2.9.1
-e git+https://github.com/pydap/pydap.git@4ae73e393b0d52bce9d1cf5571945a9ed884d526#egg=Pydap
pyflakes==2.5.0
pyparsing==3.1.4
pytest==7.0.1
pytest-attrib==0.1.3
pytest-cov==4.0.0
requests==2.27.1
requests-mock==1.12.1
six==1.17.0
soupsieve==2.3.2.post1
tomli==1.2.3
typing_extensions==4.1.1
urllib3==1.26.20
waitress==2.0.0
WebOb==1.8.9
WebTest==3.0.0
zipp==3.6.0

name: pydap
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - beautifulsoup4==4.12.3
      - cftime==1.6.0
      - charset-normalizer==2.0.12
      - coards==1.0.5
      - coverage==6.2
      - docopt==0.6.2
      - flake8==5.0.4
      - gsw==3.0.6
      - gunicorn==21.2.0
      - idna==3.10
      - importlib-metadata==4.2.0
      - iniconfig==1.1.1
      - jinja2==3.0.3
      - lxml==5.3.1
      - markupsafe==2.0.1
      - mccabe==0.7.0
      - netcdf4==1.6.2
      - numpy==1.19.5
      - ordereddict==1.1
      - packaging==21.3
      - pastedeploy==2.1.1
      - pluggy==1.0.0
      - py==1.11.0
      - pycodestyle==2.9.1
      - pyflakes==2.5.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-attrib==0.1.3
      - pytest-cov==4.0.0
      - requests==2.27.1
      - requests-mock==1.12.1
      - six==1.17.0
      - soupsieve==2.3.2.post1
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - waitress==2.0.0
      - webob==1.8.9
      - webtest==3.0.0
      - zipp==3.6.0
prefix: /opt/conda/envs/pydap

src/pydap/tests/test_model.py::test_StructureType_getitem
src/pydap/tests/test_model.py::test_DapType_quote src/pydap/tests/test_model.py::test_DapType_attributes src/pydap/tests/test_model.py::test_DapType_id src/pydap/tests/test_model.py::test_DapType_repr src/pydap/tests/test_model.py::test_DapType_id_property src/pydap/tests/test_model.py::test_DapType_getattr src/pydap/tests/test_model.py::test_DapType_children src/pydap/tests/test_model.py::test_BaseType_no_data src/pydap/tests/test_model.py::test_BaseType_data_and_dimensions src/pydap/tests/test_model.py::test_BaseType_repr src/pydap/tests/test_model.py::test_BaseType_dtype src/pydap/tests/test_model.py::test_BaseType_shape src/pydap/tests/test_model.py::test_BaseType_size src/pydap/tests/test_model.py::test_BaseType_ndim src/pydap/tests/test_model.py::test_BaseType_copy src/pydap/tests/test_model.py::test_BaseType_comparisons src/pydap/tests/test_model.py::test_BaseType_sequence_protocol src/pydap/tests/test_model.py::test_BaseType_iter_protocol src/pydap/tests/test_model.py::test_BaseType_array src/pydap/tests/test_model.py::test_StructureType_init src/pydap/tests/test_model.py::test_StructureType_instance src/pydap/tests/test_model.py::test_StructureType_repr src/pydap/tests/test_model.py::test_StructureType_len src/pydap/tests/test_model.py::test_StructureType_contains src/pydap/tests/test_model.py::test_StructureType_lazy_attribute src/pydap/tests/test_model.py::test_StructureType_children src/pydap/tests/test_model.py::test_StructureType_setitem src/pydap/tests/test_model.py::test_StructureType_getitem_tuple src/pydap/tests/test_model.py::test_StructureType_delitem src/pydap/tests/test_model.py::test_StructureType_get_data src/pydap/tests/test_model.py::test_StructureType_set_data src/pydap/tests/test_model.py::test_StructureType_copy src/pydap/tests/test_model.py::test_DatasetType_setitem src/pydap/tests/test_model.py::test_DatasetType_id src/pydap/tests/test_model.py::test_SequenceType_data src/pydap/tests/test_model.py::test_SequenceType_len src/pydap/tests/test_model.py::test_SequenceType_iterdata src/pydap/tests/test_model.py::test_SequenceType_iter src/pydap/tests/test_model.py::test_SequenceType_iter_deprecation src/pydap/tests/test_model.py::test_SequenceType_items src/pydap/tests/test_model.py::test_SequenceType_values src/pydap/tests/test_model.py::test_SequenceType_getitem src/pydap/tests/test_model.py::test_SequenceType_copy src/pydap/tests/test_model.py::test_GridType_repr src/pydap/tests/test_model.py::test_GridType_dtype src/pydap/tests/test_model.py::test_GridType_shape src/pydap/tests/test_model.py::test_GridType_size src/pydap/tests/test_model.py::test_GridType_ndim src/pydap/tests/test_model.py::test_GridType_len src/pydap/tests/test_model.py::test_GridType_getitem src/pydap/tests/test_model.py::test_GridType_getitem_not_tuple src/pydap/tests/test_model.py::test_GridType_array src/pydap/tests/test_model.py::test_GridType_array2 src/pydap/tests/test_model.py::test_GridType_maps src/pydap/tests/test_model.py::test_GridType_dimensions src/pydap/tests/test_responses_error.py::TestErrorResponse::test_body src/pydap/tests/test_responses_error.py::TestErrorResponse::test_charset src/pydap/tests/test_responses_error.py::TestErrorResponse::test_content_type src/pydap/tests/test_responses_error.py::TestErrorResponse::test_headers src/pydap/tests/test_responses_error.py::TestErrorResponse::test_status
src/pydap/handlers/lib.py src/pydap/lib.py setup.py src/pydap/parsers/__init__.py src/pydap/model.py src/pydap/handlers/csv/__init__.py src/pydap/wsgi/ssf.py src/pydap/wsgi/app.py
src/pydap/handlers/lib.py src/pydap/lib.py setup.py src/pydap/parsers/__init__.py src/pydap/model.py src/pydap/handlers/csv/__init__.py src/pydap/wsgi/ssf.py src/pydap/wsgi/app.py