Embedded Python loads module but does not load that module's internal import statements - boost

At long last(!) I've compiled Boost::Python and have gotten my XCode project to import a local module. This module starts with the line from xml.dom import minidom, but when it executes, I'm given this error:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "FeedStore.py", line 1, in <module>
from xml.dom import minidom
ImportError: No module named xml.dom
However, I know that I've installed the xml Python module -- when I open Python from my command prompt and type from xml.dom import minidom, everything goes smoothly. Moreover, when I import the module, it behaves as I would expect.
I suspected that there was something wrong with sys.path, so I compared the one I get from the prompt to the one that's being used in my embedded module. The only difference is that the embedded sys.path does not include ''. I've tried appending it, but that didn't change the behavior.
I also suspected that the embedded version was accessing a different version of Python than I was using from the prompt, but sys.prefix matched between both executions.
Here's the code that imports my module and runs it. It's pretty bare-bones at the moment (not even reference counting yet) because at this point I'd just like to make sure I'll be able to embed my module (I'm a total newbie C++ programmer).
Py_Initialize();
//PyRun_SimpleString("import sys");
//PyRun_SimpleString("sys.path.append('')"); //tried this to no avail!
PySys_SetPath("/Users/timoooo/Documents/Code/TestEmbed/"); //this allows me to import my local module
PyRun_SimpleString("import FeedStore as fs"); //here's where it whines about the lack of xml.dom
PyRun_SimpleString("store = fs.feedStore()");
PyRun_SimpleString("print store.next()");
Py_Finalize();
I'm probably misunderstanding something essential about boost::python. Can anyone help me out?

Despite having identical sys.path values, calling
PyRun_SimpleString("sys.path.append(\"<<path>>\")");
with the places I needed fixed the problem.

Related

How to import python script using ROS and unittest

I'm facing an issue in a ROS (Python 2.7) project.
Strucure
I'm working on a ROS project. The structure is the following:
probable-adventure
|
|-catkin_ws
|-src
|-ros_rover
|-include
|-launch
|-msg
|-__init__.py
|-Commands.msg
|-Teleoperation.msg
|-scripts
|-__init__.py
|-keyboard.py
|-test
|-__init__.py
|-testing.py
|-__init__.py
|-CMakeLists.txt
|-package.xml
Keyboard node (secondary problem)
keyboard.py starts as follows:
#!/usr/bin/env python
import rospy
from ros_rover.msg import Teleoperation
I describe it as a secondary problem because if I compile the project from catkin_ws directory using catkin_make command, everything works well and I can run the keyboard ROS node perfectly even though I get a pylint error in the from ros_rover.msg ... line.
Unable to import 'ros_rover.msg'
Main Problem
I just wrote the previous as context. The point is that I have to test the code within the scripts directory. I'm using unittest and I create python files in test directory.
I have create the following simple test (testing.py):
#!/usr/bin/env python
import unittest
from scripts.keyboard import GetKey
class TestBareBones(unittest.TestCase):
def test_one_equals_one(self):
self.assertEquals(1, 1, "1!=1")
if __name__ == '__main__':
unittest.main()
I think I have a problem with the imports because if I run the following python commands (from the ros_rover directory):
user#dubuntu:~/probable-adventure/catkin_ws/src/ros_rover$ python testing.py
user#dubuntu:~/probable-adventure/catkin_ws/src/ros_rover$ python -m testing
I get the following error:
File "/home/diego/Documents/probable-adventure/catkin_ws/src/ros_rover/test/prueba.py", line 5, in <module>
from scripts.keyboard import GetKey
File "scripts/keyboard.py", line 14, in <module>
from ros_rover.msg import Teleoperation
ImportError: No module named ros_rover.msg
My thought
I think the problem is related with imports because I have read that python imports depends on the directory from where you run the python command.
I run the test from ros_rover directory because the test's import is scripts.keyboard so it can found it (scripts is in ros_rover). But when the keyboard.py tries to import ros_rover.msg fails because I'm already in ros_rover directory and cannot find ros_rover.
I have read a lot here in StackOverflow and out of it but I didn't find a solution (I have added a empty __init__.py file to ros_rover, scripts and test directories).

Can future's absolute_import clear __package__? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have a Python 2 Pyramid App that is setup using buildout and a project folder activated using Mr.Developer; I am trying to futurize this project as part of Python 3 migration which changes:
import test
to:
from __future__ import absolute_import
from . import test
However for some reason ./bin/pserve development.ini doesn't come up, it says:
...
File "/apps/src/project/engine/config.py", line 3, in <module>
import utilities
File "/apps/src/project/engine/utilities.py", line 9, in <module>
from project.engine import spreadsheets
File "/apps/src/project/engine/spreadsheets.py", line 16, in <module>
from project.engine import utilities
ImportError: cannot import name utilities
It is a proper package as far as I am aware because it does have a setup.py and I ran develop activate project + buildout again.
If I type print(__package__) in that code it prints fine, but if I add a line from __future__ import absolute_import it prints None. Is it possible that future's absolute_import can simply clears out the __package__ variable and that is why it is not detecting this as a package?
This is the MWE of the real issue: Why does this circular import fail in Python 2 but not in Python 3?, it seems to be a bug in Python 2 when there is circular import. If anyone has a clean solution please let me know.
When __package__ is set to None, that's just a flag value for not yet set. It is not a problem.
From PEP 366 – Main module explicit relative imports, on the subject of __package__:
When the import system encounters an explicit relative import in a module without __package__ set (or with it set to None), it will calculate and store the correct value (__name__.rpartition('.')[0] for normal modules and __name__ for package initialisation modules). If __package__ has already been set then the import system will use it in preference to recalculating the package name from the __name__ and __path__ attributes.
If you see this set to None in the main module and it was meant to be part of a package, then set it yourself:
if __name__ == "__main__" and __package__ is None:
__package__ = "foo.bar.baz"

sphinx autodoc creates blank page on readthedocs, but correctly includes module docstring locally

I'm getting different results from autodoc when I run sphinx locally (versions 1.6.6 or 2.0.1 on Anaconda Python 3.6.8 for Mac) than when I run it on readthedocs.org (according to their log it's Sphinx version 1.8.5, and probably Python 2.7 since it's launched with python rather than python3).
The difference is in the results from the following file, Shady.Text.rst, which contains no more than:
Shady.Text Sub-module
=====================
.. automodule:: Shady.Text
Now, this sub-module happens to contain only a module-level docstring and no member docstrings—that's as intended, so the corresponding html page should contain the module docstring and no more. And this is exactly what happens when I run make html locally. However the result at https://shady.readthedocs.io/en/latest/source/Shady.Text.html is content-free (header only, no module docstring).
FWIW my autodoc-related entries in conf.py are:
autoclass_content = 'both'
autodoc_member_order = 'groupwise'
What am I doing wrong?
Thanks #StevePiercy for drawing my attention to the crucial lines in the raw log file:
WARNING: autodoc: failed to import module u'Text' from module u'Shady'; the module executes module level statement and it might call sys.exit().
WARNING: autodoc: failed to import module u'Video' from module u'Shady'; the module executes module level statement and it might call sys.exit().
(I had searched the 9000-line log file for .Text, because Text on its creates too many hits, but it hadn't occurred to me to search it for 'Text' in quotes).
To me, the message is misleading: the problem is not that "the module executes module level statements" because that per se is allowed. I wasted some time after noting that some module-level statements seemed to be allowed in other sub-modules, and tried to bundle the offending module-level statements into a class decorator thinking maybe sphinx's mysterious module-level-statement-detector would miss them then...)
No, the problem is that not the fact that the module-level statements exist and might call sys.exit(), but the fact that they did indirectly call sys.exit() during sphinx's compilation procedure. This was a quirk of the way I handle missing dependencies, which should probably be re-thought, but I could work around it for now by avoiding my sys.exit() call when os.environ.get('READTHEDOCS') is truthy.

AttributeError: 'module' object has no attribute 'testmod' Python doctest

When ever I try to doctest in python, basically whenever I run the code
if __name__ =="__main__":
import doctest
doctest.testmod()
I get this response from the interpreter
AttributeError: 'module' object has no attribute 'testmod'
I can run this code just fine, but whenever I run it on my windows machine, it doesn't work.
My machine is running Windows theirs is OS X, but are running python 2.7.5.
Thank you :)
Make sure that you are not trying to save your test file as doctest.py. The print statement suggested above will show it. If the file name is doctest.py, then rename it and try again.
AttributeError: 'module' object has no attribute 'testmod'
Clearly stats that the doctest module you're importing do not has the testmod() method.
Possible reasons can be:
You have more than one doctest modules in the lib.
and, it is the other one (without the testmod() method) which is getting imported as result of import doctest.
Solution: Look for the path of standard doctest module.
if __name__ =="__main__":
import doctest
if doctest.__file__ == "/path/to/standard/doctest-module":
doctest.testmod()
It looks like there is a different module called doctest that is being imported instead of the standard one.
To find out which module is being imported exactly, simply add the following print:
if __name__ =="__main__":
import doctest
print doctest.__file__ # add this
doctest.testmod()
The print should produce something similar to C:\Python27\lib\doctest.pyc, depending on the location and version of Python you're using. Any other output means you are importing the wrong module, and explain why you're getting the error.

How can I include ui and image files while using py2exe?

I am working on a project using Python 2.7 and PySide 1.1.2. My code is working without any problem on my GNU/Linux but I want to distribute for Windows ( 7 and 8 ) as well. I can't expect users to install Python and PySide, so I decided to use py2exe (I also tried cx_freeze and pyinstaller).
First of all, here is my file tree: My Project on GitHub
I created a setup.py, here it is:
# -*- coding: utf-8 -*-
from distutils.core import setup
import py2exe
setup(
console=['bin/metusuite.py'],
name='metusuite',
version='0.1',
author='H. Gökhan Sarı',
author_email='me#th0th.me',
packages=['metusuite_libs'],
package_dir={'metusuite_libs': 'metusuite_libs'},
package_data={'metusuite_libs': ['ui/*', 'images/*']},
scripts=['bin/metusuite.py'],
url='https://github.com/th0th/metusuite/',
license='LICENSE.txt',
description='METU Suite.',
long_description=open('README.md').read(),
)
When I run
setup.py py2exe
it successfully builds metusuite.exe in 'dist' folder, however, since application depends on external user interface files -created with Qt Designer- and it can't find them, I get an error:
Designer: An error has occurred while reading the UI file at line 1, column 0: Premature end of document.
Traceback (most recent call last):
File "metusuite.py", line 38, in <module>
File "metusuite_libs\msCafeteriaMenu.pyc", line 37, in __init__
File "metusuite_libs\msCafeteriaMenu.pyc", line 17, in __init__
RuntimeError: Unable to open/read ui device
And I couldn't figure out how am I supposed to add *.ui files (also there are some .png icons) into that structure. I was thinking of converting .ui files to Python code, then I would have encounter same issue when I need to add some icons.
Hence, how can I add my ui and png files in py2exe structure? Or is there any alternative method for what I am trying to accomplish?
Well, I think you could do one of two realistic things:
Compile your .ui files to .py files using pyside-uic and modify your code to do conditional loading of the py files for the user interface and place the png files in a Qt Resource file
Create a Qt Resource file with your ui files inside of it, compile that with pyside-rcc, and then load the ui files using QtUiTools or some similar process
pyside-uic
I greatly prefer using the pyside-uic method for loading ui files because it is the most straightforward way of loading ui files into a program that correlates with my knowledge of Qt in C++. pyside-uic is included with the PySide applications and for me it is found in the Scripts directory of my Python installation, e.g. C:\Python27\Scripts\pyside-uic.exe. Taking a note from how C++ compilation handles ui files, I typically compile my ui files to have a name like ui_[Name of the ui file].py:
C:\Python27\Scripts\pyside-uic mainwindow.ui > ui_mainwindow.py
Inside of that resulting .py file, pyside-uic creates a class named the same name as the base class of the ui file prepended with Ui_. So, for instance, if you created a mainwindow.ui that contained the definition for a class named MainWindow, the created class would be Ui_MainWindow. If the ui file defined a class named SourceWindow, the class within the .py file Ui_SourceWindow. In Qt Designer you set the class name by setting objectName in the root element of the object tree (in the upper right of the window).
With your files cafeteria_menu,ui and dialog_login.ui, you would get derived classes Ui_cafeteria_menu and Ui_dialog_login.
Once you have the .py file generated, it can be used by importing it into the definition file for your widget and used using the setupUi method of the class in the Ui file
from PySide import QtCore, QtGui
from ui_mainwindow import Ui_MainWindow
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
Once you have ui defined for the class, all of the connections and ui elements for the widget need to be accessed through self.ui
self.ui.lineEdit.textChanged[str].connect(self.processText)
Since you would have to put your .png files in a Qt Resource File, I'll talk about it in the next section.
pyside-rcc
Like pyside-uic, pyside-rcc is included with the PySide application, although mine is in the site-packages directory of Python instead of in Scripts (if it's in the same place for you, you can always copy it).
C:\Python27\lib\site-packages\PySide\pyside-rcc.exe
Before you can compile the Qt Resource File, you have to first create it using one of the Qt Tools. I use Qt Creator since it can perform almost all of the functions related to Qt in one application. The documentation for the Qt Resource System shows that the resource file is really just an XML file that defines file paths and internal paths for the resource system. You can set up and organize the files however you want but when it comes to compile, all of the files defined in the Resource File must be in the same directory or a sub-directory of the file. Once you have the Resource File defined, you need to use pyside-rcc.exe to compile it into a .py file. I typically name the resource file the same as the project and keep everything in one resource file to make dealing with the resources more concise.
C:\Python27\lib\site-packages\PySide\pyside-rcc.exe -py2 MyProject.qrc > MyProject_Resources.py
The -py2 switch defines that the output from the file should be formatted for Python 2.x. If you are using Python 3.x or plan to use it in the future, you can use the -py3 switch and the outcome will be compatible with Python 3.x.
Putting it all together
Since you are already loading the ui files directly QUiLoader, you just need to refactor your QUiLoader statements to load a QFile that opens the ui resource from the resource system. To use the files from the resource system, all you need to do is import your Resource .py file, the one generated from pyside-rcc, into the main script file of your program and the last line in the resource file is a call to qInitResources() which initializes the resources to be used in the entire program. To load a file using QFile, use a path that starts with ":" and then references the paths that were defined in the Resource File. You could create a file msResources.qrc that has ui and images that has your ui and png files defined as sub categories.
So, if your resource file looks something like this
/ui
cafeteria_menu.ui
dialog_login.ui
/images
cafeteria-menu.png
exit.png
logo.png
mail-fetch.ong
And, if you want to load those files, you just need to create a QIcon or QFile like so:
cafeteriaMenuIcon = QtGui.QIcon(":/images/cafeteria-menu.png")
cafeteriaMenuUi = QtCore.QFile(":/ui/cafeteria_menu.ui")
In use in your code for GUICafeteriaMenu in msCafeteriaMenu, I would just change the __init__ method for GuiCafeteriaMenu to load and use the ui file from the resources:
uiFile = QFile(":/ui/cafeteria_menu.ui")
uiFile.open(QFile.ReadOnly)
UiLoader.load(uiFile, self)
uiFile.close()
I would probably place the output from pyside-rcc into the metsuite_libs package into something like msResources.py and import the msResources file in the __init__.py file as part of your package. That way, once you have the .py files created and imported into your program, the extra file would be encapsulated in your package and you will not need to change your setup.py file. Before you do the py2exe conversion, running the refactored program should work just fine normally. Additionally, no matter how you handle the ui files, you will always need to use a Resource File to be able to package icons into the program. For portability reasons, using resource files for icons is probably a good habit to get in to.

Resources