Python does not show code changes from imported file - python

I am using a linux python shell and each time I make changes to the imported file I need restart the shell (I tried reimporting the file but the changes were not reflected)
I have a definition in a file called handlers.py
def testme():
print "Hello I am here"
I import the file in the python shell
>> import handlers as a
>> a.testme()
>> "Hello I am here"
I then change print statement to "Hello I am there", reimport handlers, it does not show the change?
Using Python 2.7 with Mint 17.1

You need to explicitly reload the module, as in:
import lib # first import
# later ....
import imp
imp.reload(lib) # lib being the module which was imported before
note that imp module is pending depreciation in favor of importlib and in python 3.4 one should use: importlib.reload.

You should use reload every time you make a change and then import again:
reload( handlers )
import handlers a a

As an alternative answer inside reload you can use
watchdog
.
A simple program that uses watchdog to monitor directories specified as command-line arguments and logs events generated:
From the website
Supported Platforms
Linux 2.6 (inotify)
Mac OS X (FSEvents, kqueue)
FreeBSD/BSD (kqueue)
Windows (ReadDirectoryChangesW with I/O completion ports; ReadDirectoryChangesW worker threads)
OS-independent (polling the disk for directory snapshots and comparing them periodically; slow and not recommended)

Related

executing standalone fabric script by calling it by its name, without the .py extension

