eyeseast / python-frontmatter

Parse and manage posts with YAML (or other) frontmatter
http://python-frontmatter.rtfd.io
MIT License
334 stars 42 forks source link

python3 and dump #36

Closed svenevs closed 7 years ago

svenevs commented 7 years ago

There's a problem and/or misleading documentation where frontmatter.dump is concerned. I figured I'd give a full example, but the easy fix for you is to just say

Use BytesIO with frontmatter.dump if you are using Python3.

So I'm using frontmatter to parse and re-write some things. It goes something like this

$ python3
Python 3.6.1 (default, May  8 2017, 14:55:30) 
[GCC 5.3.1 20160406 (Red Hat 5.3.1-6)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import frontmatter
>>> from io import StringIO, BytesIO
>>> with open("awkward.json", "r") as f:
...     meta, content = frontmatter.parse(f.read())
... 
>>> str_buff = StringIO()
>>> bytes_buff = BytesIO()
>>> 
>>> # ...made changes to meta and/or content ...
... 
>>> post = frontmatter.Post(content, handler=None, **meta)
>>> 
>>> frontmatter.dump(post, str_buff)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/spack/opt/spack/linux-fedora23-x86_64/gcc-5.3.1/python-3.6.1-vtgnau5wyennlx7g64w6zc6fk6jnq2ep/lib/python3.6/site-packages/frontmatter/__init__.py", line 155, in dump
    fd.write(content.encode(encoding))
TypeError: string argument expected, got 'bytes'
>>> 
>>> frontmatter.dump(post, bytes_buff)

It's because you do fd.write(content.encode(encoding)), and encode is going to return a bytes, and StringIO gets mad about that in python3.

I can think of a number of different ways to potentially allow for both, but honestly looking at the rest of your library I think you are much better equipped to decide what the correct action is :wink:

eyeseast commented 7 years ago

That should be a doc fix, I think. We need to send out bytes if we're writing to disk, and we can't assume the file-like thing will do more than write bytes, so we're stuck encoding. I wrote the first version of this for 2.7, so there are clearly still some two-isms lying around.

eyeseast commented 7 years ago

Should be fixed now. I had BytesIO in the README, but forgot to update it in the real docs. Thanks for catching.