werkzeug源码阅读

前言 基于flask 2.0.2 Local其实来源于ThreadLocal。ThreadLocal可以简单理解为用来管理不同线程中具有同一变量名、同一逻辑、但有不同具体内容的数据,使得数据只在当前线程有效。这是直观表现以及通常用法;更准确来说是管理不同线程的数据,实现thread-safe和thread-specific 这么说的原因是,我们写代码时通常只起一个变量名,但它们指代很多不同具体的个体,类似于我们起的名是一个类,代码运行时处理的是这个类的多个实例。例如A家有小孩代号为X, B家有小孩代号也为X,我们在获取它们家小孩名字时都访问了X,但X是两个不同的人。 flask的request就是基于上面的思想,后台接收到的请求都是叫request,但是是不同用户发出的request(相当于上面例子中的不同家庭的X), 即不同上下文中request具体内容不同 werkzeug实现自己Local的原因 flask需要处理线程和协程(如gevent)两种情况,而threading.ThreadLocal()只支持线程这一种情景 单纯的threading.ThreadLoacl()不能满足web框架的需求 contextvar的出现是因为协程的原因。其用来管理不同协程之间的数据,可以类比上面的ThreadLocal。且contextvars是用来取代ThreadLocal的,官方文档中描述: 在多并发环境中,有状态上下文管理器应该使用上下文变量,而不是 threading.local() 来防止他们的状态意外泄露到其他代码。 werkzeug.local.py包含内容 function: get_ident() class: Contextvar function: release_local() class: Local() class: LocalStack() class: LocalManager() class: _ProxyLookup() class: _ProxyIOp() function: _l_to_r_op() class: LocalProxy() 1. function: get_ident() 返回当前线程的标识,这个标识是唯一的,这意味着我们能唯一找到目标线程。 若使用了greenlet,则get_ident()实则为greenlet.getcurrent() 否则为threading.get_ident() 这个函数将在werkzeug 2.1移除 2. Class: Contextvar python3.7 加入了contextvars.ContextVar即上下文变量,用于管理不同协程的数据。 local.py中处理ContextVar的逻辑为: 优先使用contextvars.ContextVar 检查是否使用greenlet或evenlet,且判断是否给contextvar打补丁 若不能使用contextvars.ContextVar或者没有打好补丁,那么使用flask实现的一个简单的ContextVar,其含有一个storage字典,用于存储键值对:key=上下文标识, value=上下文字典,上下文标识在线程时为线程id,为协程时为协程id;上下文字典则用来存储对应上下文的数据,通过上下文标识获得该字典。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 class ContextVar: # type: ignore """A fake ContextVar based on the previous greenlet/threading ident function....

created: 2020-04-16  |  updated: 2020-04-16  |  阿秀

flask测试

测试 Testing Flask Applications Testing Flask Applications中文翻译 pytest相关文档 @pytest.fixture @pytest.mark.parametrize pytest的一个系列教程 要点提炼 Flask提供的测试渠道是使用Werkzeug的Client类 文件结构: 在应用的根文件夹中添加一个测试文件夹tests, 在里面新建各个测试脚本,名称类似test_*.py的文件会被 pytest 自动发现 conftest.py为全局配置文件,我们可以在里面实例化测试用的client和已经登陆了的client pytest的teardown是通过生成器返回执行对应语句实现的

created: 2020-03-21  |  updated: 2020-03-25  |  阿秀