Repository: theskumar/python-dotenv
Pull request #120 (2018-07-17 01:53:54)

fix bug: DotEnv._get_stream raise IOError when  `.env` is a directory rather than a file
# How this bug happened ?

The function `find_dotenv` try to find a file named `.env`, if there is a directory named `.env` by coincidence, then `DotEnv._get_stream` will  raise IOError.

# Fix this bug

use `os.path.isfile` instead of `os.path.exists`.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/18014901/badge)](https://coveralls.io/builds/18014901)

Coverage remained the same at 91.822% when pulling **8eb0a864b29bc2d00edfee4fc861b73ef3d70088 on ausaki:fix_find_dotenv** into **69735cf037eb4575314b562874abe5913a389b13 on theskumar:master**.


Patch:
diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index 02a26c9..9740b2a 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 0.8.2
+current_version = 0.9.1
 commit = True
 tag = True
 
diff --git a/README.md b/README.md
index 67fe928..89a1df1 100644
--- a/README.md
+++ b/README.md
@@ -261,6 +261,7 @@ Related Projects
 -   [django-environ](https://github.com/joke2k/django-environ)
 -   [django-configuration](https://github.com/jezdez/django-configurations)
 -   [dump-env](https://github.com/sobolevn/dump-env)
+-   [environs](https://github.com/sloria/environs)
 
 Contributing
 ============
diff --git a/dotenv/main.py b/dotenv/main.py
index 252a2dd..e281f51 100644
--- a/dotenv/main.py
+++ b/dotenv/main.py
@@ -31,7 +31,7 @@ def parse_line(line):
     k, v = line.split('=', 1)
 
     if k.startswith('export '):
-        k = k.lstrip('export ')
+        (_, _, k) = k.partition('export ')
 
     # Remove any leading and trailing spaces in key, value
     k, v = k.strip(), v.strip()
@@ -57,7 +57,7 @@ class DotEnv():
         if isinstance(self.dotenv_path, StringIO):
             return self.dotenv_path
 
-        if os.path.exists(self.dotenv_path):
+        if os.path.isfile(self.dotenv_path):
             self._is_file = True
             return io.open(self.dotenv_path)
 
@@ -143,7 +143,7 @@ def set_key(dotenv_path, key_to_set, value_to_set, quote_mode="always"):
         k, v = parse_line(line)
         if k == key_to_set:
             replaced = True
-            line = line_out
+            line = "{}\n".format(line_out)
         print(line, end='')
 
     if not replaced:
@@ -241,7 +241,7 @@ def find_dotenv(filename='.env', raise_error_if_not_found=False, usecwd=False):
 
     for dirname in _walk_to_root(path):
         check_path = os.path.join(dirname, filename)
-        if os.path.exists(check_path):
+        if os.path.isfile(check_path):
             return check_path
 
     if raise_error_if_not_found:
diff --git a/dotenv/version.py b/dotenv/version.py
index deded32..d69d16e 100644
--- a/dotenv/version.py
+++ b/dotenv/version.py
@@ -1,1 +1,1 @@
-__version__ = "0.8.2"
+__version__ = "0.9.1"


Test patch:
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 9f08cbd..6c9187e 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -24,13 +24,19 @@ def test_get_key():
 
 
 def test_set_key(dotenv_file):
-    success, key_to_set, value_to_set = dotenv.set_key(dotenv_path, 'HELLO', 'WORLD')
-    success, key_to_set, value_to_set = dotenv.set_key(dotenv_path, 'foo', 'bar')
-    dotenv.get_key(dotenv_path, 'HELLO') == 'WORLD'
+    success, key_to_set, value_to_set = dotenv.set_key(dotenv_file, 'HELLO', 'WORLD')
+    success, key_to_set, value_to_set = dotenv.set_key(dotenv_file, 'foo', 'bar')
+    assert dotenv.get_key(dotenv_file, 'HELLO') == 'WORLD'
+
+    with open(dotenv_file, 'r') as fp:
+        assert 'HELLO="WORLD"\nfoo="bar"' == fp.read().strip()
+
+    success, key_to_set, value_to_set = dotenv.set_key(dotenv_file, 'HELLO', 'WORLD 2')
+    assert dotenv.get_key(dotenv_file, 'HELLO') == 'WORLD 2'
+    assert dotenv.get_key(dotenv_file, 'foo') == 'bar'
 
-    success, key_to_set, value_to_set = dotenv.set_key(dotenv_path, 'HELLO', 'WORLD 2')
-    dotenv.get_key(dotenv_path, 'HELLO') == 'WORLD 2'
-    dotenv.get_key(dotenv_path, 'foo') == 'bar'
+    with open(dotenv_file, 'r') as fp:
+        assert 'HELLO="WORLD 2"\nfoo="bar"' == fp.read().strip()
 
 
 def test_list(cli, dotenv_file):
diff --git a/tests/test_core.py b/tests/test_core.py
index 1547e24..4c03f8e 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -24,6 +24,8 @@ from IPython.terminal.embed import InteractiveShellEmbed
     ("a=b space ", ('a', 'b space')),
     ("a='b space '", ('a', 'b space ')),
     ('a="b space "', ('a', 'b space ')),
+    ("export export_spam=1", ("export_spam", "1")),
+    ("export port=8000", ("port", "8000")),
 ])
 def test_parse_line(test_input, expected):
     assert parse_line(test_input) == expected