Skip to content

Handle Enum when making QVariant #1

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

Conversation

f03el
Copy link

@f03el f03el commented Jun 26, 2019

Moved here from https://sourceforge.net/p/pythonqt/discussion/631392/thread/bf34b51907/

Background

When running some Python code from PythonQt the other day, I got a segfault in PythonQtConversion.cpp. It turned out that when an Enum based class is processed by PyObjToQVariant, it's recognised as a sequence (since it's possible to iterate over an Enum in Python), but PySequence_GetItem returns nullptr when the loop gets the value to add to the QVariantList, causing the segfault when calling PyObjToVariant with a null pointer. Unless Enums should be treated in a special way, I assume that the best is to handle them as "normal" classes. In order to do that I created a small patch that checks if val->ob_type->tp_name is "EnumMeta". I'm not sure if this is an acceptable solution, so I'm open for better ways to fix it.

Python 2.7 (with enum34 installed) and 3.6 behave the same.

Files

Supplied files:

enumtest.zip:

  • pythonqt_run_enum_test.cpp: Minimal application that shows the problem
  • enumtest.py: Python module with an Enum for use with the test program

Minimal example

Building

Building the test application (very manual – I ran this on Xubuntu 18.10):

g++ -fPIC -c `pkg-config --cflags Qt5Core python-3.6 PythonQt-Qt5-Python3` -o pythonqt_run_enum_test.o pythonqt_run_enum_test.cpp
g++ -o pythonqt_run_enum_test pythonqt_run_enum_test.o `pkg-config --libs Qt5Core python-3.6 PythonQt-Qt5-Python3`
./pythonqt_run_enum_test

Expected output

Without the patch, there is a segfault when running the minimal example. With the patch applied, it outputs this:

QVariant(QVariantList, (QVariant(QVariantList, (QVariant(QString, "Color"), QVariant(PythonQtObjectPtr, ))), QVariant(QVariantList, (QVariant(QString, "Enum"), QVariant(PythonQtObjectPtr, )))))

Links regarding Enum

Distinguish Enums from normal PySequences when converting to QVariant.
@florianlink
Copy link
Collaborator

I think the string compare is not a good idea. It costs performance and will also match a user's class that is called EnumMeta.
Instead do the following:

  • import "enum" from Python in PythonQtPrivate
  • get the type object of EnumMeta and store it in PythonQtPrivate
  • add a isEnumMetaType() method to PythonQtPrivate
  • use that method instead of the string compare in the QVariant conversion

@f03el
Copy link
Author

f03el commented Jun 27, 2019

@florianlink Thanks for your input! I agree that a string comparison like that not feels great. I'm not sure though how to do what you suggested, so it might take some time to do. Did you have any special method in mind how to import "enum"?

@florianlink
Copy link
Collaborator

florianlink commented Jun 27, 2019 via email

@florianlink
Copy link
Collaborator

Current state is not acceptable, closing.

@florianlink florianlink closed this Aug 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants