diff options
author | Antony Lee <anntzer.lee@gmail.com> | 2021-08-21 19:12:26 +0200 |
---|---|---|
committer | Antony Lee <anntzer.lee@gmail.com> | 2021-08-22 22:19:24 +0200 |
commit | 14dc7d84adbfafd994d87da47170796f527af09d (patch) | |
tree | 2c252871d2f2e89f68dfd57645443cc572c3d003 | |
parent | 1fdfdfa97b0528f67f8fcf826f1e33f45569340a (diff) | |
download | numpy-14dc7d84adbfafd994d87da47170796f527af09d.tar.gz |
MAINT: Use a contextmanager to ensure loadtxt closes the input file.
This seems easier to track that a giant try... finally.
Also move the `fencoding` initialization to within the contextmanager,
in the rather unlikely case an exception occurs during the call to
`getpreferredencoding`.
-rw-r--r-- | numpy/lib/npyio.py | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py index 00b5918f8..41970f720 100644 --- a/numpy/lib/npyio.py +++ b/numpy/lib/npyio.py @@ -1028,7 +1028,7 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None, dtype_types, packer = _loadtxt_flatten_dtype_internal(dtype) - fown = False + fh_closing_ctx = contextlib.nullcontext() try: if isinstance(fname, os_PathLike): fname = os_fspath(fname) @@ -1036,7 +1036,7 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None, fh = np.lib._datasource.open(fname, 'rt', encoding=encoding) fencoding = getattr(fh, 'encoding', 'latin1') line_iter = iter(fh) - fown = True + fh_closing_ctx = contextlib.closing(fh) else: line_iter = iter(fname) fencoding = getattr(fname, 'encoding', 'latin1') @@ -1059,16 +1059,17 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None, f"or generator. Got {type(fname)} instead." ) from e - # input may be a python2 io stream - if encoding is not None: - fencoding = encoding - # we must assume local encoding - # TODO emit portability warning? - elif fencoding is None: - import locale - fencoding = locale.getpreferredencoding() + with fh_closing_ctx: + + # input may be a python2 io stream + if encoding is not None: + fencoding = encoding + # we must assume local encoding + # TODO emit portability warning? + elif fencoding is None: + import locale + fencoding = locale.getpreferredencoding() - try: # Skip the first `skiprows` lines for i in range(skiprows): next(line_iter) @@ -1165,9 +1166,6 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None, nshape[0] += len(chunk) X.resize(nshape, refcheck=False) X[pos:, ...] = chunk - finally: - if fown: - fh.close() if X is None: X = np.array([], dtype) |