Question

I am using PyContract (not PyContracts) to implement design-by-contracts for my genetic algorithms framework.

The main module is GA.py, which calls a function from crossover.py (let's call it foocross). I have written precondition and postcondition expressions for foocross.

Now, I would like those conditions to be checked when I run the main in GA.py. I introduced a false precondition in foocross just to test if the contracts were being checked, but it seems that they are not. How do I make sure that the contracts are being checked?

Here's a minimal section of my code:

# GA.py
def main():
    # some code
    crossover.foocross(params)
    # some more code

if __name__ == "__main__":
    main()

#crossover.py
def injectionco(p1, p2, chrom):
    """
        pre:
            isinstance(p1, int) # this should raise an error. p1 is never an int
            isinstance(p2, list)
            isinstance(chrom, int)
            forall(p1, lambda elem: any(isinstance(elem, i.__class__) for i in p2))
            forall(p2, lambda elem: any(isinstance(elem, i.__class__) for i in p1))
            len(p1) == len(p2)

        post:
            p1 is __old__.p1
            p2 is __old__.p2
            p1 == __old__.p1
            p2 == __old__.p2
            isinstance(__return__, p1.__class__)    # returns an individual
            len(__return__) == len(p1)
            id(__return__) not in [id(p1), id(p2)]
            forall(__return__, lambda elem: __return__.count(elem) == 1)
        """

    #code
    return #something

PS: this was a pretty difficult question for me to write because I had to strip out a LOT of my code (since the framework is pretty complex) and I'm new to design-by-contract. So if I've missed out on some information that would help answer this question, please ask and I'll happily provide more info :)

Was it helpful?

Solution

Looking at the example, seems like all you need to do would be:

# this needs to be there unconditionally.
import contract
contract.checkmod(__name__)

if __name__ == '__main__':
   import doctest, GA
   doctest.testmod(GA)

However, this below will NOT work (because inside import GA, contract.checkmod() does not happen):

if __name__ == '__main__':
   import contract
   contract.checkmod(__name__)
   import doctest, GA
   doctest.testmod(GA)

OTHER TIPS

There is another solution. For large code bases, it would be tedious to edit several files to enable/disable contract checking for each module. I was able to call all contract checks from my main module as follows:

#GA.py

import crossover # and all other required modules
import contract

for mod in [crossover]: # put all other imported modules in that list
    contract.checkmod(mod)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top