Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce code duplication #5278

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 30 additions & 18 deletions notebook/services/contents/fileio.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,8 @@ def atomic_writing(path, text=True, encoding='utf-8', log=None, **kwargs):
if os.path.isfile(path):
copy2_safe(path, tmp_path, log=log)

if text:
# Make sure that text files have Unix linefeeds by default
kwargs.setdefault('newline', '\n')
fileobj = io.open(path, 'w', encoding=encoding, **kwargs)
else:
fileobj = io.open(path, 'wb', **kwargs)

try:
fileobj = open_file(path, text, encoding, log, **kwargs)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To preserve the original integrity, this should occur prior to the try block, otherwise you need to protect the fileobj.close() call since fileobj will be None if open_file() throws an exception.

yield fileobj
except:
# Failed! Move the backup file back to the real path to avoid corruption
Expand All @@ -124,6 +118,34 @@ def atomic_writing(path, text=True, encoding='utf-8', log=None, **kwargs):
os.remove(tmp_path)


def open_file(path, text=True, encoding='utf-8', log=None, **kwargs):
"""Open file for contextmanager for writing

Parameters
----------
path : str
The target file to write to.

text : bool, optional
Whether to open the file in text mode (i.e. to write unicode). Default is
True.

encoding : str, optional
The encoding to use for files opened in text mode. Default is UTF-8.

**kwargs
Passed to :func:`io.open`."""

if os.path.islink(path):
path = os.path.join(os.path.dirname(path), os.readlink(path))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if block shouldn't be part of the reduction since this same code exists in atomic_writting() with dependent code in between.


if text:
# Make sure that text files have Unix linefeeds by default
kwargs.setdefault('newline', '\n')
return io.open(path, 'w', encoding=encoding, **kwargs)
else:
return io.open(path, 'wb', **kwargs)


@contextmanager
def _simple_writing(path, text=True, encoding='utf-8', log=None, **kwargs):
Expand All @@ -148,17 +170,9 @@ def _simple_writing(path, text=True, encoding='utf-8', log=None, **kwargs):
# realpath doesn't work on Windows: https://bugs.python.org/issue9949
# Luckily, we only need to resolve the file itself being a symlink, not
# any of its directories, so this will suffice:
if os.path.islink(path):
path = os.path.join(os.path.dirname(path), os.readlink(path))

if text:
# Make sure that text files have Unix linefeeds by default
kwargs.setdefault('newline', '\n')
fileobj = io.open(path, 'w', encoding=encoding, **kwargs)
else:
fileobj = io.open(path, 'wb', **kwargs)

try:
fileobj = open_file(path, text, encoding, log, **kwargs)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above regarding fileobj being None in exception block.

yield fileobj
except:
fileobj.close()
Expand All @@ -167,8 +181,6 @@ def _simple_writing(path, text=True, encoding='utf-8', log=None, **kwargs):
fileobj.close()




class FileManagerMixin(Configurable):
"""
Mixin for ContentsAPI classes that interact with the filesystem.
Expand Down