Skip to content
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

Can't Get pynotepad Example to Run #11

Closed
jmwright opened this issue Nov 10, 2014 · 26 comments
Labels

Comments

@jmwright
Copy link

@jmwright jmwright commented Nov 10, 2014

I started with the pynotepad.py example to learn how to set up a Python editor. When I try to run the example per the readme.rst file I get the following error.

$ python pynotepad.py 
INFO:pyqode.qt:using pyqt4
Traceback (most recent call last):
  File "pynotepad.py", line 9, in <module>
    from pynotepad import main
  File "/home/jwright/Downloads/pyqode.python/examples/pynotepad/pynotepad/__init__.py", line 13, in <module>
    from .main_window import MainWindow
  File "/home/jwright/Downloads/pyqode.python/examples/pynotepad/pynotepad/main_window.py", line 17, in <module>
    from .forms.main_window_ui import Ui_MainWindow
  File "/home/jwright/Downloads/pyqode.python/examples/pynotepad/pynotepad/forms/main_window_ui.py", line 176, in <module>
    from pyqode.python.widgets.outline import PyOutlineTreeWidget
ImportError: No module named outline

I double checked to make sure that I had pyqode.python installed.
https://pypi.python.org/pypi?%3Aaction=search&term=pyqode&submit=search

Also, is there a more beginner level example/tutorial of implementing a Python editor with pyQode? Maybe this one is beginner level, but I thought I'd ask.

@ColinDuquesnoy

This comment has been minimized.

Copy link
Contributor

@ColinDuquesnoy ColinDuquesnoy commented Nov 10, 2014

The example is out of sync with the pyqode.python version released on pypi, PyOutlineTreeWidget is a new feature which has not been released yet. You can either use the example from the released version or install all pyqode packages from source checkout.

Also, is there a more beginner level example/tutorial of implementing a Python editor with pyQode? Maybe this one is beginner level, but I thought I'd ask.

Unfortunately no, not at the moment. Using pyqode.python is almost the same as using pyqode.core. The only differences is that you will use some additional modes/panels and pyqode.python.backend.server as the main backend script.

But I can easily write a simpler example if you need it. Also if there is anything to improve to the documentation, do not hesitate to open a new issue ;)

@jmwright

This comment has been minimized.

Copy link
Author

@jmwright jmwright commented Nov 10, 2014

Ok, thanks. I'll probably just install the latest version.

Regarding pyqode.python - Do I need to do extra modes and panels imports as a first step?

from pyqode.core import modes
from pyqode.core import panels
from pyqode.python import modes
from pyqode.python import panels

A simpler example would be helpful, but I can just work my way through adapting the Getting started example to being a Python editor. I'll let you know if I get that figured out.

ColinDuquesnoy added a commit to pyQode/pyqode.python that referenced this issue Nov 11, 2014
ColinDuquesnoy added a commit to pyQode/pyqode.python that referenced this issue Nov 11, 2014
@ColinDuquesnoy

This comment has been minimized.

Copy link
Contributor

@ColinDuquesnoy ColinDuquesnoy commented Nov 11, 2014

Hello,

I added some simpler examples:

  • basic: show you the basis for setting up a simple python code editor widget with code completion, folding, line number, syntax highlighting, ...
  • prefconfigured: show you how to use the pre-configured python editor (PyCodeEdit)

I will add more simpler examples for each mode/panel/widget during the next few days but those two examples should already help you to get started ;)

@ColinDuquesnoy

This comment has been minimized.

Copy link
Contributor

@ColinDuquesnoy ColinDuquesnoy commented Nov 11, 2014

I also fixed a few bugs with PySide and Python 2.7, you might need to upgrade pyqode.qt, pyqode.core and pyqode.python from source checkout.

@jmwright

This comment has been minimized.

Copy link
Author

@jmwright jmwright commented Nov 11, 2014

That's great, thank you for creating those.

I started with the preconfigured example since I thought it would be the simplest. The stand-alone example runs fine (after updating the packages mentioned above from Github), but when I incorporate it into the FreeCAD module I get the following error dialog.

screenshot from 2014-11-11 10 58 16

