Open beloglazov opened 11 years ago
A simple definition of the contract like new_contract('virConnect', lambda x: False)
results in a similar exception:
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/pyqcy/integration.py", line 60, in test
run_tests([prop], verbosity=0, propagate_exc=True)
File "/usr/lib/python2.7/site-packages/pyqcy/runner.py", line 68, in run_tests
failure.propagate_failure()
File "/usr/lib/python2.7/site-packages/pyqcy/properties.py", line 127, in test_one
result.tags = self.__execute_test(coroutine)
File "/usr/lib/python2.7/site-packages/pyqcy/properties.py", line 148, in __execute_test
obj = next(coroutine)
File "/usr/lib/python2.7/site-packages/pyqcy/properties.py", line 81, in generator_func
func(*args, **kwargs)
File "/home/anton/repos/openstack-neat/tests/test_collector.py", line 58, in get_current_vms
collector.get_current_vms(1)
File "<string>", line 2, in get_current_vms
File "/usr/lib/python2.7/site-packages/contracts/main.py", line 267, in contracts_checker
raise e
CheckError: <unprintable CheckError object>
Can you give a minimal working example?
ok, let me see...
I've just made a simple example:
#!/usr/bin/python2
from contracts import contract, new_contract
from contracts.library.miscellaneous_aliases import ist
class ContractTest(object):
pass
new_contract('customContract', ist(ContractTest))
@contract
def test(test):
""" Test a custom contract definition.
:type test: customContract
"""
pass
if __name__ == '__main__':
test("")
And it actually works fine, shows the following error:
Traceback (most recent call last):
File "./test.py", line 24, in <module>
test("")
File "<string>", line 2, in test
File "/usr/lib/python2.7/site-packages/contracts/main.py", line 267, in contracts_checker
raise e
contracts.interface.ContractNotRespected: Breach for argument 'test' to test() in __main__.
Value is not an instance of ContractTest.
checking: function isinstance_of_ContractTest() for value: Instance of str: ''
checking: customContract for value: Instance of str: ''
I need to dig a bit more and understand the difference with my previous setup.
By the way, there is an undocumented feature that allows you to just give the type:
@contract(test=ContractTest)
def test(test):
# pycontracts understands it's a type, checks the type of test
pass
About the original problem: are you sure that the virConnect object is printable? (i.e. object.str() and object.repr() return fine)
Thanks for the tip about the type feature! Does it only work when a contract is specified inside of the decorator? I've tried it with docstrings and it breaks:
@contract
def test(test):
""" Test a custom contract definition.
:type test: ContractTest
"""
pass
This leads to the following error:
Traceback (most recent call last):
File "./test.py", line 14, in <module>
@contract
File "/usr/lib/python2.7/site-packages/contracts/main.py", line 168, in contract_decorator
raise ContractSyntaxError(e.error, e.where)
contracts.interface.ContractSyntaxError: Unknown identifier 'ContractTest'. Did you mean 'Container'? (at char 4), (line:1, col:5)
line 1 >ContractTest
^
|
here or nearby
Regarding the original problem, I think it happens because pyqcy (a testing framework) somehow catches exceptions raised from inside tests and wraps them in another object (CheckError). So it's not a problem of PyContracts. Sorry for bothering you with this!
Yes, that's a limitation. This feature doesn't work inside the docstrings. It's one of the reasons it is not official... I certainly don't want to eval() any string.
In this case, you have to use new_contract. But there is no need of using ist().
from contracts import contract, new_contract
class ContractTest(object):
pass
new_contract('ContractTest', ContractTest)
@contract
def test(test):
""" Test a custom contract definition.
:type test: ContractTest
"""
pass
if __name__ == '__main__':
test("")
Thanks so much for the help! It works :)
Hi Andrea,
I'm trying to define a custom contract using the new_contract function and the ist function from contracts.library.miscellaneous_aliases as follows:
The actual checking of the argument type works, i.e. fails when the argument is not an instance of libvirt.virConnect. However, when it fails, the error message is not properly displayed. I'm getting the following exception:
I suppose instead of, there should be a message like 'Value is not an instance of virConnect'. Do you know what the problem is?
Thanks, Anton