converter.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. """API for converting notebooks between versions."""
  2. # Copyright (c) IPython Development Team.
  3. # Distributed under the terms of the Modified BSD License.
  4. from __future__ import annotations
  5. from . import versions
  6. from .reader import get_version
  7. from .validator import ValidationError
  8. def convert(nb, to_version):
  9. """Convert a notebook node object to a specific version. Assumes that
  10. all the versions starting from 1 to the latest major X are implemented.
  11. In other words, there should never be a case where v1 v2 v3 v5 exist without
  12. a v4. Also assumes that all conversions can be made in one step increments
  13. between major versions and ignores minor revisions.
  14. Parameters
  15. ----------
  16. nb : NotebookNode
  17. to_version : int
  18. Major revision to convert the notebook to. Can either be an upgrade or
  19. a downgrade.
  20. Raises
  21. ------
  22. ValueError
  23. Notebook failed to convert.
  24. ValueError
  25. The version specified is invalid or doesn't exist.
  26. ValidationError
  27. Conversion failed due to missing expected attributes.
  28. """
  29. # Get input notebook version.
  30. (version, version_minor) = get_version(nb)
  31. # Check if destination is target version, if so return contents
  32. if version == to_version:
  33. return nb
  34. # If the version exist, try to convert to it one step at a time.
  35. if to_version in versions:
  36. # Get the the version that this recursion will convert to as a step
  37. # closer to the final revision. Make sure the newer of the conversion
  38. # functions is used to perform the conversion.
  39. if to_version > version:
  40. step_version = version + 1
  41. convert_function = versions[step_version].upgrade
  42. else:
  43. step_version = version - 1
  44. convert_function = versions[version].downgrade
  45. try:
  46. # Convert and make sure version changed during conversion.
  47. converted = convert_function(nb)
  48. if converted.get("nbformat", 1) == version:
  49. msg = "Failed to convert notebook from v%d to v%d." % (version, step_version)
  50. raise ValueError(msg)
  51. except AttributeError as e:
  52. msg = f"Notebook could not be converted from version {version} to version {step_version} because it's missing a key: {e}"
  53. raise ValidationError(msg) from None
  54. # Recursively convert until target version is reached.
  55. return convert(converted, to_version)
  56. raise ValueError(
  57. "Cannot convert notebook to v%d because that version doesn't exist" % (to_version)
  58. )