I tried to import logging inside the module, but that didn't help. I'll dig into this more later since it seems like an issue specific to using PyCodeEdit inside of FreeCAD, but if you have any ideas in the meantime, I'd be interested.

@ColinDuquesnoy

This comment has been minimized.

Copy link
Contributor

@ColinDuquesnoy ColinDuquesnoy commented Nov 11, 2014

pyQode makes extensive use of the logging module (which is in the standard library). I don't know anything about how FreeCad embeds the python interpreter but chances are that the logging module is not included. Maybe you you can try the following code into the freecad interpreter:

>>> import logging
>>> logging.basicConfig()
>>> logging.warning('Test')
WARNING:root:Test
>>> 
@jmwright

This comment has been minimized.

Copy link
Author

@jmwright jmwright commented Nov 11, 2014

Yep, that works fine in FreeCAD's Python Console. It must be an issue with the scope of the import, but I've tried importing logging everywhere that I can think of inside the module and it's not working. FreeCAD doesn't give a lot of debugging info unless it's compiled to do so. I'll keep digging on this and report back.

@jmwright

This comment has been minimized.

Copy link
Author

@jmwright jmwright commented Nov 11, 2014

Well, I got an idea quicker than I thought. I went hacking around in the FreeCAD Python Console to try to get a better view into what was going on.

Python 2.7.6 (default, Mar 22 2014, 23:03:41) 
[GCC 4.8.2] on linux2
Type 'help', 'copyright', 'credits' or 'license' for more information.
>>> import WebGui
>>> from StartPage import StartPage
>>> WebGui.openBrowserHTML(StartPage.handle(),'file://' + App.getResourceDir() + 'Mod/Start/StartPage/','Start page')
>>> from pyqode.python.widgets import PyCodeEdit
>>> mw = Gui.getMainWindow()
>>> dockWidgets = mw.findChildren(QtGui.QDockWidget)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'QtGui' is not defined
>>> from PySide import QtGui
>>> dockWidgets = mw.findChildren(QtGui.QDockWidget)
>>> cqCodeWidget = QtGui.QDockWidget("CadQuery Code View")
>>> cqCodeWidget.setObjectName("cqCodeView")
>>> mw.addDockWidget(QtCore.Qt.LeftDockWidgetArea, cqCodeWidget)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'QtCore' is not defined
>>> from PySide import QtCore
>>> mw.addDockWidget(QtCore.Qt.LeftDockWidgetArea, cqCodeWidget)
>>> codePane = PyCodeEdit(server_script=server.__file__)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'server' is not defined
>>> from pyqode.python.backend import server
>>> codePane = PyCodeEdit(server_script=server.__file__)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pyqode/python/widgets/code_edit.py", line 60, in __init__
    self.panels.append(panels.EncodingPanel(), api.Panel.Position.TOP)
  File "/usr/local/lib/python2.7/dist-packages/pyqode/core/panels/encodings.py", line 98, in __init__
    self.ui.setupUi(self)
  File "/usr/local/lib/python2.7/dist-packages/pyqode/core/_forms/pnl_encoding_ui.py", line 34, in setupUi
    self.comboBoxEncodings = EncodingsComboBox(Form)
  File "/usr/local/lib/python2.7/dist-packages/pyqode/core/widgets/encodings.py", line 40, in __init__
    self._refresh_items()
  File "/usr/local/lib/python2.7/dist-packages/pyqode/core/widgets/encodings.py", line 61, in _refresh_items
    _logger().debug('KeyError with encoding:', encoding)
  File "/usr/local/lib/python2.7/dist-packages/pyqode/core/widgets/encodings.py", line 11, in _logger
    return logging.getLogger(__name__)
NameError: global name 'logging' is not defined

It's complaining because of encodings.py. I'm almost out of time to work on this for now, but I wanted to post my findings.

Thanks for all the help.

@jmwright

This comment has been minimized.

Copy link
Author

@jmwright jmwright commented Nov 12, 2014

I manually edited /usr/local/lib/python2.7/dist-packages/pyqode/core/widgets/encodings.py to add import logging to the top and this error went away. I'm guessing that the code shouldn't need that though, or it would already have been there.

