
节日问候!
在我开始之前,我想先说清楚我将要解释的是些“窍门”。他们不是“最好的做法”,至少在一种情况下是不可取的。
说到不可取的做法,我会适时写一个“setup.py陷阱”的博文,这都是我相信你不会在setup.py模块做出的事情。
这些窍门让我使用python做打包管理变得更简单。在你完善他们之前,我建议你至少有些关于创建新包的基本经验。学python打包的两种方法是New Library Sprint (初级)和 Python Packaging User Guide (高级些)。
一切都是从这里开始的。一天我在看汤姆的代码时发现python setup.py publish命令在Django Rest Framework里的 setup.py模块里面。它像这样:
| 12345678910111213141516 | # setup.pyimport osimport sys # I\’ll discuss version tricks in a future blog post.version = \”42.0.0\” if sys.argv[–1] == \’publish\’: os.system(\”python setup.py sdist upload\”) os.system(\”python setup.py bdist_wheel upload\”) print(\”You probably want to also tag the version now:\”) print(\” git tag -a %s -m \’version %s\’\” % (version, version)) print(\” git push –tags\”) sys.exit() # Below this point is the rest of the setup() function |
用这种方法太赞了,我不需要去查找那有些晦涩的python setup.py sdist upload命令,或是真的很让人困惑的python setup.py bdist_wheel upload命令了。取而代之的是,当要把包发布在PyPI上时,我只需要打下:
| 1 | $ python setup.py publish |
好记多了!
汤姆的python setup.py publish指令的问题在于,他强迫我去打出git tag命令。好吧,诚实些,他让我复制/粘贴我屏幕上的输出。因此,全靠我自己,我“发明”了python setup.py tag 指令:
| 123456 | # setup.py if sys.argv[–1] == \’tag\’: os.system(\”git tag -a %s -m \’version %s\’\” % (version, version)) os.system(\”git push –tags\”) sys.exit() |
很漂亮,哈?现在我不需要去记住那么多模糊的git命令。我就得到了短版python setup.py publish命令:
| 1234 | if sys.argv[–1] == \’publish\’: os.system(\”python setup.py sdist upload\”) os.system(\”python setup.py bdist_wheel upload\”) sys.exit() |
当我需要做一个版本时,我用我的代码,然后打出:
| 12 | $ python setup.py publish$ python setup.py tag |
我为什么不合并那些代码?嗯,你不可以把“RC1”或“-alpha”用作你PyPI的版本名称。分离这些命令,我可以对我的包的发布有更精细的掌控。我被鼓励用alpha、beta,还有在git tag发布参与者,而不是正式的PyPI发布。
我很确定我的一些读者在这个窍门中会遇到很严重的问题。事实上,依据管理python包的基础建设的人的回应,这会在我接下来的“陷阱”博文中讲。
那么然后……
我喜欢py.test。我曾写过关于使用py.test的博客。我试着在各处用它。然而,我真的不是必须用python setup.py test的狂热分子。我感觉到用py.test不舒服的那一刻是它让我在setup.py中添加特殊类时。
不幸的是,有另一种方式:
| 1234567891011121314 | if sys.argv[–1] == \’test\’: test_requirements = [ \’pytest\’, \’flake8\’, \’coverage\’ ] try: modules = map(__import__, test_requirements) except ImportError as e: err_msg = e.message.replace(\”No module named \”, \”\”) msg = \”%s is not installed. Install your test requirments.\” % err_msg raise ImportError(msg) os.system(\’py.test\’) sys.exit() |
只意味着我要添加一个简单的代码来用py.test和python setup.py test:
| 1 | $ python setup.py test |
理论上,可以运行pip install命令安装缺少依赖包,或者从requirements文件中调用。但是,由于这是“窍门”,我想让它保持简洁好用。如果我用这个得到了足够的好结果,我会更新这个包括缺少要求的pip调用的例子。
注意:这不是说我不用tox。实际上,我用tox来调用我那一版本的python setup.py test。
有些人会问,“你为什么不利用子进程库来用这些shell命令呢?”
我的答案是,“因为,如果我杀鸡还需要用宰牛刀的话,未免太过了。”对于这些简单的窍门,os.system()函数就很够用了。
我一开始在Mac OSX和Linux上编程,我的很多开源包使用Windows。感谢AppVeyor,我正不断测试在那环境中的代码。实际上,我会给Windows使用者改进我的“窍门”。
2015年初会发布“陷阱”博客,敬请期待