Repository: pydap/pydap

Issue:
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'
]
```


Discussion:
rabernat: Is anyone maintaining this package? Why haven't PR's like this one been merged?

Patch:
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))


Test patch:
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('/')