readthedocs.org: mkdocs.yml parsing error with `!!` in `format: !!python/name:pymdownx.superfences.fence_div_format`

Thank you very much for this wonderful service, it makes my life at documenting on https://docs.qownnotes.org/ so much easier!

Details

Expected Result

Being able to use !!python/name:pymdownx.superfences.fence_div_format in mkdocs.yml, like it works when building with MkDocs locally.

  - pymdownx.superfences:
      custom_fences:
        - name: mermaid
          class: mermaid
          # this doesn't work on ReadTheDocs, we need to use `<div class="mermaid"></div>` instead
          format: !!python/name:pymdownx.superfences.fence_div_format

Actual Result

I get a parsing error in https://github.com/pbek/QOwnNotes/blob/develop/docs/mkdocs.yml#L85 at the !! (I’ve now commented the line out).

Your mkdocs.yml could not be loaded, possibly due to a syntax error (line 84, column 19).

Thank you very much.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 21 (7 by maintainers)

Most upvoted comments

I’d like to bump this issue, as I am getting the same error. When I inspect the resulting mkdocs.yml, after it has been parsed on your end, the configuration looks like this:

- pymdownx.superfences:
    custom_fences:
    - class: mermaid
      format: null
      name: mermaid

The format: null is (not surprisingly) the result of dropping any potentially unsafe !! yaml directives. However, this breaks our Mkdocs configuration and the build fails; because pymdownx.superfences expects to receive a callable Python format function there.

My first thought was that pymdown-extensions should just accept a string for format and fetch the formatter at runtime. Unfortunately, this issue was already raised and closed on their side based on this argument: https://github.com/facelessuser/pymdown-extensions/issues/892#issuecomment-612942643

Since ReadTheDocs is already running the repository’s install scripts, there’s probably no additional vulnerability that could be caused by the “unsafe” yaml.load().

Would it be possible to parse mkdocs.yml with ordinary yaml.load after installing the project dependencies? I think that ought to provide the most flexibility for MkDocs builds.

OK! I took a look at this and I understand the problem. I had no idea what was the !! in YAML since I never seen it before.

For example, using !! here we can cast the 2 as a float, instead of a integer.

In [13]: import yaml 
    ...: print(yaml.load(""" 
    ...: gold: !!float 2 
    ...: """))                                                                                                                                    
{'gold': 2.0}

Using !!python we can convert that field to a Python object,

In [15]: import yaml 
    ...: print(yaml.load(""" 
    ...: gold: !!python/name:int 
    ...: """))                                                                                                                                    
{'gold': <class 'int'>}

So, I think the problem is that we are parsing your file before installing all the dependencies of your project, and so, Python can’t find the module and it fails.

The solution, should be to try to load your YAML configuration file skipping these calls to !!python/name:.