Repository: rochacbruno/dynaconf
Pull request #172 (2019-04-22 12:55:36)

Fix some open file descriptors on exampls and tests

pep8speaks: Hello @rochacbruno! Thanks for opening this PR. We checked the lines you've touched for [PEP 8](https://www.python.org/dev/peps/pep-0008) issues, and found:















* In the file [`example/custom_loader/app.py`](https://github.com/rochacbruno/dynaconf/blob/b493ce555d3a8a98f5dbf7ba1b77b1c222d2961b/example/custom_loader/app.py):

> [Line 4:37](https://github.com/rochacbruno/dynaconf/blob/b493ce555d3a8a98f5dbf7ba1b77b1c222d2961b/example/custom_loader/app.py#L4): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ','










codecov[bot]: # [Codecov](https://codecov.io/gh/rochacbruno/dynaconf/pull/172?src=pr&el=h1) Report
> Merging [#172](https://codecov.io/gh/rochacbruno/dynaconf/pull/172?src=pr&el=desc) into [master](https://codecov.io/gh/rochacbruno/dynaconf/commit/b939fa20917c9e871fb0c17128187f53780fb096?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/rochacbruno/dynaconf/pull/172/graphs/tree.svg?width=650&token=GXszVzJcqW&height=150&src=pr)](https://codecov.io/gh/rochacbruno/dynaconf/pull/172?src=pr&el=tree)

```diff
@@          Coverage Diff          @@
##           master   #172   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files          18     18           
  Lines         690    700   +10     
=====================================
+ Hits          690    700   +10
```


| [Impacted Files](https://codecov.io/gh/rochacbruno/dynaconf/pull/172?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [dynaconf/loaders/ini\_loader.py](https://codecov.io/gh/rochacbruno/dynaconf/pull/172/diff?src=pr&el=tree#diff-ZHluYWNvbmYvbG9hZGVycy9pbmlfbG9hZGVyLnB5) | `100% <ø> (ø)` | :arrow_up: |
| [dynaconf/loaders/json\_loader.py](https://codecov.io/gh/rochacbruno/dynaconf/pull/172/diff?src=pr&el=tree#diff-ZHluYWNvbmYvbG9hZGVycy9qc29uX2xvYWRlci5weQ==) | `100% <100%> (ø)` | :arrow_up: |
| [dynaconf/loaders/toml\_loader.py](https://codecov.io/gh/rochacbruno/dynaconf/pull/172/diff?src=pr&el=tree#diff-ZHluYWNvbmYvbG9hZGVycy90b21sX2xvYWRlci5weQ==) | `100% <100%> (ø)` | :arrow_up: |
| [dynaconf/loaders/yaml\_loader.py](https://codecov.io/gh/rochacbruno/dynaconf/pull/172/diff?src=pr&el=tree#diff-ZHluYWNvbmYvbG9hZGVycy95YW1sX2xvYWRlci5weQ==) | `100% <100%> (ø)` | :arrow_up: |
| [dynaconf/cli.py](https://codecov.io/gh/rochacbruno/dynaconf/pull/172/diff?src=pr&el=tree#diff-ZHluYWNvbmYvY2xpLnB5) | `100% <100%> (ø)` | :arrow_up: |
| [dynaconf/utils/files.py](https://codecov.io/gh/rochacbruno/dynaconf/pull/172/diff?src=pr&el=tree#diff-ZHluYWNvbmYvdXRpbHMvZmlsZXMucHk=) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/rochacbruno/dynaconf/pull/172?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/rochacbruno/dynaconf/pull/172?src=pr&el=footer). Last update [b939fa2...7ccd6d1](https://codecov.io/gh/rochacbruno/dynaconf/pull/172?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/dynaconf/cli.py b/dynaconf/cli.py
index dd7dd84..ad8190c 100644
--- a/dynaconf/cli.py
+++ b/dynaconf/cli.py
@@ -13,6 +13,7 @@ from dynaconf import LazySettings
 from dynaconf.loaders.py_loader import get_module
 from dynaconf.validator import Validator, ValidationError
 from dynaconf.utils.parse_conf import parse_conf_data
+from dynaconf.utils.files import read_file
 from dotenv import cli as dotenv_cli
 from contextlib import suppress
 
@@ -99,11 +100,11 @@ def split_vars(_vars):
 
 
 def read_file_in_root_directory(*names, **kwargs):
-    """Read a file."""
-    return io.open(
+    """Read a file on root dir."""
+    return read_file(
         os.path.join(os.path.dirname(__file__), *names),
         encoding=kwargs.get('encoding', 'utf-8')
-    ).read().strip()
+    )
 
 
 def print_version(ctx, param, value):
diff --git a/dynaconf/loaders/ini_loader.py b/dynaconf/loaders/ini_loader.py
index e2d3898..846e789 100644
--- a/dynaconf/loaders/ini_loader.py
+++ b/dynaconf/loaders/ini_loader.py
@@ -46,15 +46,14 @@ def write(settings_path, settings_data, merge=True):
     """
     settings_path = Path(settings_path)
     if settings_path.exists() and merge:  # pragma: no cover
-        object_merge(
-            ConfigObj(
-                io.open(
-                    str(settings_path),
-                    encoding=default_settings.ENCODING_FOR_DYNACONF
-                )
-            ).dict(),
-            settings_data
-        )
+        with io.open(
+            str(settings_path),
+            encoding=default_settings.ENCODING_FOR_DYNACONF
+        ) as open_file:
+            object_merge(
+                ConfigObj(open_file).dict(),
+                settings_data
+            )
     new = ConfigObj()
     new.update(settings_data)
     new.write(open(str(settings_path), 'bw'))
diff --git a/dynaconf/loaders/json_loader.py b/dynaconf/loaders/json_loader.py
index 46e6def..f13597b 100644
--- a/dynaconf/loaders/json_loader.py
+++ b/dynaconf/loaders/json_loader.py
@@ -51,20 +51,14 @@ def write(settings_path, settings_data, merge=True):
     """
     settings_path = Path(settings_path)
     if settings_path.exists() and merge:  # pragma: no cover
-        object_merge(
-            json.load(
-                io.open(
-                    str(settings_path),
-                    encoding=default_settings.ENCODING_FOR_DYNACONF
-                )
-            ),
-            settings_data
-        )
-
-    json.dump(
-        settings_data,
-        io.open(
-            str(settings_path), 'w',
+        with io.open(
+            str(settings_path),
             encoding=default_settings.ENCODING_FOR_DYNACONF
-        )
-    )
+        ) as open_file:
+            object_merge(json.load(open_file), settings_data)
+
+    with io.open(
+        str(settings_path), 'w',
+        encoding=default_settings.ENCODING_FOR_DYNACONF
+    ) as open_file:
+        json.dump(settings_data, open_file)
diff --git a/dynaconf/loaders/toml_loader.py b/dynaconf/loaders/toml_loader.py
index d7149d2..e8d6d92 100644
--- a/dynaconf/loaders/toml_loader.py
+++ b/dynaconf/loaders/toml_loader.py
@@ -46,20 +46,14 @@ def write(settings_path, settings_data, merge=True):
     """
     settings_path = Path(settings_path)
     if settings_path.exists() and merge:  # pragma: no cover
-        object_merge(
-            toml.load(
-                io.open(
-                    str(settings_path),
-                    encoding=default_settings.ENCODING_FOR_DYNACONF
-                )
-            ),
-            settings_data
-        )
-
-    toml.dump(
-        settings_data,
-        io.open(
-            str(settings_path), 'w',
+        with io.open(
+            str(settings_path),
             encoding=default_settings.ENCODING_FOR_DYNACONF
-        )
-    )
+        ) as open_file:
+            object_merge(toml.load(open_file), settings_data)
+
+    with io.open(
+        str(settings_path), 'w',
+        encoding=default_settings.ENCODING_FOR_DYNACONF
+    ) as open_file:
+        toml.dump(settings_data, open_file)
diff --git a/dynaconf/loaders/yaml_loader.py b/dynaconf/loaders/yaml_loader.py
index 44e25fc..282371b 100644
--- a/dynaconf/loaders/yaml_loader.py
+++ b/dynaconf/loaders/yaml_loader.py
@@ -59,20 +59,14 @@ def write(settings_path, settings_data, merge=True):
     """
     settings_path = Path(settings_path)
     if settings_path.exists() and merge:  # pragma: no cover
-        object_merge(
-            yaml.full_load(
-                io.open(
-                    str(settings_path),
-                    encoding=default_settings.ENCODING_FOR_DYNACONF
-                )
-            ),
-            settings_data
-        )
-
-    yaml.dump(
-        settings_data,
-        io.open(
-            str(settings_path), 'w',
+        with io.open(
+            str(settings_path),
             encoding=default_settings.ENCODING_FOR_DYNACONF
-        )
-    )
+        ) as open_file:
+            object_merge(yaml.full_load(open_file), settings_data)
+
+    with io.open(
+        str(settings_path), 'w',
+        encoding=default_settings.ENCODING_FOR_DYNACONF
+    ) as open_file:
+        yaml.dump(settings_data, open_file)
diff --git a/dynaconf/utils/files.py b/dynaconf/utils/files.py
index a28009f..57bde9a 100644
--- a/dynaconf/utils/files.py
+++ b/dynaconf/utils/files.py
@@ -1,4 +1,5 @@
 import os
+import io
 import inspect
 from dynaconf.utils import raw_logger, deduplicate
 
@@ -84,3 +85,10 @@ def find_file(filename='.env', project_root=None, skip_files=None, **kwargs):
 
     # return empty string if not found so it can still be joined in os.path
     return ''
+
+
+def read_file(path, **kwargs):
+    content = ''
+    with io.open(path, **kwargs) as open_file:
+        content = open_file.read().strip()
+    return content
diff --git a/example/common-encoding/program.py b/example/common-encoding/program.py
index 9e79541..1f77233 100644
--- a/example/common-encoding/program.py
+++ b/example/common-encoding/program.py
@@ -29,19 +29,17 @@ print(settings.dynaconf_banner)
 print('#' * 79)
 print('\n* The settings are defined in .toml files\n')
 print('$ cat settings.toml')
-print(
-    io.open(
-        settings.find_file('settings.toml'),
-        encoding=os.environ.get('ENCODING_FOR_DYNACONF')
-    ).read()
-)
+with io.open(
+    settings.find_file('settings.toml'),
+    encoding=os.environ.get('ENCODING_FOR_DYNACONF')
+) as settings_file:
+    print(settings_file.read())
 print('$ cat .secrets.toml')
-print(
-    io.open(
-        settings.find_file('.secrets.toml'),
-        encoding=os.environ.get('ENCODING_FOR_DYNACONF')
-    ).read()
-)
+with io.open(
+    settings.find_file('.secrets.toml'),
+    encoding=os.environ.get('ENCODING_FOR_DYNACONF')
+) as secrets_file:
+    print(secrets_file.read())
 
 print('#' * 79)
 print('\n* Acessing settings defined in .toml files\n')
diff --git a/example/custom_loader/app.py b/example/custom_loader/app.py
index f8edc52..3708206 100644
--- a/example/custom_loader/app.py
+++ b/example/custom_loader/app.py
@@ -1,9 +1,7 @@
 from dynaconf import settings
 
-print(
-    'settings from sff file\n',
-    open(settings.find_file('settings.sff')).read()
-)
+with open(settings.find_file('settings.sff')) as settings_file:
+    print('settings from sff file\n', settings_file.read())
 
 assert settings.NAME == "Bruno Rocha"
 assert settings.EMAIL == 'bruno@rocha.com.from_env'
diff --git a/example/custom_loader/my_custom_loader/sff_loader.py b/example/custom_loader/my_custom_loader/sff_loader.py
index 89a929e..ea55c6d 100644
--- a/example/custom_loader/my_custom_loader/sff_loader.py
+++ b/example/custom_loader/my_custom_loader/sff_loader.py
@@ -27,13 +27,15 @@ def load(obj, env=None, silent=True, key=None, filename=None):
         obj.logger.debug('Cannot find settings.sff')
         return
 
-    for line in open(found_file).readlines():
-        if line.startswith('#'):
-            continue
-        if line.startswith('KEYS:'):
-            keys = line.strip('KEYS:').strip('\n').split(';')
-        if line.startswith('VALUES:'):
-            values = line.strip('VALUES:').strip('\n').split(';')
+    with open(found_file) as settings_file:
+        for line in settings_file.readlines():
+            if line.startswith('#'):
+                continue
+            if line.startswith('KEYS:'):
+                keys = line.strip('KEYS:').strip('\n').split(';')
+            if line.startswith('VALUES:'):
+                values = line.strip('VALUES:').strip('\n').split(';')
+
     # // PLEASE DON'T USE THIS SFF file format :)
 
     data = dict(zip(keys, values))
diff --git a/example/simple/app.py b/example/simple/app.py
index cbeffe1..9a0f726 100644
--- a/example/simple/app.py
+++ b/example/simple/app.py
@@ -21,7 +21,8 @@ print('IS Dynaconf loaded?', settings.configured)
 print('# ^ That means that settings was read! dynaconf is loaded')
 print('# Lets read a file using settings.find_file...')
 print('\n')
-print(open(settings.find_file('settings.toml')).read())
+with open(settings.find_file('settings.toml')) as settings_file:
+    print(settings_file.read())
 
 from dynaconf.utils.files import SEARCHTREE  # noqa
 print('Searchtree', SEARCHTREE)
diff --git a/setup.py b/setup.py
index bc14daf..8ea71b4 100644
--- a/setup.py
+++ b/setup.py
@@ -11,10 +11,13 @@ except ImportError:
 
 def read(*names, **kwargs):
     """Read a file."""
-    return io.open(
+    content = ''
+    with io.open(
         os.path.join(os.path.dirname(__file__), *names),
         encoding=kwargs.get('encoding', 'utf8')
-    ).read().strip()
+    ) as open_file:
+        content = open_file.read().strip()
+    return content
 
 
 setup(


Test patch:
diff --git a/tests/test_cli.py b/tests/test_cli.py
index a21ed1f..4ebc5b2 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -5,6 +5,7 @@ from pathlib import Path
 from click.testing import CliRunner
 from dynaconf import LazySettings, default_settings
 from dynaconf.cli import main, EXTS, WRITERS, ENVS, read_file_in_root_directory
+from dynaconf.utils.files import read_file
 from dotenv import cli as dotenv_cli
 
 
@@ -53,26 +54,26 @@ def test_init_with_path(fileformat, tmpdir):
 
     sets = Path(str(path))
     assert sets.exists() is True
-    assert 'bruno' in io.open(
+    assert 'bruno' in read_file(
         str(sets),
         encoding=default_settings.ENCODING_FOR_DYNACONF
-    ).read()
+    )
 
     if secs_path:
         secs = Path(str(secs_path))
         assert secs.exists() is True
-        assert 'secret for' in io.open(
+        assert 'secret for' in read_file(
             str(secs),
             encoding=default_settings.ENCODING_FOR_DYNACONF
-        ).read()
+        )
 
     if fileformat != 'env':
         gign = Path(str(tmpdir.join('.gitignore')))
         assert gign.exists() is True
-        assert ".secrets.*" in io.open(
+        assert ".secrets.*" in read_file(
             str(gign),
             encoding=default_settings.ENCODING_FOR_DYNACONF
-        ).read()
+        )
 
 
 def test_list(testdir):
@@ -209,24 +210,24 @@ def test_write(writer, env, onlydir, tmpdir):
     )
     if writer != 'env':
         assert "Data successful written to {}".format(settingspath) in result
-        assert "TESTVALUE" in io.open(
+        assert "TESTVALUE" in read_file(
             str(settingspath),
             encoding=default_settings.ENCODING_FOR_DYNACONF
-        ).read()
-        assert "SECRETVALUE" in io.open(
+        )
+        assert "SECRETVALUE" in read_file(
             str(secretfile),
             encoding=default_settings.ENCODING_FOR_DYNACONF
-        ).read()
+        )
     else:
         assert "Data successful written to {}".format(env_file) in result
-        assert "TESTVALUE" in io.open(
+        assert "TESTVALUE" in read_file(
             str(env_file),
             encoding=default_settings.ENCODING_FOR_DYNACONF
-        ).read()
-        assert "SECRETVALUE" in io.open(
+        )
+        assert "SECRETVALUE" in read_file(
             str(env_file),
             encoding=default_settings.ENCODING_FOR_DYNACONF
-        ).read()
+        )
 
 
 @pytest.mark.parametrize("path", ('.env', './.env'))
@@ -245,14 +246,14 @@ def test_write_dotenv(path, tmpdir):
     )
 
     assert "Data successful written to {}".format(env_file) in result
-    assert "TESTVALUE" in io.open(
+    assert "TESTVALUE" in read_file(
         str(env_file),
         encoding=default_settings.ENCODING_FOR_DYNACONF
-    ).read()
-    assert "SECRETVALUE" in io.open(
+    )
+    assert "SECRETVALUE" in read_file(
         str(env_file),
         encoding=default_settings.ENCODING_FOR_DYNACONF
-    ).read()
+    )
 
 
 VALIDATION = """