Importing Python script with nonstandard name - python

I am writing a series of python scripts to extend the QGIS software suite. As such I am trying to follow their naming conventions. In this instance the file I am trying to import is called "r.sun.distributed". Ive tried using import r.sun.distributed and import("r.sun.distributed") However, python says it can't find a module by that name in both cases.
Is there a work around, or do I need to rename my scripts so they fit Python's conventions?

You can use the imp module to import modules without .py extension:
import imp
imp.load_source(path)

you have to convert it to .pyc to call it.
import py_compile
py_compile.compile('filename.py')

Related

Custom Module with Custom Python Package - Module not found error

I wrote a custom python package for Ansible to handle business logic for some servers I manage. I have multiple files and they reference each other by re-importing the package.
So my package named <MyCustomPackage> has functions <Function1> <Function2> <Function3>, etc all in their own files... Some of these functions reference functions in the same package, so to do that the file has:
import MyCustomPackage
at the top. I did it this way instead of a relative import because I'm also unit testing these and mocking would not work with relative paths because of a __init__ file in the test directory which was needed for test discovery. The only way I could mock was through importing the package itself. Seemed simple enough.
The problem is with Ansible. These packages are in module_utils. I import them with:
from ansible.module_utils.MyCustomPackage import MyCustomPackage
but when I use the commands I get module not found errors - and traced it back to the import MyCustomPackage statement in the package itself.
So - how should I be structuring my package? Should I try again with relative file imports, or have the package modify the path so it's found with the friendly name?
Any tips would be helpful! Or if someone has a module they've written with Python modules in module_utils and unit tests that they'd be willing to share, that'd be great also!
Many people have problems with relative imports and imports in general in Python because they are ambiguous and surprisingly depend on your current working directory (and other things).
Thus I've created an experimental, new import library: ultraimport
It gives you more control over your imports and lets you do file system based, relative imports.
Given that you have a file function1.py, to import a function from function2.py, you would then write:
import ultraimport
Function2 = ultraimport('__dir__/function2.py', 'Function2')
This will always work, no matter how you run your code. It also does not force you to a specific package structure. You can just have any files you like.

Is it possible to specify the search path for a module in a python script? If it is, how do I do that?

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.

Python Standard Library Import Relationships

I am writing an application in C# with VisualStudio and am using IronPython to write some Python scripts for my application. However, it does not have the entire standard library support by default. So to import some modules (such as os) I need to point my C# code to where the os module actually is. I also understand that it will still be limited to libraries implemented in pure python.
Ultimately I want to have something that can be installed on another machine. My current workaround is to include a copy of https://github.com/python/cpython/tree/2.7/Lib in the Debug folder where the executable is running and it seems excessive/unnecessary to have to include the entire thing. I tried just placing the files I need (for example os.py) here but obviously it imports other modules, which import other modules, etc... I would have to re-run the code to get the error for which module it couldn't find and add them in 1 by 1 and it was getting too tedious.
I was wondering if there was any sort of resource that specifies the relationships between standard library modules and could tell me exactly what files to copy. Essentially what I'm looking for is the graph of the standard library imports. So if I want to import os in these scripts I know to copy os.py, ntpath.py, ...
Thanks
you probably don't need the imports as a tree, but as a simple list, so you can just copy the needed files. You can get that from sys.modules, after you import everything that your script needs - it will contain all modules needed by those that you imported, e.g.:
import sys # even if you don't use it - it's a built-in module, won't add a file to the list, needed to get sys.modules
import os
import time
#import whatever-else
# this gives a list of tuples (module,file)
m=[(z,x.__file__) for z,x in sys.modules.items() if hasattr(x,"__file__") ]
for x in m:
print x[0],x[1]

Importing a f2py .pyd from an explicit path (Bad magic number ImportError)

I have built a .pyd module from some fortran code via f2py, which we can call foo.pyd. I want to import this into a python code, which we can call main.py. When I import as:
import foo
everything works fine. However, because this python will eventually be 'frozen' into an executable, and I will have to package the foo.pyd along with the main.exe, I need to specify an explicit path to import from.
Thus, I tried using the imp module, specifically imp.load_compiled(). When I try:
import imp
foo = imp.load_compiled('foo','foo.pyd')
or even:
foo = imp.load_compiled('foo','./foo.pyd')
I get the following error:
ImportError: Bad magic number in foo.pyd
It seems that this error comes from trying to build in one Python dist, and import in another. However, I'm using the same Python for both, and it works with the standard import command!
Has anyone out there experienced this, and/or possibly have some guidance? I greatly appreciate any help or advice you may have.
imp.load_compiled() is for .pyc files. You're looking for imp.load_dynamic(). Alternatively, you can add the directory you want in sys.path, after which regular imports will work.

Where should my Python 3 modules be?

I recently installed Python 3 on my Mac OSX 10.6.8 and I haven't had any problems with modules or imports until now. I'm writing a function that tests whether or not a triangle is right angled based on the length of the sides and the guide that the exercise was in has a bunch of equalities to test so I can see if it works:
testEqual(is_rightangled(1.5,2.0,2.5), True)
testEqual(is_rightangled(4.0,8.0,16.0), False)
testEqual(is_rightangled(4.1,8.2,9.1678787077), True)
testEqual(is_rightangled(4.1,8.2,9.16787), True)
testEqual(is_rightangled(4.1,8.2,9.168), False)
testEqual(is_rightangled(0.5,0.4,0.64031), True)
I should apparently import a function called testEqual(a,b,c) from a module called test, since the example programme in the guide starts with from test import testEqual, but when I typed that into my file I got this message:
from test import testEqual
ImportError: cannot import name testEqual
I suppose I should specify the path to the test module, but I can't find it my Python 3 library anywhere in my computer – just the 2.x ones that came installed with the computer, which are in /Library/Python. import turtle and import math worked, so it must be somewhere.
The test module in the Python stdlib doesn't contain a function called testEqual(). Its documentation starts with
Note: The test package is meant for internal use by Python only. It is
documented for the benefit of the core developers of Python. Any use
of this package outside of Python’s standard library is discouraged as
code mentioned here can change or be removed without notice between
releases of Python.
Are you sure that this guide you're following doesn't have its own test.py program that you're supposed to use instead?
When you write your testEqual() function make note of the directory you are working in. For instance on my mac I created a directory (folder) in documents so my path looks like: /Users/myName/Documents/python. Save your function (module) as testEqual.py and when you write you test.py script import testEqual after the shebang line. Once you have your scripts debugged your modules will be in a folder that python creates titled pycache don't remove that as it is compiled code. Now, as long as you are working in the same dir as your module you should not need to do anything other than use the import statement.

Categories