<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>润物无声 &#187; PyPI</title>
	<atom:link href="http://blog.zhourunsheng.com/tag/pypi/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.zhourunsheng.com</link>
	<description>天空一朵雨做的云</description>
	<lastBuildDate>Sat, 08 May 2021 05:17:21 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.41</generator>
	<item>
		<title>Python模块发布文件setup.py vs requirements.txt</title>
		<link>http://blog.zhourunsheng.com/2013/08/python%e6%a8%a1%e5%9d%97%e5%8f%91%e5%b8%83%e6%96%87%e4%bb%b6setup-py-vs-requirements-txt/</link>
		<comments>http://blog.zhourunsheng.com/2013/08/python%e6%a8%a1%e5%9d%97%e5%8f%91%e5%b8%83%e6%96%87%e4%bb%b6setup-py-vs-requirements-txt/#comments</comments>
		<pubDate>Sun, 04 Aug 2013 09:06:39 +0000</pubDate>
		<dc:creator><![CDATA[润物无声]]></dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[PyPI]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.zhourunsheng.com/?p=1710</guid>
		<description><![CDATA[<p>我们都知道发布Python模块的时候需要准备几份文件，其中就包括了setup.py和requirements. [&#8230;]</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2013/08/python%e6%a8%a1%e5%9d%97%e5%8f%91%e5%b8%83%e6%96%87%e4%bb%b6setup-py-vs-requirements-txt/">Python模块发布文件setup.py vs requirements.txt</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></description>
				<content:encoded><![CDATA[<p>我们都知道发布Python模块的时候需要准备几份文件，其中就包括了setup.py和requirements.txt，这两份文件中都需要填写待发布模块的依赖关系，那么是不是这样就会出现信息的重复，维护起来也不方便呢？ 如下的文章解释了这两个文件中重复信息的不同功用，前者为“虚引用”，后者为“具体引用”，那么他们利用的场合和背后的机制是什么样子的，马上就会知晓了。</p>
<p>There's a lot of misunderstanding between <code>setup.py</code> and <code>requirements.txt</code> and their roles. A lot of people have felt they are duplicated information and have even created <a href="https://pypi.python.org/pypi/pbr/#requirements">tools</a> to handle this "duplication".<span id="more-1710"></span></p>
<h2>Python Libraries</h2>
<p>A Python library in this context is something that has been developed and released for others to use. You can find a number of them on <a href="https://pypi.python.org/pypi">PyPI</a> that others have made available. A library has a number of pieces of metadata that need to be provided in order to successfully distribute it. These are things such as the Name, Version, Dependencies, etc. The <code>setup.py</code> file gives you the ability to specify this metadata like:</p>
<div>
<pre>from setuptools import setup

setup(
    name="MyLibrary",
    version="1.0",
    install_requires=[
        "requests",
        "bcrypt",
    ],
    # ...
)</pre>
</div>
<p>This is simple enough, you have the required pieces of metadata declared. However something you don't see is a specification as to where you'll be getting those dependencies from. There's no url or filesystem where you can fetch these dependencies from, it's just "requests" and "bcrypt". This is important and for lack of a better term I call these "abstract dependencies". They are dependencies which exist only as a name and an optional version specifier. Think of it like duck typing your dependencies, you don't care what specific "requests" you get as long as it looks like "requests".</p>
<h2>Python Applications</h2>
<p>Here when I speak of a Python application I'm going to typically be speaking about something that you specifically deploy. It may or may not exist on PyPI but it's something that likely does not have much in the way of reusability. An application that does exist on PyPI typically requires a deploy specific configuration file and this section deals with the "deploy specific" side of a Python application.</p>
<p>An application typically has a set of dependencies, often times even a very complex set of dependencies, that it has been tested against. Being a specific instance that has been deployed, it typically does not have a name, nor any of the other packaging related metadata. This is reflected in the abilities of a <a href="http://pip-installer.org/">pip</a>requirements file. A typical requirements file might look something like:</p>
<div>
<pre># This is an implicit value, here for clarity
--index https://pypi.python.org/simple/

MyPackage==1.0
requests==1.2.0
bcrypt==1.0.2</pre>
</div>
<p>Here you have each dependency shown along with an exact version specifier. While a library tends to want to have wide open ended version specifiers an application wants very specific dependencies. It may not have mattered up front what version of requests was installed but you want the same version to install in production as you developed and tested with locally.</p>
<p>At the top of this file you'll also notice a <code>--index https://pypi.python.org/simple/</code>. Your typical requirements.txt won't have this listed explicitly like this unless they are not using PyPI, it is however an important part of a <code>requirements.txt</code>. This single line is what turns the abstract dependency of <code>requests==1.2.0</code> into a "concrete" dependency of "requests 1.2.0 from https://pypi.python.org/simple/". This is not like duck typing, this is the packaging equivalent of an <code>isinstance()</code> check.</p>
<h2>So Why Does Abstract and Concrete Matter?</h2>
<p>You've read this far and maybe you've said, ok I know that <code>setup.py</code> is designed for redistributable things and that <code>requirements.txt</code> is designed for non-redistributable things but I already have something that reads a <code>requirements.txt</code> and fills out my <code>install_requires=[...]</code> so why should I care?</p>
<p>This split between abstract and concrete is an important one. It was what allows the PyPI mirroring infrastructure to work. It is what allows a company to host their own private package index. It is even what enables you to fork a library to fix a bug or add a feature and use your own fork. Because an abstract dependency is a name and an optional version specifier you can install it from PyPI or from Crate.io, or from your own filesystem. You can fork a library, change the code, and as long as it has the right name and version specifier that library will happily go on using it.</p>
<p>A more extreme version of what can happen when you use a concrete requirement where an abstract requirement should be used can be found in the <a href="http://golang.org/">Go language</a>. In the go language the default package manager (<code>go get</code>) allows you to specify your imports via an url inside the code which the package manager collects and downloads. This would look something like:</p>
<div>
<pre>import (
        "github.com/foo/bar"
)</pre>
</div>
<p>Here you can see that an exact url to a dependency has been specified. Now if I used a library that specified its dependencies this way and I wanted to change the "bar" library because of a bug that was affecting me or a feature I needed, I would not only need to fork the bar library, but I would also need to fork the library that depended on the bar library to update it. Even worse, if the bar library was say, 5 levels deep, then that's a potential of 5 different packages that I would need to fork and modify only to point it at a slightly different "bar".</p>
<h3>A Setuptools Misfeature</h3>
<p>Setuptools has a feature similar to the Go example. It's called<a href="http://pythonhosted.org/setuptools/setuptools.html#dependencies-that-aren-t-in-pypi">dependency links</a> and it looks like this:</p>
<div>
<pre>from setuptools import setup

setup(
    # ...
    dependency_links = [
        "http://packages.example.com/snapshots/",
        "http://example2.com/p/bar-1.0.tar.gz",
    ],
)</pre>
</div>
<p>This "feature" of setuptools removes the abstractness of its dependencies and hardcodes an exact url from which you can fetch the dependency from. Now very similarly to Go if we want to modify packages, or simply fetch them from a different server we'll need to go in and edit each package in the dependency chain in order to update the <code>dependency_links</code>.</p>
<h2>Developing Reusable Things or How Not to Repeat Yourself</h2>
<p>The "Library" and "Application" distinction is all well and good, but whenever you're developing a Library, in a way <em>it</em> becomes your application. You want a specific set of dependencies that you want to fetch from a specific location and you know that you should have abstract dependencies in your <code>setup.py</code> and concrete dependencies in your <code>requirements.txt</code> but you don't want to need to maintain two separate lists which will inevitably go out of sync. As it turns out pip requirements file have a construct to handle just such a case. Given a directory with a <code>setup.py</code> inside of it you can write a requirements file that looks like:</p>
<div>
<pre>--index https://pypi.python.org/simple/

-e .</pre>
</div>
<p>Now your <code>pip install -r requirements.txt</code> will work just as before. It will first install the library located at the file path <code>.</code> and then move on to its abstract dependencies, combining them with its <code>--index</code> option and turning them into concrete dependencies and installing them.</p>
<p>This method grants another powerful ability. Let's say you have two or more libraries that you develop as a unit but release separately, or maybe you've just split out part of a library into its own piece and haven't officially released it yet. If your top level library still depends on just the name then you can install the development version when using the <code>requirements.txt</code> and the release version when not, using a file like:</p>
<div>
<pre>--index https://pypi.python.org/simple/

-e https://github.com/foo/bar.git#egg=bar
-e .</pre>
</div>
<p>This will first install the bar library from https://github.com/foo/bar.git, making it equal to the name "bar", and then will install the local package, again combining its dependencies with the <code>--index</code> option and installing but this time since the "bar" dependency has already been satisfied it will skip it and continue to use the in development version.</p>
<p><em><strong>Recognition:</strong> This post was inspired by <a href="http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/">Yehuda Katz's blog post</a> on a similar issue in Ruby with <code>Gemfile</code> and <code>gemspec</code>.</em></p>
<p>文章选自：<a href="https://caremad.io/blog/setup-vs-requirements/?utm_source=pycoders&amp;utm_campaign=47251bf186-Pycoder_s_Weekly_Issue_76_Caremad7_26_2013&amp;utm_medium=email&amp;utm_term=0_64134e0a27-47251bf186-49523505">setup-vs-requirements</a></p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2013/08/python%e6%a8%a1%e5%9d%97%e5%8f%91%e5%b8%83%e6%96%87%e4%bb%b6setup-py-vs-requirements-txt/">Python模块发布文件setup.py vs requirements.txt</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zhourunsheng.com/2013/08/python%e6%a8%a1%e5%9d%97%e5%8f%91%e5%b8%83%e6%96%87%e4%bb%b6setup-py-vs-requirements-txt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>分享Python模块到PyPI</title>
		<link>http://blog.zhourunsheng.com/2013/08/%e5%88%86%e4%ba%abpython%e6%a8%a1%e5%9d%97%e5%88%b0pypi/</link>
		<comments>http://blog.zhourunsheng.com/2013/08/%e5%88%86%e4%ba%abpython%e6%a8%a1%e5%9d%97%e5%88%b0pypi/#comments</comments>
		<pubDate>Sat, 03 Aug 2013 01:40:54 +0000</pubDate>
		<dc:creator><![CDATA[润物无声]]></dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[PyPI]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.zhourunsheng.com/?p=1687</guid>
		<description><![CDATA[<p>怎么样打包自己的Python模块，并且分享到PyPI，相信下面的文章会给你一个满意的答案！ A complet [&#8230;]</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2013/08/%e5%88%86%e4%ba%abpython%e6%a8%a1%e5%9d%97%e5%88%b0pypi/">分享Python模块到PyPI</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></description>
				<content:encoded><![CDATA[<p>怎么样打包自己的Python模块，并且分享到PyPI，相信下面的文章会给你一个满意的答案！</p>
<p>A completely incomplete guide to packaging a Python module and sharing it with the world on PyPI.</p>
<h2>Abstract</h2>
<p>Few things give me <a href="https://twitter.com/hynek/status/344358831163310081">caremads</a> like Python modules I want to use that aren’t on <a href="https://pypi.python.org/">PyPI</a> (pronounced “pie pee eye”, or “cheese shop”, <em>not</em> “<a href="http://pypy.org/">pie pie</a>”!). On the other hand – as<a href="http://pydanny.com/made-up-statistics.html#debate-statistics">pydanny points out</a> – the current situation on packaging is rather confusing.</p>
<p>Therefore I want to help everyone who has some great code but feels lost with getting it on PyPI. I will be using my latest opus “<a href="https://github.com/hynek/pem">pem</a>” as a realistic yet simple example of how to get a pure-Python 2 <em>and</em> 3 module packaged up, tested and uploaded to PyPI. Including the new and shiny binary <a href="http://wheel.readthedocs.org/">wheel</a> format that’s faster and allows for binary extensions (read the <a href="http://wheel.readthedocs.org/en/latest/story.html">wheel story</a> if you want to know more)!</p>
<p>I’ll keep it <em>super simple</em> to get everyone started. At the end, I’ll link more complete documentation to show you the way ahead. Sorry, no Windows.<span id="more-1687"></span></p>
<h2>Tools Used</h2>
<p>This is not a history lesson, therefore we will use:</p>
<ul>
<li><a href="http://www.pip-installer.org/">pip</a> 1.4+ (if you have no pip yet, <a href="http://www.pip-installer.org/en/latest/installing.html#using-get-pip">bootstrapping</a> is easy),</li>
<li><a href="http://pythonhosted.org/setuptools/">setuptools</a> 0.9+,</li>
<li>and <a href="http://wheel.readthedocs.org/">wheel</a> 0.21+.</li>
</ul>
<div>
<pre>$ pip install -U "pip&gt;=1.4" "setuptools&gt;=0.9" "wheel&gt;=0.21"</pre>
</div>
<p>Please make sure all installs succeed, ancient installations may need some extra manual labor.</p>
<h3>A Minimal Glimpse Into The Past</h3>
<p><em>Forget</em> that there ever was <del>distribute</del> (<a href="http://pythonhosted.org/setuptools/merge.html">cordially merged into setuptools</a>), <del>easy_install</del> (part of setuptools, supplanted by pip), or <del>distutils2</del> aka <del>packaging</del> (was supposed to be the official thing from Python 3.3 on, didn’t get done in time due to lack of helping hands, <a href="http://mail.python.org/pipermail/python-dev/2012-June/120430.html">got ripped out by a heart-broken Éric</a> and abandoned now).</p>
<p>Be just <em>vaguely aware</em> that there are <a href="http://docs.python.org/2/library/distutils.html">distutils</a> and <a href="https://distlib.readthedocs.org/">distlib</a>somewhere underneath but ideally it shouldn't matter to you at all <em>for now</em>.</p>
<h2>setup.py</h2>
<p>Nowadays, every project that you want to package needs a<code>setup.py</code> file. Let’s have a look at what pem’s could look like:</p>
<div>
<pre>from setuptools import setup

setup(
    name='pem',
    version='0.1.0',
    description='Parse and split PEM files painlessly.',
    long_description=(open('README.rst').read() + '\n\n' +
                      open('HISTORY.rst').read() + '\n\n' +
                      open('AUTHORS.rst').read()),
    url='http://github.com/hynek/pem/',
    license='MIT',
    author='Hynek Schlawack',
    author_email='hs@ox.cx',
    py_modules=['pem'],
    include_package_data=True,
    classifiers=[
        'Development Status :: 5 - Production/Stable',
        'Intended Audience :: Developers',
        'Natural Language :: English',
        'License :: OSI Approved :: MIT License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 2.6',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.3',
        'Topic :: Software Development :: Libraries :: Python Modules',
    ],
)</pre>
</div>
<p>In the simplest case, you just import <code>setup</code> from <code>setuptools</code>and run it with some keyword arguments.</p>
<p>Before I go into these arguments, I want to point out one of the most neglected and yet most important one: <code>license</code>.<em>Always</em> <a href="http://giovanni.bajo.it/post/56510184181/is-gpl-still-relevant">set a license</a>! Otherwise nobody can use your module, which would be a pity, right?</p>
<p>I take a few shortcuts here which you may want to copy too:</p>
<ul>
<li>I love <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a>, therefore my long description is just a concatenation of my README, change log and author credits.</li>
<li>I use <a href="https://pypi.python.org/pypi/bumpversion/">bumpversion</a> for manipulating my version strings.</li>
</ul>
<p>An essential field is <code>py_modules</code> which you'll use to denote the relevant code for packaging, if your package is actually just a single module like in <a href="https://github.com/hynek/pem/blob/master/pem.py">pem’s case</a>. If you have a full-blown package (i.e. a directory), you’ll go for:</p>
<div>
<pre>from setuptools import setup, find_packages

setup(
...
    packages=find_packages(exclude=['tests*']),
...
)</pre>
</div>
<p>The <a href="http://pythonhosted.org/distribute/setuptools.html#using-find-packages"><code>exclude</code></a> makes sure that a top-level <code>tests</code> package doesn’t get <em>installed</em> (it’s still part of the source distribution) since that would wreak havoc.</p>
<p>You can also specify them by hand like I used to for<a href="https://github.com/hynek/doc2dash/">doc2dash</a>’s <a href="https://github.com/hynek/doc2dash/blob/2357c81adc87a885952e08671fcd8db9a177b6d7/setup.py#L15"><code>setup.py</code></a>. However, unless you have good reasons, just use <code>find_packages()</code> and be done.</p>
<p>The classifiers field’s usefulness is openly disputed, nevertheless pick them from <a href="https://pypi.python.org/pypi?%3Aaction=list_classifiers">here</a>. PyPI will refuse to accept packages with unknown classifiers, hence I like to use <code>"Private :: Do Not Upload"</code> for private packages to protect myself from my own stupidity.</p>
<p>One icky thing are dependencies. Unless you <em>really</em> know what you’re doing, <strong><a href="https://caremad.io/blog/setup-vs-requirements/">don’t pin</a></strong> them (specifying minimal version your package <em>requires</em> to work is fine of course) or your users won’t be able to install security updates of your dependencies:</p>
<div>
<pre>setup(
...
    install_requires=['Django', 'django-annoying'],
...
)</pre>
</div>
<p>Rule of thumb: <a href="http://www.pip-installer.org/en/latest/logic.html#requirements-file-format"><code>requirements.txt</code></a> should contain <em>only</em> <code>==</code>,<code>setup.py</code> the rest (<code>&gt;=</code>, <code>!=</code>, <code>&lt;=</code>, …).</p>
<h2>Non-Code Files</h2>
<p>Every Python project has a “Fix MANIFEST.in” commit. Look it up, it’s true.</p>
<p>But it’s not really that hard: you add all files and directories that are <em>not</em> packaged due to <code>py_modules</code> or <code>packages</code> in your <code>setup.py</code>.</p>
<p>For “pem”, it’s just</p>
<pre>include *.rst LICENSE</pre>
<p>For more commands, have a look at the <a href="http://docs.python.org/2/distutils/sourcedist.html#commands"><code>MANIFEST.in</code> docs</a> – especially <code>recursive-include</code> is used widely. There’s also a handy tool to validate your <code>MANIFEST.in</code>: <a href="https://pypi.python.org/pypi/check-manifest">check-manifest</a>.</p>
<p><strong>Important</strong>: If you want the files and directories from<code>MANIFEST.in</code> to also be <em>installed</em> (e.g. if it’s runtime-relevant data), you will have to set <code>include_package_data=True</code> in your<code>setup()</code> call as in the example above!</p>
<h2>Configuration</h2>
<p>For our minimal Python-only project, we’ll only need two lines in setup.cfg:</p>
<div>
<pre>[wheel]
universal = 1</pre>
</div>
<p>These will make wheel build a universal wheel file (e.g.<code>pem-0.1.0-<strong>py2.py3</strong>-none-any.whl</code>) and you won’t have to circle through virtual environments of all supported Python versions to build them separately.</p>
<h2>Documentation</h2>
<p>As I’ve hopefully established, every open source project needs a <a href="http://choosealicense.com/">license</a>. No excuses.</p>
<p>Additionally, even the simplest package needs a README that tells potential users what they’re looking at. Make it<a href="http://sphinx-doc.org/rest.html#rst-primer">reStructuredText</a> (reST) so PyPI can properly render it on your project page. As a courtesy to your users, also keep a change log so they know what to expect from your releases. And finally it’s good style to credit your contributors in a third file. I like to call them <code>README.rst</code>,<code>HISTORY.rst</code>, and <code>AUTHORS.rst</code> respectively, but there’s no hard rule.</p>
<p>My long project description and thus PyPI text is the concatenation of those three (and I’ve shamelessly stolen it from <a href="https://github.com/kennethreitz/requests/blob/786fe94ac43eacc580d93442097cd3fc64090ffd/setup.py#L33">Kenneth Reitz</a>).</p>
<p>If you host on GitHub, you may want to add a<a href="https://github.com/blog/1184-contributing-guidelines"><code>CONTRIBUTING.md</code></a> that gets displayed when someone wants to open a pull request. Unfortunately it has to be a Markdown file because GitHub doesn’t support reST for this. Have a look at <a href="https://github.com/hynek/pem/blob/master/CONTRIBUTING.md">pem’s</a> if you need inspiration.</p>
<h2>Let’s Build Finally!</h2>
<p>Building a source distribution (which is what is usually used for pure-Python project) is just a matter of</p>
<div>
<pre>$ python setup.py sdist</pre>
</div>
<p>Because it’s 2013 and wheels are awesome, we’ll build one too! Fortunately, it’s just as easy (please note that you’ll need to install <code>wheel</code> as per above for this to work!):</p>
<div>
<pre>$ python setup.py bdist_wheel</pre>
</div>
<p>Of course, the wheel package is <em>optional</em>, but your users will thank you for much faster installation times.</p>
<p>Now you should have a new directory called <code>dist</code> containing a source distribution file and a wheel file. For pem, it currently looks like this:</p>
<pre>dist
├── pem-0.1.0-py2.py3-none-any.whl
└── pem-0.1.0.tar.gz</pre>
<p>You can test whether both install properly before we move on to uploading:</p>
<pre>$ rm -rf 27-sdist  # ensure clean state if ran repeatedly
$ virtualenv 27-sdist
...
$ 27-sdist/bin/pip install --no-index dist/pem-0.1.0.tar.gz
Ignoring indexes: https://pypi.python.org/simple/
Unpacking ./dist/pem-0.1.0.tar.gz
  Running setup.py egg_info for package from file:///Users/hynek/Projects/pem/dist/pem-0.1.0.tar.gz

Installing collected packages: pem
  Running setup.py install for pem

Successfully installed pem
Cleaning up...
$ 27-sdist/bin/python
Python 2.7.4 (default, Apr 21 2013, 09:35:41)
[GCC 4.2.1 Compatible Apple LLVM 4.2 (clang-425.0.27)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; import pem
&gt;&gt;&gt; pem.__version__
'0.1.0'</pre>
<p>and</p>
<pre>$ rm -rf 27-wheel  # ensure clean state if ran repeatedly
$ virtualenv 27-wheel
...
$ 27-wheel/bin/pip install --use-wheel --no-index --find-links dist pem
Ignoring indexes: https://pypi.python.org/simple/
Downloading/unpacking pem
Installing collected packages: pem
Successfully installed pem
Cleaning up...
$ 27-wheel/bin/python
Python 2.7.4 (default, Apr 21 2013, 09:35:41)
[GCC 4.2.1 Compatible Apple LLVM 4.2 (clang-425.0.27)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; import pem
&gt;&gt;&gt; pem.__version__
'0.1.0'</pre>
<p>Please note the lack of “Running setup.py install for pem” in the second test. Yes, you can finally install packages without executing arbitrary code!</p>
<p>So you’re confident that your package is perfect? Let’s use the <a href="http://wiki.python.org/moin/TestPyPI">Test PyPI server</a> to find out!</p>
<h2>The PyPI Staging Server</h2>
<p>Again, I’ll be using “pem” as the example project name to avoid <code>&lt;your project name&gt;</code> everywhere.</p>
<p>First, sign up on the <a href="https://testpypi.python.org/">test server</a>, you will receive a user name and a password. Please note that this is independent from the live servers. Thus you’ll have to re-register both yourself and your packages. It also gets cleaned from time to time so don’t be surprised if it suddenly doesn’t know about you or your projects anymore. Just re-register.</p>
<p>Next, create a <code>~/.pypirc</code> consisting of:</p>
<div>
<pre>[distutils]
index-servers=
    test

[test]
repository = https://testpypi.python.org/pypi
username = &lt;your user name goes here&gt;
password = &lt;your password goes here&gt;</pre>
</div>
<p>Then use</p>
<div>
<pre>$ python setup.py register -r test</pre>
</div>
<p>to register your project with the PyPI test server.</p>
<p>Finally, upload your distributions:</p>
<div>
<pre>$ python setup.py sdist upload -r test
$ python setup.py bdist_wheel upload -r test</pre>
</div>
<p>Please note that calling <code>upload</code> without building something in the <em>same command line</em> will give you a:</p>
<pre>error: No dist file created in earlier command</pre>
<p>Now test your packages again:</p>
<div>
<pre>$ pip install -i https://testpypi.python.org/pypi pem</pre>
</div>
<p>Everything dandy? Then lets tackle the last step: putting it on the <em>real</em> PyPI!</p>
<h2>The Final Step</h2>
<p>First, register at <a href="https://pypi.python.org/">PyPI</a>, then complete your <code>~/.pypirc</code>:</p>
<div>
<pre>[distutils]
index-servers=
    pypi
    test

[test]
repository = https://testpypi.python.org/pypi
username = &lt;your test user name goes here&gt;
password = &lt;your test password goes here&gt;

[pypi]
repository = http://pypi.python.org/pypi
username = &lt;your production user name goes here&gt;
password = &lt;your production password goes here&gt;</pre>
</div>
<p>One last deep breath and let’s rock:</p>
<div>
<pre>$ python setup.py sdist upload -r pypi
$ python setup.py bdist_wheel upload -r pypi</pre>
</div>
<p>And thus, your package is only a <code>pip install</code> away for everyone! Congratulations, do more of that!</p>
<h2>Next Steps</h2>
<p>The information herein will probably get you pretty far but if you get stuck, the current <em>canonical</em> truths for Python packaging are:</p>
<ul>
<li><a href="https://python-packaging-user-guide.readthedocs.org/">Python Packaging User Guide</a></li>
<li><a href="http://pythonhosted.org/setuptools/">setuptools</a></li>
<li><a href="http://wheel.readthedocs.org/">wheel</a></li>
<li><a href="http://docs.python.org/2/library/distutils.html">distutils</a></li>
<li>and specifically the <a href="http://docs.python.org/2/distutils/packageindex.html">PyPI chapter</a> in the latter one.</li>
</ul>
<p>Please don’t let your software rot on GitHub or launchpad! Share!</p>
<h2>Thanks</h2>
<p>This article has been kindly proof-read by <a href="https://twitter.com/roguelynn">Lynn Root</a>,<a href="https://twitter.com/dstufft">Donald Stufft</a>, <a href="https://twitter.com/alex_gaynor/">Alex Gaynor</a>, <a href="http://sec.fu.cx/">Thomas Heinrichsdobler</a>, and<a href="https://twitter.com/jezdez">Jannis Leidel</a>. All mistakes are still mine though.</p>
<p>I’d be happy if you have any feedback to make this article even more straight-forward for people new to Python packaging!</p>
<p>文章出自：<a href="http://hynek.me/articles/sharing-your-labor-of-love-pypi-quick-and-dirty/">sharing-your-labor-of-love-pypi-quick-and-dirty</a></p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2013/08/%e5%88%86%e4%ba%abpython%e6%a8%a1%e5%9d%97%e5%88%b0pypi/">分享Python模块到PyPI</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zhourunsheng.com/2013/08/%e5%88%86%e4%ba%abpython%e6%a8%a1%e5%9d%97%e5%88%b0pypi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
