survey: is shelve broken? should it be fixed?

holger krekel pyth at devel.trillke.net
Wed May 8 06:36:06 EDT 2002


Alex Martelli wrote:
> On Wednesday 08 May 2002 12:16 am, holger krekel wrote:
> 	...
> > Might i ask whether you read my suggestion to
> > implement the "smart"-switch at the global module level?
> 
> Yes, you might:-).
> 
> Unfortunately, globals always have downsides as well as sometimes pluses.
> 
> Say my program uses frameworks A, B, and C.  How ever should I know
> which of those frameworks uses shelve, and how it uses it?  What if
> framework B happens to need shelve's old behavior -- how shall a global
> flag in module shelve deal with that?  If shelve.open's behavior is
> controlled with a local argument, each shelve.open is responsible to know
> whether it needs old or new behavior or is indifferent.  This is doable.  If 
> the control is less fine-grained, and must apply to ALL shelve.open's in
> several independently developed frameworks used by the same program,
> I don't think the problem is even theoretically solvable.

I wonder if this isn't actually only of theoretic importance in our
special case... 

> It's convenient for middling/small programs which have a few calls to
> shelve all under the program author's control.
> 
> It's poisonous for very large programs.
> Globals are often this way.  Handy for a middling program, disaster as
> the program scales up.

Globally that's a valid point. I'd add that different behaviours
for shelve in a largish application don't make things easier. If you
have a shelve instance somewhere you don't really know which behaviour
it adheres to.

I argued in another posting that with the 'global switch' 
you can encapsulate version-dependent *fixes* basically like so:

    assert(pythonversion>2.2.4)
    if pythonversion < 3.0:
        shelve.returncopies=0
        somemodule.otherfix=1

This program will run *without changes* on newer (fixed)
python-versions. And if python3 or python4 don't want
to take care of old broken behaviour this script will still run 
fine. 

Plus if you insist on using the old behaviour (to be 
compatible with python2 and python1.5.2) you can say:

    assert(pythonversion<3.0) 
    if pythonversion > 2.3:
        shelve.returncopies=1

and your code will run on every version up to the one
where the broken behaviour is not allowed any more.

Generally i would *try* to avoid scattering version-dependent
code all over the place. This is really annoying for 
authors and users.

If this doesn't convince you maybe you could agree to this:

- have a global default value

- have a keyword-argument that modifies the instance's behaviour
  and in the absence of the keyword-argument defaults to the 
  global value.

This changes very few lines of your patch and everyone
willing to mix behaviours in large programs could still do 
so. Then i could at least choose  to globally work with the 
'fixed' behaviour rather than passing keyword-arguments 
everywhere.  Note that a large program mixing behaviour will be 
incompatible with older python versions *and* incompatible
with new-enough versions (unless python keeps the switch in forever,
sigh).

More generally, we are talking about a scheme to introduce *fixes* for
'unpythonic/unexpected/astonishing' behaviour that needs
to be preserved for one or two years in case somebody relied
on it. But we should *try* to make it easy for someone to choose to 

- rely on old behaviour (drop compatibility with new-enough pythons)

- rely on new behaviour (drop comptatibility with too-old pythons)

- rely on mixed behaviours (drop compatibility with too-old and too-new
  pythons).

regards,

    holger





More information about the Python-list mailing list