Porting from SimPy 3 to 4

SimPy 4 drops support for Python 2.7 and requires Python 3.6+. SimPy 4 also breaks compatibility with SimPy 3 in a few minor ways.

Python 3.6+

When porting a SimPy application to SimPy 4, the first step is to ensure that the application works with SimPy 3 on Python >= 3.6. Once the application works with Python 3.6, most of the work in porting to SimPy 4 is complete.

For more information on porting from Python 2 to 3, see this guide from the Python docs.

Environment Subclasses

The BaseEnvironment class has been removed in SimPy 4. The Environment class is now the most base environment class. Any code that inherited from BaseEnvironment should be modified to inherit from Environment instead.

For example, the following SimPy 3 code:

class MyEnvironment(simpy.BaseEnvironment):
    ...

would be rewritten as follows for SimPy 4:

class MyEnvironment(simpy.Environment):
    ...

Returning from Process Generators

In Python 2 it is a syntax error for a generator (i.e. a function using the yield keyword) to return a value using the return keyword. SimPy 3, supports a process generator returning a value via the Environment.exit(value) method, which simply raises a StopProcess exception. This mechanism was required for Python 2, but also works with Python 3.

In Python 3, it is legal to use return to return a value from a generator. Returning from a Process generator is also supported in SimPy 3 for applications using Python 3 exclusively.

In SimPy 4, the Environment.exit() method and the StopProcess exception are eliminated. Applications with generators that need to either return early or return a value must use the return Python keyword.

Note

No change is required for generators that do not return a value or that do not have control flow that requires returning early. This is the most common case for process generators used with SimPy.

Once a SimPy 3 application is ported to run with Python 3, it may then replace any uses of Environment.exit(value) and raise StopProcess(value) with return value. Once all occurrences are changed, the application will be ready to run with SimPy 4.

Example: Return from Generator

In the following example, Environment.exit() is used to return the first the first “needle” from a store of items. When using SimPy 3 with Python 2, this is the only way to return a value from a process generator.

def find_first_needle(env, store):
    while True:
        item = yield store.get()
        if is_needle(item):
            env.exit(item)  # Python2 generators cannot use return

def proc(env, store):
    needle = yield env.process(find_first_needle(env, store))

In SimPy 4 or with SimPy 3 and Python 3, find_first_needle() can be rewritten as:

def find_first_needle(env, store):
    while True:
        item = yield store.get()
        if is_needle(item):
            return item  # A Python3 generator can return

Sticking with SimPy 3

For applications that are not yet ready to upgrade to SimPy 4 and Python 3, or that may never upgrade, the SimPy dependency must be pinned to version 3.x.

When installing SimPy with pip, use the following to force the latest SimPy 3.x to be installed:

pip install 'simpy<4'

A similar version specification can be used in requirements files:

simpy<4

Or in the install_requires list in a setup.py file:

setup(
    ...,
    install_requires=['simpy<4'],
    ...,
)