On 2019-02-26, Stephan Witt wrote:
> Am 26.02.2019 um 09:06 schrieb Guenter Milde <mi...@users.sf.net>:
>> On 2019-02-26, Stephan Witt wrote:

>>> I’m having a problem with lib/scripts/convertDefault.py and Python 3,
>>> see below:

>>> Traceback (most recent call last):
>>>  File "/Users/stephan/git/lyx/lib/scripts/convertDefault.py", line 38, in 
>>> <module>
>>>    output = output.decode()
>>> AttributeError: 'str' object has no attribute 'decode'

>> ...

>>> Is this to be expected?

...

>> Does the following patch help?

> Yes, of course. But IMO the AttributeError should happen in any case.

I may have misunderstood the backlog. It seems to have not happened for
others, yet.

> Not only on error. Probably it’s a copy-n-paste error… the same
> construct to detect Python 3 is used in unicode_symbols.py and
> lyxpreview2bitmap.py. Probably the code in these files is ok. But it
> would be good if you’d review it.

Yes, there are some other cases where special action for Py2 vs. Py3 is
required. I had a look, the other files seem OK.

However, my "fix" may work (by coincidence) but is not correct: 

  The next action is to match the `output` string to a regular expression
  (given as string-literal, i.e. a unicode-string in Py3 and a
  bytes-string in Py2).

  With my patch, the `output` is decoded to a unicode-string under Py2.
  For the match, it is implicitely re-converted to a bytes-string.
  This works (as long as it only contains ASCII chars) but is unnecessary. 

I suppose that the unpatched code is correct with older Py3 versions, where
`os.popen()` may have returned a bytes-string but the regexp-match a
unicode-string and no implicit conversion is done.

In this case, a better patch would be:

diff --git a/lib/scripts/convertDefault.py b/lib/scripts/convertDefault.py
index 8678965013..a247ce640a 100644
--- a/lib/scripts/convertDefault.py
+++ b/lib/scripts/convertDefault.py
@@ -35,7 +35,10 @@ if fout.close() != None:
     output = fout.readline()
     fout.close()
 if not PY2:
-    output = output.decode()
+    try:
+        output = output.decode()
+    except AttributeError:
+        pass
 
 version = re_version.match(output)
 

Otherwise the if clause can go alltogether:

--- a/lib/scripts/convertDefault.py
+++ b/lib/scripts/convertDefault.py
@@ -19,8 +19,6 @@
 from __future__ import print_function
 import os, re, sys
 
-PY2 = sys.version_info[0] == 2
-
 # We may need some extra options only supported by recent convert versions
 re_version = re.compile(r'^Version:.*ImageMagick\s*(\d*)\.(\d*)\.(\d*).*$')
 # imagemagick 7
@@ -34,8 +32,6 @@ if fout.close() != None:
     fout = os.popen('convert -version 2>&1')
     output = fout.readline()
     fout.close()
-if not PY2:
-    output = output.decode()
 
 version = re_version.match(output)


In any case, os.popen is deprecated since Python 2.6 and should be replaced
by calls to subprocess. https://docs.python.org/3/library/subprocess.html

Hope this helps,

Günter




Reply via email to