Mailing List Archive

My quarterly question on Design by Contract in Python...
Hi all,

Every so often after a minor or major Python
release I like to ask the gurus of this group
about implementing Design By Contract mechanisms
(a-la Eiffel) in Python.

Has anything changed in the 1.5.x releases that
would make doing this any harder or easier? Have
experiences with the Extension class stuff shown
any new insights?

I'm not trying to turn Python into Eiffel, but
even a partial DBC implementation would be
very useful.

Please be gentle,

Stu
My quarterly question on Design by Contract in Python... [ In reply to ]
[Stuart Hungerford]
> Every so often after a minor or major Python
> release I like to ask the gurus of this group
> about implementing Design By Contract mechanisms
> (a-la Eiffel) in Python.

And if everything runs true to form, they'll leave the question unanswered
for a week, at which point I'll jump in to rekindle the illusion that
someone has been taking this seriously <wink>.

> Has anything changed in the 1.5.x releases that
> would make doing this any harder or easier? Have
> experiences with the Extension class stuff shown
> any new insights?

The good news is that, as of 1.5.2, "assert" has still not been removed from
the language. Other than that, though, no. Well, yes: you can assign to a
class's __bases__ attribute now, so Python is even more dynamic than it was,
dashing all hope of capturing any of the class hierarchy at compile-time.

> I'm not trying to turn Python into Eiffel, but
> even a partial DBC implementation would be
> very useful.
>
> Please be gentle,

There's a large bed of feathers waiting for you in Python's Types-SIG. My
guess is that automated-- or efficiently automatable --DBC's only realistic
hope rides on Python2. Slicker metaprogramming of all kinds is a Python2
goal, and even more interesting than building DBC into the language would be
building a core "type system" on top of which DBC could be built via
metaprogramming magic.

finally-found-a-use-for-curly-braces<wink>-ly y'rs - tim
My quarterly question on Design by Contract in Python... [ In reply to ]
Tim Peters wrote:

>
> [Stuart Hungerford]
> > Every so often after a minor or major Python
> > release I like to ask the gurus of this group
> > about implementing Design By Contract mechanisms
> > (a-la Eiffel) in Python.
>
> And if everything runs true to form, they'll leave the question unanswered
> for a week, at which point I'll jump in to rekindle the illusion that
> someone has been taking this seriously <wink>.

Thanks Tim -- Somehow you always manage to both
inform me and put a smile on my face with your
replies. Thanks!

Now...I wonder if it could be done with a
Python pre-processor?

Stu
My quarterly question on Design by Contract in Python... [ In reply to ]
On Fri, 07 May 1999 22:25:40 +1000, Stuart Hungerford wrote:
>Hi all,

>Every so often after a minor or major Python
>release I like to ask the gurus of this group
>about implementing Design By Contract mechanisms
>(a-la Eiffel) in Python.

Nobody seems to have made this connectionn yet, but...

Sommeone posted a system a while ago which allowed addition of arbitrary
code before and after a function. With some work, that system could be
mixed into a class (perhaps even a metaclass) to implement pre/post
conditions and invariants.

>Stu

--
-William "Billy" Tanksley
"But you shall not escape my iambics."
-- Gaius Valerius Catullus
My quarterly question on Design by Contract in Python... [ In reply to ]
[Stuart Hungerford, smilingly informed]
> ...
> Now...I wonder if it [Eiffel-like design by contract] could be
> done with a Python pre-processor?

What it really needs is someone with both interest and time to pursue it. I
guess that makes it unique in the world <wink>.

Metaclasses, preprocessing, and bytecode rewriting are all plausible
approaches.

looking-forward-to-doing-this-again-after-1.6<1/1.6-wink>-ly y'rs - tim
My quarterly question on Design by Contract in Python... [ In reply to ]
Stuart Hungerford:
|> > Every so often after a minor or major Python release I like to ask
|> > the gurus of this group about implementing Design By Contract
|> > mechanisms (a-la Eiffel) in Python.
...
| Now...I wonder if it could be done with a Python pre-processor?

On that subject, is there a mechanism to "optimize away" a function call?
I'm using something like this:

if __debug__:

def PRE( *precond_list ):
for precond in precond_list: assert precond, "Precondition Violation"

def POST( *postcond_list ):
for postcond in postcond_list: assert postcond, "Postcondition Violation"

else:

def PRE ( *args ): pass
def POST( *args ): pass

In this case, if -O is given, will PRE/POST functions be generated, and
called when invoked? Is there a way to have PRE and POST invocations
effectively be no-ops? Ala:

#ifdef DEBUG
# define PRE(x) assert(x)
#else
# define PRE(x)
#endif

Thanks,

Randall
My quarterly question on Design by Contract in Python... [ In reply to ]
On Sat, 08 May 1999 18:26:13 GMT, wtanksle@dolphin.openprojects.net
(William Tanksley) wrote:

