Repository: sloria/environs

Issue:
Allow opening other files, not just .env
Currently environs read only hard-coded `.env` files, and only path is available.
Yet more and more tools allow custom .env files.

I believe environs should add parameter like `file='.env'` to be able to override defaults. 

Comments:

Patch:
diff --git a/README.md b/README.md
index bc89ef1..a5d5a21 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,7 @@ It allows you to store configuration separate from your code, as per
 * [Basic usage](#basic-usage)
 * [Supported types](#supported-types)
 * [Reading .env files](#reading-env-files)
+   * [Reading a specific file](#reading-a-specific-file)
 * [Handling prefixes](#handling-prefixes)
 * [Proxied variables](#proxied-variables)
 * [Validation](#validation)
@@ -119,6 +120,27 @@ env.bool("DEBUG")  # => True
 env.int("PORT")  # => 4567
 ```
 
+### Reading a specific file
+
+By default, `Env.read_env` will look for a `.env` file in current
+directory and recurse upwards until a `.env` file is found.
+
+You can also read a specific file:
+
+```python
+from environs import Env
+
+with open(".env.test", "w") as fobj:
+    fobj.write("A=foo\n")
+    fobj.write("B=123\n")
+
+env = Env()
+env.read_env(".env.test", recurse=False)
+
+assert env("A") == "foo"
+assert env.int("B") == 123
+```
+
 ## Handling prefixes
 
 ```python
diff --git a/environs.py b/environs.py
index 4b60270..bc9d22b 100644
--- a/environs.py
+++ b/environs.py
@@ -12,6 +12,12 @@ except ImportError:
     # Python 2
     import urlparse
 
+try:
+    from collections.abc import Mapping
+except ImportError:
+    # Python 2
+    from collections import Mapping
+
 import marshmallow as ma
 from dotenv import load_dotenv
 from dotenv.main import _walk_to_root
@@ -108,6 +114,9 @@ def _preprocess_list(value, **kwargs):
 
 
 def _preprocess_dict(value, **kwargs):
+    if isinstance(value, Mapping):
+        return value
+
     subcast = kwargs.get("subcast")
     return {
         key.strip(): subcast(val.strip()) if subcast else val.strip()


Test patch:
diff --git a/tests/test_environs.py b/tests/test_environs.py
index 3d54638..5c5afe0 100644
--- a/tests/test_environs.py
+++ b/tests/test_environs.py
@@ -74,6 +74,12 @@ class TestCasting:
         set_env({"LIST": "1,2,3"})
         assert env.list("LIST") == ["1", "2", "3"]
 
+    def test_list_with_default_from_string(self, set_env, env):
+        assert env.list("LIST", "1,2") == ["1", "2"]
+
+    def test_list_with_default_from_list(self, set_env, env):
+        assert env.list("LIST", ["1"]) == ["1"]
+
     def test_list_with_subcast(self, set_env, env):
         set_env({"LIST": "1,2,3"})
         assert env.list("LIST", subcast=int) == [1, 2, 3]
@@ -100,6 +106,12 @@ class TestCasting:
         set_env({"DICT": "key1=1,key2=2"})
         assert env.dict("DICT", subcast=int) == {"key1": 1, "key2": 2}
 
+    def test_dict_with_default_from_string(self, set_env, env):
+        assert env.dict("DICT", "key1=1,key2=2") == {"key1": "1", "key2": "2"}
+
+    def test_dict_with_default_from_dict(self, set_env, env):
+        assert env.dict("DICT", {"key1": "1"}) == {"key1": "1"}
+
     def test_decimat_cast(self, set_env, env):
         set_env({"DECIMAL": "12.34"})
         assert env.decimal("DECIMAL") == Decimal("12.34")