Skip to content

Unicode utf8 is deprecated #99

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 16 commits into from

Conversation

hdd
Copy link
Contributor

@hdd hdd commented Aug 10, 2016

Please consider this (as much as the others) as an early pull request.
Put in place so we can chat on top of it.

It does lack of tests at the moment , but for the ones I've been running, seems to be able to leverage the differences.

@hdd
Copy link
Contributor Author

hdd commented Aug 22, 2016

tests has now been added to check backward compatibilty

assert QtWidgets.QApplication.UnicodeUTF8 is not None

# use patched method with old arguments
QtWidgets.QApplication.translate(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to include a return value in the test, to make sure it produces the expected value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing, just wanted to check the overall testing first (which is failing).
I'll add a check of the return value once I have something basic working ;)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok. No problem.

As tests now require all bindings, I'd imagine it can get tricky to replicate this environment locally. The developer guide has instructions on how to run these via Docker, if you have access to this. It'll let you run tests locally without installing any bindings, exactly the way Travis is running it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool I'll have a look, if you don't mind though , for now, I'll hammer a bit your remote testing ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checking now on local docker installation so I don't mess to much up with travis

@mottosso
Copy link
Owner

For unicode strings, try putting a u infront of the strings. E.g. u"MyString".

Python 3 is picky with that.

force strings to unicode for py3k binding
@hdd
Copy link
Contributor Author

hdd commented Aug 22, 2016

Cheers for that, keep forgetting about py3k and unicode stuff.... (not using py3k at all really ;))
installed all the docker locally and tests are now passing.
pushing the fixes.

make so it works on py2 and py3
@hdd
Copy link
Contributor Author

hdd commented Aug 22, 2016

added tests for return values.

preferred = os.getenv("QT_PREFERRED_BINDING")
verbose = os.getenv("QT_VERBOSE") is not None
bindings = (_pyside2, _pyqt5, _pyside, _pyqt4)

if preferred:

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a look and see if you can't remove these whitespaces inbetween lines. A linter could help here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

always.
it has now been removed, and code cleaned up from trailing spaces.

code cleanup
@mottosso
Copy link
Owner

So just to confirm, is it the case that PySide, PyQt4, and PyQt5 all behave like PySide2 now? I wouldn't expect to see any changes to PySide2 on this, but I haven't had a close enough look yet as to what that change is or whether it's needed.

@hdd hdd mentioned this pull request Aug 25, 2016
@hdd
Copy link
Contributor Author

hdd commented Aug 25, 2016

worth closing this one as well.
Cheers.

@mottosso
Copy link
Owner

Let's not get hasty. :) It looks like we do need this in order to develop for Qt 5.

Only it looks like you've patched PySide2 and PyQt5 to conform to PySide and PyQt4, when it should have been the other way around.

Remember, PySide2 is the reference implementation, right after the official docs of Qt 5.

Having said this, I'd still be keen to see an actual example of it in use, and where it causes a problem. You mention you are using it with pyside-uic? Could you provide an example?

@fredrikaverpil
Copy link
Collaborator

fredrikaverpil commented Aug 26, 2016

This is nice @hdd !

You mention you are using it with pyside-uic? Could you provide an example?

I have second what @mottosso said; we need example code to fully grasp what this is about.

@hdd
Copy link
Contributor Author

hdd commented Aug 26, 2016

Hi, unittests are provided to test and show forward and backward compatibility approaches.

If you compile a ui, (pyside-uic <.ui file> -o <.py file>) is quite easy to spot (thought I did mention at the beginning of the ticket...) In any case, Mr Google can help on this : http://stackoverflow.com/questions/4442286/python-code-genration-with-pyside-uic

It looks like we do need this in order to develop for Qt 5.

Yeap that's why I did work on this.

Only it looks like you've patched PySide2 and PyQt5 to conform to PySide and PyQt4, when it should have been the other way around.

You simply can't, as PySide2 and PyQt5 remove an argument from the function and a property from the object, therefore is not possible doing this on PySide and PyQt4, what this does, is to provide PySide2/Qt5 with this extra argument, so doesn't break, same for the property, which is now missing .

Out of curiosity, how would do the other way round ?

Marcus, I'm not being hasty just objective. #96 has been closed for good, and is fine for me, but either I get to use a module which allows me to do the work I need (and therefore I'm happy to contribute back) , or I better put my efforts on something separated (which is exactly what I did started doing yesterday eve):
https://bitbucket.org/efestolab/qtext, which simply use Qt.py as dependency ad does patch for what I need.

