I've written an irc bot that runs some commands when told so, the commands are predefined python functions that will be called on the server where the bot is running.
I have to call those functions without knowing exactly what they'll do
(more I/O or something computationally expensive, nothing harmful since I review them when I accept them), but I need to get their return value in order to give a reply back to the irc channel.
What module do you recommend for running several of these callbacks in parallel and why?
The threading or multiprocessing modules, something else?
I heard about twisted, but I don't know how it will fit in my current implementation since I know nothing about it and the bot is fully functional from the point of view of the protocol.
Also requiring the commands to do things asynchronously is not an option since I want the bot to be easily extensible.
There is no definitive answer to your question: it really depends what the functions do, how often they are called and what level of parallelism you need.
The threading and multiprocessing modules work in radically different ways.
threading implements native threads within the Python interpreter: fairly inexpensive to create but limited in parallelism due to Python's Global Interpreter Lock (GIL). Threads share the same address space, so may interfere with each other (e.g. if a thread causes the interpreter to crash, all threads, including your app, die), but inter-thread communication is cheap and fast as a result.
multiprocessing implements parallelism using distinct processes: the setup is far more expensive than threads (required creation of a new process), but each process runs its own copy of the interpreter (hence no GIL related locking issues) and run in different address spaces (isolating your main app). The child processes communicate with the parent over IPC channels and required Python objects to be pickled/unpickled - so again, more expensive than threads.
You need to figure out what trade-off is best suited to your purpose.
What module to use for calling user-defined functions in parallel