Git Product home page Git Product logo

Comments (14)

lruzicka avatar lruzicka commented on July 26, 2024

This issue prevents Frescobaldi from starting on Fedora 37. That is a serious problem for all Fedora Frescobaldi users.

from frescobaldi.

jeanas avatar jeanas commented on July 26, 2024

If I do print(ev) at that point, I get

TypeError: a member of enum 'StandardKey' is expected not 'QEvent'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/jean/repos/frescobaldi/frescobaldi_app/view.py", line 107, in event
    print(type(ev))
          ^^^^^^^^
SystemError: <class 'type'> returned a result with an exception set
TypeError: a member of enum 'StandardKey' is expected not 'QEvent'

Which points to a problem in the C++ bindings Frescobaldi uses. Unfortunately, I have no clue how to debug this.

Meanwhile, the Flatpak package works just fine.

from frescobaldi.

jeanas avatar jeanas commented on July 26, 2024

Maybe this warning is something we want to pay attention to:

QSocketNotifier: Can only be used with threads started with QThread

from frescobaldi.

jeanas avatar jeanas commented on July 26, 2024

This is quite strange. If I do

diff --git a/frescobaldi_app/view.py b/frescobaldi_app/view.py
index 245847b2..46270731 100644
--- a/frescobaldi_app/view.py
+++ b/frescobaldi_app/view.py
@@ -94,6 +94,9 @@ class View(QPlainTextEdit):
         - handle Tab and Backtab to change the indent
 
         """
+        print(ev)
+        print(type(ev))
+        return super().event(ev)
         if ev in (
                 # avoid the line separator, makes no sense in plain text
                 QKeySequence.InsertLineSeparator,

I get Frescobaldi opening, and working about as usual, with the exception of the things this function implements, like the fact that pressing Tab when text is selected doesn't replace that text with a tab but increase the indentation of that text. The console prints lots of output from the print() calls, which looks like this:

<PyQt5.QtCore.QEvent object at 0x7f7f7882dfc0>
<class 'PyQt5.QtCore.QEvent'>
<PyQt5.QtCore.QEvent object at 0x7f7f7882e050>
<class 'PyQt5.QtCore.QEvent'>
<PyQt5.QtCore.QEvent object at 0x7f7f7882e050>
<class 'PyQt5.QtCore.QEvent'>
<PyQt5.QtCore.QChildEvent object at 0x7f7f7882e0e0>
<class 'PyQt5.QtCore.QChildEvent'>
<PyQt5.QtCore.QEvent object at 0x7f7f7882e170>
<class 'PyQt5.QtCore.QEvent'>
<PyQt5.QtCore.QEvent object at 0x7f7f7882e170>
<class 'PyQt5.QtCore.QEvent'>
<PyQt5.QtCore.QEvent object at 0x7f7f7882e170>
<class 'PyQt5.QtCore.QEvent'>
<PyQt5.QtCore.QChildEvent object at 0x7f7f7882e170>
<class 'PyQt5.QtCore.QChildEvent'>
<PyQt5.QtCore.QChildEvent object at 0x7f7f7882e170>

Seems expected.

However, as soon as I try to use ev later, the error pops up.

Meanwhile, at least we know that it's possible to get a version of Frescobaldi that roughly works.

from frescobaldi.

jeanas avatar jeanas commented on July 26, 2024

I think the error location given by the Python interpreter is misleading. While experimenting, I got some errors pointing to lines like print("here"). My understanding is that the problem lies in the code

        if ev in (
                # avoid the line separator, makes no sense in plain text
                QKeySequence.InsertLineSeparator,
                # those can better be called via the menu actions, then they
                # work better
                QKeySequence.Undo,
                QKeySequence.Redo,
            ):
            return False

Which is just before the line if ev.type() == QEvent.KeyPress:. If I remove this bit of code, Frescobaldi works just fine.

ev is an object of type QEvent, while the attributes of QKeySequence are instances of a custom int subclass defined in PyQt, so it seems to me that this condition could never be true. Nevertheless, it seems to raise an error because of the different types. That's quite strange because comparing Python values of different, unrelated types is normally supposed to return False, not to raise an exception. I can reproduce this outside of Frescobaldi and it looks quite abnormal to me, I'll soon ask about this on the PyQt5 mailing list.

Meanwhile, @limburgher I suggest to patch Frescobaldi for Fedora 37 by removing this if block. I'm pretty sure this is the right thing to do. I want to investigate a bit more before submitting it as PR here, but since the release of Fedora 37 is imminent and the Frescobaldi maintainer is currently unresponsive anyway, there's little chance a PR can be merged before F37 gets released.

from frescobaldi.

jeanas avatar jeanas commented on July 26, 2024

Question asked at https://www.riverbankcomputing.com/pipermail/pyqt/2022-October/045001.html

from frescobaldi.

lruzicka avatar lruzicka commented on July 26, 2024

I can confirm that the fix proposed by @jean-abou-samra works for me and when I comment out the piece of code, Frescobaldi starts again on Python 3.11 and Fedora 37.

Thank you, Jean, for having investigated it.

from frescobaldi.

limburgher avatar limburgher commented on July 26, 2024

Will do, thank you!

from frescobaldi.

jeanas avatar jeanas commented on July 26, 2024

Unfortunately, there seem to be other instances of this bug in some places, although not severe as preventing startup altogether. My Frescobaldi is now about functional, but if I press Control-F (for searching), I get

Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/frescobaldi_app/plugin.py", line 79, in instance
    return _instances[cls][obj]
           ~~~~~~~~~~^^^^^
  File "/usr/lib64/python3.11/weakref.py", line 415, in __getitem__
    return self.data[ref(key)]
           ~~~~~~~~~^^^^^^^^^^
KeyError: <weakref at 0x7fefcfc6e3e0; to 'sip.wrappertype' at 0x562f54d62bb0 (Search)>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/frescobaldi_app/search/__init__.py", line 364, in event
    elif ev.type() == QEvent.KeyPress:
         ^^^^^^^
TypeError: a member of enum 'StandardKey' is expected not 'QEvent'

from frescobaldi.

jeanas avatar jeanas commented on July 26, 2024
$ git grep "\bev =="
frescobaldi_app/editinplace.py:191:        if ev == QKeySequence.InsertLineSeparator:
frescobaldi_app/gadgets/cursorkeys.py:90:        home = ev == QKeySequence.MoveToStartOfLine
frescobaldi_app/gadgets/cursorkeys.py:91:        s_home = ev == QKeySequence.SelectStartOfLine
frescobaldi_app/gadgets/cursorkeys.py:112:        if ev == QKeySequence.MoveToNextChar or ev == QKeySequence.SelectNextChar:
frescobaldi_app/gadgets/cursorkeys.py:114:        elif ev == QKeySequence.MoveToPreviousChar or ev == QKeySequence.SelectPreviousChar:
frescobaldi_app/gadgets/cursorkeys.py:127:        if ev == QKeySequence.MoveToPreviousLine or ev == QKeySequence.MoveToPreviousPage:
frescobaldi_app/gadgets/cursorkeys.py:134:        elif ev == QKeySequence.SelectPreviousLine or ev == QKeySequence.SelectPreviousPage:
frescobaldi_app/gadgets/cursorkeys.py:141:        elif ev == QKeySequence.MoveToNextLine or ev == QKeySequence.MoveToNextPage:
frescobaldi_app/gadgets/cursorkeys.py:148:        elif ev == QKeySequence.SelectNextLine or ev == QKeySequence.SelectNextPage:
frescobaldi_app/gadgets/wordboundary.py:191:        if ev == QKeySequence.DeleteEndOfWord:
frescobaldi_app/gadgets/wordboundary.py:194:        elif ev == QKeySequence.DeleteStartOfWord:
frescobaldi_app/gadgets/wordboundary.py:197:        elif ev == QKeySequence.MoveToNextWord:
frescobaldi_app/gadgets/wordboundary.py:200:        elif ev == QKeySequence.MoveToPreviousWord:
frescobaldi_app/gadgets/wordboundary.py:203:        elif ev == QKeySequence.SelectNextWord:
frescobaldi_app/gadgets/wordboundary.py:206:        elif ev == QKeySequence.SelectPreviousWord:
frescobaldi_app/search/__init__.py:360:        if ev == QKeySequence.HelpContents:

Makes me wonder if these comparisons maybe were supported in past versions of PyQt. Because all of these now can't return True, but can cause exceptions.

from frescobaldi.

dexgs avatar dexgs commented on July 26, 2024

I think it's possible that these comparisons were always incorrect, but they're only now throwing a type error, i.e. it might be safe to remove all the if branches where the conditional is a comparison between QEvent and QKeySequence.

The QKeySequence enum doesn't seem inherit from QEvent's Type enum at all, but I didn't look through PyQt's history to see if that's always been the case.

Of course I'm not very familiar with PyQt nor Frescobaldi's codebase and could be completely wrong, so please take the above with a grain of salt.

from frescobaldi.

jeanas avatar jeanas commented on July 26, 2024

#1480 works for me, but I need some help to understand if it's the right thing to do (@PeterBjuhr @fedelibre @dliessi @wbsoft).

from frescobaldi.

mr-bronson avatar mr-bronson commented on July 26, 2024

This one has me kind of discouraged. We're apparently dealing with bugs in Qt or PyQt5 or Python with the result that the error messages we get are unreliable. Like jeanas reported

While experimenting, I got some errors pointing to lines like print("here").

He also got an error with Ctrl+F. I got an error with Ctrl+F, but it's a different one and totally bogus.

/path/to/frescobaldi/frescobaldi_app/search/__init__.py", line 364, in event
    elif ev.type() == QEvent.KeyPress:
AttributeError: 'QChildEvent' object has no attribute 'type'

A QChildEvent inherits its type method from QEvent; there's no good reason or conceivable way it should be missing.

While trying to hunt down the differences between two branches that might lead to this error, I found really stupid stuff, like:

  1. I seem to need to clear out my __pycache__ directories before every run just to ensure that the difference I'm seeing is coming from a change in the code I just made. Even then, I only have about 95% confidence because I'm sure at least once I got a failure to reproduce the error on the same exact code that usually produces the error and with my caches as clear as I know how.

  2. The difference between reproducing and not reproducing could depend on something as simple but counterintuitive as:

if somefunc().somemethod()...

vs

val = somefunc()
if val.somemethod()...

It could also depend on whether certain modules were imported. You didn't even have to do anything with the module; just import it and the error magically went away.

But while doing that, I also got it to report a different bogus error:

/path/to/frescobaldi/frescobaldi_app/view.py", line 107, in event
    if ev.type() == QEvent.KeyPress:
AttributeError: 'QHoverEvent' object has no attribute 'type'

Once again, there's no way a QHoverEvent doesn't have a type method, which it would inherit from QEvent. This one came up just by starting the program; I didn't even need to press Ctrl+F. And every time I moved the mouse, it came back. That's better than the Ctrl+F bug, because at least I can click Cancel and Alt+F4. The other one persists infinitely, meaning I have to force close it from the terminal. Also, this one is considerably more shy. Other than the first run, I have not been able to reproduce it, even with identical code and running method and even trying starting with my mouse cursor in different positions in case that matters.

I've always been a little bothered by how easy it is to get a SegFault using Qt, or sometimes also get in a spin-loop with the same code just by doing something somewhat unexpected or not how Qt or PyQt5 intended itself to be used. If you know exactly what you're doing that leads to such things, you can at least avoid doing that. But when you have a fairly significant codebase, and you get bogus error messages, it could be anywhere and anything and maybe not be anything you're doing "wrong".

Sigh.

from frescobaldi.

jeanas avatar jeanas commented on July 26, 2024

Apparently, this was eventually recognized to be a sip bug. See https://www.riverbankcomputing.com/pipermail/pyqt/2023-February/045172.html

from frescobaldi.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.