diff --git a/IPython/nbformat/__init__.py b/IPython/nbformat/__init__.py index d5ba916..d66b4de 100644 --- a/IPython/nbformat/__init__.py +++ b/IPython/nbformat/__init__.py @@ -5,6 +5,8 @@ Use this module to read or write notebook files as particular nbformat versions. # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. +import io +from IPython.utils import py3compat from IPython.utils.log import get_logger @@ -112,8 +114,8 @@ def read(fp, as_version, **kwargs): Parameters ---------- - fp : file - Any file-like object with a read method. + fp : file or str + Any file-like object with a read method, or a path to a file. as_version: int The version of the notebook format to return. The notebook will be converted, if necessary. @@ -124,6 +126,10 @@ def read(fp, as_version, **kwargs): nb : NotebookNode The notebook that was read. """ + if isinstance(fp, py3compat.string_types): + with io.open(fp, encoding='utf-8') as f: + return read(f, as_version, **kwargs) + return reads(fp.read(), as_version, **kwargs) @@ -136,14 +142,19 @@ def write(nb, fp, version=NO_CONVERT, **kwargs): ---------- nb : NotebookNode The notebook to write. - fp : file - Any file-like object with a write method that accepts unicode. + fp : file or str + Any file-like object with a write method that accepts unicode, or + a path to write a file. version : int, optional The nbformat version to write. If nb is not this version, it will be converted. If unspecified, or specified as nbformat.NO_CONVERT, the notebook's own version will be used and no conversion performed. """ + if isinstance(fp, py3compat.string_types): + with open(fp, 'w', encoding='utf-8') as f: + return write(nb, f, version=version, **kwargs) + s = writes(nb, version, **kwargs) if isinstance(s, bytes): s = s.decode('utf8') diff --git a/IPython/nbformat/tests/test_api.py b/IPython/nbformat/tests/test_api.py index 1fb1585..f16f612 100644 --- a/IPython/nbformat/tests/test_api.py +++ b/IPython/nbformat/tests/test_api.py @@ -4,11 +4,13 @@ # Distributed under the terms of the Modified BSD License. import json +import os from .base import TestsBase +from IPython.utils.tempdir import TemporaryDirectory from ..reader import get_version -from IPython.nbformat import read, current_nbformat, writes +from IPython.nbformat import read, current_nbformat, writes, write class TestAPI(TestsBase): @@ -35,3 +37,13 @@ class TestAPI(TestsBase): nb2 = json.loads(jsons) (major, minor) = get_version(nb2) self.assertEqual(major, 2) + + def test_read_write_path(self): + """read() and write() take filesystem paths""" + path = os.path.join(self._get_files_path(), u'test4.ipynb') + nb = read(path, as_version=4) + + with TemporaryDirectory() as td: + dest = os.path.join(td, 'echidna.ipynb') + write(nb, dest) + assert os.path.isfile(dest)