When I instantiate PyCodeEdit, and new instance of FreeCAD starts up, I assume this is an artifact of starting the pyQode server up. I'll have to figure out how to get around that once we've figured out the logging import issue.

ColinDuquesnoy added a commit to pyQode/pyqode.core that referenced this issue Nov 12, 2014
@ColinDuquesnoy

This comment has been minimized.

Copy link
Contributor

@ColinDuquesnoy ColinDuquesnoy commented Nov 12, 2014

I manually edited /usr/local/lib/python2.7/dist-packages/pyqode/core/widgets/encodings.py to add import logging to the top and this error went away. I'm guessing that the code shouldn't need that though, or it would already have been there.

Nice finding! Actually it has to be there, I probably introduced this bug with the latest refactoring. What I don't understand is that there is a KeyError with one encoding that triggers the call to logging. This does not happen for me that's why I have not seen this error sooner. May I ask you to run the following code snippet in the freecad interpreter and paste the output here?

[colin@KaOS ~]$ python
Python 2.7.8 (default, Aug 26 2014, 20:44:45) 
[GCC 4.8.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyqode.core.cache import Cache
>>> Cache().preferred_encodings
[u'cp1252', u'utf_8']
>>> 

When I instantiate PyCodeEdit, and new instance of FreeCAD starts up, I assume this is an artifact of starting the pyQode server up. I'll have to figure out how to get around that once we've figured out the logging import issue.

There is a second parameter for the server script (interpreter) which takes the path to the python interpreter to use to run the backend and which defaults to sys.executable. I guess that sys.executable points to the FreeCad main executable:

editor = PyCodeEdit(server_script=server.__file__, interpreter='/usr/bin/python2.7')
@jmwright

This comment has been minimized.

Copy link
Author

@jmwright jmwright commented Nov 12, 2014

Here's what I got using Cache inside the FreeCAD Python Console.

>>> from pyqode.core.cache import Cache
>>> Cache().preferred_encodings
[u'ansi_x3.4_1968']

Adding the interpreter parameter fixed the problem and the pyQode widget seems to work fine now. I checked, and you are correct about sys.executable.

>>> import sys
>>> print sys.executable
/usr/bin/freecad

I might be able to figure the path out from:

import os
os.__file__

But it will take some work to make it cross-platform. I'll dig into whether FreeCAD has some built in method for telling what the Python executable path is.

@ColinDuquesnoy

This comment has been minimized.

Copy link
Contributor

@ColinDuquesnoy ColinDuquesnoy commented Nov 12, 2014

[u'ansi_x3.4_1968']

Interesting, this encoding is not in the ENCODINGS map (which has been established based on this documentation: https://docs.python.org/3.4/library/codecs.html#standard-encodings). This explains the bug and this also explains why I haven't seen that error sooner ;) I guess that encoding is just a variant of ASCII.

@jmwright

This comment has been minimized.

Copy link
Author

@jmwright jmwright commented Nov 12, 2014

Hmmm...interesting, I wonder why they would use that encoding over the others they could have chosen.

Do you have everything you need on this? It sounds like the logging import should fix it, but if there's something else I need to try, let me know.

@ColinDuquesnoy

This comment has been minimized.

Copy link
Contributor

@ColinDuquesnoy ColinDuquesnoy commented Nov 12, 2014

Yes I have everything I need, thanks!

ColinDuquesnoy added a commit to pyQode/pyqode.core that referenced this issue Nov 12, 2014
@ColinDuquesnoy

This comment has been minimized.

Copy link
Contributor

@ColinDuquesnoy ColinDuquesnoy commented Nov 12, 2014

I have fixed this strange encoding issue by applying some additional aliases. Please upgrade your installation from the latest source checkout

ColinDuquesnoy added a commit to pyQode/pyqode.core that referenced this issue Nov 12, 2014
Cleanup
@jmwright

This comment has been minimized.

Copy link
Author

@jmwright jmwright commented Nov 12, 2014

Done. Thanks.

@DrRob

This comment has been minimized.

Copy link

@DrRob DrRob commented Dec 7, 2014

Hello,

On my Mac, locale.getpreferredencoding() (in Cache.preferred_encodings() in pyqode/core/cache.py, embedded into jmwright's cadquery-freecad-module, used with FreeCAD 0.14) returns None.

I tried to fix it by borrowing some code from the end of this thread:
http://stackoverflow.com/questions/492483/setting-the-correct-encoding-when-piping-stdout-in-python

but the fifth time that preferred_encodings() is called (during cadquery-freecad-module startup), the value is None again, and I can't work out where that call is coming from.

Any suggestions?

Rob.

@ColinDuquesnoy

This comment has been minimized.

Copy link
Contributor

@ColinDuquesnoy ColinDuquesnoy commented Dec 7, 2014

Strange issue, does it only happen within freecad or do you have the same results when using a regular interpreter?

On my mac, locale.getpreferredencoding() return UTF-8:

Python 2.7.6 (default, Sep  9 2014, 15:04:36) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.getpreferredencoding()
'UTF-8'
>>> 
@ColinDuquesnoy

This comment has been minimized.

Copy link
Contributor

@ColinDuquesnoy ColinDuquesnoy commented Dec 7, 2014

Also what did you try exactly (from the SO thread)?

@DrRob

This comment has been minimized.

Copy link

@DrRob DrRob commented Dec 7, 2014

It seems that it only affects the python that's embedded in FreeCAD - both the command-line versions I have (one that came with Mac OS X, and one installed via "brew") return "UTF-8".

Here's what I did based on the SO thread - I added a getpreferredencoding method to the Cache class:

def getpreferredencoding(self):
    import sys

    enc = None
    try:
        enc = locale.getpreferredencoding()
    except:
        pass
    if enc is None:
        try:
            enc = sys.getfilesystemencoding()
        except:
            pass
    if enc is None:
        try:
            enc = sys.stdin.encoding
        except:
            pass
    if enc is None:
        enc = 'UTF-8'
    return enc

then changed preferred_encodings to use it:

@property
def preferred_encodings(self):
    """
    The list of user defined encodings, for display in the encodings
    menu/combobox.

    """
    from pyqode.core.api import encodings
    return json.loads(self._settings.value(
        'userDefinedEncodings', '["%s"]' % encodings.convert_to_codec_key(
            self.getpreferredencoding())))

The convert_to_codec_key() function then gets called during startup three times with value="utf-8", then once with "UTF-8", then with None. I tried using the traceback module to see where that last call came from only the last entry on the stack is shown (the line that tries to call value.replace(), and fails because value is None).

If I hack it by forcing value to be "utf_8" in convert_to_codec_key() then the CADQuery Workbench starts up ok.

@ColinDuquesnoy

This comment has been minimized.

Copy link
Contributor

@ColinDuquesnoy ColinDuquesnoy commented Dec 7, 2014

Hmm I have no idea where this None value come from. Anyway convert_to_codec_key should definitely check for None or empty values.

@ColinDuquesnoy

This comment has been minimized.

Copy link
Contributor

@ColinDuquesnoy ColinDuquesnoy commented Dec 7, 2014

@jmwright I've fixed this issue in that commit

@jmwright

This comment has been minimized.

Copy link
Author

@jmwright jmwright commented Dec 7, 2014

Awesome guys, thanks.

Does convert_to_codec_key use a default value now if it sees None?

I'll get this commit merged into the module as soon as I can.

@ColinDuquesnoy

This comment has been minimized.

Copy link
Contributor

@ColinDuquesnoy ColinDuquesnoy commented Dec 7, 2014

Does convert_to_codec_key use a default value now if it sees None?

Yes it falls back to UTF-8.

@jmwright

This comment has been minimized.

Copy link
Author

@jmwright jmwright commented Dec 7, 2014

I've incorporated this fix into commit 123c2b439c626c7c764ef332430b7657b9bb60c9

@DrRob and @ColinDuquesnoy - Please try the latest version of the module out and let me know if it's fixed the issue.

@DrRob

This comment has been minimized.

Copy link

@DrRob DrRob commented Dec 8, 2014

Fixed, thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.