Python Tech

Python.org的相关技术

Python.org使用了Django框架,基于Python3.3开发,是在生产环境应用Python3+Django的好例子,所以clone了它的源代码来学习,使用的是868d254版,整理如下。

Deploy

搭建Python环境自然先想到virtualenv,但Python.org源代码根目录里有Vagrantfile文件,支持用vagrant来搭建环境。虽然之前做ROR的环境时都配好了,但Python.org的配置用vagrant 1.0.1版本运行会出错,升级成最新的vagrant 1.5.1就正常了,执行vagrant up命令会自动下载Ubuntu 12.04 64bit来部署:

$ vagrant up
==> default: Successfully added box ‘hashicorp/precise64’ (v1.1.0) for ‘virtualbox’!
==> default: Setting the name of the VM: pythondotorg_default_1396007711925_54940
default: Adapter 1: nat
==> default: Forwarding ports…
default: 8000 => 8000 (adapter 1)
==> default: Booting VM
==> default: Running provisioner: chef_solo
Generating chef JSON and uploading
Running chef-solo
[2014-03-29T03:28:59+00:00] INFO: *** Chef 10.14.2 ***

如果宿主机是32位的,通常需要在VirtualBox配置文件或者图形界面中取消勾选Enable PAE/NX,否则可能会报VT-x is not available. (VERR_VMX_NO_VMX).的错误。网速很差的情况下可以先把box文件下载到本地,再修改配置文件config.vm.box = “box文件名”,重新执行vagrant up会直接使用指定的box文件。

输出的最后一行显示vagrant运行了chef-sole,用Chef来做配置管理,配置文件和命令都在源代码的chef/目录下, 会根据这些配置自动安装数据库(postgresql)、对应的Python/Pip版本、依赖的Python包。该项目的Django版本是1.5.4,Django1.5开始支持Python3。从commit记录来看,Python.org的开发者们最初是使用1.5a1,升级到1.5.4就没有再升级过版本。

Chef执行结束后运行vagrant ssh连到虚拟机,会自动切换到virtualenv中。migrate数据库后,启动Django测试服务器就能访问网站了。

我clone的这个版本漏掉了susy,需要手动gem install 装上;数据库密码可以在chef/roles/python-dev-box.json里清掉,如果用dj-database-url要设置export DATABASE_URL=”postgres://postgres:pydotorg@localhost/python.org”

Testing

Python.org的测试代码有用Django的TestCase,也有用Python自带的unittest,用coverage测试覆盖率得到的报告结果是87%:

$ coverage report

Name Stmts Miss Branch BrMiss Cover
TOTAL 3007 310 296 107 87%

测试代码用到了ddt,实现在一个测试用例中使用多个测试数据,比如这段代码(正则部分很有意思所以一起复制了):


import ddt
import unittest
import re

PAGE_PATH_RE = re.compile(r"""
    ^
    /?                      # We can optionally start with a /
    ([a-z0-9-\.]+)            # Then at least one path segment...
    (/[a-z0-9-\.]+)*        # And then possibly more "/whatever" segments
    /?                      # Possibly ending with a slash
    $
    """,
    re.X
)

@ddt.ddt
class PagePathReTests(unittest.TestCase):

    good_paths = {
        "path" : 1,
        "path/2" : 2,
        "yet/another/path/wow": 3,
        "/initial-slash" : 4,
        "trailing/slash/" : 5,
    }

    bad_paths = (
        "Path",
        "",
        "no_underscores",
        "no/special!/chars?",
    )

    @ddt.data(*good_paths)
    def test_good_path(self, p):
        self.assertTrue(PAGE_PATH_RE.match(p), "'%s' didn't match (it shoulld)" % p)

    @ddt.data(*bad_paths)
    def test_bad_path(self, p):
        self.assertFalse(PAGE_PATH_RE.match(p), "'%s' matched (it shouldn't)" % p)

引入dtt,在名为ddt.data的decorator中传入一个可iterate的对象作为参数,也支持直接读取json文件,执行测试时就自动遍历了。

Others

就架构来说,其实我最关心的是API部分,结果Python.org的API还是用tastypie实现的,非常规范的实现方式,目前没什么可借鉴的。tastypie我虽然11年就写文章分享过,但至今为止只在两个项目中用过,其他项目要不就是直接nodejs+restify来做,要不就自己手写。

另一个小发现是整个项目用了不少的models.Manager,确实简化了models.py的代码,也让结构更清晰了,看来以后这部分还是不能偷懒。以及,forms仍然没人用…

Afterword

Python3发布也五六年了,一直没有取代Python2。不用Python3的理由很多,它不向下兼容,性能也没大的提升,看了Python.org的源代码,发现其实没用到多少Python3的语言特征。可能跟Web开发的特性有关:合作开发(代码不能写得太复杂让别人都看不懂)强调服务稳定(不能随便引入新特性避免兼容问题)。但我还是建议各位升级到Python3,比如:虽然对于大部分开发者来说,Python3解决的坑,各位在Python2里基本都踩过了,但至少是为了不继续坑其它人,咱们还是往Python3上转吧。

0 0 投票数
文章评分
订阅评论
提醒
guest

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

0 评论
内联反馈
查看所有评论