Skip to main content

Call a command when a directory or file has changed. (Mac OS only)

Project description

icemac.callonchange calls a specific command when a directory or something in it has changed. It was developed to ease test driven development (TDD): it can call the test case under development each time the test case or the developed code changes.


0.8 (2018-08-03)

0.7.0 (2011-01-18)

  • Added new option to run the utility immediately after invoking callonchange. This option was also added to the default options when using the recipe.

0.6.1 (2010-12-11)

  • Made tests more robust.
  • Added more similar tools to the list.

0.6 (2010-07-28)

  • Added compatibility with Python 2.4.
  • Now officially supporting Python 2.6 and 2.7, too.

Older changes

  • See OLD_CHANGES.rst inside the package.


  • Mac OS X 10.5+ (Leopard)
  • Python 2.7

General usage

Usage: callonchange [options] path utility [utility arguments]

callonchange invokes utility with its utility arguments when path or something in it changes.

--version show program’s version number and exit
-h, --help show this help message and exit
-e EXTENSION only call utility on changes of a file with this extension (option might be used multiple times)
-i Run utility immediately after callonchange has been started. (By default the utility is only run when something changed.)
-q Do not display any output of callonchange. (Still displays the output of the utility.)

EXTENSION might be specified with or without a leading dot:

-e .py is equal to -e py is equal to -epy

Caution: optional arguments must be specified before the positional arguments (path and utility). Arguments specified after the positional arguments are taken as arguments of the utility.

Usage as script


To install callonchange as script call:

$ python install

or install it using a package manager like easy_install or pip.

Call as script

To call it as a script add the path to the directory to be observed and the command (script or program) to be called when the directory or something in it has changed.

Example to call xeyes when a file with the extension log has changed in /var/log enter:

$ callonchange -e log /var/log xeyes

Caution: In this example xeyes is called on every new entry in the log file.

In buildout

There is a recipe in the package which eases installation using buildout.

Installation with default arguments

Add a section to your buildout to generate a script for callonchange (don’t forget to add it to the parts!):

recipe = icemac.callonchange

This creates a callonchange script with default arguments. These are:

'-i', '-e', 'py', '-e', 'zcml', '-e', 'pt', '-e', 'txt', 'src', 'bin/test', '-cv'

Which means: observe in the src directory files with the extensions py, zcml, pt and txt. Call bin/test with the arguments cv (verbose and color) when callonchange has been invoked and later on when something has changed.

Installation with customized arguments

To override the default arguments add an arguments parameter to the buildout section:

recipe = icemac.callonchange
name = coc
arguments = 'Products', 'bin/ztest'

This means: The created script will be named coc. When called it will observe the Products directory and call bin/ztest on changes.

Usage as buildout script

You can add additional parameters when you call the generated script:

$ bin/callonchange -t testObserver

When you use the default arguments in the buildout section, this command line calls bin/test -cv -t testObserver on each change of py, zcml, pt or txt files in the src directory.

Stopping callonchange

To stop a running callonchange instance hit ^C (Control-C).


Thanks to Malte Borch for the great MacFSEvents which icemac.callonchange is based on.

Similar tools

(Sorted by the time I got to know them.)

  • pest: “Auto tester for python” Seems to be designed to run tests and nothing else. Has growl integration. Current version (1.0.3) has no automatic tests.
  • sniffer: “An automatic test runner. Supports nose out of the box.” Supports Linux, Windows and Mac OS X. Current version (0.2.2) has no automatic tests.
  • autonose: “continuous test tracker / runner for nosetests” Seems to focus on nose tests. Version 0.2 only acts on changes of python files.
  • PyZen: “Continuous testing for paranoid developers.” Seems to be tightly integrated into python’s unittest framework and Django. Detects file changes using comparison of file modification time stamps. So it is slow on larger code bases. Version 0.1 has no automatic tests.
  • Flask-Zen: “Flask-Script commands to integrate with PyZen.” Light layer around PyZen to integrate it into Flask. Version 0.1 has no automatic tests.
  • nosier: “Monitors paths and upon detecting changes runs the specified command” It is however limited to Linux 2.6 since it depends on the inotify facility. Uses black lists and white lists for files thos changes sould be tracked and has some other nice features. Version 1.1 has no automatic tests.
  • supcut: “Simple unobtrusive Python continuous unit testing” It is limited to Linux as it depends on inotify. Expects some of its template files are installed in /usr/share/doc/python-supcut/examples. Although it always talks about running nose tests, it might be used for arbitrary calls, too. Can send e-mails about test run. Version 0.5.1 has no automatic tests.
  • rerun: “Command-line executable Python script to re-run the given command every time files are modified in the current directory or its subdirectories.” Runs OS independent but polls the change times of files. Version 1.0.16 has no automatic tests.


  • It would be nice to have predefined argument lines (profiles) even when not using buildout. They could be stored in the home directory of the user. (Should support profiles which reverence other profiles.)
  • In buildout recipe: default script name should be section name.
  • A minimal time between calls (delay) might be nice, so a change does not result in a call of the utility when it occurred during the delay time.
  • The options of callonchange should have long variants, too.
  • White list/black list approach of nosier seems to be nice.
  • When observing large trees for changes of files with a specific extension, starting up the script can take while as the whole tree has to to be scanned once. During this start up period changes are not yet handled, so a message would be nice when start up is done.
  • could be a way to get callonchange running on Linux and Windows, too.


Source code

Get the source code:

$ hg clone

or fork me on:

Running Tests

(Currently not running successfully on Travis-CI until Mac OS X gets supported there.)

To run the tests of icemac.callonchange call:

$ python test

or use zc.buildout:

$ python
$ bin/buildout
$ bin/test

or use callonchange itself:

$ python
$ bin/buildout
$ bin/callonchange

In the last version you have to change something inside the src directory of the package so the observer lets the tests run.

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for icemac.callonchange, version 0.8
Filename, size File type Python version Upload date Hashes
Filename, size icemac.callonchange-0.8.tar.gz (18.0 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page