Importing different implementations of the library

1 view
Skip to first unread message

snim2

unread,
Jul 27, 2010, 5:58:43 PM7/27/10
to python-csp
Just a quick note about this, because Stefan commented the code...

The decision logic for importing the processes / threads versions of
the library is held in csp/csp.py it could probably be simplified. On
obvious way to simplify would just be to say:

try:
import .os_process
except:
import .os_thread

however, when unit testing the code it's useful to be able to test
against every available version of the code via environment variables.
So at some point we need to check os.environ and let the user override
the default behaviour of the library.

I've fixed the other bug though!

Thanks,

Sarah

Stefan Schwarzer

unread,
Jul 27, 2010, 7:01:20 PM7/27/10
to pytho...@googlegroups.com
Hi Sarah,

On 2010-07-27 23:58, snim2 wrote:
> The decision logic for importing the processes / threads versions of
> the library is held in csp/csp.py it could probably be simplified. On
> obvious way to simplify would just be to say:
>
> try:
> import .os_process
> except:
> import .os_thread

If it can be avoided, I wouldn't use a bare except without
specifying any exception classes.

> however, when unit testing the code it's useful to be able to test
> against every available version of the code via environment variables.

I wouldn't use environment variables. I'd rather import
both modules explicitly and, if it's necessary, access the
contents via their respective module namespaces (see below).

As the APIs for both implementations should be the same,
unit tests should work for both CSP process implementations
with only trivial changes. Look at the unit testing code for
the builtins module. There I defined only tests for the
os_process implementation and get tests for other
implementations by making a trivial derived class for each
of them.

> So at some point we need to check os.environ and let the user override
> the default behaviour of the library.

When or why should a user want to do this? I guess, s/he can
either explicitly import the module s/he wants,

from csp import os_process

or choose a "recommended" implementation,

from csp import os_recommended

(maybe with a better name ;-) ). `os_recommended` would
contain some decision logic to import the module/names it
wants. This is similar to the current logic in `csp.py`.

I'm really no friend of "from module import *", but if a
user should be able to afterwards find out which module s/he
has gotten, just define a name `process_implementation` in
each of the modules which contains a constant for the
(perhaps implicitly) chosen implementation. However, if we
have a consistent API, there really shouldn't be a need for
such an introspection.

Stefan

snim2

unread,
Jul 27, 2010, 7:13:13 PM7/27/10
to python-csp
On Jul 28, 12:01 am, Stefan Schwarzer <sschwar...@sschwarzer.net>
wrote:
> Hi Sarah,
>
> On 2010-07-27 23:58, snim2 wrote:
>
> > The decision logic for importing the processes / threads versions of
> > the library is held in csp/csp.py it could probably be simplified. On
> > obvious way to simplify would just be to say:
>
> > try:
> >     import .os_process
> > except:
> >     import .os_thread
>
> If it can be avoided, I wouldn't use a bare except without
> specifying any exception classes.

Very sensible. There are probably a few such instances of a bare
except in the code base :(

> > however, when unit testing the code it's useful to be able to test
> > against every available version of the code via environment variables.
>
> I wouldn't use environment variables. I'd rather import
> both modules explicitly and, if it's necessary, access the
> contents via their respective module namespaces (see below).
>
> As the APIs for both implementations should be the same,
> unit tests should work for both CSP process implementations
> with only trivial changes. Look at the unit testing code for
> the builtins module. There I defined only tests for the
> os_process implementation and get tests for other
> implementations by making a trivial derived class for each
> of them.

Agreed, for the unit testing code it makes a lot of sense. I was
thinking in particular of the benchmarking code where you might want
to say something like (on the command line):

$ export CSP=PROCESSES
$ python my_benchmark.py >results.txt
$ export CSP=THREADS
$ python my_benchmark.py >>results.txt
$ python analyse_results.py results.py

That said, I guess we could build this straight into the benchmarks in
the way you suggest.

> > So at some point we need to check os.environ and let the user override
> > the default behaviour of the library.
>
> When or why should a user want to do this? I guess, s/he can
> either explicitly import the module s/he wants,
>
>     from csp import os_process
>
> or choose a "recommended" implementation,
>
>     from csp import os_recommended
>
> (maybe with a better name ;-) ). `os_recommended` would
> contain some decision logic to import the module/names it
> wants. This is similar to the current logic in `csp.py`.

Yes, I think it's fine to keep everything in csp/csp.py though.

> I'm really no friend of "from module import *", but if a
> user should be able to afterwards find out which module s/he
> has gotten, just define a name `process_implementation` in
> each of the modules which contains a constant for the
> (perhaps implicitly) chosen implementation. However, if we
> have a consistent API, there really shouldn't be a need for
> such an introspection.

Agreed. It's only really useful for things like benchmarks AFAICT. I
tend to see python-csp as a DSL rather than a library, so prefer
import *, but YMMV.

Thanks,

Sarah
Reply all
Reply to author
Forward
0 new messages