I have a Python script which runs perfectly with CPython (under virtualenv), unfortunately throws ModuleNotFoundError error when I run it with PyPy3 (under virtualenv).
My package is parser and I import Analyze with from parser.Analyze import Analyze. There is parser directory under the same directory with my script. And parser directory has __init__.py file in it too.
Should I do something special for PyPy?
On both PyPy and CPython parser is a built-in module. Can you see if the problem is that the built-in is masking your package? You can rename it to something like myparser. PyPy tracks issues at https://bitbucket.org/pypy/pypy/issues or you can reach out on IRC at #pypy
Related
I am trying to follow the tutorial for creating python packages from shared objects compiled from C++ via boost::python, but I am running into some problems I need clarification about.
Assume I have a local $install_dir into which I install the compiled shared objects in the form of a python package via CMake. Parallel to the tutorial liked above, my structure is:
$installdir/
my_package/
__init__.py
module/
__init__.py
_module.so
I have added $installdir to my $PYTHONPATH.
$installdir/my_package/__init__.py is empty.
$installdir/my_package/module/__init__.py contains:
from _module import *
When I then import my_package.module I get ModuleNotFoundError: No module named '_module' raised from $installdir/my_package/module/__init__.py.
The issue seems to be that _module.so is not found from $installdir/my_package/module/__init__.py.
Why is the approach from the tutorial not working?
If I add $installdir/my_package/module to $PYTHONPATH directly everything works fine, but it feels like that should not be neccessary, as $installdir/my_package/module/__init__.py should find _module.so locally.
I implemented the following portable workaround for now within $installdir/my_package/module/__init__.py:
import sys, pathlib
sys.path.insert(0,str(pathlib.Path(__file__).parent.absolute()))
from _module import *
Bonus Question:
Changing the file name extension from .so to .pyd breaks the import (ModuleNotFoundError) even without any packaging and .pyd being accessible directly via $PYTHONPATH. I define the extension via CMake's SUFFIX target property. This is obviously mostly cosmetic, but I would still like to understand the reason and how to fix it.
Edit:
This is Ubuntu 20.04 with python 3.8 and boost 1.71
On windows I have built a very simple "hello world" C extension (the file hello.c from this site https://gist.github.com/physacco/2e1b52415f3a964ad2a542a99bebed8f). Using VS2015 I successfully obtain hello.dll. The problem is that I can't figure out how to import this file/module.
In the python shell (python 3.7) I have made sure that I'm in the same folder as the hello.dll. I have also made sure that sys.path() contains the folder path. But when I write "import hello" I get an error "ModuleNotFoundError: No module named 'hello'"
Does anyone has an idea of what is wrong is this very simple setup?
Update:
When trying to import a module that does not exist the ModuleNotFoundError is reported. After renaming the hello.dll to hello.pyd an ImportError is returned. So it seems like it tries to actually load the module.
Python compiled modules on Windows have the extension .pyd, not .dll. If you'd built it using setup.py the file would be built with the correct name. However, you built it yourself and gave it a name that Python doesn't recognise as a module.
In terms of the build command: you have to link it with libpython. You don't look to be doing this. The error you report is definitely one that you can get if the module is not linked against all its dependencies.
I know you don't want to use setup.py, however I'd use it at least once just to see what it does and if it works. You'll then at least have a command that you can copy with a working set of options.
I have been coding in python for about 2 months, but I'm only familiar with basic object-oriented programming, so I do not really understand things like how searching for modules is implemented. (Basically I'm a noob.)
I pip installed a package called Opentrons Opentrons 2.5.2 and all its dependencies into the samefolder as a python script I'm currently writing. However when I tried to import the module below[1], I get an error saying that "Opentrons is not a module". Then, I tried shifting it into the python library because I found out the search path using the pprint module and it seems to work. I was wondering if I can specify the search path from the .py file itself instead of manually printing the search path and putting the file into the library that the script searches for. (Willing to put in images of the directories I put the opentrons package in if it helps.)
[1]
import sys
import pprint
pprint.pprint(search.path)
from opentrons import robot, containers, instruments
Edit: I realise that the fact that I am running all my scripts in a Spyder console located in a python 3.6 environment might be important.
You can try using the __import__ function, or importlib. This should allow you to specify the path.
Okay, so in the past, I've made my own Python packages with Python 2.x (most recently, 2.7.5). It has worked fine. Let me explain how I did that, for reference:
Make a directory within the working directory. We'll call it myPackage.
Make a file called __init__.py in the directory myPackage.
Make sure all the modules that you want to be part of the package are imported within __init__.py. These modules are typically in the myPackage folder.
From a Python program in the working directory, type import myPackage (and it imports fine, and is usable).
However, in Python 3, I get errors with that. (ImportError: No module named 'Whatever the first imported module is')
I researched the problem and found the following:
Starred imports don't work in Python 3.3.
The __init__.py file is not required in Python 3.3.
So, I removed the stars from my imports, and leaving the __init__.py file in, I still got errors (ImportError: No module named 'Whatever the first imported module is'). So, I removed the __init__.py file, and I don't get any errors, but my package doesn't include any of my modules.
Okay, so I discovered by doing a web search for python3 __init__.py or some such that I can do the following, although I don't have any clue if this is the standard way of doing things:
In the modules in the package, make sure there are no plain imports (not just no starred ones). Only do from myModule import stuff. However, you need to put a . in front of myModule: e.g. from .myModule import stuff. Then, I can import myPackage.oneOfMyModules
I found that by following this rule in the __init__.py file, it also works.
Once again, I don't know if this is how it's supposed to work, but it seems to work.
I found this page that is supposed to have something to do with the changes in packages in Python 3.something, but I'm not sure how it relates to what I'm doing:
http://legacy.python.org/dev/peps/pep-0420/
So, what is the standard way to do this? Where is it documented (actually saying the syntax)? Is the way I'm doing it right? Can I do regular imports instead of from package import module?
After analyzing some Python 3 packages installed on my system (I should have tried that to start with!) I discovered that they often seem to do things a little differently. Instead of just doing from .myModule import stuff they would do from myPackage.myModule import stuff (inside the modules in the package). So, that works, too, I suppose, and seems to be more frequently used.
I installed nose using the 'setup.py install' on the command line , I am able to run 'nosetests' and any python file matching testMatch regular expression is picked up and tests are automated in the %python home%\Scripts directory. Now I want nose to work with my iron Python files , how do I install nose on the %Iron Python home% directory ? i noticed my Iron Python Home directory does not even have a Scripts folder.
If i try running 'nosetests' with iron python code , it throws all sorts of exception
for eg. no module named clr.
Is anybody using nose with iron python ? if yes , please guide me. I have been struggling with this since an entire day,
currently my only workaround has been adding the following in my IronPython code:
import nose
nose.main(argv=['<arguments>'])
is this is the only way to go about using nose in iron python files ?
if there is no other way , then I wanted to know how to use the several plugins that nose has ? especially the coverage plugin ? i installed it for python2.6 , but how to make it work for ironpython ?
The reason I am asking is because with python , it gets easy to use the plugins just by calling the command line , but with IronPython I don't know how to make it work.
Your solution is actually all nosetests does:
#!/usr/bin/env python
from nose import main
if __name__ == '__main__':
main()
You'll want to make sure you add your system's Python lib to the path for it to find the nose extensions:
>>>import sys
>>>sys.path.append(r'C:\Python26\lib')
And you'll need to make sure you're executing your script with ipy.exe and not your system's Python executable.
I've been trying to run the sqlalchemy test suite, which uses nose and a plugin. So, this may be useful if anyone is trying to run nose on ironpython with plugins.
this tends not to work transparently on ipy, because setuptools doesn't quite work on ironpython.
after a bit of diggin, i found the nose init.py instructions for registering a plugin manually - essentially, import the plugin class (which subclasses nose.plugins.Plugin), and add it to the call to main().
here's what my script ended up looking like:
import sys, os
#import ironclad #not needed. i think.
sys.path.append(r'C:\Python26\lib')
#now load Jeff Hardys sqlite dll which is in sqlite folder (sqlite not supported on ipy)
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)),'sqlite'))
import clr
clr.AddReference('IronPython.SQLite')
#load plugin
from sqlalchemy.test.noseplugin import NoseSQLAlchemy
from nose import main
if __name__ == '__main__':
main(addplugins=[NoseSQLAlchemy()])
Hope this helps someone!