运行时验证框架

pythonrv的Python项目详细描述


#pythonrv是python的运行时验证框架。这是目前正在撰写的硕士论文的
实现。请参见
[tgwizard.github.com/论文](http://tgwizard.github.com/thesis)了解更多
信息。

[![构建状态](https://secure.travis-ci.org/tgwizard/pythonrv.png)(http://travis-ci.org/tgwizard/pythonrv)

\使用
[pip](http://www.pip-installer.org/en/latest/index.html)安装它,就像
这样:


pip install pythonrv

pythonrv已经用python 2.7进行了测试。它还不能与python 3一起工作。

可能还有
[virtualenvwrapper](http://www.doughellmann.com/docs/virtualenvwrapper/):



运行测试:

./run tests.sh



在执行过程中的程序。验证是通过检查程序是否符合其规范来完成的。它基于这样一种思想,即规范应该用目标语言编写,其方式与单元测试类似,因此,让
它们更具表现力,也更易于学习。

pythonrv中编写的规范被"烘焙"到目标的源代码中,这样,每当调用函数时,规范都能很好地执行。

显示pythonrv api的示例。有关更实际的
示例,请参见
[示例](https://github.com/tgwizard/pythonrv/tree/master/examples)文件夹。
[单元
测试](https://github.com/tgwizard/pythonrv/tree/master/pythonrv/test)可能也有助于了解什么是有效的。

首先,假设我们有一个函数我们要验证的正确性:

~~ python
factorial.py
def factorial(n):
res=1
对于范围(2,n)内的i
res*=i
return res
~~

我们现在可以为它编写规范,最好在另一个文件中:

~~ python rv import rv的python
rvspecs.py
import factorial

@rv.monitor(fact=factorial.factorial)
仅定义输入规范(event):
断言事件.fn.fact.inputs[0]>;=0

@rv.monitor(fact=factorial.factorial)
@rv.spec(when=rv.post)
def simple_specification(event):
assert event.fn.fact.result>;=event.fn.fact.inputs[0]

@rv.monitor(fact=factorial.factorial)
@rv.spec(when=rv.post,history_size=rv.infinite_history_size)
def simple_specification(event):
in_out=(event.fn.fact.inputs[0],event.fn.fact.result)
old_in_out=[(x.inputs[0],x.result)for x in event.fn.fact.history]

for a in old_in_out:
if in_out[0]>;旧的输入输出[0]:
断言输入输出[1]>;=旧的输入输出[1]
~~

>第一个规范检查所有输入是否大于或等于零。
第二个规范检查所有输出是否至少与输入一样大。第三个规范根据函数的
历史数据验证输入/输出;给定较大的输入,输出必须大于或等于以前的值。注意,最后两个规范是在调用factorial之后执行的。这使它们可以访问返回值和输出参数。


向规范发送一个事件,其中包含被调用函数的信息、其
历史记录以及所有规范监控的功能。

~~ python rv import rv中的python

import mymodule

@rv.monitor(foo=mymodule.foo,bar=mymodule.bar)
@rv.spec(when=rv.post,历史记录大小=20)
定义更多的规范(事件):
#我们还可以检查是否调用了函数assert event.fn.foo.called

输出和结果可以这样访问:输入参数元组的副本event.fn.foo.inputs;输入关键字参数dict
event.fn.foo.input
event.fn.foo.outputs
event.fn.foo.output
event.output
event.fn.foo.output
event.fn.foo.result
#我们可以访问上一个事件,前一个函数调用event.prev
event.fn.foo.prev

访问"整个"历史
对于事件中的旧事件。历史:
传递
;对于事件中的旧调用。fn.foo。历史:
传递
;这显然是一个很大的内存消耗,因此,默认情况下,历史记录中只存储两个
事件(此事件和前一事件)。这是可以更改的,
就像我们在这里使用@rv.spec(history\u size=20)

我们还可以说,下次调用某个受监视的函数时,
事件。下一个名为"应该"(event.fn.bar)

没有必要继续这个验证"

def call_next_time(event):
活动
监视。这可以自定义:

~~ python
@rv.monitor(f=func)
@rv.spec(when=rv.post)
def spec(event):
pass

不需要显式指定pre
@rv.monitor(f=func)
@rv.spec(when=rv.pre)
def spec_before(event):
pass
~~


`语句可以)。当这种情况发生时,pythonrv在默认情况下允许这个错误传播,如果没有注意到,程序就会停止。

如果这不是所需的行为,则可以对其进行更改。对于日志记录错误
处理程序,请从python rv import rv
rv.configure(error_handler=rv.loggingerrorhandler())
~~~

通过[python logging
模块](http://docs.python.org/library/logging.html)。


规范可以用错误级别进行标记:

~~ python
@rv.monitor(f=func)
@rv.spec(level=rv.debug)
def spec(event):
pass
~~

调试、信息、警告、错误和严重错误(只需
与日志模块中一样)。


有关错误处理的更多信息,请参阅[源代码
(source)"(https://github.com/tgwizard/python rv/blob/master/pythonrv/rv.py)和
[单元
测试(https://github.com/tgwizard/pythonrv/blob/master/pythonrv/test/rv戋u configuration戋u test.py)。


具体原因如下。

在编写规范时,这是**错误的**方法:

~~ python
这不起作用
从mymodule import myfunc
@rv.monitor(f=myfunc)
def spec(event):
pass
~~~~

这是正确的方法:

~~ python
这起作用
importmymodule
@rv.monitor(f=mymodule.myfunc)
def spec(event):
pass
~~~


第一个示例创建对myfunc的引用并将其插入到当前模块(定义规范的模块)中。监视函数意味着在它周围添加一个包装器,在本例中,我们只为当前模块中的myfunc引用添加一个包装器。我们不修改mymodule,它将使用所有其他代码。第二个例子解决了这个问题。

上述原因还解释了为什么在执行的一开始就应该导入/定义规范:其他模块可能会使用from x import y样式,如果它们在rv规范
有机会监视/检测函数之前这样做,它们将得到
对它们的未监视/未检测引用。

pythonrv复制参数以确保它存储的历史不会在之后和/或从外部更改。这也使得输入参数实际上是输入
参数,而不是由函数本身修改。

这有时可能被认为是不必要的,或者是不必要的开销。它可能有时甚至不起作用,例如当涉及到
[`cstringio`](http://docs.python.org/library/stringio.html)时。对于v1.4.x中的[django](https://www.djangoproject.com/)请求,情况是这样的:
(但不在master上)。


对于所有规范,都可以关闭复制:

~~ python
from python rv import rv
rv.configure(enable_copy_args=false)
~~

规范:

~~ python rv import rv中的python
@rv.monitor(func=somemodule.somefunc)
@rv.spec(enable_copy_args=false)
def spec(event):
pass
~~~~

注意:对一个规范禁用参数复制实际上会对所有规范禁用参数复制监控该规范的功能。其他监视相同函数的规范也不会得到参数复制。这是"一个特性"。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java集合属性值   java字符串==运算符是否比较引用?   java是否存在过太多的ListView或适配器?   json获取java中类路径中下载的文件   我可以用java代码解决数据库并发问题吗?   在多个线程中使用forEach()或使用forEach()和lambdas进行java集合迭代   java输出JFrame中的整个循环   java禁用高度详细的日志记录   java在没有特定属性的对象中访问模型的值   java Smack xmpp建立连接   处理过时域对象引起的并发问题的java策略(Grails/GORM/Hibernate)   java从ObservableList中提取元素   使用图像进行java相似图像搜索   java ListView和图像:我快疯了   在Java中,如何从毫秒时间戳中提取一天的周期?   java我需要这样的设计,但我面临两个问题   java如何获取JGoodies FormLayout中的单元格大小   Spring引导生成的java War文件未部署到Weblogic 12c