diff --git a/.github/scripts/parse_ref.py b/.github/scripts/parse_ref.py index 526cb4d6..f27e9187 100644 --- a/.github/scripts/parse_ref.py +++ b/.github/scripts/parse_ref.py @@ -22,10 +22,10 @@ def parse_ref(current_ref): The github reference string. """ if not current_ref.startswith("refs/tags/"): - raise Exception(f"Invalid ref `{current_ref}`!") + raise Exception(f"Invalid ref `{current_ref}`!") # noqa tag_name = current_ref.replace("refs/tags/", "") - print(tag_name) + print(tag_name) # noqa if __name__ == "__main__": diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cef8dfa0..fdbcdb28 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -35,7 +35,7 @@ repos: - id: black - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.207 + rev: v0.0.237 hooks: - id: ruff args: ["--fix"] diff --git a/docs/conf.py b/docs/conf.py index e5f1ba08..e2b1b38b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -19,6 +19,7 @@ import os import shutil +from importlib.metadata import version as get_version HERE = os.path.abspath(os.path.dirname(__file__)) @@ -60,7 +61,7 @@ # General information about the project. project = "nbformat" -copyright = "2015, Jupyter Development Team" +copyright = "2015, Jupyter Development Team" # noqa author = "Jupyter Development Team" # numpydoc configuration @@ -72,8 +73,6 @@ # built documents. # # The short X.Y version. -from importlib.metadata import version as get_version - version = ".".join(get_version("nbformat").split(".")[:2]) # The full version, including alpha/beta/rc tags. release = version diff --git a/nbformat/__init__.py b/nbformat/__init__.py index bf32f8bd..9b93ef23 100644 --- a/nbformat/__init__.py +++ b/nbformat/__init__.py @@ -39,12 +39,12 @@ 4: v4, } -from . import reader -from .converter import convert -from .notebooknode import NotebookNode, from_dict -from .v4 import nbformat as current_nbformat -from .v4 import nbformat_minor as current_nbformat_minor -from .validator import ValidationError, validate +from . import reader # noqa +from .converter import convert # noqa +from .notebooknode import NotebookNode, from_dict # noqa +from .v4 import nbformat as current_nbformat # noqa +from .v4 import nbformat_minor as current_nbformat_minor # noqa +from .validator import ValidationError, validate # noqa class NBFormatError(ValueError): diff --git a/nbformat/_imports.py b/nbformat/_imports.py index 59fe2f0e..fc20d5bd 100644 --- a/nbformat/_imports.py +++ b/nbformat/_imports.py @@ -26,7 +26,7 @@ def import_item(name): """ parts = name.rsplit(".", 1) - if len(parts) == 2: + if len(parts) == 2: # noqa # called with 'foo.bar....' package, obj = parts module = __import__(package, fromlist=[obj]) diff --git a/nbformat/_struct.py b/nbformat/_struct.py index 66dd76af..75e816d0 100644 --- a/nbformat/_struct.py +++ b/nbformat/_struct.py @@ -87,7 +87,7 @@ def __setattr__(self, key, value): you can't set a class member """ # If key is an str it might be a class member or instance var - if isinstance(key, str): + if isinstance(key, str): # noqa # I can't simply call hasattr here because it calls getattr, which # calls self.__getattr__, which returns True for keys in # self._data. But I only want keys in the class and in @@ -181,7 +181,7 @@ def __isub__(self, other): >>> s1 {'b': 30} """ - for k in other.keys(): + for k in other: if k in self: del self[k] return self @@ -200,7 +200,7 @@ def __dict_invert(self, data): outdict[entry] = k return outdict - def dict(self): + def dict(self): # noqa """Get the dict representation of the struct.""" return self @@ -216,7 +216,7 @@ def copy(self): """ return Struct(dict.copy(self)) - def hasattr(self, key): + def hasattr(self, key): # noqa """hasattr function available as a method. Implemented like has_key. @@ -352,7 +352,7 @@ def merge(self, __loc_data__=None, __conflict_solve=None, **kw): ("add_flip", add_flip), ("add_s", add_s), ]: - if name in inv_conflict_solve_user.keys(): + if name in inv_conflict_solve_user: inv_conflict_solve_user[func] = inv_conflict_solve_user[name] del inv_conflict_solve_user[name] conflict_solve.update(self.__dict_invert(inv_conflict_solve_user)) diff --git a/nbformat/converter.py b/nbformat/converter.py index e6969926..7f73b237 100644 --- a/nbformat/converter.py +++ b/nbformat/converter.py @@ -56,13 +56,11 @@ def convert(nb, to_version): # Convert and make sure version changed during conversion. converted = convert_function(nb) if converted.get("nbformat", 1) == version: - raise ValueError( - "Failed to convert notebook from v%d to v%d." % (version, step_version) - ) + msg = "Failed to convert notebook from v%d to v%d." % (version, step_version) + raise ValueError(msg) except AttributeError as e: - raise ValidationError( - f"Notebook could not be converted from version {version} to version {step_version} because it's missing a key: {e}" - ) from None + msg = f"Notebook could not be converted from version {version} to version {step_version} because it's missing a key: {e}" + raise ValidationError(msg) from None # Recursively convert until target version is reached. return convert(converted, to_version) diff --git a/nbformat/corpus/tests/test_words.py b/nbformat/corpus/tests/test_words.py index f04ab912..2e26deed 100644 --- a/nbformat/corpus/tests/test_words.py +++ b/nbformat/corpus/tests/test_words.py @@ -3,12 +3,12 @@ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. -from .. import words +from nbformat.corpus import words def test_generate_corpus_id(recwarn): """Test generating a corpus id.""" - assert len(words.generate_corpus_id()) > 7 + assert len(words.generate_corpus_id()) > 7 # noqa # 1 in 4294967296 (2^32) times this will fail - assert words.generate_corpus_id() != words.generate_corpus_id() - assert len(recwarn) == 0 + assert words.generate_corpus_id() != words.generate_corpus_id() # noqa + assert len(recwarn) == 0 # noqa diff --git a/nbformat/current.py b/nbformat/current.py index 5d1eb0f9..b27682fc 100644 --- a/nbformat/current.py +++ b/nbformat/current.py @@ -11,15 +11,6 @@ import re import warnings -warnings.warn( - """nbformat.current is deprecated since before nbformat 3.0 - -- use nbformat for read/write/validate public API -- use nbformat.vX directly to composing notebooks of a particular version -""", - DeprecationWarning, -) - from traitlets.log import get_logger from nbformat import v3 as _v_latest @@ -45,6 +36,15 @@ from .reader import reads as reader_reads from .validator import ValidationError, validate +warnings.warn( + """nbformat.current is deprecated since before nbformat 3.0 + +- use nbformat for read/write/validate public API +- use nbformat.vX directly to composing notebooks of a particular version +""", + DeprecationWarning, +) + __all__ = [ "NotebookNode", "new_code_cell", @@ -148,7 +148,7 @@ def writes_py(nb, **kwargs): # High level API -def reads(s, format="DEPRECATED", version=current_nbformat, **kwargs): +def reads(s, format="DEPRECATED", version=current_nbformat, **kwargs): # noqa """Read a notebook from a string and return the NotebookNode object. This function properly handles notebooks of any version. The notebook @@ -177,7 +177,7 @@ def reads(s, format="DEPRECATED", version=current_nbformat, **kwargs): return nb -def writes(nb, format="DEPRECATED", version=current_nbformat, **kwargs): +def writes(nb, format="DEPRECATED", version=current_nbformat, **kwargs): # noqa """Write a notebook to a string in a given format in the current nbformat version. This function always writes the notebook in the current nbformat version. @@ -207,7 +207,7 @@ def writes(nb, format="DEPRECATED", version=current_nbformat, **kwargs): return versions[version].writes_json(nb, **kwargs) -def read(fp, format="DEPRECATED", **kwargs): +def read(fp, format="DEPRECATED", **kwargs): # noqa """Read a notebook from a file and return the NotebookNode object. This function properly handles notebooks of any version. The notebook @@ -226,7 +226,7 @@ def read(fp, format="DEPRECATED", **kwargs): return reads(fp.read(), **kwargs) -def write(nb, fp, format="DEPRECATED", **kwargs): +def write(nb, fp, format="DEPRECATED", **kwargs): # noqa """Write a notebook to a file in a given format in the current nbformat version. This function always writes the notebook in the current nbformat version. diff --git a/nbformat/json_compat.py b/nbformat/json_compat.py index 5fc63cb9..f761ca1c 100644 --- a/nbformat/json_compat.py +++ b/nbformat/json_compat.py @@ -81,7 +81,8 @@ def error_tree(self, errors): # Another way forward for compatibility: we could distill both validator errors into a custom collection # for this data. Since implementation details of ValidationError is used elsewhere, we would probably # just use this data for schema introspection. - raise NotImplementedError("JSON schema error introspection not enabled for fastjsonschema") + msg = "JSON schema error introspection not enabled for fastjsonschema" + raise NotImplementedError(msg) _VALIDATOR_MAP = [ @@ -93,15 +94,15 @@ def error_tree(self, errors): def _validator_for_name(validator_name): if validator_name not in VALIDATORS: - raise ValueError( - f"Invalid validator '{validator_name}' value!\nValid values are: {VALIDATORS}" - ) + msg = f"Invalid validator '{validator_name}' value!\nValid values are: {VALIDATORS}" + raise ValueError(msg) for (name, module, validator_cls) in _VALIDATOR_MAP: if module and validator_name == name: return validator_cls # we always return something. - raise ValueError(f"Missing validator for {repr(validator_name)}") + msg = f"Missing validator for {repr(validator_name)}" + raise ValueError(msg) def get_current_validator(): diff --git a/nbformat/notebooknode.py b/nbformat/notebooknode.py index d78fe24c..3eb9b8a0 100644 --- a/nbformat/notebooknode.py +++ b/nbformat/notebooknode.py @@ -27,7 +27,7 @@ def update(self, *args, **kwargs): for key in other: self[key] = other[key] elif hasattr(other, "keys"): - for key in other.keys(): + for key in other: self[key] = other[key] else: for key, value in other: diff --git a/nbformat/reader.py b/nbformat/reader.py index 8877a8cf..c97e5ab5 100644 --- a/nbformat/reader.py +++ b/nbformat/reader.py @@ -21,7 +21,7 @@ def parse_json(s, **kwargs): except ValueError as e: message = f"Notebook does not appear to be JSON: {s!r}" # Limit the error message to 80 characters. Display whatever JSON will fit. - if len(message) > 80: + if len(message) > 80: # noqa message = message[:77] + "..." raise NotJSONError(message) from e return nb_dict @@ -79,9 +79,8 @@ def reads(s, **kwargs): try: return versions[major].to_notebook_json(nb_dict, minor=minor) except AttributeError as e: - raise ValidationError( - f"The notebook is invalid and is missing an expected key: {e}" - ) from None + msg = f"The notebook is invalid and is missing an expected key: {e}" + raise ValidationError(msg) from None else: raise NBFormatError("Unsupported nbformat version %s" % major) diff --git a/nbformat/sign.py b/nbformat/sign.py index 45a24cb2..2e1dbca5 100644 --- a/nbformat/sign.py +++ b/nbformat/sign.py @@ -9,7 +9,7 @@ import typing as t from collections import OrderedDict from contextlib import contextmanager -from datetime import datetime +from datetime import datetime, timezone from hmac import HMAC try: @@ -204,7 +204,7 @@ def store_signature(self, digest, algorithm): INSERT INTO nbsignatures (algorithm, signature, last_seen) VALUES (?, ?, ?) """, - (algorithm, digest, datetime.utcnow()), + (algorithm, digest, datetime.now(tz=timezone.utc)), ) else: self.db.execute( @@ -212,7 +212,7 @@ def store_signature(self, digest, algorithm): algorithm = ? AND signature = ?; """, - (datetime.utcnow(), algorithm, digest), + (datetime.now(tz=timezone.utc), algorithm, digest), ) self.db.commit() @@ -239,7 +239,7 @@ def check_signature(self, digest, algorithm): algorithm = ? AND signature = ?; """, - (datetime.utcnow(), algorithm, digest), + (datetime.now(tz=timezone.utc), algorithm, digest), ) self.db.commit() return True @@ -276,7 +276,7 @@ def yield_everything(obj): if isinstance(obj, dict): for key in sorted(obj): value = obj[key] - assert isinstance(key, str) + assert isinstance(key, str) # noqa yield key.encode() yield from yield_everything(value) elif isinstance(obj, (list, tuple)): @@ -293,11 +293,11 @@ def yield_code_cells(nb): nbformat version independent """ - if nb.nbformat >= 4: + if nb.nbformat >= 4: # noqa for cell in nb["cells"]: if cell["cell_type"] == "code": yield cell - elif nb.nbformat == 3: + elif nb.nbformat == 3: # noqa for ws in nb["worksheets"]: for cell in ws["cells"]: if cell["cell_type"] == "code": @@ -448,7 +448,7 @@ def check_signature(self, nb): - the requested scheme is available from hashlib - the computed hash from notebook_signature matches the stored hash """ - if nb.nbformat < 3: + if nb.nbformat < 3: # noqa return False signature = self.compute_signature(nb) return self.store.check_signature(signature, self.algorithm) @@ -458,7 +458,7 @@ def sign(self, nb): Stores hash algorithm and hmac digest in a local database of trusted notebooks. """ - if nb.nbformat < 3: + if nb.nbformat < 3: # noqa return signature = self.compute_signature(nb) self.store.store_signature(signature, self.algorithm) @@ -480,7 +480,7 @@ def mark_cells(self, nb, trusted): This function is the inverse of check_cells """ - if nb.nbformat < 3: + if nb.nbformat < 3: # noqa return for cell in yield_code_cells(nb): @@ -502,7 +502,7 @@ def _check_cell(self, cell, nbformat_version): return True # explicitly safe output - if nbformat_version >= 4: + if nbformat_version >= 4: # noqa unsafe_output_types = ["execute_result", "display_data"] safe_keys = {"output_type", "execution_count", "metadata"} else: # v3 @@ -528,7 +528,7 @@ def check_cells(self, nb): This function is the inverse of mark_cells. """ - if nb.nbformat < 3: + if nb.nbformat < 3: # noqa return False trusted = True for cell in yield_code_cells(nb): @@ -596,28 +596,28 @@ def sign_notebook_file(self, notebook_path): def sign_notebook(self, nb, notebook_path=""): """Sign a notebook that's been loaded""" if self.notary.check_signature(nb): - print("Notebook already signed: %s" % notebook_path) + print("Notebook already signed: %s" % notebook_path) # noqa else: - print("Signing notebook: %s" % notebook_path) + print("Signing notebook: %s" % notebook_path) # noqa self.notary.sign(nb) def generate_new_key(self): """Generate a new notebook signature key""" - print("Generating new notebook key: %s" % self.notary.secret_file) + print("Generating new notebook key: %s" % self.notary.secret_file) # noqa self.notary._write_secret_file(os.urandom(1024)) def start(self): """Start the trust notebook app.""" if self.reset: if os.path.exists(self.notary.db_file): - print("Removing trusted signature cache: %s" % self.notary.db_file) + print("Removing trusted signature cache: %s" % self.notary.db_file) # noqa os.remove(self.notary.db_file) self.generate_new_key() return if not self.extra_args: self.log.debug("Reading notebook from stdin") nb_s = sys.stdin.read() - assert isinstance(nb_s, str) + assert isinstance(nb_s, str) # noqa nb = reads(nb_s, NO_CONVERT) self.sign_notebook(nb, "") else: diff --git a/nbformat/v1/convert.py b/nbformat/v1/convert.py index d5e5e477..8540ecb9 100644 --- a/nbformat/v1/convert.py +++ b/nbformat/v1/convert.py @@ -14,4 +14,5 @@ def upgrade(nb, orig_version=None): """Upgrade a notebook.""" - raise ValueError("Cannot convert to v1 notebook format") + msg = "Cannot convert to v1 notebook format" + raise ValueError(msg) diff --git a/nbformat/v1/nbbase.py b/nbformat/v1/nbbase.py index a00a056c..8e531b5a 100644 --- a/nbformat/v1/nbbase.py +++ b/nbformat/v1/nbbase.py @@ -16,7 +16,7 @@ # Imports # ----------------------------------------------------------------------------- -from .._struct import Struct +from nbformat._struct import Struct # ----------------------------------------------------------------------------- # Code diff --git a/nbformat/v1/rwbase.py b/nbformat/v1/rwbase.py index c08fae65..691908a8 100644 --- a/nbformat/v1/rwbase.py +++ b/nbformat/v1/rwbase.py @@ -26,7 +26,8 @@ class NotebookReader: def reads(self, s, **kwargs): """Read a notebook from a string.""" - raise NotImplementedError("loads must be implemented in a subclass") + msg = "loads must be implemented in a subclass" + raise NotImplementedError(msg) def read(self, fp, **kwargs): """Read a notebook from a file like object""" @@ -38,7 +39,8 @@ class NotebookWriter: def writes(self, nb, **kwargs): """Write a notebook to a string.""" - raise NotImplementedError("loads must be implemented in a subclass") + msg = "loads must be implemented in a subclass" + raise NotImplementedError(msg) def write(self, nb, fp, **kwargs): """Write a notebook to a file like object""" diff --git a/nbformat/v2/__init__.py b/nbformat/v2/__init__.py index 09b4b0ed..db9fe7fa 100644 --- a/nbformat/v2/__init__.py +++ b/nbformat/v2/__init__.py @@ -79,13 +79,13 @@ def parse_filename(fname): """ basename, ext = os.path.splitext(fname) if ext == ".ipynb": - format = "json" + format_ = "json" elif ext == ".json": - format = "json" + format_ = "json" elif ext == ".py": - format = "py" + format_ = "py" else: basename = fname fname = fname + ".ipynb" - format = "json" - return fname, basename, format + format_ = "json" + return fname, basename, format_ diff --git a/nbformat/v2/convert.py b/nbformat/v2/convert.py index 501b90f6..64d094a1 100644 --- a/nbformat/v2/convert.py +++ b/nbformat/v2/convert.py @@ -59,4 +59,5 @@ def downgrade(nb): nb : NotebookNode The Python representation of the notebook to convert. """ - raise Exception("Downgrade from notebook v2 to v1 is not supported.") + msg = "Downgrade from notebook v2 to v1 is not supported." + raise Exception(msg) diff --git a/nbformat/v2/nbbase.py b/nbformat/v2/nbbase.py index 3944a4c8..58ffdc68 100644 --- a/nbformat/v2/nbbase.py +++ b/nbformat/v2/nbbase.py @@ -21,7 +21,7 @@ # Imports # ----------------------------------------------------------------------------- -from .._struct import Struct +from nbformat._struct import Struct # ----------------------------------------------------------------------------- # Code @@ -47,7 +47,7 @@ def from_dict(d): return d -def new_output( +def new_output( # noqa output_type=None, output_text=None, output_png=None, @@ -85,9 +85,8 @@ def new_output( if output_javascript is not None: output.javascript = str(output_javascript) - if output_type == "pyout": - if prompt_number is not None: - output.prompt_number = int(prompt_number) + if output_type == "pyout" and prompt_number is not None: + output.prompt_number = int(prompt_number) if output_type == "pyerr": if etype is not None: @@ -100,7 +99,9 @@ def new_output( return output -def new_code_cell(input=None, prompt_number=None, outputs=None, language="python", collapsed=False): +def new_code_cell( + input=None, prompt_number=None, outputs=None, language="python", collapsed=False # noqa +): """Create a new code cell with input and output""" cell = NotebookNode() cell.cell_type = "code" @@ -158,7 +159,9 @@ def new_notebook(metadata=None, worksheets=None): return nb -def new_metadata(name=None, authors=None, license=None, created=None, modified=None, gistid=None): +def new_metadata( + name=None, authors=None, license=None, created=None, modified=None, gistid=None # noqa +): """Create a new metadata node.""" metadata = NotebookNode() if name is not None: diff --git a/nbformat/v2/nbpy.py b/nbformat/v2/nbpy.py index 525e5817..cec76eee 100644 --- a/nbformat/v2/nbpy.py +++ b/nbformat/v2/nbpy.py @@ -42,7 +42,7 @@ def reads(self, s, **kwargs): """Convert a string to a notebook.""" return self.to_notebook(s, **kwargs) - def to_notebook(self, s, **kwargs): + def to_notebook(self, s, **kwargs): # noqa """Convert a string to a notebook.""" lines = s.splitlines() cells = [] @@ -82,10 +82,10 @@ def to_notebook(self, s, **kwargs): def new_cell(self, state, lines): """Create a new cell.""" if state == "codecell": - input = "\n".join(lines) - input = input.strip("\n") - if input: - return new_code_cell(input=input) + input_ = "\n".join(lines) + input_ = input_.strip("\n") + if input_: + return new_code_cell(input=input_) elif state == "htmlcell": text = self._remove_comments(lines) if text: @@ -131,22 +131,22 @@ def writes(self, nb, **kwargs): for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == "code": - input = cell.get("input") - if input is not None: + input_ = cell.get("input") + if input_ is not None: lines.extend(["# ", ""]) - lines.extend(input.splitlines()) + lines.extend(input_.splitlines()) lines.append("") elif cell.cell_type == "html": - input = cell.get("source") - if input is not None: + input_ = cell.get("source") + if input_ is not None: lines.extend(["# ", ""]) - lines.extend(["# " + line for line in input.splitlines()]) + lines.extend(["# " + line for line in input_.splitlines()]) lines.append("") elif cell.cell_type == "markdown": - input = cell.get("source") - if input is not None: + input_ = cell.get("source") + if input_ is not None: lines.extend(["# ", ""]) - lines.extend(["# " + line for line in input.splitlines()]) + lines.extend(["# " + line for line in input_.splitlines()]) lines.append("") lines.append("") return str("\n".join(lines)) diff --git a/nbformat/v2/rwbase.py b/nbformat/v2/rwbase.py index edfc8deb..aee36db6 100644 --- a/nbformat/v2/rwbase.py +++ b/nbformat/v2/rwbase.py @@ -145,7 +145,8 @@ class NotebookReader: def reads(self, s, **kwargs): """Read a notebook from a string.""" - raise NotImplementedError("loads must be implemented in a subclass") + msg = "loads must be implemented in a subclass" + raise NotImplementedError(msg) def read(self, fp, **kwargs): """Read a notebook from a file like object""" @@ -157,7 +158,8 @@ class NotebookWriter: def writes(self, nb, **kwargs): """Write a notebook to a string.""" - raise NotImplementedError("loads must be implemented in a subclass") + msg = "loads must be implemented in a subclass" + raise NotImplementedError(msg) def write(self, nb, fp, **kwargs): """Write a notebook to a file like object""" diff --git a/nbformat/v3/__init__.py b/nbformat/v3/__init__.py index 7708b274..975fd76b 100644 --- a/nbformat/v3/__init__.py +++ b/nbformat/v3/__init__.py @@ -87,13 +87,13 @@ def parse_filename(fname): """ basename, ext = os.path.splitext(fname) if ext == ".ipynb": - format = "json" + format_ = "json" elif ext == ".json": - format = "json" + format_ = "json" elif ext == ".py": - format = "py" + format_ = "py" else: basename = fname fname = fname + ".ipynb" - format = "json" - return fname, basename, format + format_ = "json" + return fname, basename, format_ diff --git a/nbformat/v3/convert.py b/nbformat/v3/convert.py index c11b3d37..0719487e 100644 --- a/nbformat/v3/convert.py +++ b/nbformat/v3/convert.py @@ -35,7 +35,7 @@ def upgrade(nb, from_version=2, from_minor=0): from_minor : int The original minor version of the notebook to convert (only relevant for v >= 3). """ - if from_version == 2: + if from_version == 2: # noqa # Mark the original nbformat so consumers know it has been converted. nb.nbformat = nbformat nb.nbformat_minor = nbformat_minor @@ -46,16 +46,17 @@ def upgrade(nb, from_version=2, from_minor=0): for cell in ws["cells"]: cell.setdefault("metadata", {}) return nb - elif from_version == 3: + elif from_version == 3: # noqa if from_minor != nbformat_minor: nb.orig_nbformat_minor = from_minor nb.nbformat_minor = nbformat_minor return nb else: - raise ValueError( + msg = ( "Cannot convert a notebook directly from v%s to v3. " "Try using the nbformat.convert module." % from_version ) + raise ValueError(msg) def heading_to_md(cell): @@ -78,7 +79,7 @@ def downgrade(nb): nb : NotebookNode The Python representation of the notebook to convert. """ - if nb.nbformat != 3: + if nb.nbformat != 3: # noqa return nb nb.nbformat = 2 for ws in nb.worksheets: diff --git a/nbformat/v3/nbbase.py b/nbformat/v3/nbbase.py index 9d8a98ae..440ba80e 100644 --- a/nbformat/v3/nbbase.py +++ b/nbformat/v3/nbbase.py @@ -11,7 +11,7 @@ import warnings -from .._struct import Struct +from nbformat._struct import Struct # ----------------------------------------------------------------------------- # Code @@ -46,7 +46,8 @@ def str_passthrough(obj): """ Used to be cast_unicode, add this temporarily to make sure no further breakage. """ - assert isinstance(obj, str) + if not isinstance(obj, str): + raise AssertionError return obj @@ -63,11 +64,12 @@ def cast_str(obj): ) return obj.decode("ascii", "replace") else: - assert isinstance(obj, str) + if not isinstance(obj, str): + raise AssertionError return obj -def new_output( +def new_output( # noqa output_type, output_text=None, output_png=None, @@ -91,7 +93,8 @@ def new_output( if metadata is None: metadata = {} if not isinstance(metadata, dict): - raise TypeError("metadata must be dict") + msg = "metadata must be dict" + raise TypeError(msg) if output_type in {"pyout", "display_data"}: output.metadata = metadata @@ -114,9 +117,8 @@ def new_output( if output_javascript is not None: output.javascript = str_passthrough(output_javascript) - if output_type == "pyout": - if prompt_number is not None: - output.prompt_number = int(prompt_number) + if output_type == "pyout" and prompt_number is not None: + output.prompt_number = int(prompt_number) if output_type == "pyerr": if ename is not None: @@ -133,7 +135,7 @@ def new_output( def new_code_cell( - input=None, + input=None, # noqa prompt_number=None, outputs=None, language="python", @@ -214,7 +216,9 @@ def new_notebook(name=None, metadata=None, worksheets=None): return nb -def new_metadata(name=None, authors=None, license=None, created=None, modified=None, gistid=None): +def new_metadata( + name=None, authors=None, license=None, created=None, modified=None, gistid=None # noqa +): """Create a new metadata node.""" metadata = NotebookNode() if name is not None: diff --git a/nbformat/v3/nbpy.py b/nbformat/v3/nbpy.py index 0349afbb..c515d35b 100644 --- a/nbformat/v3/nbpy.py +++ b/nbformat/v3/nbpy.py @@ -50,7 +50,7 @@ def reads(self, s, **kwargs): """Convert a string to a notebook""" return self.to_notebook(s, **kwargs) - def to_notebook(self, s, **kwargs): + def to_notebook(self, s, **kwargs): # noqa """Convert a string to a notebook""" lines = s.splitlines() cells = [] @@ -113,13 +113,13 @@ def to_notebook(self, s, **kwargs): nb = new_notebook(worksheets=[ws]) return nb - def new_cell(self, state, lines, **kwargs): + def new_cell(self, state, lines, **kwargs): # noqa """Create a new cell.""" if state == "codecell": - input = "\n".join(lines) - input = input.strip("\n") - if input: - return new_code_cell(input=input) + input_ = "\n".join(lines) + input_ = input_.strip("\n") + if input_: + return new_code_cell(input=input_) elif state == "htmlcell": text = self._remove_comments(lines) if text: @@ -167,7 +167,7 @@ def split_lines_into_blocks(self, lines): class PyWriter(NotebookWriter): """A Python notebook writer.""" - def writes(self, nb, **kwargs): + def writes(self, nb, **kwargs): # noqa """Convert a notebook to a string.""" lines = ["# -*- coding: utf-8 -*-"] lines.extend( @@ -179,35 +179,35 @@ def writes(self, nb, **kwargs): for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == "code": - input = cell.get("input") - if input is not None: + input_ = cell.get("input") + if input_ is not None: lines.extend(["# ", ""]) - lines.extend(input.splitlines()) + lines.extend(input_.splitlines()) lines.append("") elif cell.cell_type == "html": - input = cell.get("source") - if input is not None: + input_ = cell.get("source") + if input_ is not None: lines.extend(["# ", ""]) - lines.extend(["# " + line for line in input.splitlines()]) + lines.extend(["# " + line for line in input_.splitlines()]) lines.append("") elif cell.cell_type == "markdown": - input = cell.get("source") - if input is not None: + input_ = cell.get("source") + if input_ is not None: lines.extend(["# ", ""]) - lines.extend(["# " + line for line in input.splitlines()]) + lines.extend(["# " + line for line in input_.splitlines()]) lines.append("") elif cell.cell_type == "raw": - input = cell.get("source") - if input is not None: + input_ = cell.get("source") + if input_ is not None: lines.extend(["# ", ""]) - lines.extend(["# " + line for line in input.splitlines()]) + lines.extend(["# " + line for line in input_.splitlines()]) lines.append("") elif cell.cell_type == "heading": - input = cell.get("source") + input_ = cell.get("source") level = cell.get("level", 1) - if input is not None: + if input_ is not None: lines.extend(["# " % level, ""]) - lines.extend(["# " + line for line in input.splitlines()]) + lines.extend(["# " + line for line in input_.splitlines()]) lines.append("") lines.append("") return "\n".join(lines) diff --git a/nbformat/v3/rwbase.py b/nbformat/v3/rwbase.py index 064db9d1..53f70649 100644 --- a/nbformat/v3/rwbase.py +++ b/nbformat/v3/rwbase.py @@ -162,7 +162,8 @@ class NotebookReader: def reads(self, s, **kwargs): """Read a notebook from a string.""" - raise NotImplementedError("loads must be implemented in a subclass") + msg = "loads must be implemented in a subclass" + raise NotImplementedError(msg) def read(self, fp, **kwargs): """Read a notebook from a file like object""" @@ -175,7 +176,8 @@ class NotebookWriter: def writes(self, nb, **kwargs): """Write a notebook to a string.""" - raise NotImplementedError("loads must be implemented in a subclass") + msg = "loads must be implemented in a subclass" + raise NotImplementedError(msg) def write(self, nb, fp, **kwargs): """Write a notebook to a file like object""" diff --git a/nbformat/v4/__init__.py b/nbformat/v4/__init__.py index 73ba0e0f..044a33f4 100644 --- a/nbformat/v4/__init__.py +++ b/nbformat/v4/__init__.py @@ -20,6 +20,7 @@ "upgrade", ] +from .convert import downgrade, upgrade from .nbbase import ( nbformat, nbformat_minor, @@ -36,5 +37,3 @@ reads_json = reads writes_json = writes to_notebook_json = to_notebook - -from .convert import downgrade, upgrade diff --git a/nbformat/v4/convert.py b/nbformat/v4/convert.py index c197e555..0e50e149 100644 --- a/nbformat/v4/convert.py +++ b/nbformat/v4/convert.py @@ -8,9 +8,8 @@ from traitlets.log import get_logger -from nbformat import v3 +from nbformat import v3, validator -from .. import validator from .nbbase import NotebookNode, nbformat, nbformat_minor, random_cell_id @@ -24,7 +23,7 @@ def _warn_if_invalid(nb, version): get_logger().error("Notebook JSON is not valid v%i: %s", version, e) -def upgrade(nb, from_version=None, from_minor=None): +def upgrade(nb, from_version=None, from_minor=None): # noqa """Convert a notebook to latest v4. Parameters @@ -40,16 +39,15 @@ def upgrade(nb, from_version=None, from_minor=None): from_version = nb["nbformat"] if not from_minor: if "nbformat_minor" not in nb: - if from_version == 4: - raise validator.ValidationError( - "The v4 notebook does not include the nbformat minor, which is needed." - ) + if from_version == 4: # noqa + msg = "The v4 notebook does not include the nbformat minor, which is needed." + raise validator.ValidationError(msg) else: from_minor = 0 else: from_minor = nb["nbformat_minor"] - if from_version == 3: + if from_version == 3: # noqa # Validate the notebook before conversion _warn_if_invalid(nb, from_version) @@ -77,7 +75,7 @@ def upgrade(nb, from_version=None, from_minor=None): # Validate the converted notebook before returning it _warn_if_invalid(nb, nbformat) return nb - elif from_version == 4: + elif from_version == 4: # noqa if from_minor == nbformat_minor: return nb @@ -85,7 +83,7 @@ def upgrade(nb, from_version=None, from_minor=None): # if from_minor < 3: # if from_minor < 4: - if from_minor < 5: + if from_minor < 5: # noqa for cell in nb.cells: cell.id = random_cell_id() @@ -154,7 +152,7 @@ def downgrade_cell(cell): source = cell.get("source", "") if "\n" not in source and source.startswith("#"): match = re.match(r"(#+)\s*(.*)", source) - assert match is not None + assert match is not None # noqa prefix, text = match.groups() cell.cell_type = "heading" cell.source = text diff --git a/nbformat/v4/nbbase.py b/nbformat/v4/nbbase.py index eaf15fbe..95514016 100644 --- a/nbformat/v4/nbbase.py +++ b/nbformat/v4/nbbase.py @@ -9,8 +9,8 @@ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. -from ..corpus.words import generate_corpus_id as random_cell_id -from ..notebooknode import NotebookNode +from nbformat.corpus.words import generate_corpus_id as random_cell_id +from nbformat.notebooknode import NotebookNode # Change the nbformat_minor and nbformat_schema variables when incrementing the # nbformat version @@ -35,7 +35,7 @@ def validate(node, ref=None): """validate a v4 node""" - from .. import validate as validate_orig + from nbformat import validate as validate_orig return validate_orig(node, ref=ref, version=nbformat) diff --git a/nbformat/v4/nbjson.py b/nbformat/v4/nbjson.py index b2d9f42a..32834de5 100644 --- a/nbformat/v4/nbjson.py +++ b/nbformat/v4/nbjson.py @@ -6,7 +6,8 @@ import copy import json -from ..notebooknode import from_dict +from nbformat.notebooknode import from_dict + from .rwbase import NotebookReader, NotebookWriter, rejoin_lines, split_lines, strip_transient diff --git a/nbformat/v4/rwbase.py b/nbformat/v4/rwbase.py index ad38de2a..eb0f4179 100644 --- a/nbformat/v4/rwbase.py +++ b/nbformat/v4/rwbase.py @@ -46,9 +46,8 @@ def rejoin_lines(nb): output_type = output.get("output_type", "") if output_type in {"execute_result", "display_data"}: _rejoin_mimebundle(output.get("data", {})) - elif output_type: - if isinstance(output.get("text", ""), list): - output.text = "".join(output.text) + elif output_type and isinstance(output.get("text", ""), list): + output.text = "".join(output.text) return nb @@ -87,9 +86,8 @@ def split_lines(nb): for output in cell.outputs: if output.output_type in {"execute_result", "display_data"}: _split_mimebundle(output.get("data", {})) - elif output.output_type == "stream": - if isinstance(output.text, str): - output.text = output.text.splitlines(True) + elif output.output_type == "stream" and isinstance(output.text, str): + output.text = output.text.splitlines(True) return nb @@ -111,7 +109,8 @@ class NotebookReader: def reads(self, s, **kwargs): """Read a notebook from a string.""" - raise NotImplementedError("reads must be implemented in a subclass") + msg = "reads must be implemented in a subclass" + raise NotImplementedError(msg) def read(self, fp, **kwargs): """Read a notebook from a file like object""" @@ -124,7 +123,8 @@ class NotebookWriter: def writes(self, nb, **kwargs): """Write a notebook to a string.""" - raise NotImplementedError("writes must be implemented in a subclass") + msg = "writes must be implemented in a subclass" + raise NotImplementedError(msg) def write(self, nb, fp, **kwargs): """Write a notebook to a file like object""" diff --git a/nbformat/validator.py b/nbformat/validator.py index 49f2132b..c2e53808 100644 --- a/nbformat/validator.py +++ b/nbformat/validator.py @@ -25,10 +25,7 @@ def _relax_additional_properties(obj): """relax any `additionalProperties`""" if isinstance(obj, dict): for key, value in obj.items(): - if key == "additionalProperties": - value = True - else: - value = _relax_additional_properties(value) + value = True if key == "additionalProperties" else _relax_additional_properties(value) obj[key] = value elif isinstance(obj, list): for i, value in enumerate(obj): @@ -54,10 +51,7 @@ def get_validator(version=None, version_minor=None, relax_add_props=False, name= if version_minor is None: version_minor = current_minor - if name: - current_validator = _validator_for_name(name) - else: - current_validator = get_current_validator() + current_validator = _validator_for_name(name) if name else get_current_validator() version_tuple = (current_validator.name, version, version_minor) @@ -101,7 +95,8 @@ def _get_schema_json(v, version=None, version_minor=None): # load the latest schema schema_path = os.path.join(os.path.dirname(v.__file__), v.nbformat_schema[(None, None)]) else: - raise AttributeError("Cannot find appropriate nbformat schema file.") + msg = "Cannot find appropriate nbformat schema file." + raise AttributeError(msg) with open(schema_path) as f: schema_json = json.load(f) return schema_json @@ -126,7 +121,8 @@ def isvalid(nbjson, ref=None, version=None, version_minor=None): else: return True finally: - assert nbjson == orig + if nbjson != orig: + raise AssertionError def _format_as_index(indices): @@ -219,7 +215,7 @@ def __unicode__(self): __str__ = __unicode__ -def better_validation_error(error, version, version_minor): +def better_validation_error(error, version, version_minor): # noqa """Get better ValidationError on oneOf failures oneOf errors aren't informative. @@ -257,7 +253,7 @@ def better_validation_error(error, version, version_minor): except Exception: # if it fails for some reason, # let the original error through - pass + pass # noqa return NotebookValidationError(error, ref) @@ -371,7 +367,8 @@ def _normalize( stacklevel=3, ) else: - raise ValidationError(f"Non-unique cell id '{cell_id}' detected.") + msg = f"Non-unique cell id '{cell_id}' detected." + raise ValidationError(msg) seen_ids.add(cell_id) if strip_invalid_metadata: changes += _strip_invalida_metadata( @@ -396,7 +393,7 @@ def _dep_warn(field): ) -def validate( +def validate( # noqa nbdict: Any = None, ref: Optional[str] = None, version: Optional[int] = None, @@ -444,7 +441,7 @@ def validate( Please explicitly call `normalize` if you need to normalize notebooks. """ - assert isinstance(ref, str) or ref is None + assert isinstance(ref, str) or ref is None # noqa if strip_invalid_metadata is _deprecated: strip_invalid_metadata = False @@ -464,7 +461,8 @@ def validate( elif nbjson is not None: nbdict = nbjson else: - raise TypeError("validate() missing 1 required argument: 'nbdict'") + msg = "validate() missing 1 required argument: 'nbdict'" + raise TypeError(msg) if ref is None: # if ref is not specified, we have a whole notebook, so we can get the version @@ -479,8 +477,8 @@ def validate( version, version_minor = 1, 0 if ref is None: - assert isinstance(version, int) - assert isinstance(version_minor, int) + assert isinstance(version, int) # noqa + assert isinstance(version_minor, int) # noqa _normalize( nbdict, version, @@ -507,7 +505,8 @@ def _get_errors( ) -> Any: validator = get_validator(version, version_minor, relax_add_props=relax_add_props) if not validator: - raise ValidationError(f"No schema for validating v{version}.{version_minor} notebooks") + msg = f"No schema for validating v{version}.{version_minor} notebooks" + raise ValidationError(msg) iter_errors = validator.iter_errors(nbdict, *args) errors = list(iter_errors) # jsonschema gives the best error messages. @@ -522,7 +521,7 @@ def _get_errors( return iter(errors) -def _strip_invalida_metadata( +def _strip_invalida_metadata( # noqa nbdict: Any, version: int, version_minor: int, relax_add_props: bool ) -> int: """ @@ -557,9 +556,8 @@ def _strip_invalida_metadata( name="jsonschema", ) if not validator: - raise ValidationError( - f"No jsonschema for validating v{version}.{version_minor} notebooks" - ) + msg = f"No jsonschema for validating v{version}.{version_minor} notebooks" + raise ValidationError(msg) errors = validator.iter_errors(nbdict) error_tree = validator.error_tree(errors) if "metadata" in error_tree: @@ -587,7 +585,7 @@ def _strip_invalida_metadata( rel_path = error.relative_path error_for_intended_schema = error.schema_path[0] == schema_index is_top_level_metadata_key = ( - len(rel_path) == 2 and rel_path[0] == "metadata" + len(rel_path) == 2 and rel_path[0] == "metadata" # noqa ) if error_for_intended_schema and is_top_level_metadata_key: nbdict["cells"][cell_idx]["metadata"].pop(rel_path[1], None) @@ -596,7 +594,7 @@ def _strip_invalida_metadata( return changes -def iter_validate( +def iter_validate( # noqa nbdict=None, ref=None, version=None, @@ -622,7 +620,8 @@ def iter_validate( elif nbjson is not None: nbdict = nbjson else: - raise TypeError("iter_validate() missing 1 required argument: 'nbdict'") + msg = "iter_validate() missing 1 required argument: 'nbdict'" + raise TypeError(msg) if version is None: version, version_minor = get_version(nbdict) diff --git a/pyproject.toml b/pyproject.toml index 26ad9bad..0348dce5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,7 +87,7 @@ dependencies = ["mypy>=0.990"] test = "mypy --install-types --non-interactive {args:nbformat tests}" [tool.hatch.envs.lint] -dependencies = ["black[jupyter]==22.12.0", "mdformat>0.7", "ruff==0.0.207"] +dependencies = ["black[jupyter]==22.12.0", "mdformat>0.7", "ruff==0.0.237"] detached = true [tool.hatch.envs.lint.scripts] style = [ @@ -158,38 +158,19 @@ extend-exclude = "^/tests.*ipynb$" target-version = "py37" line-length = 100 select = [ - "A", "B", "C", "E", "F", "FBT", "I", "N", "Q", "RUF", "S", "T", - "UP", "W", "YTT", + "A", "B", "C", "DTZ", "E", "EM", "F", "FBT", "I", "ICN", "ISC", "N", + "PLC", "PLE", "PLR", "PLW", "Q", "RUF", "S", "SIM", "T", "TID", "UP", + "W", "YTT", ] ignore = [ - # Allow non-abstract empty methods in abstract base classes - "B027", - # Ignore McCabe complexity - "C901", - # Allow boolean positional values in function calls, like `dict.get(... True)` - "FBT003", - # Use of `assert` detected - "S101", - # Line too long - "E501", - # Relative imports are banned - "TID252", - # Boolean ... in function definition - "FBT001", "FBT002", - # Module level import not at top of file - "E402", - # A001/A002/A003 .. is shadowing a python builtin - "A001", "A002", "A003", - # Possible hardcoded password - "S105", "S106", # Q000 Single quotes found but double quotes preferred "Q000", - # N806 Variable `B` in function should be lowercase - "N806", - # T201 `print` found - "T201", - # N802 Function name `CreateWellKnownSid` should be lowercase - "N802", "N803" + # FBT001 Boolean positional arg in function definition + "FBT001", "FBT002", "FBT003", + # E501 Line too long (158 > 100 characters) + "E501", + # SIM105 Use `contextlib.suppress(...)` + "SIM105", ] unfixable = [ # Don't touch print statements @@ -207,7 +188,9 @@ unfixable = [ # B007 Loop control variable `i` not used within the loop body. # N802 Function name `assertIn` should be lowercase # RUF001 contains ambiguous unicode character '–' (did you mean '-'?) -"tests/*" = ["B011", "F841", "C408", "E402", "T201", "B007", "N802", "RUF001", "RUF002"] +# S101 Use of `assert` detected +# PLR2004 Magic value used in comparison +"tests/*" = ["B011", "F841", "C408", "E402", "T201", "B007", "N802", "RUF001", "RUF002", "S101", "PLR2004"] # F401 `nbxml.to_notebook` imported but unused "nbformat/*__init__.py" = ["F401"] diff --git a/tests/base.py b/tests/base.py index 02ccbfc3..395c3475 100644 --- a/tests/base.py +++ b/tests/base.py @@ -14,7 +14,7 @@ class TestsBase(unittest.TestCase): @classmethod def fopen(cls, f, mode="r", encoding="utf-8"): - return open(os.path.join(cls._get_files_path(), f), mode, encoding=encoding) + return open(os.path.join(cls._get_files_path(), f), mode, encoding=encoding) # noqa @classmethod def _get_files_path(cls): diff --git a/tests/test_nbformat.py b/tests/test_nbformat.py index 714179d4..2eacab8d 100644 --- a/tests/test_nbformat.py +++ b/tests/test_nbformat.py @@ -8,9 +8,8 @@ def test_read_invalid_iowrapper(tmpdir): ipynb_filepath = tmpdir.join("empty.ipynb") ipynb_filepath.write("{}") - with pytest.raises(ValidationError) as excinfo: - with ipynb_filepath.open() as fp: - read(fp, as_version=4) + with pytest.raises(ValidationError) as excinfo, ipynb_filepath.open() as fp: + read(fp, as_version=4) assert "cells" in str(excinfo.value) diff --git a/tests/test_reader.py b/tests/test_reader.py index 4f3e2f5f..70e5fb19 100644 --- a/tests/test_reader.py +++ b/tests/test_reader.py @@ -39,11 +39,13 @@ def test_read(self): self.assertEqual(major, 2) def test_read_fails_on_missing_worksheets(self): - with self.fopen("test3_no_worksheets.ipynb", "r") as f: - with self.assertRaisesRegex(ValidationError, r"worksheets"): - nb = read(f) + with self.fopen("test3_no_worksheets.ipynb", "r") as f, self.assertRaisesRegex( + ValidationError, r"worksheets" + ): + nb = read(f) def test_read_fails_on_missing_worksheet_cells(self): - with self.fopen("test3_worksheet_with_no_cells.ipynb", "r") as f: - with self.assertRaisesRegex(ValidationError, r"cells"): - nb = read(f) + with self.fopen("test3_worksheet_with_no_cells.ipynb", "r") as f, self.assertRaisesRegex( + ValidationError, r"cells" + ): + nb = read(f) diff --git a/tests/test_validator.py b/tests/test_validator.py index 800043c7..64315111 100644 --- a/tests/test_validator.py +++ b/tests/test_validator.py @@ -259,9 +259,8 @@ def test_validation_no_version(validator_name): def test_invalid_validator_raises_value_error(): """Test that an invalid notebook with no version fails validation""" set_validator("foobar") - with pytest.raises(ValueError): - with TestsBase.fopen("test2.ipynb", "r") as f: - nb = read(f, as_version=4) + with pytest.raises(ValueError), TestsBase.fopen("test2.ipynb", "r") as f: + nb = read(f, as_version=4) def test_invalid_validator_raises_value_error_after_read(): @@ -292,13 +291,11 @@ def test_non_unique_cell_ids(): with TestsBase.fopen("invalid_unique_cell_id.ipynb", "r") as f: # Avoids validate call from `.read` nb = nbformat.from_dict(json.load(f)) - with pytest.raises(ValidationError): - with pytest.warns(DeprecationWarning): - validate(nb, repair_duplicate_cell_ids=False) + with pytest.raises(ValidationError), pytest.warns(DeprecationWarning): + validate(nb, repair_duplicate_cell_ids=False) # try again to verify that we didn't modify the content - with pytest.raises(ValidationError): - with pytest.warns(DeprecationWarning): - validate(nb, repair_duplicate_cell_ids=False) + with pytest.raises(ValidationError), pytest.warns(DeprecationWarning): + validate(nb, repair_duplicate_cell_ids=False) def test_repair_non_unique_cell_ids(): @@ -319,13 +316,11 @@ def test_no_cell_ids(): with TestsBase.fopen("v4_5_no_cell_id.ipynb", "r") as f: # Avoids validate call from `.read` nb = nbformat.from_dict(json.load(f)) - with pytest.raises(ValidationError): - with pytest.warns(DeprecationWarning): - validate(nb, repair_duplicate_cell_ids=False) + with pytest.raises(ValidationError), pytest.warns(DeprecationWarning): + validate(nb, repair_duplicate_cell_ids=False) # try again to verify that we didn't modify the content - with pytest.raises(ValidationError): - with pytest.warns(DeprecationWarning): - validate(nb, repair_duplicate_cell_ids=False) + with pytest.raises(ValidationError), pytest.warns(DeprecationWarning): + validate(nb, repair_duplicate_cell_ids=False) @pytest.mark.filterwarnings("ignore::nbformat.warnings.MissingIDFieldWarning") diff --git a/tests/v3/formattest.py b/tests/v3/formattest.py index 01bcb5d4..5c72eb31 100644 --- a/tests/v3/formattest.py +++ b/tests/v3/formattest.py @@ -9,7 +9,7 @@ def open_utf8(fname, mode): - return open(fname, mode=mode, encoding="utf-8") + return open(fname, mode=mode, encoding="utf-8") # noqa class NBFormatTest: diff --git a/tests/v3/test_misc.py b/tests/v3/test_misc.py index 6bc4de5d..8d6947c1 100644 --- a/tests/v3/test_misc.py +++ b/tests/v3/test_misc.py @@ -6,10 +6,10 @@ class MiscTests(TestCase): def check_filename(self, path, exp_fname, exp_bname, exp_format): - fname, bname, format = parse_filename(path) + fname, bname, fmt = parse_filename(path) self.assertEqual(fname, exp_fname) self.assertEqual(bname, exp_bname) - self.assertEqual(format, exp_format) + self.assertEqual(fmt, exp_format) def test_parse_filename(self): diff --git a/tests/v4/formattest.py b/tests/v4/formattest.py index 01bcb5d4..5c72eb31 100644 --- a/tests/v4/formattest.py +++ b/tests/v4/formattest.py @@ -9,7 +9,7 @@ def open_utf8(fname, mode): - return open(fname, mode=mode, encoding="utf-8") + return open(fname, mode=mode, encoding="utf-8") # noqa class NBFormatTest: diff --git a/tests/v4/test_convert.py b/tests/v4/test_convert.py index c5e3a6fa..95803b90 100644 --- a/tests/v4/test_convert.py +++ b/tests/v4/test_convert.py @@ -8,7 +8,7 @@ from nbformat.v4 import convert from nbformat.v4.nbjson import reads -from ..v3 import nbexamples as v3examples +from ..v3 import nbexamples as v3examples # noqa from . import nbexamples @@ -29,26 +29,27 @@ def test_downgrade_notebook(): def test_upgrade_heading(): # Fake the uuid generation for ids cell_ids = ["cell-1", "cell-2", "cell-3"] - with mock.patch("nbformat.v4.convert.random_cell_id", side_effect=cell_ids): - with mock.patch("nbformat.v4.nbbase.random_cell_id", side_effect=cell_ids): - v3h = v3.new_heading_cell - v4m = v4.new_markdown_cell - for v3cell, expected in [ - ( - v3h(source="foo", level=1), - v4m(source="# foo"), - ), - ( - v3h(source="foo\nbar\nmulti-line\n", level=4), - v4m(source="#### foo bar multi-line"), - ), - ( - v3h(source="ünìcö∂e–cønvërsioñ", level=4), - v4m(source="#### ünìcö∂e–cønvërsioñ"), - ), - ]: - upgraded = convert.upgrade_cell(v3cell) - assert upgraded == expected + with mock.patch("nbformat.v4.convert.random_cell_id", side_effect=cell_ids), mock.patch( + "nbformat.v4.nbbase.random_cell_id", side_effect=cell_ids + ): + v3h = v3.new_heading_cell + v4m = v4.new_markdown_cell + for v3cell, expected in [ + ( + v3h(source="foo", level=1), + v4m(source="# foo"), + ), + ( + v3h(source="foo\nbar\nmulti-line\n", level=4), + v4m(source="#### foo bar multi-line"), + ), + ( + v3h(source="ünìcö∂e–cønvërsioñ", level=4), + v4m(source="#### ünìcö∂e–cønvërsioñ"), + ), + ]: + upgraded = convert.upgrade_cell(v3cell) + assert upgraded == expected def test_downgrade_heading():