I have a fabric script called fwp.py that I run without calling it throug fab by using:
if __name__ == '__main__':
# imports for standalone mode only
import sys
import fabric.main
fabric.main.main(fabfile_locations=[__file__])
The thing is then have to call the script by calling fwp.py. I'd like to rename it as fwp to be able to call it as fwp. But doing that would result in
Fatal error: Couldn't find any fabfiles!
Is there a way to make Python/Fabric import this file, despite the lack of a ".py" extension?
To reiterate and clarify:
I'm not using the "fab" utility (e.g. as fab task task:parameter); just calling my script as fwp.py task task:parameter, and would like to be able to call it as fwp task task:parameter.
Update
It's not a duplicate of this question. The question is not "How to run a stand-alone fabric script?", but "How to do so, while having a script without a .py" extension.
EDIT: Original answer corrected
The fabric.main.main() function automatically adds .py to the end of supplied fabfile locations (see https://github.com/fabric/fabric/blob/master/fabric/main.py#L93). Unfortunately that function also uses Python's import machinery to load the file so it has to look like a module or package. Without reimplementing much of the fabric.main module I don't think it will be possible. You could try monkey-patching both fabric.main.find_fabfiles and fabric.main.load_fabfiles to make it work.
Origininal answer (wrong)
I can get this to work unaltered on a freshly installed fabric package. The following will execute with a filename fwp and executable permission on version 1.10.1, Python2.7. I would just try upgrading fabric.
#!/usr/bin/env python
from fabric.api import *
import fabric.main
def do():
local('echo "Hello World"')
if __name__ == '__main__':
fabric.main.main(fabfile_locations=[__file__])
Output:
$ ./fwp do
Hello World
Done

How to check if all modules imported by a Python script are installed without running the script?

I would like to check if all modules imported by a script are installed before I actually run the script, because the script is quite complex and is usually running for many hours. Also, it may import different modules depending on the options passed to it, so just running it once may not check everything. So, I wouldn't like to run this script on a new system for few hours only to see it failing before completion because of a missing module.
Apparently, pyflakes and pychecker are not helpful here, correct me if I'm wrong. I can do something like this:
$ python -c "$(cat *.py|grep import|sed 's/^\s\+//g'|tr '\n' ';')"
but it's not very robust, it will break if the word 'import' appears in a string, for example.
So, how can I do this task properly?
You could use ModuleFinder from the standard lib modulefinder
Using the example from the docs
from modulefinder import ModuleFinder
finder = ModuleFinder()
finder.run_script('bacon.py')
print 'Loaded modules:'
for name, mod in finder.modules.iteritems():
print '%s: ' % name,
print ','.join(mod.globalnames.keys()[:3])
print '-'*50
print 'Modules not imported:'
print '\n'.join(finder.badmodules.iterkeys())
You could write a test.py that just contains all the possible imports for example:
import these
import are
import some
import modules
Run it and if there are any problems python will let you know

Google App Engine Local (Development) IPython Shell

In my local Google app engine development environment, I would like to use an ipython shell, especially to be able to check out models with data that was created via dev_server.py,
very much like how django's manage.py shell command works.
(This means that the ipython shell should be started after sys.path was fixed and app.yaml was read and analyzed, and the local datastore is ready)
Any simple solution for this?
For starters, you can put your application root directory and the SDK root directory (google_appengine) in your Python path. You'll also need a few libraries like yaml, either installed or added to the library path from the SDK's lib directory. Then you can import modules and call some features.
>>> import sys
>>> sys.path.append('/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine')
Of course, as soon as a code path tries to make a service call, the library will raise an exception, saying it isn't bound to anything. To bind the service libraries to test stubs, use the testbed library:
>>> from google.appengine.ext import testbed
>>> tb = testbed.Testbed()
>>> tb.activate()
>>> tb.init_datastore_v3_stub()
>>> from google.appengine.ext import db
>>> import models
>>> m = models.Entry()
>>> m.title = ‘Test’
>>> m.put()
To tell the datastore test stub to use your development server's datastore file, pass the path to the file to init_datastore_v3_stub() as the datastore_file argument. See the doc comment for the method in google.appengine.ext.testbed for more information.
For more information on testbed: https://developers.google.com/appengine/docs/python/tools/localunittesting
Basically you'll need to use this: https://developers.google.com/appengine/articles/remote_api
For IPython support you have two options:
(1) If you're working with Python 2.7 (and IPython 0.13) you will need to use this to embed an IPython shell:
from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
shell = TerminalInteractiveShell(user_ns=namespace)
shell.mainloop()
(2) If you're working with Python 2.5 (and IPython 0.10.2) you will need to use this line to embed an IPython shell:
from IPython.Shell import IPShellEmbed
ipshell = IPShellEmbed(user_ns=namespace, banner=banner)
ipshell()
This is the one that I use: https://gist.github.com/4624108 so you just type..
>> python console.py your-app-id
Once you run dev_appserver.py
you will get
starting module "default" running at: http://127.0.0.1:8080
Starting admin server at : http://localhost:8000
so basically what you want to do is to access http://localhost:8000 and there you will find "Interactive Console" you can use it to play around with

import local python module in HTCondor

This concerns the importing of my own python modules in a HTCondor job.
Suppose 'mymodule.py' is the module I want to import, and is saved in directory called a XDIR.
In another directory called YDIR, I have written a file called xImport.py:
#!/usr/bin/env python
import os
import sys
print sys.path
import numpy
import mymodule
and a condor submit file:
executable = xImport.py
getenv = True
universe = Vanilla
output = xImport.out
error = xImport.error
log = xImport.log
queue 1
The result of submitting this is that, in xImport.out, the sys.path is printed out, showing XDIR. But in xImport.error, there is an ImporError saying 'No module named mymodule'. So it seems that the path to mymodule is in sys.path, but python does not find it. I'd also like to mention that error message says that the ImportError originates from the file
/mnt/novowhatsit/YDIR/xImport.py
and not YDIR/xImport.py.
How can I edit the above files to import mymodule.py?
When condor runs your process, it creates a directory on that machine (usually on a local hard drive). It sets that as the working directory. That's probably the issue you are seeing. If XDIR is local to the machine where you are running condor_submit, then it's contents don't exist on the remote machine where the xImport.py is running.
Try using the .submit feature transfer_input_files mechanism (see http://research.cs.wisc.edu/htcondor/manual/v7.6/2_5Submitting_Job.html) to copy the mymodule.py to the remote machines.

Use PYTHONSTARTUP to interactively test a python file in the interpreter

I want to establish a standard script file that is imported into python at startup using the PYTHONSTARTUP environment variable. Additionally, I want to be able to conveniently reload the same script file after modifying it in an external editor, to test its behavior after the modification.
I created a ~/.pythonrc.py file and set it as PYTHONSTARTUP:
import os
import imp
def load_wb():
_cwd = os.getcwd()
os.chdir(os.path.join(os.getenv('HOME'),'Skripte'))
import workbench
imp.reload(workbench)
os.chdir(_cwd)
load_wb()
This is my very minimal script file for the start:
def dull_function():
print('Not doing much...')
print('Workbench loaded.')
When I launch Python 3.1.2, .pythonrc is successfully executed and the workbench.py is imported, but dull_function does not appear in the global namespace or in a local one. What do I have to do differently?
Move the import statement outside the function. You're basically importing the workbench module into the function scope, not the global scope (Try calling workbench.dull_function from inside load_wb to see for yourself).
In other words, change your code to:
import os
import imp
import workbench
def load_wb():
_cwd = os.getcwd()
os.chdir(os.path.join(os.getenv('HOME'), 'Skripte'))
imp.reload(workbench)
os.chdir(_cwd)
load_wb()
Not really solving your immediate problem but... You might appreciate using iPython shell for testing in that case. Using the autoimport functionality, you can mark a module for (re)loading on each executed line if needed.
That means you can %aimport workbench and then every time you run some_function_Im_testing(), workbench will be reloaded if it changed. Just add the autoimport line into the configuration file for ipython and you're done.

Categories

Resources