Skip to content

marimo convert fails on markdown cells ending in double quotes #6741

@wjhopper

Description

@wjhopper

In the process of converting a jupyter notebook to a marimo notebook, I believe ran into a bug in marimo convert. This Jupyter notebook included a markdown cell with text that ended in double quotes, and this caused marimo convert to fail.

Will you submit a PR?

  • Yes

Environment

{
  "marimo": "0.16.5",
  "editable": false,
  "location": "/home/will/.cache/uv/archive-v0/1y9AY_TYw0xFV3URXXTgB/lib/python3.13/site-packages/marimo",
  "OS": "Linux",
  "OS Version": "6.16.8+deb14-amd64",
  "Processor": "",
  "Python Version": "3.13.7",
  "Locale": "en_US",
  "Binaries": {
    "Browser": "--",
    "Node": "v20.19.4"
  },
  "Dependencies": {
    "click": "8.3.0",
    "docutils": "0.22.2",
    "itsdangerous": "2.2.0",
    "jedi": "0.19.2",
    "markdown": "3.9",
    "narwhals": "2.7.0",
    "packaging": "25.0",
    "psutil": "7.1.0",
    "pygments": "2.19.2",
    "pymdown-extensions": "10.16.1",
    "pyyaml": "6.0.3",
    "starlette": "0.48.0",
    "tomlkit": "0.13.3",
    "typing-extensions": "missing",
    "uvicorn": "0.35.0",
    "websockets": "15.0.1"
  },
  "Optional Dependencies": {
    "nbformat": "5.10.4",
    "loro": "1.8.1"
  },
  "Experimental Flags": {}
}

Code to reproduce

If you have a file named test-quotes.py with the following contents

# %% [markdown]
# "Marimo is the best"

and run uvx --with=jupytext marimo convert test-quote.py, the following error occurs:

Traceback (most recent call last):
  File "/home/will/.cache/uv/archive-v0/1y9AY_TYw0xFV3URXXTgB/bin/marimo", line 12, in <module>
    sys.exit(main())
             ~~~~^^
  File "/home/will/.cache/uv/archive-v0/1y9AY_TYw0xFV3URXXTgB/lib/python3.13/site-packages/click/core.py", line 1462, in __call__
    return self.main(*args, **kwargs)
           ~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/will/.cache/uv/archive-v0/1y9AY_TYw0xFV3URXXTgB/lib/python3.13/site-packages/click/core.py", line 1383, in main
    rv = self.invoke(ctx)
  File "/home/will/.cache/uv/archive-v0/1y9AY_TYw0xFV3URXXTgB/lib/python3.13/site-packages/click/core.py", line 1850, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/home/will/.cache/uv/archive-v0/1y9AY_TYw0xFV3URXXTgB/lib/python3.13/site-packages/click/core.py", line 1246, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/will/.cache/uv/archive-v0/1y9AY_TYw0xFV3URXXTgB/lib/python3.13/site-packages/click/core.py", line 814, in invoke
    return callback(*args, **kwargs)
  File "/home/will/.cache/uv/archive-v0/1y9AY_TYw0xFV3URXXTgB/lib/python3.13/site-packages/marimo/_cli/convert/commands.py", line 105, in convert
    ).to_py()
      ~~~~~^^
  File "/home/will/.cache/uv/archive-v0/1y9AY_TYw0xFV3URXXTgB/lib/python3.13/site-packages/marimo/_convert/converters.py", line 35, in to_py
    return generate_filecontents_from_ir(self.ir)
  File "/home/will/.cache/uv/archive-v0/1y9AY_TYw0xFV3URXXTgB/lib/python3.13/site-packages/marimo/_ast/codegen.py", line 362, in generate_filecontents_from_ir
    return generate_filecontents(
        codes=[cell.code for cell in ir.cells],
    ...<3 lines>...
        header_comments=ir.header.value if ir.header else None,
    )
  File "/home/will/.cache/uv/archive-v0/1y9AY_TYw0xFV3URXXTgB/lib/python3.13/site-packages/marimo/_ast/codegen.py", line 390, in generate_filecontents
    cell_blocks = [serialize_cell(extraction, status) for status in extraction]
                   ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
  File "/home/will/.cache/uv/archive-v0/1y9AY_TYw0xFV3URXXTgB/lib/python3.13/site-packages/marimo/_ast/codegen.py", line 325, in serialize_cell
    return generate_unparsable_cell(
        code=status.code, config=status.cell_config, name=status.name
    )
  File "/home/will/.cache/uv/archive-v0/1y9AY_TYw0xFV3URXXTgB/lib/python3.13/site-packages/marimo/_ast/codegen.py", line 303, in generate_unparsable_cell
    flags = dict(config.__dict__)
                 ^^^^^^^^^^^^^^^
AttributeError: 'CellConfig' object has no attribute '__dict__'. Did you mean: '__dir__'?

If you remove the closing quotes, the file converts without issue. This issue does not occur when the markdown cell ends in a single quote.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions