PyContracts is a Python package that allows to declare constraints on function parameters and return values. Contracts can be specified using Python3 annotations, or inside a docstring. PyContracts supports a basic type system, variables binding, arithmetic constraints, and has several specialized contracts and an extension API.
I'm just trying out pycontracts and found this strange behavior when using different contract notations.
I import my module and run the function with an invalid argument and the contract's checks work fine when using this notation:
square_size = 9 # type: int
nr_rows = square_size # type: int
nr_cols = square_size # type: int
@contract(row_nr='int, >= 0, < $nr_rows', col_nr='int, >= 0, < $nr_cols',
returns='int,>= 0, < $square_size')
def loc2square_nr(row_nr, col_nr):
# type: (int, int) -> int
"""Convert location (row, column) to square number.
(int, int) -> int
:param row_nr: Row number to convert to square number.
:param col_nr: Column number to convert to square number.
:return: Square number.
"""
square_nr = (int(row_nr / square_side) * square_side
+ int(col_nr / square_side)) # type: int
return square_nr
But if I change the contract notation to inside the docstring, like this:
square_size = 9 # type: int
nr_rows = square_size # type: int
nr_cols = square_size # type: int
@contract
def loc2square_nr(row_nr, col_nr):
# type: (int, int) -> int
"""Convert location (row, column) to square number.
:param row_nr: Row number to convert to square number.
:type row_nr: int, >= 0, < $nr_rows
:param col_nr: Column number to convert to square number.
:type col_nr: int, >= 0, < $nr_cols
:return: Square number.
:rtype: int, >= 0, < $square_size
"""
square_nr = (int(row_nr / square_side) * square_side
+ int(col_nr / square_side)) # type: int
return square_nr
Python returns a huge error when importing the module (I called it base.py).
This is the final part of the error:
value = self._parseNoCache(instring, loc, doActions, callPreParse)
File "C:\Users\JMatos\Envs\solve_sudoku\lib\site-packages\pyparsing.py", line
1405, in _parseNoCache
tokens = fn( instring, tokensStart, retTokens )
File "C:\Users\JMatos\Envs\solve_sudoku\lib\site-packages\pyparsing.py", line
1049, in wrapper
ret = func(*args[limit[0]:])
File "C:\Users\JMatos\Envs\solve_sudoku\lib\site-packages\contracts\utils.py",
line 247, in f2
return f(*args, **kwargs)
File "C:\Users\JMatos\Envs\solve_sudoku\lib\site-packages\contracts\library\sc
oped_variables.py", line 95, in scoped_parse_action
val = _lookup_from_calling_scope(tokens[0])
File "C:\Users\JMatos\Envs\solve_sudoku\lib\site-packages\contracts\library\sc
oped_variables.py", line 67, in _lookup_from_calling_scope
raise ExternalScopedVariableNotFound(token)
contracts.interface.ExternalScopedVariableNotFound: Token not found: 'square_siz
e'.
>>>
If I understand correctly, pycontracts doesn't recognize the variable square_size in the 2nd notation. But it does on the 1st.
I'm using Python 32b 3.5.4 with pycontracts 1.8.3. I'm running on a Windows 7 Pro x64 PC.
Hello,
I'm just trying out pycontracts and found this strange behavior when using different contract notations. I import my module and run the function with an invalid argument and the contract's checks work fine when using this notation:
But if I change the contract notation to inside the docstring, like this:
Python returns a huge error when importing the module (I called it base.py). This is the final part of the error:
If I understand correctly, pycontracts doesn't recognize the variable square_size in the 2nd notation. But it does on the 1st.
I'm using Python 32b 3.5.4 with pycontracts 1.8.3. I'm running on a Windows 7 Pro x64 PC.
Thanks,
JM