diff --git a/jupytext/jupytext.py b/jupytext/jupytext.py index 08d951cd6..0ed7ff87c 100644 --- a/jupytext/jupytext.py +++ b/jupytext/jupytext.py @@ -191,7 +191,7 @@ def writes(self, nb, metadata=None, **kwargs): def reads(text, fmt, as_version=4, **kwargs): """Read a notebook from a string""" - fmt = copy(fmt) + fmt = copy(fmt) if fmt else divine_format(text) fmt = long_form_one_format(fmt) ext = fmt['extension'] @@ -224,21 +224,21 @@ def read(fp, as_version=4, fmt=None, **kwargs): """Read a notebook from a file""" if fp == '-': text = sys.stdin.read() - fmt = fmt or divine_format(text) return reads(text, fmt) - if isinstance(fp, (py3compat.unicode_type, bytes)): - _, ext = os.path.splitext(fp) + if not hasattr(fp, 'read'): + _, ext = os.path.splitext(str(fp)) fmt = copy(fmt or {}) fmt.update({'extension': ext}) with io.open(fp, encoding='utf-8') as stream: return read(stream, as_version=as_version, fmt=fmt, **kwargs) - fmt = long_form_one_format(fmt) - if fmt['extension'] == '.ipynb': - notebook = nbformat.read(fp, as_version, **kwargs) - rearrange_jupytext_metadata(notebook.metadata) - return notebook + if fmt is not None: + fmt = long_form_one_format(fmt) + if fmt['extension'] == '.ipynb': + notebook = nbformat.read(fp, as_version, **kwargs) + rearrange_jupytext_metadata(notebook.metadata) + return notebook return reads(fp.read(), fmt, **kwargs) @@ -283,8 +283,9 @@ def write(nb, fp, version=nbformat.NO_CONVERT, fmt=None, **kwargs): write(nb, sys.stdout, version=version, fmt=fmt, **kwargs) return - if isinstance(fp, (py3compat.unicode_type, bytes)): + if not hasattr(fp, 'write'): fmt = copy(fmt or {}) + fp = str(fp) _, ext = os.path.splitext(fp) fmt = long_form_one_format(fmt, update={'extension': ext}) create_prefix_dir(fp, fmt) diff --git a/requirements-dev.txt b/requirements-dev.txt index 4955baafc..c1b8f940d 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -5,3 +5,6 @@ codecov notebook jupyter_client nbconvert + +# Python 2 +pathlib \ No newline at end of file diff --git a/tests/test_read_write_functions.py b/tests/test_read_write_functions.py new file mode 100644 index 000000000..06ff8f134 --- /dev/null +++ b/tests/test_read_write_functions.py @@ -0,0 +1,78 @@ +from io import StringIO +from pathlib import Path +import nbformat +from nbformat.v4.nbbase import new_notebook, new_markdown_cell +import jupytext +from jupytext.compare import compare + + +def test_simple_hook(tmpdir): + nb_file = str(tmpdir.join('notebook.ipynb')) + md_file = str(tmpdir.join('notebook.md')) + nbformat.write(new_notebook(cells=[new_markdown_cell('Some text')]), nb_file) + + nb = jupytext.read(nb_file) + jupytext.write(nb, md_file) + + with open(md_file) as fp: + text = fp.read() + + assert 'Some text' in text.splitlines() + + +def test_simple_hook_with_explicit_format(tmpdir): + nb_file = str(tmpdir.join('notebook.ipynb')) + py_file = str(tmpdir.join('notebook.py')) + nbformat.write(new_notebook(cells=[new_markdown_cell('Some text')]), nb_file) + + nb = jupytext.read(nb_file) + jupytext.write(nb, py_file, fmt='py:percent') + + with open(py_file) as fp: + text = fp.read() + + assert '# %% [markdown]' in text.splitlines() + assert '# Some text' in text.splitlines() + + +def test_no_error_on_path_object(tmpdir): + nb_file = Path(str(tmpdir.join('notebook.ipynb'))) + md_file = nb_file.with_suffix('.md') + nbformat.write(new_notebook(cells=[new_markdown_cell('Some text')]), str(nb_file)) + + nb = jupytext.read(nb_file) + jupytext.write(nb, md_file) + + +def test_read_ipynb_from_stream(): + def stream(): + return StringIO(u"""{ + "cells": [ + { + "cell_type": "code", + "metadata": {}, + "source": [ + "1 + 1" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 4 +} +""") + + nb = jupytext.read(stream()) + nb2 = jupytext.read(stream(), fmt='ipynb') + compare(nb, nb2) + + +def test_read_py_percent_from_stream(): + def stream(): + return StringIO(u"""# %% +1 + 1 +""") + + nb = jupytext.read(stream()) + nb2 = jupytext.read(stream(), fmt='py:percent') + compare(nb, nb2)