zestsoftware / zest.releaser

Python software releasing made easy and repeatable
https://zestreleaser.readthedocs.io
GNU General Public License v2.0
198 stars 62 forks source link

fullrelease fails if setup.py has no utf-8 BOM #297

Closed JocelynDelalande closed 5 years ago

JocelynDelalande commented 5 years ago

Crashing on fullrelease command.

I quick-fixed it for my project adding the BOM header, but I suspect it to be a zest.releaser bug.

Faulty setup.py

Commit "Fixing" setup.py.

The error was the following : 

± make release 
/home/jocelyn/.virtualenvs/ihm3/bin/fullrelease
INFO: Starting prerelease.
Changelog entries for version 2.1.1:

2.1.1 (unreleased)
------------------

Fixed
=====

- Fix broken install with pip >= 10 (#340)
- Fix the generation of the supervisord template (#309)
Enter version [2.1.1]: 3.0
Traceback (most recent call last):
  File "/home/jocelyn/.virtualenvs/ihm3/bin/fullrelease", line 11, in <module>
    sys.exit(main())
  File "/home/jocelyn/.virtualenvs/ihm3/lib/python3.5/site-packages/zest/releaser/fullrelease.py", line 23, in main
    prereleaser.run()
  File "/home/jocelyn/.virtualenvs/ihm3/lib/python3.5/site-packages/zest/releaser/baserelease.py", line 391, in run
    self.execute()
  File "/home/jocelyn/.virtualenvs/ihm3/lib/python3.5/site-packages/zest/releaser/prerelease.py", line 74, in execute
    self._write_version()
  File "/home/jocelyn/.virtualenvs/ihm3/lib/python3.5/site-packages/zest/releaser/baserelease.py", line 320, in _write_version
    self.vcs.version = self.data['new_version']
  File "/home/jocelyn/.virtualenvs/ihm3/lib/python3.5/site-packages/zest/releaser/vcs.py", line 259, in _update_version
    fallback_encoding=self.fallback_encoding,
  File "/home/jocelyn/.virtualenvs/ihm3/lib/python3.5/site-packages/zest/releaser/utils.py", line 163, in read_text_file
    coding += data[pos]
TypeError: can't concat bytes to int
Makefile:48 : la recette pour la cible « release » a échouée

Let me know if I can help in any way :-)

reinout commented 5 years ago

zest.releaser does its best to detect encodings in a reliable way. There are several ways in which it does this. Adding the BOM at the start takes you into one part of the code (which works), without it you end up in another part (which apparently fails).

I took your "faulty" setup.py (thanks for the link) and I could reproduce the issue perfectly.

The failing part looks for a -*- encoding: string just like you have and only concatenates the characters behind that encoding hint until it finds a space or a '\n'. This is where it weirdly fails. I have a tiny example (python 3.7):

>>> example = b'just a bytes string'
>>> type(example)
<class 'bytes'>
>>> example[0]
106
>>> type(example[0])
<class 'int'>

What? Grabbing an item from bytes gives an int? Concatenating with '+=' won't work then!

I expected it to give me a one-character bytes string. I just checked: it works on python 2.7. So there's some 2/3 weirdness going on.

reinout commented 5 years ago

On python 3, I get back "bytes" when I use a range (length 1...):

>>> example = b'just a string'
>>> example[0]  # We don't want an int
106
>>> example[0:1]  # This way we get bytes
b'j'
JocelynDelalande commented 5 years ago

I expected it to give me a one-character bytes string. I just checked: it works on python 2.7. So there's some 2/3 weirdness going on.

Weird. That was my first guess, and I had tested, for me it did not work better on py2.

Thanks for your quick (and scenarized ;-)) answer and diagnosis :-).

mauritsvanrees commented 5 years ago

Fixed by Reinout in 6.15.3.

JocelynDelalande commented 5 years ago

:heart: :-) Thanks @mauritsvanrees @reinout