@mottosso
Copy link
Owner

In any case, Mr Google can help on this

I would very much rather see how you encounter this issue, and how a solution might help you. What I need is to be able to reproduce the problem and see that we're really solving something that needs solving. I expect this from every single issue and pull-request and I don't think it's too much to ask.

Tell me this, are you expecting a shim providing a PySide2 binding to work with a GUI generated for PySide(1)?

If so, may I direct you to #90 followed by #107? The problem being that the code produced by pyside-uic is for Qt 4, whereas this shim enables code written for Qt 5 to also run on Qt 4.

Alternatively, can you compile your UI files with the PySide2 or PyQt5 equivalent? This should work well on Qt 5, and whatever problems you have running this code on Qt 4 that's what we should be resolving here.

Until I see a reproducible example, this is a non-issue.

@mottosso
Copy link
Owner

Hi @hdd, I have got some time this weekend to dive into this.

If you could share a snippet of code that breaks for you without this fix, then I can have a look at making it work!

@salvaom
Copy link

salvaom commented Sep 7, 2016

Hello!

I believe that the problem encountered by @hdd is the same I've been having. I've uploaded a gist to illustrate: https://gist.github.com/salvaom/afe312982140c926c21005d822c0f116. widget_designer1.ui is created with Designer from PySide(1) and widget_designer2.ui with Qt Creator Community (Qt 5.6.1). I've compiled only the first one (since they are identical) with the pyside-uic(1) from PyPI and with Maya's (2017) pyside2uic.

I also have a thousand .ui files compiled for various applications and it's not a big deal to change all from PySdie ... to from Qt ..., but the UTF8 issue remains since the syntax varies from one PySide to another.

I think this subject was also mentioned in #129

@mottosso
Copy link
Owner

mottosso commented Sep 7, 2016

Hi @salvaom, thanks for this!

With #129 in mind, in addition to search-and-replacing PySide2 with Qt, do you think it would also make sense to replace calls made to QApplication.translate with our own version, for example Qt.translate?

That way we might be able to sidestep the issue of monkey patching the class.

@salvaom
Copy link

salvaom commented Sep 7, 2016

Hey @mottosso, I thought about that as well, but the problem still remains since PySide2 does not have QtWidgets.QApplication.UnicodeUTF8, so even if I were to change QtGui.QApplication.translate to Qt.translate, the code will still error on the last argument in files compiled with PySide(1).

The only solutions I can think of are either what @hdd has proposed or if there is no intention of monkey patching the module itself, having a variable called (for example) UnicodeUTF8 which in PySide is a reference to QtGui.QApplication.UnicodeUTF8 and on PySide2 just -1, this way it would be a matter of changing QtGui.QApplication.UnicodeUTF8 to Qt.UnicodeUTF8.

@mottosso
Copy link
Owner

mottosso commented Sep 7, 2016

Ah, I see.

How about this; in addition to search-and-replacing translate() with our own, we also remove this last argument?

>>> line = """self.label.setText(QtGui.QApplication.translate("uic", "Bienvenidos a Espa?a", None, QtGui.QApplication.UnicodeUTF8))"""
>>> new_line = line.replace("QtGui.QApplication.translate", "Qt.translate")
>>> new_line = new_line.replace(", QtGui.QApplication.UnicodeUTF8", "")
>>> print(new_line)
'self.label.setText(Qt.translate("uic", "Bienvenidos a Espa?a", None))'

@mottosso
Copy link
Owner

mottosso commented Sep 7, 2016

if there is no intention of monkey patching the module itself, having a variable called (for example) UnicodeUTF8 which in PySide is a reference to QtGui.QApplication.UnicodeUTF8 and on PySide2 just -1, this way it would be a matter of changing QtGui.QApplication.UnicodeUTF8 to Qt.UnicodeUTF8.

Sorry I just re-read this, yes! This sounds better!

This was referenced Sep 7, 2016
@mottosso
Copy link
Owner

mottosso commented Oct 3, 2016

With #131, this should be solved.

@salvaom, @hdd could you let me know whether this works for you?

@salvaom
Copy link

salvaom commented Oct 4, 2016

Hello!

Not quite, for what I'm seeing convert only supports .ui files compiled with PySide2 but the problem I (and I belive @hdd as well) was having was the thousand (approx) of .ui files compiled with PySide(1) I've got that I would like to have converted to Qt.py.

