A small task runner inspired by npm scripts.

run, task, runner, execute, bump, bumper, build, tool, npm, build-tool, cli, python, python2, python3, task-runner
pip install pyxcute==0.8.1



Documentation Status .github/workflows/build.yml

A small task runner inspired by npm scripts.


  • Use it like setuptools.
  • Chain tasks with _pre, _err, _post, _fin suffix.
  • A builtin Bump task which can bump version with semver.
  • A small set of cross-platform CLI utils.


From pypi

pip install pyxcute



Create a cute.py file:

from xcute import cute

  hello = 'echo hello xcute!'

then run:

$ cute hello
> Task: hello
> Cmd: echo hello xcute!
hello xcute!
If you got a "not a command" error, see How do I make Python scripts executable?)

"hello" is the name of the task that should be executed. If cute.py is executed without a task name, it will run the "default" task.

Provide additional arguments:

$ cute hello 123
> Task: hello
> Cmd: echo hello xcute! 123
hello xcute! 123

The arguments will be passed into the executor, which is xcute.Cmd.__call__ in this case.


It can be a str:

from xcute import cute

  hello = 'echo hello'

If it match the name of another task, pyxcute will execute that task:

from xcute import cute

  hello = 'world', # execute "world" task when "hello" task is executed
  world = 'echo I am world task'

Use a list:

from xcute import cute

  hello = ['echo task1', 'echo task2']

Using an Exception would make the task fail:

from xcute import cute
  hello = Exception("error message")

Use anything that is callable:

from xcute import cute

  hello = lambda: print('say hello')

Actually, when you assign a non-callable value as a task, pyXcute converts it into a callable according to its type.

Task chain

Define the workflow with _pre, _err, _post, _fin suffix:

from xcute import cute

        hello_pre = 'echo _pre runs before the task',
        hello = 'echo say hello',
        hello_err = 'echo _err runs if there is an error in task, i.e, an uncaught exception or non-zero return code',
        hello_post = 'echo _post runs after the task if task successfully returned',
        hello_fin = 'echo _fin always runs after _post, _err just like finally'

When a task is executed, the task runner try to execute _pre task first, then the task itself, then the _post task. If the task raised an exception, then it goes to the _err task. _fin task would be executed whenever the task failed or not.

Pseudo code:

run(name + "_pre")
        run(name, args)
except Exception:
        run(name + "_err")
        run(name + "_post")
        run(name + "_fin")

Format string

pyXcute expands the command string with xcute.conf dictionary. The expansion is happened at run-time:

from xcute import conf, cute

conf["my_name"] = "world"

def change_my_name():
  conf["my_name"] = "bad world"

  hello = [
    "echo hello {my_name}",
    "echo hello {my_name}"
$ cute hello
> Task: hello
> Cmd: echo hello world
hello world
> Cmd: echo hello bad world
hello bad world

Cross-platform utils

There are some CLI utils inspired by npm-build-tools, including:

  • x-clean
  • x-cat
  • x-copy
  • x-pipe

Run each command with -h to see the help message.

Live example

Checkout the cute file of pyXcute itself.




  • 0.8.0 (Feb 4, 2024)
    • Change: drop natsort, implement filename sorting by ourselves.
  • 0.7.0 (Oct 22, 2023)
    • Change: now we only test pyxcute on Python>=3.7.
    • Add: cfg argument in Bump.
  • 0.6.0 (Nov 1, 2019)
    • Add: LiveReload.
  • 0.5.2 (Jun 14, 2018)
    • Add: support bumper argument in Bump.
    • Add: support Python 3.4. Drop subprocess32.
  • 0.5.1 (May 12, 2018)
    • Add: conf["py"] variable.
  • 0.5.0 (May 11, 2018)
    • Add: support Python 2.
    • Add: documentation.
    • Add: Skip, run_task, task_converter.
    • Add: `Bump` task now update the version number inside `setup.cfg`.
    • Fix: Cmd task failed on Unix due to shell=True and passing args as a list.
    • Change: the command of `Cmd` is now logged. The log message is also changed.
    • Drop: `noop`.
  • 0.4.1 (Apr 3, 2017)
    • Better description for x-clean.
    • Fix broken pipe error in x-pipe.
  • 0.4.0 (Mar 28, 2017)
    • Switch to setup.cfg.
    • Add log, exc, noop, Throw, Try.
    • Drop Exc, Exit.
    • Add x-* utils.
  • 0.3.1 (Mar 23, 2017)
    • Find version from {pkg_name}/__pkginfo__.py.
  • 0.3.0 (Jul 21, 2016)
    • Add pkg_name task.
    • Add default tasks bump, version.
  • 0.2.0 (May 14, 2016)
    • Add _fin tag, which represent finally clause.
    • Add Exc and Exit tasks.
  • 0.1.2 (Apr 20, 2016)
    • Move _pre out of try clause.
  • 0.1.1 (Apr 20, 2016)
    • Bump dev status.
  • 0.1.0 (Apr 20, 2016)
    • First release.