>: On Fri, 07 May 1999 22:25:40 +1000, Stuart Hungerford wrote:
>: >Hi all,
>:
>: >Every so often after a minor or major Python
>: >release I like to ask the gurus of this group
>: >about implementing Design By Contract mechanisms
>: >(a-la Eiffel) in Python.
>:
>: Nobody seems to have made this connectionn yet, but...
>:
>: Sommeone posted a system a while ago which allowed addition of arbitrary
>: code before and after a function. With some work, that system could be
>: mixed into a class (perhaps even a metaclass) to implement pre/post
>: conditions and invariants.

I'm the guy. If interested by the 'patching' module, email to me, I
will give you the code (too large to be posted here I think) and the
html doc file.

A+

Laurent.

---
Laurent POINTAL - CNRS/LURE - Service Informatique Experiences
Tel/fax: 01 64 46 82 80 / 01 64 46 41 48
email : pointal@lure.u-psud.fr ou lpointal@planete.net
My quarterly question on Design by Contract in Python... [ In reply to ]
On Tue, 11 May 1999 06:52:56 -0400, Randall Hopper
<aa8vb@vislab.epa.gov> wrote:

>: In this case, if -O is given, will PRE/POST functions be generated, and
>: called when invoked? Is there a way to have PRE and POST invocations
>: effectively be no-ops? Ala:
>:
>: #ifdef DEBUG
>: # define PRE(x) assert(x)
>: #else
>: # define PRE(x)
>: #endif
>:

I wrote a small tool to automatically comment/uncomment blocs of code
between balises like #<BALISE> and #</BALISE>.
Not perfect (especially if the two balises are not set
correspondingly). Maybe can be optimized. But it does its job and it
took only on quarter of hour to write.

A+

Laurent.


Here my conditional.py file:
------------------------------------------------------------------
"""Change comments status on conditional code in Python.

Generally used to automatically comment/uncomment a serial of lines
between two marks, generally debugging lines.

To comment : python conditional.py COND_SYMB fileName
To uncomment : python conditional.py /COND_SYMB fileName
"""

from sys import argv, exit
from string import find, whitespace

def CountSpaces (l) :
cpt = 0
for c in l :
if (not c in whitespace) : return cpt
cpt = cpt + 1

def Work (lines, symbol, bComment) :
niv = 0 # Number of symbol counted.
blancs = 0
for i in range(len(lines)) :
l = lines[i]

# Search #</SYMBOL>
if (find (l, "#</"+symbol+">") != -1) :
niv = niv-1
if (niv == 0) :
blancs = 0
continue

# Search #<SYMBOL>
if (find (l, "#<"+symbol+">") != -1) :
niv = niv+1
if (niv == 1) :
blancs = CountSpaces (l)
continue

# Process lines between symbols.
if (niv > 0) :
if (bComment) :
l = l[0:blancs] + "#" + l[blancs:]
else :
l = l[0:blancs] + l[blancs+1:]
lines[i] = l

return lines

if __name__ == '__main__' :
if (len (argv) != 3) :
print "Usage: python conditional.py symbol fileName"
print " If symbol is in the form SYMBOL, conditional lines
are commented."
print " If symbol is in the form /SYMBOL, conditional lines
are uncommented."
exit ()

# Get symbol.
symb = argv[1]
if (symb[0]=='/') :
symb = symb[1:]
bComment = 0
else :
bComment = 1

# Read file.
lines = open (argv[2], "r").readlines ()

# Work.
lines = Work (lines, symb, bComment)

# Write file.
open (argv[2], "w").writelines (lines)
------------------------------------------------------------------


---
Laurent POINTAL - CNRS/LURE - Service Informatique Experiences
Tel/fax: 01 64 46 82 80 / 01 64 46 41 48
email : pointal@lure.u-psud.fr ou lpointal@planete.net
My quarterly question on Design by Contract in Python... [ In reply to ]
On Tue, 11 May 1999 12:37:45 GMT, pointal@lure.u-psud.fr (Laurent
POINTAL) wrote:

>: I wrote a small tool to automatically comment/uncomment blocs of code
>: between balises like #<BALISE> and #</BALISE>.
>: Not perfect (especially if the two balises are not set
>: correspondingly). Maybe can be optimized. But it does its job and it
>: took only on quarter of hour to write.

Carreful: the balises must have the same indentation, and the code
between the two balises must be at least with the same indentation of
the balises (note: when I write same, its exactly same, where
tab!=space).
Failing to this rule break the code... (work on a copy to test it).

A+

Laurent.

---
Laurent POINTAL - CNRS/LURE - Service Informatique Experiences
Tel/fax: 01 64 46 82 80 / 01 64 46 41 48
email : pointal@lure.u-psud.fr ou lpointal@planete.net