But even if we were to add another two conversion lines in the convert() function, the problem still remains since the QtGui.QApplication.translate does exists in both PySides with the same argument count but the variable QtGui.QApplication.UnicodeUTF8 doesn't in PySide2, which inevitably makes any .ui file compiled with PySide(1) fail, no matter the translate function that is being used.

I can make a pull request that includes the changes I think would be necessary to make Qt.py compatible with any PySide(*) compiled .ui file, let me know.

Just to better illustrate:

PySide

>>> import PySide
>>> PySide.__version__
'1.2.2'
>>> from PySide import QtGui
>>> QtGui.QApplication.translate('MyText', 'MyText', None, QtGui.QApplication.UnicodeUTF8)
u'MyText'
>>> import Qt
>>> Qt.__version__
'1.2.2'
>>> from Qt import QtWidgets
>>> QtWidgets.QApplication.translate('MyText', 'MyText', None, QtGui.QApplication.UnicodeUTF8)
u'MyText'
>>>

PySide2

>>> import PySide2
>>> PySide2.__version__
'2.0.0~alpha0'
>>> import Qt
>>> Qt.__version__
'2.0.0~alpha0'
>>> from PySide2 import QtWidgets
>>> QtWidgets.QApplication.translate('MyText', 'MyText', None, QtWidgets.QApplication.UnicodeUTF8)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'PySide2.QtWidgets.QApplication' has no attribute 'UnicodeUTF8'
>>> Qt.QtCompat.translate('MyText', 'MyText', None, QtWidgets.QApplication.UnicodeUTF8)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'PySide2.QtWidgets.QApplication' has no attribute 'UnicodeUTF8'
>>> QtWidgets.QApplication.translate('MyText', 'MyText', None, -1)
u'MyText'
>>>

So I think this is still the best option:

if there is no intention of monkey patching the module itself, having a variable called (for example) UnicodeUTF8 which in PySide is a reference to QtGui.QApplication.UnicodeUTF8 and on PySide2 just -1, this way it would be a matter of changing QtGui.QApplication.UnicodeUTF8 to Qt.UnicodeUTF8.

Or in any case to Qt.QtCompat.UnicodeUTF8

@mottosso
Copy link
Owner

mottosso commented Oct 4, 2016

Hey @salvaom,

thousand (approx) of .ui files

What about compiling them with PySide2?

All of your existing Qt Designer files should work well with Qt.py, given you compile them with PySide2, the reference binding.

I'd have a chat with @artbycrunk in #90 and #107 about joining the effort in making PySide(1) code run on other bindings, I can certainly see the demand for it. But personally, and with this project, the philosophy is to enable future code to run on older platforms, not the other way around.

It opens your code up to advances to Qt, whilst enabling you to transition smoothly across. Consider it?

@salvaom
Copy link

salvaom commented Oct 6, 2016

Hello!

I understand and share the philosophy, but even if I was to compile with PySide2 all files again, the problem remains since translate in PySide(1) accepts as a 4th argument only an instance of QCoreApplication::Encoding, which has only three possible values and -1 is not one of them, so as you can probably guess already, running a PySide2 compiled file with a PySide(1) environment yields an error:

>>> from Qt import QtWidgets
>>> QtWidgets.QApplication.translate('Foo', 'Foo', None, -1)

Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    QtWidgets.QApplication.translate('Foo', 'Foo', None, -1)
TypeError: 'PySide.QtCore.QCoreApplication.translate' called with wrong argument types:
  PySide.QtCore.QCoreApplication.translate(str, str, NoneType, int)
Supported signatures:
  PySide.QtCore.QCoreApplication.translate(str, str, str = None, PySide.QtCore.QCoreApplication.Encoding = CodecForTr)
  PySide.QtCore.QCoreApplication.translate(str, str, str, PySide.QtCore.QCoreApplication.Encoding, int)

I understand your concern, and if there is another way to skip this I'm open to try it out and embrace it, but so far this is the only way I can think of making this work for both PySide(1) and PySide2.

Please let me know what you think.

@mottosso
Copy link
Owner

mottosso commented Oct 6, 2016

the problem remains since translate in PySide(1) accepts as a 4th argument

Ah! Sorry, I should have made myself more clear. This has actually already been addressed in the fix above!

Qt.py ships with it's own translate that the conversion redirects the original calls to.

See here:

The result is a .py file with no calls to the original .translate.

I'd love for you to try compiling just one, and see whether that works for you. The goal is full compatibility with any and all Qt Designer files. If something isn't working right, then that's a bug and we'll need it squashed.

@mottosso
Copy link
Owner

If this remains an issue, feel free to re-open!

@mottosso mottosso closed this Nov 21, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants