Howdy all,
Question: I have Python modules named without '.py' as the extension,
and I'd like to be able to import them. How can I do that?
Background:
On Unix, I write programs intended to be run as commands to a file
with no extension. This allows other programs to use the command as an
interface, and I can re-write the program in some other language
without obsoleting the commandline interface.
e.g., I might write 'frobnicate-foo' as a shell program so that other
programs can 'frobnicate-foo --bar baz'. If I later decide to
re-implement 'frobnicate-foo' in Python, I'll save the top level
module to the same file name since it implements the same command-line
interface.
Now that I've got it written as a Python module, I'd like to write
unit tests for that module, which of course will need to import the
program module to test it. The unit test can explicitly add the
directory where the program module lives to 'sys.path' for the purpose
of importing that module.
However, the Python reference tells me that 'import' (specifically,
'__import__()') needs modules to live in files named a particular way:
with a '.py' suffix. But my module is in a file called
'frobnicate-foo', with no suffix, and that's part of the definition of
the program interface.
I don't want symbolic links, or anything else that presents two
filenames for the same module, because there's no need for that except
for Python's apparent insistence on a particular naming
convention. Also, avoiding symbolic links inside the source code tree
makes version control smoother.
What are my options to import a module from a file whose name can't
change?
--
\ "[W]e are still the first generation of users, and for all that |
`\ we may have invented the net, we still don't really get it." |
_o__) -- Douglas Adams |
Ben Finney 10 3692
Ben Finney wrote:
Howdy all,
Question: I have Python modules named without '.py' as the extension,
and I'd like to be able to import them. How can I do that?
Background:
On Unix, I write programs intended to be run as commands to a file
with no extension. This allows other programs to use the command as an
interface, and I can re-write the program in some other language
without obsoleting the commandline interface.
e.g., I might write 'frobnicate-foo' as a shell program so that other
programs can 'frobnicate-foo --bar baz'. If I later decide to
re-implement 'frobnicate-foo' in Python, I'll save the top level
module to the same file name since it implements the same command-line
interface.
Now that I've got it written as a Python module, I'd like to write
unit tests for that module, which of course will need to import the
program module to test it. The unit test can explicitly add the
directory where the program module lives to 'sys.path' for the purpose
of importing that module.
If it can do that, it can copy the MUT to some temp directory, adding
..py to the end of the name of the new file, and put the temp directory
in sys.path .... can't it?
Cheers,
John
"John Machin" <sj******@lexicon.netwrites:
Ben Finney wrote:
Now that I've got it written as a Python module, I'd like to write
unit tests for that module, which of course will need to import
the program module to test it. The unit test can explicitly add
the directory where the program module lives to 'sys.path' for the
purpose of importing that module.
If it can do that, it can copy the MUT to some temp directory,
adding .py to the end of the name of the new file, and put the temp
directory in sys.path .... can't it?
Sounds like a nasty hack (not that fiddling sys.path isn't a hack, but
at least that one's addressed in Python 2.5 with relative and absolute
imports).
The problem with importing the program module from a file in a
different directory is that the program won't be able to find its own
relative modules. That leads to either *more* sys.path hackery, or
importing from a temporary file in the *same* directory.
Besides which, that's still two file names for the same module
code. The whole point of testing is to know that I'm testing the same
module; with a two-file shim, that's one step further away from that
ideal.
What you describe is possible, but leads to very smelly hacks. I'd
like to see what other options there are.
--
\ "It's not what you pay a man, but what he costs you that |
`\ counts." -- Will Rogers |
_o__) |
Ben Finney
Ben Finney wrote:
"John Machin" <sj******@lexicon.netwrites:
Ben Finney wrote:
Now that I've got it written as a Python module, I'd like to write
unit tests for that module, which of course will need to import
the program module to test it. The unit test can explicitly add
the directory where the program module lives to 'sys.path' for the
purpose of importing that module.
If it can do that, it can copy the MUT to some temp directory,
adding .py to the end of the name of the new file, and put the temp
directory in sys.path .... can't it?
Sounds like a nasty hack (not that fiddling sys.path isn't a hack, but
at least that one's addressed in Python 2.5 with relative and absolute
imports).
The problem with importing the program module from a file in a
different directory is that the program won't be able to find its own
relative modules. That leads to either *more* sys.path hackery, or
importing from a temporary file in the *same* directory.
Please explain both the "own" and "relative" in "its own relative
modules". Do these modules not have names that end in ".py"?
>
Besides which, that's still two file names for the same module
code. The whole point of testing is to know that I'm testing the same
module; with a two-file shim, that's one step further away from that
ideal.
The two-file caper exists only for the duration of the test. You'll
have to trust yourselt to write and test a file copying gadget. :-)
>
What you describe is possible, but leads to very smelly hacks. I'd
like to see what other options there are.
Probably smellier ones ...:<)
Cheers,
John
"John Machin" <sj******@lexicon.netwrites:
Ben Finney wrote:
"John Machin" <sj******@lexicon.netwrites:
If it can [modify sys.path], it can copy the MUT to some temp
directory, adding .py to the end of the name of the new file,
and put the temp directory in sys.path .... can't it?
The problem with importing the program module from a file in a
different directory is that the program won't be able to find its
own relative modules. That leads to either *more* sys.path
hackery, or importing from a temporary file in the *same*
directory.
Please explain both the "own" and "relative" in "its own relative
modules". Do these modules not have names that end in ".py"?
The program can import modules with relative paths, because it can
expect its position in the directory tree to remain the same relative
to those modules. If the program module suddenly exists in a different
directory, that assumption no longer holds and the relative imports
performed by the program will fail.
Thus to avoid that problem, testing needs to be done on the program
module with its position relative to all other modules the same as
when that program runs.
--
\ "It may be that our role on this planet is not to worship God |
`\ -- but to create him." -- Arthur C. Clarke |
_o__) |
Ben Finney
Ben Finney wrote:
Howdy all,
Question: I have Python modules named without '.py' as the extension,
and I'd like to be able to import them. How can I do that?
This is a piece of cake in Python.
>>from types import ModuleType x = ModuleType('myModName') data = open('myfilename').read() exec data in x.__dict__
Your output here...
This won't save a .pyc, but as your message later explains, this is for
unittesting, so this could probably be considered a feature for this
usage.
Regards,
Pat
Ben Finney wrote:
Howdy all,
Question: I have Python modules named without '.py' as the extension,
and I'd like to be able to import them. How can I do that?
Background:
On Unix, I write programs intended to be run as commands to a file
with no extension. This allows other programs to use the command as an
interface, and I can re-write the program in some other language
without obsoleting the commandline interface.
e.g., I might write 'frobnicate-foo' as a shell program so that other
programs can 'frobnicate-foo --bar baz'. If I later decide to
re-implement 'frobnicate-foo' in Python, I'll save the top level
module to the same file name since it implements the same command-line
interface.
Now that I've got it written as a Python module, I'd like to write
unit tests for that module, which of course will need to import the
program module to test it. The unit test can explicitly add the
directory where the program module lives to 'sys.path' for the purpose
of importing that module.
However, the Python reference tells me that 'import' (specifically,
'__import__()') needs modules to live in files named a particular way:
with a '.py' suffix. But my module is in a file called
'frobnicate-foo', with no suffix, and that's part of the definition of
the program interface.
I don't want symbolic links, or anything else that presents two
filenames for the same module, because there's no need for that except
for Python's apparent insistence on a particular naming
convention. Also, avoiding symbolic links inside the source code tree
makes version control smoother.
What are my options to import a module from a file whose name can't
change?
--
\ "[W]e are still the first generation of users, and for all that |
`\ we may have invented the net, we still don't really get it." |
_o__) -- Douglas Adams |
Ben Finney
Leave your python module with the .py extension and create a small
python script without the .py extension to import and run your code
from the command line.
For example, on my [linux] system /usr/local/bin/idle contains this:
#!/usr/bin/python
from idlelib.PyShell import main
if __name__ == '__main__':
main()
You also get a modest performance boost because the interpreter will
only process the text of this small script but will use the precompiled
byte-code .pyc files (when available) of your main module, rather than
re-parsing its text.
HTH,
~Simon
"Patrick Maupin" <pm*****@gmail.comwrites:
Ben Finney wrote:
Question: I have Python modules named without '.py' as the extension,
and I'd like to be able to import them. How can I do that?
This is a piece of cake in Python.
>from types import ModuleType x = ModuleType('myModName') data = open('myfilename').read() exec data in x.__dict__
Your output here...
This won't save a .pyc, but as your message later explains, this is for
unittesting, so this could probably be considered a feature for this
usage.
Very nice. Okay, my unit testing scaffold module now has a new function:
def make_module_from_file(module_name, file_name):
""" Make a new module object from the code in specified file """
from types import ModuleType
module = ModuleType(module_name)
module_file = open(file_name, 'r')
exec module_file in module.__dict__
return module
The unit test now just imports that functionality, and then makes the
module object via that function:
import scaffold
module_name = 'frobnicate_foo'
module_file_under_test = os.path.join(scaffold.code_dir, 'frobnicate-foo')
frobnicate_foo = scaffold.make_module_from_file(
module_name, module_file_under_test)
The rest of the unit test then has 'frobnicate_foo' as a module to test.
It's working fine. Does anyone foresee any problems with doing it this way?
--
\ "Injustice is relatively easy to bear; what stings is justice." |
`\ -- Henry L. Mencken |
_o__) |
Ben Finney
Ben Finney schrieb:
Question: I have Python modules named without '.py' as the extension,
and I'd like to be able to import them. How can I do that?
I recommend to use imp.load_module.
Regards,
Martin
"Martin v. Löwis" <ma****@v.loewis.dewrites:
Ben Finney schrieb:
Question: I have Python modules named without '.py' as the extension,
and I'd like to be able to import them. How can I do that?
I recommend to use imp.load_module.
I've tried this; as Patrick Maupin alludes to, it compiles the module
leaving a strangely-named file behind.
Program in a file named 'frob_foo'; no other file names needed nor
desired.
import imp
file_name = "frob_foo"
module_name = 'frob_foo'
module_file = open(file_name, 'r')
module_desc = ("", 'r', imp.PY_SOURCE)
module = imp.load_module(module_name, module_file, file_name, module_desc)
Result: two files, 'frob_foo' and 'frob_fooc'. I can see why this
happens, but it's not what's desired. Currently I'm going with:
file_name = "frob_foo"
module_name = 'frob_foo'
from types import ModuleType
module = ModuleType(module_name)
module_file = open(file_name, 'r')
exec module_file in module.__dict__
Still, the purpose is simply to get a module object out, with a named
file as input. If the 'imp' module can do that without leaving
unwanted turds behind, it seems more elegant. Can anyone suggest a way
to get the same result as the above 'exec' method, using the 'imp'
module?
--
\ "...one of the main causes of the fall of the Roman Empire was |
`\ that, lacking zero, they had no way to indicate successful |
_o__) termination of their C programs." -- Robert Firth |
Ben Finney This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Matthew Wilson |
last post by:
Hi-
I'm writing a bunch of classes, several of which need functions and
variables defined in the math module. In some instances, I'm going to
import my module like this:
import myshapes
...
|
by: Paul Rubin |
last post by:
That's what the Python style guides advise. They don't seem to like
def frob(x):
import re
if re.search('sdfxyz', x): ...
instead preferring that you pollute your module's global namespace...
|
by: Peter L. Buschman |
last post by:
I have a package tree laid out like this
foo/bar/module/submodule
foo/bar/module/submodule/test
foo/bar/module/submodule/test/test1.py
foo/bar/module/submodule/test/test2.py
....
What I...
|
by: Grant D. Watson |
last post by:
If this has been answered before, or if my terminology is off, please bear with
me; my Python experience is limited to use in one class and to personal
projects.
I'd like to do something rather...
|
by: Steve Holden |
last post by:
This is even stranger: it makes it if I import the module a second time:
import dbimp as dbimp
import sys
if __name__ == "__main__":
dbimp.install()
#k = sys.modules.keys()
#k.sort()
#for...
|
by: Jim |
last post by:
I would be very grateful for help on the following.
I have the following modules in a program. Names changed to protect the
innocent.
1.Simulation
2.Branches
3.MyFiles
I import Branches,...
|
by: fegge |
last post by:
i have written script save as hello.py. i can run it. but why cant i
import it as a modular in other programs?
|
by: Roland Hedberg |
last post by:
Hi!
I'm having a bit of a problem with import.
I'm writing a marshalling system that based on a specification will
create one or more files containing mostly class definitions.
If there are...
|
by: dmitrey |
last post by:
howto check does module 'asdf' exist (is available for import) or no?
(without try/cache of course)
Thx in advance, D.
|
by: John Boy |
last post by:
First post and very much a newbie to Python. Have 2.5 on Linux (GG). I
think I have set up PYTHONPATH correctly in that I can import a module
apply_bp and it complains about line 20 in apply_bp...
|
by: erikbower65 |
last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps:
1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal.
2. Connect to...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Sept 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM)
The start time is equivalent to 19:00 (7PM) in Central...
|
by: DJRhino1175 |
last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this -
If...
|
by: Rina0 |
last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
|
by: DJRhino |
last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer)
If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _
310030356 Or 310030359 Or 310030362 Or...
|
by: lllomh |
last post by:
Define the method first
this.state = {
buttonBackgroundColor: 'green',
isBlinking: false, // A new status is added to identify whether the button is blinking or not
}
autoStart=()=>{
|
by: lllomh |
last post by:
How does React native implement an English player?
|
by: Mushico |
last post by:
How to calculate date of retirement from date of birth
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
| |