Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
123 lines (115 sloc) 68.8 KB
<!doctype html><html lang="en"><head><meta charset="utf-8"><title>How to publish your package to PyPI, 2018</title><meta content="Tutorial, how you can publish your Python package to PyPI" name="description"><meta content="width=device-width,initial-scale=1" name="viewport"><meta content="IE=edge" http-equiv="X-UA-Compatible"><meta content="How to publish your package to PyPI, 2018" property="og:title"><meta content="article" property="og:type"><meta content="https://i.imgur.com/mO0Fnsk.jpg" property="og:image"><meta content="https://kristinita.netlify.com/IT-articles/How-to-publish-your-package-to-PyPI-2018.html" property="og:url"><meta content="Tutorial, how you can publish your Python package to PyPI" property="og:description"><meta content="Поиск Кристиниты" property="og:site_name"><meta content="2018-01-27" property="article:published_time"><meta content="2019-06-14" property="article:modified_time"><meta content="IT-articles" property="article:section"><meta content="it-articles" property="article:tag"><meta content="python" property="article:tag"><meta content="pypi" property="article:tag"><meta content="release" property="article:tag"><script type="application/ld+json">{ "@context": "https://schema.org", "@type": "HowTo", "name": "How to publish your package to PyPI, 2018", "description": "Tutorial, how you can publish your Python package to PyPI", "headline": "How to publish your package to PyPI, 2018", "datePublished": "2018-01-27 10:59:14+03:00", "dateModified": "2019-06-14 16:10:22+03:00", "author": { "@type": "Person", "name": "Sasha Chernykh" }, "image": "https://i.imgur.com/mO0Fnsk.jpg", "url": "https://kristinita.netlify.com/IT-articles/How-to-publish-your-package-to-PyPI-2018.html" }</script><link href="https://kristinita.netlify.com/favicon.ico" rel="shortcut icon"><link href="https://kristinita.netlify.com/feeds/all.atom.xml" rel="alternate" type="application/atom+xml"><link href="https://kristinita.netlify.com/feeds/it-articles.atom.xml" rel="alternate" type="application/atom+xml"><script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js" defer></script><script src="https://kristinita.netlify.com/theme/js/target-blank/target-blank.min.e11e5105efa99a3d.js" defer></script><script src="https://cdn.jsdelivr.net/npm/gemini-scrollbar/index.min.js" defer></script><script src="https://kristinita.netlify.com/theme/js/Gemini/GeminiAndJQueryLazy.min.6e0d649a835b799d.js" defer></script><script src="https://cdn.jsdelivr.net/jquery.lazy/latest/jquery.lazy.min.js" defer></script><script src="https://cdn.jsdelivr.net/jquery.lazy/latest/jquery.lazy.plugins.min.js" defer></script><script src="https://kristinita.netlify.com/theme/js/Browser-Update/browser-update.min.e45fe54cc9cb8588.js" defer></script><script src="https://cdn.jsdelivr.net/npm/typo-reporter/lib/TypoReporter.min.js" defer></script><script src="https://kristinita.netlify.com/theme/js/typo-reporter/typo-reporter-en.min.f4d148db23221baf.js" defer></script><script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox/dist/jquery.fancybox.min.js" defer></script><script src="https://kristinita.netlify.com/theme/js/Fancybox/fancybox.min.eb8f09c393877937.js" defer></script><script src="https://cdn.jsdelivr.net/jquery.tooltipster/latest/js/tooltipster.bundle.min.js" defer></script><style>body,html{height:100%;overflow:hidden}.SashaBottomAside,a,ol>li{overflow-wrap:break-word;word-break:break-all}ol>li{margin-left:1rem}body{font-family:Arial,Helvetica,sans-serif;font-size:1.1875rem;margin:0;padding:0}a{text-decoration:none}noscript{color:#fff;font-family:sans-serif;font-weight:700;text-align:center;padding:1rem 0;background:rgba(0,0,0,.9);position:fixed;top:0;z-index:1}img{max-width:100%;margin:0 auto}.SashaVersion{font-size:.9rem;font-weight:700}div.a2a_floating_style{padding:.0625rem;top:30%}.SashaBottomAside,h1{font-family:Play,sans-serif}.SashaBottomAside,h1{font-size:1.9375rem;font-weight:lighter;font-style:normal}a{font-style:italic}a{font-family:El Messiri,sans-serif;font-size:1.3rem;font-weight:700}.SashaIconAside{background-size:cover;height:100%;top:0}.SashaBottomAside{font-size:2rem;line-height:2rem;text-align:center;position:absolute;bottom:7%;left:10%;width:80%}@media screen and (orientation:portrait){.SashaIconAside{width:100%;position:relative}noscript{width:100%}}@media screen and (orientation:landscape){.SashaIconAside{width:35%;position:fixed}main,noscript{width:65%}}noscript{right:0}@media screen and (orientation:landscape){article{margin-right:2rem;margin-left:1rem}main{float:right}}@media screen and (orientation:portrait){article{margin-right:3rem;margin-left:1rem}}.a2a_floating_style{right:0}body{background:#87e1be;color:#465550}a{color:#dc3f17}img{box-shadow:0 0 2rem #000}.SashaPageLoading{box-shadow:none}.SashaBottomAside{color:#fff;bottom:8%}@font-face{font-family:'El Messiri';font-style:normal;font-weight:400;font-display:swap;src:local('El Messiri'),local('ElMessiri-Regular'),url(https://fonts.gstatic.com/s/elmessiri/v6/K2F0fZBRmr9vQ1pHEey6MomABw.ttf) format('truetype')}@font-face{font-family:Play;font-style:normal;font-weight:700;font-display:swap;src:local('Play Bold'),local('Play-Bold'),url(https://fonts.gstatic.com/s/play/v11/6ae84K2oVqwItm4TCpQy3w.ttf) format('truetype')}</style><link href="https://cdn.jsdelivr.net/jquery.tooltipster/latest/css/tooltipster.bundle.min.css" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link href="https://cdn.jsdelivr.net/jquery.tooltipster/latest/css/tooltipster.bundle.min.css" rel="stylesheet"></noscript><link href="https://cdn.jsdelivr.net/npm/tooltipster/dist/css/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-punk.min.css" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link href="https://cdn.jsdelivr.net/npm/tooltipster/dist/css/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-punk.min.css" rel="stylesheet"></noscript><script src="https://kristinita.netlify.com/theme/js/Tooltipster/tooltip.min.25ef24827c8d23a2.js" defer></script><script src="https://cdn.jsdelivr.net/clipboard.js/latest/clipboard.min.js" defer></script><script src="https://kristinita.netlify.com/theme/js/Clipboard-js/Clipboard.min.13347deb67c2a82a.js" defer></script><script src="https://static.addtoany.com/menu/page.js" defer></script><script src="https://kristinita.netlify.com/theme/js/AddToAny/addtoany.min.27de59cb13b5ac52.js" async></script><script src="https://kristinita.netlify.com/theme/js/Wildfire/wildfire.min.8244a84c73913d2e.js" async></script><script src="https://cdn.jsdelivr.net/npm/wildfire/dist/wildfire.auto.js" defer></script><link href="https://cdn.jsdelivr.net/npm/gemini-scrollbar/gemini-scrollbar.min.css" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link href="https://cdn.jsdelivr.net/npm/gemini-scrollbar/gemini-scrollbar.min.css" rel="stylesheet"></noscript><link href="https://kristinita.netlify.com/theme/css/script-colors/Gemini/gemini.min.32c3d46b921839e9.css" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link href="https://kristinita.netlify.com/theme/css/script-colors/Gemini/gemini.min.32c3d46b921839e9.css" rel="stylesheet"></noscript><link href="https://kristinita.netlify.com/theme/css/general/basic.min.681a7bf2ace60968.css" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link href="https://kristinita.netlify.com/theme/css/general/basic.min.681a7bf2ace60968.css" rel="stylesheet"></noscript><link href="https://kristinita.netlify.com/theme/css/general/fonts.min.5159f9ebf5d3de35.css" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link href="https://kristinita.netlify.com/theme/css/general/fonts.min.5159f9ebf5d3de35.css" rel="stylesheet"></noscript><link href="https://kristinita.netlify.com/theme/css/general/aside.min.5363eb891d9658ee.css" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link href="https://kristinita.netlify.com/theme/css/general/aside.min.5363eb891d9658ee.css" rel="stylesheet"></noscript><script src="https://kristinita.netlify.com/theme/js/Modernizr/modernizr-custom.min.03944c2c1dc0413e.js" defer></script><style>.webp .SashaIconAside{background-image:url(https://kristinita.netlify.com/theme/images/aside/SashaGreenSweater.webp)}.no-webp .SashaIconAside{background-image:url(https://kristinita.netlify.com/theme/images/aside/SashaGreenSweater.jpg)}</style><link href="https://kristinita.netlify.com/theme/css/general/image_left.min.7bc834d18484b4e0.css" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link href="https://kristinita.netlify.com/theme/css/general/image_left.min.7bc834d18484b4e0.css" rel="stylesheet"></noscript><link href="https://kristinita.netlify.com/theme/css/sections/it-articles.min.7646e7d4a34c26df.css" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link href="https://kristinita.netlify.com/theme/css/sections/it-articles.min.7646e7d4a34c26df.css" rel="stylesheet"></noscript><link href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox/dist/jquery.fancybox.min.css" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox/dist/jquery.fancybox.min.css" rel="stylesheet"></noscript><link href="https://kristinita.netlify.com/theme/css/script-colors/typo-reporter/typo-reporter.min.667472c6a558afee.css" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link href="https://kristinita.netlify.com/theme/css/script-colors/typo-reporter/typo-reporter.min.667472c6a558afee.css" rel="stylesheet"></noscript><link href="https://kristinita.netlify.com/theme/css/script-colors/Admonition/admonition.min.cb53ef4d77a61632.css" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link href="https://kristinita.netlify.com/theme/css/script-colors/Admonition/admonition.min.cb53ef4d77a61632.css" rel="stylesheet"></noscript><link href="https://fonts.googleapis.com/css?family=Play:700%7CEl+Messiri%7CScada:700i%7CFira+Mono%7CMaterial+Icons%7CMarck+Script&amp;subset=cyrillic&amp;display=swap" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link href="https://fonts.googleapis.com/css?family=Play:700%7CEl+Messiri%7CScada:700i%7CFira+Mono%7CMaterial+Icons%7CMarck+Script&amp;subset=cyrillic&amp;display=swap" rel="stylesheet"></noscript></head><body><div role="alert"><noscript><p>Sorry, this site doesn't work, if JavaScript disabled. Please, <a href="http://activatejavascript.org/en/instructions">enable JavaScript for your browser</a>.</p><p>This site is open source; you can view <a href="https://github.com/Kristinita/Kristinita.github.io/blob/master/IT-articles/How-to-publish-your-package-to-PyPI-2018.html">source of this page</a>, to make sure that it's not dangerous for your computer.</p>Owner of this site think that <a href="https://stackoverflow.com/a/17073999/5951529">JavaScript disabling — is obsolete action in 2019</a> and <a href="https://www.reddit.com/r/webdev/comments/48z7jz/do_you_take_into_account_those_who_disable/d0nxftd/">will not support users who did this</a>. Probably, <a href="https://www.howtogeek.com/138865/htg-explains-should-you-disable-javascript/">you don't need turn off JavaScript</a>.</noscript><script>!function(n){"use strict";n.loadCSS||(n.loadCSS=function(){});var o=loadCSS.relpreload={};if(o.support=function(){var e;try{e=n.document.createElement("link").relList.supports("preload")}catch(t){e=!1}return function(){return e}}(),o.bindMediaToggle=function(t){var e=t.media||"all";function a(){t.addEventListener?t.removeEventListener("load",a):t.attachEvent&&t.detachEvent("onload",a),t.setAttribute("onload",null),t.media=e}t.addEventListener?t.addEventListener("load",a):t.attachEvent&&t.attachEvent("onload",a),setTimeout(function(){t.rel="stylesheet",t.media="only x"}),setTimeout(a,3e3)},o.poly=function(){if(!o.support())for(var t=n.document.getElementsByTagName("link"),e=0;e<t.length;e++){var a=t[e];"preload"!==a.rel||"style"!==a.getAttribute("as")||a.getAttribute("data-loadcss")||(a.setAttribute("data-loadcss",!0),o.bindMediaToggle(a))}},!o.support()){o.poly();var t=n.setInterval(o.poly,500);n.addEventListener?n.addEventListener("load",function(){o.poly(),n.clearInterval(t)}):n.attachEvent&&n.attachEvent("onload",function(){o.poly(),n.clearInterval(t)})}"undefined"!=typeof exports?exports.loadCSS=loadCSS:n.loadCSS=loadCSS}("undefined"!=typeof global?global:this);</script></div><aside role="presentation"><div class="a2a_floating_style a2a_kit a2a_kit_size_17 a2a_vertical_style"><a class="a2a_button_mastodon"></a> <a class="a2a_button_diaspora"></a> <a class="a2a_button_telegram"></a> <a class="a2a_button_care2_news"></a> <a class="a2a_button_printfriendly"></a> <a class="a2a_dd"></a></div></aside><aside class="SashaIconAside"><div class="SashaBottomAside">How to publish your package to PyPI, 2018</div></aside><main><article><header><h1 class="SashaTopHeader">How to publish your package to PyPI, 2018</h1><img alt="Page loading, please, little wait" class="SashaPageLoading" src="https://2no.co/1vWK5.png"><div class="SashaVersion">Version 0.1.0</div><div class="SashaVersion">Posted — 2018-01-27T10:59:14+0300</div><div class="SashaVersion">Last modified — 2019-06-14T16:10:22+0300</div></header><section><ol><li><a href="#Overview">Overview</a></li><li><a href="#Audience">Audience</a></li><li><a href="#Relevance">Relevance</a></li><li><a href="#Motivation">Motivation</a></li><li><a href="#Demonstration">Demonstration</a></li><li><a href="#Features">Features</a></li><li><a href="#Limitations">Limitations</a></li><li><a href="#Installation">Installation</a></li><li><a href="#Configuration">Configuration</a><ol><li><a href="#Files">Files</a></li><li><a href="#9595init9595py">&#95;&#95;init&#95;&#95;.py</a></li><li><a href="#License">License</a></li><li><a href="#README">README</a><ol><li><a href="#READMEmd">README.md</a></li><li><a href="#READMErst">README.rst</a></li></ol></li><li><a href="#setupcfg">setup.cfg</a><ol><li><a href="#long_description">long_description</a></li><li><a href="#classifiers">classifiers</a></li><li><a href="#zip_safe">zip_safe</a></li><li><a href="#packages">packages</a></li><li><a href="#console_scripts">console_scripts</a></li><li><a href="#bdist_wheel">bdist_wheel</a></li></ol></li><li><a href="#Dependencies">Dependencies</a><ol><li><a href="#Difference-between-requirementstxt-and-install_requires">Difference between requirements.txt and install_requires</a><ol><li><a href="#install_requires">install_requires</a></li><li><a href="#requirementstxt">requirements.txt</a></li></ol></li><li><a href="#setuppy">setup.py</a></li><li><a href="#requirementstxt-1">requirements.txt</a></li><li><a href="#MANIFESTin">MANIFEST.in</a></li></ol></li><li><a href="#pyroma">pyroma</a></li></ol></li><li><a href="#TestPyPI">TestPyPI</a><ol><li><a href="#What-is-TestPyPI">What is TestPyPI</a></li><li><a href="#Registration">Registration</a></li><li><a href="#Twine-settings">Twine settings</a></li><li><a href="#Build-package">Build package</a></li><li><a href="#Publish-to-TestPyPI">Publish to TestPyPI</a></li><li><a href="#Visit-TestPyPI">Visit TestPyPI</a></li><li><a href="#virtualenv">virtualenv</a><ol><li><a href="#Why-virtual-environment">Why virtual environment?</a></li><li><a href="#Using-virtualenv-and-virtualenvwrapper">Using virtualenv and virtualenvwrapper</a></li><li><a href="#Checking">Checking</a></li></ol></li></ol></li><li><a href="#PyPI">PyPI</a></li><li><a href="#Updating">Updating</a></li><li><a href="#Automatic-updating-release-and-changelog">Automatic updating, release and changelog</a><ol><li><a href="#Demonstration-1">Demonstration</a></li><li><a href="#Features-1">Features</a></li><li><a href="#Limitations-1">Limitations</a></li><li><a href="#Installation-and-setting-up">Installation and setting-up</a><ol><li><a href="#release-itjson">.release-it.json</a></li></ol></li><li><a href="#Usage">Usage</a></li></ol></li><li><a href="#Testing-environment">Testing environment</a></li></ol><p><a id="Overview"></a></p><h2>1. Overview <a href="#Overview" class="headerlink" title="Permanent link">¶</a></h2><p>Tutorial, how you can add your Python package to <a href="https://en.wikipedia.org/wiki/Python_Package_Index">PyPI — Python Package Index</a>.</p><p>If you want, that users install your Python <a href="https://stackoverflow.com/a/7948504/5951529">package</a> via command:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>pip install &lt;your_package&gt;
</pre></div><p>Read this article.</p><div class="admonition info"><p class="admonition-title">Info</p><p>In this article I wrote the most common method at February 2018. But you can consider another tools as <a href="https://github.com/takluyver/flit">flit</a> and <a href="https://github.com/sdispater/poet">poet</a>.</p></div><p><a id="Audience"></a></p><h2>2. Audience <a href="#Audience" class="headerlink" title="Permanent link">¶</a></h2><p>Python developers, that:</p><ol><li>publish package to PyPI first time,</li><li>already published packages to PyPI, but want to do it more qualitatively.</li></ol><p><a id="Relevance"></a></p><h2>3. Relevance <a href="#Relevance" class="headerlink" title="Permanent link">¶</a></h2><p>This article is relevant for February 2018. In the future, the data in this article may be obsolete.</p><p><a id="Motivation"></a></p><h2>4. Motivation <a href="#Motivation" class="headerlink" title="Permanent link">¶</a></h2><p>One more article? Why?</p><p>I read some articles about PyPI publishing → I think, that articles, which I read, have disadvantages:</p><ol><li>outdated;</li><li>not show real examples and demonstrations;</li><li>not all-in-one; I needed force read other resources;</li><li>They do not describe all the difficulties the developer has encountered, when try to publish package on PyPI.</li></ol><p>I don't want, that another beginner Python developers take a lot of time for PyPI publishing as me. And I try to write an article, that:</p><ol><li>non-outdated at February 2018;</li><li>show examples and demos;</li><li>all-in-one; I try to add in my article all information, that I need for first PyPI publishing;</li><li>described all problems, to solve that personally I spent my time.</li></ol><p><a id="Demonstration"></a></p><h2>5. Demonstration <a href="#Demonstration" class="headerlink" title="Permanent link">¶</a></h2><p>For examples in this article, I select my Erichek package.</p><p><a href="https://pypi.python.org/pypi/erichek">pypi.python.org/pypi/erichek</a> page at February 2018:</p><p><a href="https://i.imgur.com/yzNSQNm.png" class="fancybox"><img alt="Erichek on pypi.python.org" class="SashaLazy" src="https://kristinita.netlify.com/theme/images/interface-images/transparent-one-pixel.png" data-src="https://i.imgur.com/yzNSQNm.png"></a></p><p><a href="https://pypi.org/project/erichek">pypi.org/project/erichek</a> <a href="https://pyfound.blogspot.com/2018/02/python-package-maintainers-help-test.html">Warehouse</a> page at February 2018:</p><p><a href="https://i.imgur.com/DjMYPrP.png" class="fancybox"><img alt="Erichek on pypi.org" class="SashaLazy" src="https://kristinita.netlify.com/theme/images/interface-images/transparent-one-pixel.png" data-src="https://i.imgur.com/DjMYPrP.png"></a></p><p><a href="https://i.imgur.com/rdfBR5j.png" class="fancybox"><img alt="Erichek on pypi.org 2" class="SashaLazy" src="https://kristinita.netlify.com/theme/images/interface-images/transparent-one-pixel.png" data-src="https://i.imgur.com/rdfBR5j.png"></a></p><p>You can install Erichek, use command:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>pip install erichek
</pre></div><p>If you want to have similar behavior, read on.</p><p>If I have explained something incomprehensibly, see files of <a href="https://github.com/Kristinita/Erichek">Erichek GitHub repository</a>.</p><p><a id="Features"></a></p><h2>6. Features <a href="#Features" class="headerlink" title="Permanent link">¶</a></h2><ol><li>This article — cross platform solution.</li></ol><p><a id="Limitations"></a></p><h2>7. Limitations <a href="#Limitations" class="headerlink" title="Permanent link">¶</a></h2><ol><li>You must be able to write working Python packages.</li><li>Erichek and another my packages solely for Python 3. I don't want support Python 2. If you want support Python 2, possibly, you will need some other action.</li><li>If you can have a configuration different, that Erichek, possibly, you will need in another actions.</li></ol><p><a id="Installation"></a></p><h2>8. Installation <a href="#Installation" class="headerlink" title="Permanent link">¶</a></h2><p>Please, install via pip (<em>pip install &lt;package&gt;</em>):</p><ol><li><a href="https://github.com/pypa/twine">twine</a>,</li><li><a href="https://pypi.python.org/pypi/wheel">wheel</a>,</li><li><a href="https://virtualenv.pypa.io/en/stable/">virtualenv</a>,</li><li><a href="https://virtualenvwrapper.readthedocs.io/">virtualenvwrapper</a> for Linux/macOS, <a href="https://pypi.python.org/pypi/virtualenvwrapper-win">virtualenvwrapper-win</a> for Windows,</li><li><a href="https://pypi.python.org/pypi/pyroma/">pyroma</a>,</li><li>update your <a href="https://pypi.python.org/pypi/setuptools">setuptools</a>, to be sure, that <a href="https://github.com/regebro/pyroma/issues/16">pyroma works correct</a> — <code class="SashaInlineHighlight">pip install -U setuptools</code>.</li></ol><p><a id="Configuration"></a></p><h2>9. Configuration <a href="#Configuration" class="headerlink" title="Permanent link">¶</a></h2><p><a id="Files"></a></p><h3>9.1. Files <a href="#Files" class="headerlink" title="Permanent link">¶</a></h3><p>Simplify configuration. Real project configuration see in <a href="https://github.com/Kristinita/Erichek">Erichek GitHub repository</a>.</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>│ .release-it.json
│ CHANGELOG.md
│ LICENSE.md
│ MANIFEST.in
│ README.rst
│ package.json
│ requirements.txt
│ setup.cfg
│ setup.py
├───erichek
│ __init__.py
│ __main__.py
</pre></div><p>In <a href="https://softwareengineering.stackexchange.com/q/301691/264224">Software Engineering site recommends</a> use uppercase for README and some another text files.</p><div class="admonition question"><p class="admonition-title">Question</p><p>I <a href="https://softwareengineering.stackexchange.com/questions/365410/readme-md-vs-readme-md">ask a question</a>, need I use uppercase for file extension or no? <em>README.rst</em> or <em>README.RST</em>? But I get 7 minuses and my question will delete.</p><p>I don't find standard. Personally I use lowercase for file extensions, but you can use uppercase.</p></div><p><a id="9595init9595py"></a></p><h3>9.2. &#95;&#95;init&#95;&#95;.py <a href="#9595init9595py" class="headerlink" title="Permanent link">¶</a></h3><p>See <a href="https://stackoverflow.com/a/4116384/5951529">answer</a>, why <em>__init__.py</em> need. This file may be blank or contains content.</p><p><a id="License"></a></p><h3>9.3. License <a href="#License" class="headerlink" title="Permanent link">¶</a></h3><p>Add text of license for your package to <em>LICENSE.md</em> file.</p><p>If your editor is <a href="https://www.sublimetext.com/3">Sublime Text 3</a>, you can use <a href="https://packagecontrol.io/packages/Licence%20Snippets">License Snippets</a> package.</p><p><a id="README"></a></p><h3>9.4. README <a href="#README" class="headerlink" title="Permanent link">¶</a></h3><p><a id="READMEmd"></a></p><h4>9.4.1. README.md <a href="#READMEmd" class="headerlink" title="Permanent link">¶</a></h4><p>If you preferred write README in Markdown, you can have problems.</p><p>At February 2018 <a href="https://github.com/pypa/warehouse/issues/869">PyPI doesn't support Readme.md</a> without dependencies. Possibly, <a href="https://github.com/dhimmel/hetio/issues/7#issuecomment-283797432">it seems like there is no easy way to use a markdown README for PyPI. Solutions involve requiring pandoc locally, which is a heavy dependency</a>.</p><div class="admonition hint"><p class="admonition-title">Hint</p><p>You can <a href="https://bfroehle.com/2013/04/26/converting-md-to-rst/">convert Markdown to reStructuredText</a> use <a href="http://pandoc.org">Pandoc</a>.</p></div><p><a id="READMErst"></a></p><h4>9.4.2. README.rst <a href="#READMErst" class="headerlink" title="Permanent link">¶</a></h4><p>I recommend write README in <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> — you need use file <em>README.rst</em>. I add to <a href="https://github.com/Kristinita/Erichek/blob/master/README.rst">my README.rst</a> next information:</p><ol><li>Short package description,</li><li>Badges,</li><li>Link to long package description on my site.</li></ol><p>I prefer to add long description to personal site, not to README, because I have much more options in the design of the description.</p><p><a id="setupcfg"></a></p><h3>9.5. setup.cfg <a href="#setupcfg" class="headerlink" title="Permanent link">¶</a></h3><div class="admonition info"><p class="admonition-title">Info</p><p>You can add your parameters to <em>setup.py</em>, not to <em>setup.cfg</em>, see <a href="https://github.com/pypa/python-packaging-user-guide/issues/378">discussion</a>. I believe, that adding to <em>setup.cfg</em> more convenient.</p></div><p><a href="https://github.com/4383/sampleproject/blob/update/distribute/setup.cfg">See example <em>setup.cfg</em></a>. Copy content of this file to your <em>setup.cfg</em> and change example values of parameters to your real values.</p><p>In the subsections below I describe the places that caused me difficulties.</p><p><a id="long_description"></a></p><h4>9.5.1. long_description <a href="#long_description" class="headerlink" title="Permanent link">¶</a></h4><p>my value:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button><span class="na">long_description</span> <span class="o">=</span> <span class="s">file: Readme.rst</span>
</pre></div><p>Set your README file as value. Letters <a href="https://github.com/regebro/pyroma/issues/16#issuecomment-362904598">must be in same register as in file</a>. For example, if your file is <em>Readme.rst</em>, you need to set <em>file: README.rst</em>, not <em>file: Readme.rst</em> or <em>file: README.RST</em>.</p><p><a id="classifiers"></a></p><h4>9.5.2. classifiers <a href="#classifiers" class="headerlink" title="Permanent link">¶</a></h4><p>You can use solely classifiers from <a href="https://pypi.python.org/pypi?%3Aaction=list_classifiers">this list</a>. If no, you can't publish your package to PyPI.</p><p>Possibly, UNIX users can select classifiers via <a href="https://github.com/mbr/pypi-classifiers">pypi-classifiers GUI</a>, but <a href="https://github.com/mbr/pypi-classifiers/issues/2">I can't set this program for Windows 10</a>.</p><p><a id="zip_safe"></a></p><h4>9.5.3. zip_safe <a href="#zip_safe" class="headerlink" title="Permanent link">¶</a></h4><p>my value:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button><span class="na">zip_safe</span> <span class="o">=</span> <span class="s">False</span>
</pre></div><p>If you build your package use Wheels, <a href="https://stackoverflow.com/a/16541150/5951529">you don't need this parameter</a>, but pyroma <a href="https://github.com/regebro/pyroma/issues/19">will show lower value</a>. And so I recommend add <code class="SashaInlineHighlight"><span class="na">zip_safe</span> <span class="o">=</span> <span class="s">False</span></code> or <code class="SashaInlineHighlight"><span class="na">zip_safe</span> <span class="o">=</span> <span class="s">True</span></code> (unimportant) to your <em>setup.cfg</em> file.</p><p><a id="packages"></a></p><h4>9.5.4. packages <a href="#packages" class="headerlink" title="Permanent link">¶</a></h4><p>my value:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button><span class="na">packages</span> <span class="o">=</span> <span class="s">find:</span>
</pre></div><p>If no <code class="SashaInlineHighlight"><span class="na">packages</span> <span class="o">=</span> <span class="s">find:</span></code>, users doesn't download folder with your Python module.</p><p><a id="console_scripts"></a></p><h4>9.5.5. console_scripts <a href="#console_scripts" class="headerlink" title="Permanent link">¶</a></h4><p>What is it. If Erichek user want run Erichek, he/she wrote in console:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>python <span class="s2">&quot;path/to/__main__.py&quot;</span>
</pre></div><p>But since <em>console_scripts</em> exist in <em>setup.cfg</em>, Erichek user merely can use command, that get same behavior:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>erichek
</pre></div><p>my value:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button><span class="na">console_scripts</span> <span class="o">=</span>
<span class="s"> erichek = erichek.__main__:main</span>
</pre></div><p>Parameter and values:</p><ul><li><code class="SashaInlineHighlight">erichek</code> — name of command, that users of your package will run.</li><li><code class="SashaInlineHighlight">erichek.__main__</code> — relative path to your main module. For me it <a href="https://github.com/Kristinita/Erichek/blob/master/erichek/__main__.py"><em>__main__.py</em> file in <em>erichek</em> folder</a>.</li><li><code class="SashaInlineHighlight">:main</code> — function, that run, when you run your module. For my <em>__main__.py</em> it <code class="SashaInlineHighlight"><span class="n">main</span><span class="p">()</span></code> function.</li></ul><p><a id="bdist_wheel"></a></p><h4>9.5.6. bdist_wheel <a href="#bdist_wheel" class="headerlink" title="Permanent link">¶</a></h4><p>my value:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button><span class="k">[bdist_wheel]</span>
<span class="na">python-tag</span> <span class="o">=</span> <span class="s">py3</span>
</pre></div><p>See <a href="https://wheel.readthedocs.io/en/stable/">what is Wheels</a> and why <a href="https://www.python.org/dev/peps/pep-0427/#comparison-to-egg"><em>.whl</em> preferred than <em>.egg</em></a>.</p><p>Erichek — Python 3 package, so I have <code class="SashaInlineHighlight"><span class="na">python-tag</span> <span class="o">=</span> <span class="s">py3</span></code>. If your package support Python 2 and 3 both, <a href="https://wheel.readthedocs.io/en/stable/#defining-the-python-version">you need use</a> next code:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button><span class="k">[bdist_wheel]</span>
<span class="na">universal</span> <span class="o">=</span> <span class="s">1</span>
</pre></div><p><a id="Dependencies"></a></p><h3>9.6. Dependencies <a href="#Dependencies" class="headerlink" title="Permanent link">¶</a></h3><p>In this section I tell, what you need, that dependencies of your package from file <em>requirements.txt</em> automatically install for user. You don't need to write same dependencies in <em>requirements.txt</em> and <em>setup.cfg</em>/<em>setup.py</em>.</p><div class="admonition caution"><p class="admonition-title">Caution</p><p>Some developers <a href="https://stackoverflow.com/a/33685899/5951529">criticize this method</a>. If you need different dependencies for <em>requirements.txt</em> and <em>install_requires</em>, please, add list of your dependencies in <em>requirements.txt</em> and <em>setup.cfg</em> both.</p></div><p><a id="Difference-between-requirementstxt-and-install_requires"></a></p><h4>9.6.1. Difference between requirements.txt and install_requires <a href="#Difference-between-requirementstxt-and-install_requires" class="headerlink" title="Permanent link">¶</a></h4><p>Simplified definition.</p><p><a id="install_requires"></a></p><h5>9.6.1.1. install_requires <a href="#install_requires" class="headerlink" title="Permanent link">¶</a></h5><p><em>install_requires</em> parameter in <em>setup.cfg</em> or <em>setup.py</em> show, which packages will install, if user install your package via pip. For example, user install <a href="https://pypi.org/project/sasha/">clize package</a>:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>pip install clize
</pre></div><p><a href="https://github.com/epsy/clize/blob/3d9804b6b652415215677846a44d59fc7ae8929d/setup.py#L13-L19">Part of clize <em>setup.py</em></a>:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button><span class="n">install_requires</span><span class="o">=</span><span class="p">[</span>
<span class="s1">&#39;six&#39;</span><span class="p">,</span>
<span class="s1">&#39;sigtools &gt;= 2.0&#39;</span><span class="p">,</span>
<span class="s1">&#39;attrs &gt;= 17.4.0&#39;</span><span class="p">,</span>
<span class="s1">&#39;od&#39;</span><span class="p">,</span>
<span class="s1">&#39;docutils&#39;</span><span class="p">,</span>
<span class="p">],</span>
</pre></div><p>In clize installation process <a href="https://github.com/thusoy/sasha/blob/38e50791436859e9e054e50d5c511bbc46011f89/setup.py#L16-L19"><em>six</em>, <em>sigtools</em>, <em>docutils</em>, <em>od</em> and <em>attrs</em> packages</a> automatically install for user, if this packages no already installed.</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>D:<span class="se">\&gt;</span>pip install clize
Collecting clize
Using cached clize-4.0.3-py2.py3-none-any.whl
Requirement already satisfied: six in c:<span class="se">\p</span>ython36<span class="se">\l</span>ib<span class="se">\s</span>ite-packages <span class="o">(</span>from clize<span class="o">)</span>
Requirement already satisfied: sigtools&gt;<span class="o">=</span><span class="m">2</span>.0 in c:<span class="se">\p</span>ython36<span class="se">\l</span>ib<span class="se">\s</span>ite-packages <span class="o">(</span>from clize<span class="o">)</span>
Requirement already satisfied: docutils in c:<span class="se">\p</span>ython36<span class="se">\l</span>ib<span class="se">\s</span>ite-packages <span class="o">(</span>from clize<span class="o">)</span>
Collecting od <span class="o">(</span>from clize<span class="o">)</span>
Using cached od-1.0-py3-none-any.whl
Requirement already satisfied: attrs&gt;<span class="o">=</span><span class="m">17</span>.4.0 in c:<span class="se">\p</span>ython36<span class="se">\l</span>ib<span class="se">\s</span>ite-packages <span class="o">(</span>from clize<span class="o">)</span>
Installing collected packages: od, clize
Successfully installed clize-4.0.3 od-1.0
</pre></div><p><a id="requirementstxt"></a></p><h5>9.6.1.2. requirements.txt <a href="#requirementstxt" class="headerlink" title="Permanent link">¶</a></h5><p>For example, I am Python package developer and have local dependencies for my package.</p><ol><li><p>If I want to update local dependencies, I update versions in <em>requirements.txt</em> → I run in console:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>pip install -r requirements.txt -t . --upgrade
</pre></div><p>it update my local dependencies.</p></li><li><p>Services as <a href="https://dependabot.com/">Dependabot</a> or <a href="https://pyup.io/">Pyup</a> check dependencies from <em>requirements.txt</em> and update numbers of outdated versions.</p></li></ol><p><a id="setuppy"></a></p><h4>9.6.2. setup.py <a href="#setuppy" class="headerlink" title="Permanent link">¶</a></h4><p>In this and 2 next sections I wrote, how you can get <a href="#install_requires">install_requires behavior</a>, use solely <em>requirements.txt</em> file. You don't need add your dependencies to install_requires.</p><p>Add <a href="https://stackoverflow.com/a/16624700/5951529">this code</a> to your <em>setup.py</em>:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button><span class="kn">from</span> <span class="nn">setuptools</span> <span class="kn">import</span> <span class="n">setup</span>
<span class="kn">from</span> <span class="nn">pip.req</span> <span class="kn">import</span> <span class="n">parse_requirements</span>
<span class="c1"># parse_requirements() returns generator of pip.req.InstallRequirement objects</span>
<span class="n">install_reqs</span> <span class="o">=</span> <span class="n">parse_requirements</span><span class="p">(</span><span class="s1">&#39;requirements.txt&#39;</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="s1">&#39;hack&#39;</span><span class="p">)</span>
<span class="c1"># reqs is a list of requirements</span>
<span class="c1"># e.g. [&#39;django==1.5.1&#39;, &#39;mezzanine==1.4.6&#39;]</span>
<span class="n">reqs</span> <span class="o">=</span> <span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">ir</span><span class="o">.</span><span class="n">req</span><span class="p">)</span> <span class="k">for</span> <span class="n">ir</span> <span class="ow">in</span> <span class="n">install_reqs</span><span class="p">]</span>
<span class="n">setup</span><span class="p">(</span>
<span class="n">install_requires</span> <span class="o">=</span> <span class="n">reqs</span>
<span class="p">)</span>
</pre></div><div class="admonition note"><p class="admonition-title">Note</p><p>Author of answer by link above doesn't add a line in answer:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button><span class="kn">from</span> <span class="nn">setuptools</span> <span class="kn">import</span> <span class="n">setup</span>
</pre></div><p>But you need to add it.</p></div><p><a id="requirementstxt-1"></a></p><h4>9.6.3. requirements.txt <a href="#requirementstxt-1" class="headerlink" title="Permanent link">¶</a></h4><p><a href="https://pip.readthedocs.io/en/1.1/requirements.html">Add list of your dependencies</a> to <em>requirements.txt</em>.</p><p><a id="MANIFESTin"></a></p><h4>9.6.4. MANIFEST.in <a href="#MANIFESTin" class="headerlink" title="Permanent link">¶</a></h4><p>Add a line to <em>MANIFEST.in</em> file:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>include requirements.txt
</pre></div><p>If no, <a href="https://stackoverflow.com/q/26319101/5951529">users can't install your package</a>.</p><p><a id="pyroma"></a></p><h3>9.7. pyroma <a href="#pyroma" class="headerlink" title="Permanent link">¶</a></h3><p><a href="https://pypi.python.org/pypi/pyroma/">pyroma</a> — PyPI configuration validator.</p><p>If you set all your configuration files, run command in root directory of your Python module:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>pyroma .
</pre></div><p>You need get 10/10 final rating, example:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>$ pyroma .
------------------------------
Checking .
Registered VCS backend: git
Registered VCS backend: hg
Registered VCS backend: svn
Registered VCS backend: bzr
Found erichek
------------------------------
Final rating: <span class="m">10</span>/10
Your cheese is so fresh most people think it<span class="err">&#39;</span>s a cream: Mascarpone
------------------------------
</pre></div><p>If no 10/10, please, see pyroma messages and try fix your package.</p><p><a id="TestPyPI"></a></p><h2>10. TestPyPI <a href="#TestPyPI" class="headerlink" title="Permanent link">¶</a></h2><p><a id="What-is-TestPyPI"></a></p><h3>10.1. What is TestPyPI <a href="#What-is-TestPyPI" class="headerlink" title="Permanent link">¶</a></h3><p>If you publish your package first time or not sure that everything is doing right, I recommend at first publish package to <a href="https://test.pypi.org/">TestPyPI</a>. TestPyPI — is a service, where you can test uploading, downloading and display your package on PyPI site before you share package to PyPI.</p><p><a id="Registration"></a></p><h3>10.2. Registration <a href="#Registration" class="headerlink" title="Permanent link">¶</a></h3><p>Please, register on <a href="https://testpypi.python.org">TestPyPI</a> and <a href="https://pypi.python.org/pypi">PyPI</a> sites.</p><p>It would be nice, if you will use same username and password for both sites, that <a href="#Twine-settings">Twine</a> works correct.</p><p><a id="Twine-settings"></a></p><h3>10.3. Twine settings <a href="#Twine-settings" class="headerlink" title="Permanent link">¶</a></h3><p><a href="https://github.com/pypa/twine#options">Add environment variables</a> <em>TWINE_USERNAME</em> and <em>TWINE_PASSWORD</em> with values — your PyPI and TestPyPI username and password.</p><p>See, how you can add environment variables for:</p><ul><li><a href="https://askubuntu.com/a/58828/582218">UNIX</a>,</li><li><a href="https://superuser.com/a/79614/572069">Windows</a>.</li></ul><div class="admonition caution"><p class="admonition-title">Caution</p><p>Also <a href="http://peterdowns.com/posts/first-time-with-pypi.html">you can add</a> your username and password to <em>.pypirc</em> file, but it <a href="https://packaging.python.org/tutorials/distributing-packages/#create-an-account">not recommended</a>.</p></div><p><a id="Build-package"></a></p><h3>10.4. Build package <a href="#Build-package" class="headerlink" title="Permanent link">¶</a></h3><p>Print in your terminal:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>python setup.py bdist_wheel
</pre></div><div class="admonition note"><p class="admonition-title">Note</p><p><a href="http://peterdowns.com/posts/first-time-with-pypi.html"><em>python setup.py register</em></a> <a href="https://packaging.python.org/tutorials/distributing-packages/#uploading-your-project-to-pypi">is obsolete method</a>.</p></div><div class="admonition info"><p class="admonition-title">Info</p><p>If by some reasons you don't want use Wheels, <a href="https://packaging.python.org/tutorials/distributing-packages/#source-distributions">you can build your package</a>, use command <code class="SashaInlineHighlight">python setup.py sdist</code></p></div><p><a id="Publish-to-TestPyPI"></a></p><h3>10.5. Publish to TestPyPI <a href="#Publish-to-TestPyPI" class="headerlink" title="Permanent link">¶</a></h3><p><a href="https://packaging.python.org/guides/using-testpypi/#using-testpypi-with-twine">Enter in your terminal</a>:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>twine upload --repository-url https://test.pypi.org/legacy/ dist/*
</pre></div><p>If no errors in your configuration, package must successful upload to TestPyPI.</p><div class="admonition bug"><p class="admonition-title">Bug</p><p><a href="https://github.com/pypa/packaging-problems/issues/74">Known bug</a> at February 2018 — in PyPI and TestPyPI you never can't overwrite specific version of your package, even if you delete your package. I.e., for example, you publish to PyPI or TestPyPI version <em>4.14.7</em> of your package <em>mypackage</em> → you delete <em>mypackage</em> from PyPI and/or TestPyPI → you can't upload <em>4.14.7</em> version of <em>mypackage</em> again.</p></div><p><a id="Visit-TestPyPI"></a></p><h3>10.6. Visit TestPyPI <a href="#Visit-TestPyPI" class="headerlink" title="Permanent link">¶</a></h3><p>After uploading visit 2 pages:</p><ul><li><code class="SashaInlineHighlight">https://testpypi.python.org/pypi/&lt;your_package&gt;</code>,</li><li><code class="SashaInlineHighlight">https://test.pypi.org/project/&lt;your_package&gt;</code>.</li></ul><p>Examples for Erichek at February 2018:</p><ul><li><a href="https://test.pypi.org/project/erichek">test.pypi.org/project/erichek</a>:</li></ul><p><a href="https://i.imgur.com/WW0M2Io.png" class="fancybox"><img alt="Erichek TestPyPI" class="SashaLazy" src="https://kristinita.netlify.com/theme/images/interface-images/transparent-one-pixel.png" data-src="https://i.imgur.com/WW0M2Io.png"></a></p><p><a href="https://i.imgur.com/r5kIabM.png" class="fancybox"><img alt="Erichek TestPyPI 2" class="SashaLazy" src="https://kristinita.netlify.com/theme/images/interface-images/transparent-one-pixel.png" data-src="https://i.imgur.com/r5kIabM.png"></a></p><ul><li><a href="https://testpypi.python.org/pypi/erichek">testpypi.python.org/pypi/erichek</a>:</li></ul><p><a href="https://i.imgur.com/FDXRBtv.png" class="fancybox"><img alt="Erichek TestPyPI Python" class="SashaLazy" src="https://kristinita.netlify.com/theme/images/interface-images/transparent-one-pixel.png" data-src="https://i.imgur.com/FDXRBtv.png"></a></p><p>If the result suits you, in next step install package, that you upload, use virtual environment.</p><div class="admonition caution"><p class="admonition-title">Caution</p><p>You can't find your package, if you use search form on <a href="https://test.pypi.org">test.pypi.org</a> or <a href="https://pypi.org">pypi.org</a>. <a href="https://github.com/pypa/warehouse/issues/2899#issuecomment-364150430">The search indexes may update ~24 hours for a new package or deleted package to appear in a search</a>.</p></div><div class="admonition note"><p class="admonition-title">Note</p><p>On <a href="https://testpypi.python.org">testpypi.python.org</a> can't show last version of your package. That fix it, login at <a href="https://testpypi.python.org">testpypi.python.org</a> → visit <code class="SashaInlineHighlight">https://testpypi.python.org/pypi?%3Aaction=pkg_edit&amp;name=&lt;your_package&gt;</code> (<a href="https://testpypi.python.org/pypi?%3Aaction=pkg_edit&amp;name=erichek">testpypi.python.org/pypi?%3Aaction=pkg_edit&amp;name=erichek</a> for Erichek) → <a href="https://i.imgur.com/bGjKHzS.png">set <em>Hide? No</em></a> for latest version.</p><p>If you have this problem for <a href="https://pypi.python.org">pypi.python.org</a>, make same actions.</p></div><p><a id="virtualenv"></a></p><h3>10.7. virtualenv <a href="#virtualenv" class="headerlink" title="Permanent link">¶</a></h3><p>I recommend install your TestPyPI package, use virtual environment.</p><p><a id="Why-virtual-environment"></a></p><h4>10.7.1. Why virtual environment? <a href="#Why-virtual-environment" class="headerlink" title="Permanent link">¶</a></h4><p>Citation from <a href="https://www.apress.com/us/book/9781484222409">Pro Python Best Practices</a> book:</p><blockquote><p>Virtualenv is like building a moat around the house. It prevents a fire from spreading — in both directions. Likewise, a virtual environment prevents that Python projects interfere with each other.</p></blockquote><p><a href="https://i.imgur.com/fRISif0.png" class="fancybox"><img alt="virtualenv" class="SashaLazy" src="https://kristinita.netlify.com/theme/images/interface-images/transparent-one-pixel.png" data-src="https://i.imgur.com/fRISif0.png"></a></p><p>Reasons of use virtual environment for TestPyPI installation:</p><ol><li>You can have bugs in your package. Bugs may have a negative impact of your environment. If you will use virtual environment, these bugs does not affect your global Python environment.</li><li>You can have some globally dependencies in your environment, but users of your package may haven't them. If you use virtual environment, you see, how your package will install and works without, possibly, pre-installed global dependencies on your machine.</li></ol><p><a id="Using-virtualenv-and-virtualenvwrapper"></a></p><h4>10.7.2. Using virtualenv and virtualenvwrapper <a href="#Using-virtualenv-and-virtualenvwrapper" class="headerlink" title="Permanent link">¶</a></h4><div class="admonition caution"><p class="admonition-title">Caution</p><p>If you on Windows, please, use <a href="https://conemu.github.io/en/Delusions.html#delusion-2">standard Windows console</a> for correct virtualenvwrapper-win works or use plugin for your preferred terminal. You can't use command lines command from this section in <a href="https://pypi.python.org/pypi/virtualenvwrapper-win">PowerShell</a> or <a href="https://github.com/FarGroup/FarManager/issues/23">Far Manager</a>.</p></div><p>Open terminal in any directory. Run these commands:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>C<span class="p">:</span><span class="nl">\Users\SashaChernykh</span><span class="c1">&gt;mkvirtualenv erichekenv</span>
Using base prefix &#39;c:\\python36&#39;
New python executable in C:\Users\SashaChernykh\Envs\erichekenv\Scripts\python.exe
Installing setuptools, pip, wheel...done.
<span class="p">(</span>erichekenv<span class="p">)</span> C:\Users\SashaChernykh<span class="p">&gt;</span>toggleglobalsitepackages
Disabled global site-packages
<span class="p">(</span>erichekenv<span class="p">)</span> C:\Users\SashaChernykh<span class="p">&gt;</span>pip install --extra-index-url https://test.pypi.org/simple/ erichek
</pre></div><p>Where:</p><ul><li><em>erichekenv</em> — name of your virtual environment; you can use any name instead of <em>erichek</em>, if virtual environment with this name not already exist;</li><li><em>erichek</em> — name of your package; use real name of your package instead of <em>erichek</em>.</li></ul><div class="admonition note"><p class="admonition-title">Note</p><p><a href="https://stackoverflow.com/a/34561435/5951529">Use <em>--extra-index-url</em></a>, <a href="https://packaging.python.org/guides/using-testpypi/#using-testpypi-with-pip">not <em>--index-url</em></a> command line argument for correct dependencies installation.</p></div><div class="admonition caution"><p class="admonition-title">Caution</p><p>Can take ~10 minutes, before you can install last version of your package. For example, you upload <em>4.14.7</em> version your package <em>mypackage</em> to TestPyPI → you print in a terminal <code class="SashaInlineHighlight">pip install --extra-index-url https://test.pypi.org/simple/ mypackage==4.14.7</code> → you can get an error:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>Could not find a version that satisfies the requirement <span class="nv">mypackage</span><span class="o">==</span><span class="m">4</span>.14.7 <span class="o">(</span>from versions: <span class="m">4</span>.14.6<span class="o">)</span>
No matching distribution found <span class="k">for</span> <span class="nv">mypackage</span><span class="o">==</span><span class="m">4</span>.14.7
</pre></div><p>You may need wait ~10 minutes, that 4.14.7 version index on TestPyPI. You can have a similar problem for PyPI.</p></div><p><a id="Checking"></a></p><h4>10.7.3. Checking <a href="#Checking" class="headerlink" title="Permanent link">¶</a></h4><p>If you can't have bugs in installation process, check, that you package works correct. For example, Erichek check, contains errors in <em>.txt</em> files in a folder or no. I run <em>erichek</em> console command.</p><p>If error in one of text file:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>C<span class="p">:</span><span class="nl">\ErichekExamples</span><span class="c1">&gt;erichek</span>
[2018-02-08 08:49:43.058353] NOTICE: eric_encoding logbook: All files in Windows-1251 encoding
[2018-02-08 08:49:43.060355] NOTICE: eric_body logbook: All files contains <span class="p">&lt;</span>body&gt;
[2018-02-08 08:49:43.062358] NOTICE: eric_asterisks logbook: All needest lines contains asterisks
[2018-02-08 08:49:43.063357] ERROR: eric_head logbook: Air_crashes.txt not contains «Постоянный адрес пакета:»
[2018-02-08 08:49:43.064359] ERROR: eric_head logbook: One or more packages not contains one or more head data. Please, add correct head data to your package.
[2018-02-08 08:49:43.064359] ERROR: summary logbook: You have errors in your packages. Please, fix them.
</pre></div><p>If all <em>.txt</em> files correct:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>C<span class="p">:</span><span class="nl">\ErichekExamples</span><span class="c1">&gt;erichek</span>
[2018-02-08 08:51:23.840987] NOTICE: eric_encoding logbook: All files in Windows-1251 encoding
[2018-02-08 08:51:23.841997] NOTICE: eric_body logbook: All files contains <span class="p">&lt;</span>body&gt;
[2018-02-08 08:51:23.843991] NOTICE: eric_asterisks logbook: All needest lines contains asterisks
[2018-02-08 08:51:23.844992] NOTICE: eric_head logbook: All files contains correct head data
[2018-02-08 08:51:23.844992] NOTICE: summary logbook: Congratulations! You haven&#39;t errors in your packages!
</pre></div><p>Erichek works as expected.</p><p>After succsessful checking <a href="https://github.com/davidmarble/virtualenvwrapper-win/#main-commands">you can remove</a> your virtual environment (<em>erichekenv</em> in example):</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>(erichekenv) C:\Users\SashaChernykh&gt;rmvirtualenv erichekenv
Deleted C:\Users\SashaChernykh\Envs\erichekenv
C:\Users\SashaChernykh&gt;
</pre></div><p><a id="PyPI"></a></p><h2>11. PyPI <a href="#PyPI" class="headerlink" title="Permanent link">¶</a></h2><p>If all actions from <a href="#TestPyPI">TestPyPI section</a> success for you, you can publish your package to PyPI and then install it.</p><ol><li>change version in your <em>setup.cfg</em> file (it must be <a href="https://semver.org/">semver</a>-compatible);</li><li><p>in root folder of your package open terminal and print:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>python setup.py bdist_wheel <span class="o">&amp;&amp;</span> twine upload dist/*
</pre></div></li><li><p>visit <code class="SashaInlineHighlight">https://pypi.python.org/pypi/&lt;your_package&gt;</code> and <code class="SashaInlineHighlight">https://pypi.org/project/&lt;your_package&gt;</code>, as you <a href="#Visit-TestPyPI">visit TestPyPI</a> and check, is everything okay;</p></li><li><p>install your package, use pip:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>pip install &lt;your_package&gt;
</pre></div></li><li><p>check, that your package works correct <a href="#Checking">as in previous section</a>.</p></li></ol><p>If all okay, <strong>congratulations! You successful publish your package to PyPI!</strong></p><p><a href="https://i.imgur.com/4cvn8jX.jpg" class="fancybox"><img alt="Congratulations" class="SashaLazy" src="https://kristinita.netlify.com/theme/images/interface-images/transparent-one-pixel.png" data-src="https://i.imgur.com/4cvn8jX.jpg"></a></p><p><a id="Updating"></a></p><h2>12. Updating <a href="#Updating" class="headerlink" title="Permanent link">¶</a></h2><p>That update your package in PyPI:</p><ol><li>Make new changes,</li><li>Make same actions as in <a href="#PyPI">section above</a>.</li></ol><p><a id="Automatic-updating-release-and-changelog"></a></p><h2>13. Automatic updating, release and changelog <a href="#Automatic-updating-release-and-changelog" class="headerlink" title="Permanent link">¶</a></h2><div class="admonition note"><p class="admonition-title">Note</p><p>In this article I wrote not detailed. If you want to read details, how it worked, see <a href="Fastest-way-to-add-new-version-of-Sublime-Text-3-package">my another article</a>. I recommend read it before making actions from this section.</p></div><div class="admonition caution"><p class="admonition-title">Caution</p><p>I recommend in first do actions from this section for test project, not real. Argumentation:</p><ul><li>You or I can make a typo(s);</li><li>Differences in my and your environment;</li><li>Different versions of tools from this article can do another behavior, <a href="https://github.com/webpro/release-it/issues/233">example</a></li></ul></div><p><a id="Demonstration-1"></a></p><h3>13.1. Demonstration <a href="#Demonstration-1" class="headerlink" title="Permanent link">¶</a></h3><p>I enter command to the terminal:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button>release-it -n -V
</pre></div><p>I get <a href="https://github.com/Kristinita/Erichek/commit/be58c1d53bbc8aeb764807463b0db159b59200f6">behavior</a>:</p><ol><li><p>All commits description add to <em>CHANGELOG.md</em>:</p><p><a href="https://i.imgur.com/pmePvzQ.png" class="fancybox"><img alt="Changelog" class="SashaLazy" src="https://kristinita.netlify.com/theme/images/interface-images/transparent-one-pixel.png" data-src="https://i.imgur.com/pmePvzQ.png"></a></p></li><li><p>New release <a href="https://github.com/Kristinita/Erichek/releases/tag/0.2.0">publish to GitHub</a>:</p><p><a href="https://i.imgur.com/fiMNQAw.png" class="fancybox"><img alt="New release" class="SashaLazy" src="https://kristinita.netlify.com/theme/images/interface-images/transparent-one-pixel.png" data-src="https://i.imgur.com/fiMNQAw.png"></a></p></li><li><p>Version updates in <em>setup.cfg</em>:</p><p><a href="https://i.imgur.com/4C1jnLm.png" class="fancybox"><img alt="Version in setup.cfg" class="SashaLazy" src="https://kristinita.netlify.com/theme/images/interface-images/transparent-one-pixel.png" data-src="https://i.imgur.com/4C1jnLm.png"></a></p></li><li><p>New version of Erichek publish to PyPI.</p></li></ol><p>If you want to have same behavior, read on.</p><p><a id="Features-1"></a></p><h3>13.2. Features <a href="#Features-1" class="headerlink" title="Permanent link">¶</a></h3><p>See <a href="Fastest-way-to-add-new-version-of-Sublime-Text-3-package#Features">these features</a>.</p><p><a id="Limitations-1"></a></p><h3>13.3. Limitations <a href="#Limitations-1" class="headerlink" title="Permanent link">¶</a></h3><p>See <a href="Fastest-way-to-add-new-version-of-Sublime-Text-3-package#Limitations">these limitations</a>.</p><p><a id="Installation-and-setting-up"></a></p><h3>13.4. Installation and setting-up <a href="#Installation-and-setting-up" class="headerlink" title="Permanent link">¶</a></h3><ol><li>you need to install all from <a href="Fastest-way-to-add-new-version-of-Sublime-Text-3-package#Installation">this section</a> except <em>tee</em>, <em>cat</em>, <em>mv</em> and <em>js-beautify</em>;</li><li>please, follow <a href="Fastest-way-to-add-new-version-of-Sublime-Text-3-package#Github-token">these</a>, <a href="Fastest-way-to-add-new-version-of-Sublime-Text-3-package#Upstream-branch">these</a> and <a href="Fastest-way-to-add-new-version-of-Sublime-Text-3-package#CHANGELOGmd">these</a> instructions;</li><li><a href="Fastest-way-to-add-new-version-of-Sublime-Text-3-package#packagejson">create a file <em>package.json</em></a> in root folder of your repository.</li></ol><p><a id="release-itjson"></a></p><h4>13.4.1. .release-it.json <a href="#release-itjson" class="headerlink" title="Permanent link">¶</a></h4><p>Create a file <em>.release-it.json</em> in root folder of your repository with content:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button><span class="p">{</span>
<span class="nt">&quot;buildCommand&quot;</span><span class="p">:</span> <span class="s2">&quot;changelog -u https:\/\/${repo.host}\/${repo.repository} -f CHANGELOG.md &amp;&amp; sed -i &#39;s\/^version = .*$\/version = ${version}\/g&#39; setup.cfg &amp;&amp; python setup.py bdist_wheel &amp;&amp; twine upload dist\/*&quot;</span><span class="p">,</span>
<span class="nt">&quot;changelogCommand&quot;</span><span class="p">:</span> <span class="s2">&quot;changelog -f -&quot;</span><span class="p">,</span>
<span class="nt">&quot;github&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;release&quot;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nt">&quot;tokenRef&quot;</span><span class="p">:</span> <span class="s2">&quot;TOKEN_GITHUB_FOR_RELEASE_IT&quot;</span>
<span class="p">},</span>
<span class="nt">&quot;npm&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;publish&quot;</span><span class="p">:</span> <span class="kc">false</span>
<span class="p">},</span>
<span class="nt">&quot;safeBump&quot;</span><span class="p">:</span> <span class="kc">false</span>
<span class="p">}</span>
</pre></div><p>Where:</p><ul><li><p><code class="SashaInlineHighlight">sed -i &#39;s\/^version = .*$\/version = ${version}\/g&#39; setup.cfg</code> — command for replacing version in your <em>setup.cfg</em> to the newest, see <a href="https://askubuntu.com/a/20416/582218">find and replace via sed</a>:</p><p><a href="https://i.imgur.com/4C1jnLm.png" class="fancybox"><img alt="Version in setup.cfg" class="SashaLazy" src="https://kristinita.netlify.com/theme/images/interface-images/transparent-one-pixel.png" data-src="https://i.imgur.com/4C1jnLm.png"></a></p></li><li><p><code class="SashaInlineHighlight">python setup.py bdist_wheel &amp;&amp; twine upload dist\/*</code> — <a href="#PyPI">build and publish</a> your package.</p></li></ul><div class="admonition note"><p class="admonition-title">Note</p><p><a href="https://github.com/Kristinita/Erichek/blob/master/.release-it.json">In <em>.release-it.json</em> of real Erichek repository</a> I add also next text:</p><div class="SashaBlockHighlight"><pre><button class="SashaButton SashaTooltip"><img alt="Clipboard button" class="SashaNotModify" src="https://kristinita.netlify.com/theme/images/interface-images/clippy.svg"></button><span class="err">&amp;&amp;</span> <span class="err">sed</span> <span class="err">-i</span> <span class="err">&#39;s\/^VERSION</span> <span class="err">=</span> <span class="err">\</span><span class="s2">&quot;.*\&quot;$\/VERSION = \&quot;${version}\&quot;\/g&#39; \&quot;erichek\/eric_config.py\&quot;</span>
</pre></div><p>It change a version in <em>eric_config.py</em> file, that command <code class="SashaInlineHighlight">erichek --version</code> works correct.</p><p><a href="https://i.imgur.com/xMrSbew.png" class="fancybox"><img alt="Version in eric_config.py" class="SashaLazy" src="https://kristinita.netlify.com/theme/images/interface-images/transparent-one-pixel.png" data-src="https://i.imgur.com/xMrSbew.png"></a></p><p>If you don't want to have this behavior, please, do not add this text to your <em>.release-it.json</em>.</p></div><p>See <a href="Fastest-way-to-add-new-version-of-Sublime-Text-3-package#release-itjson-1">here</a>, if you want to know details about another parts of <em>.release-it.json</em>.</p><p><a id="Usage"></a></p><h3>13.5. Usage <a href="#Usage" class="headerlink" title="Permanent link">¶</a></h3><p>See <a href="Fastest-way-to-add-new-version-of-Sublime-Text-3-package#Usage">usage instructions</a>.</p><p><a id="Testing-environment"></a></p><h2>14. Testing environment <a href="#Testing-environment" class="headerlink" title="Permanent link">¶</a></h2><ul><li>Windows 10 Enterprise LTSB 64-bit EN,</li><li>Python 3.6.4,</li><li>setuptools 38.4.1,</li><li>pip 9.0.1,</li><li>Twine 1.9.1,</li><li>Wheel 0.30.0,</li><li>virtualenv 15.1.0,</li><li>virtualenvwrapper-win 1.2.5,</li><li>pyroma 2.3,</li><li>Node.js 9.4.0,</li><li>git 2.16.0.windows.2,</li><li>release-it 7.0.0,</li><li>changelog 1.7.0,</li><li>sed (GNU sed) 4.2.2.</li></ul></section><footer><div class="clearfix"><span class="SashaPreviousNeighbor"><a href="https://kristinita.netlify.com/IT-articles/Fastest-way-to-add-new-version-of-Sublime-Text-3-package.html" title="Fastest way to add new version of your Sublime Text package">← Previous article</a></span> <span class="SashaNextNeighbor"><a href="https://kristinita.netlify.com/IT-articles/typo-reporter.html" title="typo-reporter">Next article →</a></span></div><div class="SashaClearBoth"></div><div class="SashaEmNoColorBottom"><p><a id="Like"></a></p><h2>Like? <a href="#Like" class="headerlink" title="Permanent link">¶</a></h2><ol><li>Share this web-page in your preferred social network, use share buttons on the side of page.</li><li><p>Subcsribe to all articles or specific tag/category, use your preferred RSS Reader. I use <a href="http://quiterss.org">QuiteRSS</a> for Windows.</p></li></ol><p><a id="Problems"></a></p><h2>Problems? <a href="#Problems" class="headerlink" title="Permanent link">¶</a></h2><ol><li>(PC only, not for mobile devices). If you find in this article typo or small error, please, report about it use <a href="https://kristinita.netlify.com/IT-articles/typo-reporter">typo-reporter</a>. Select text with typo → press <kbd>Ctrl+Enter</kbd> (<kbd>⌘Enter</kbd> for Mac) → write comment → send typo report.</li><li>If you find more serious errors in this article and/or site, <a href="https://github.com/Kristinita/KristinitaPelican/issues/new">create GitHub issue</a>.</li><li>You can also <a href="https://github.com/Kristinita/KristinitaPelican/edit/master/content/IT-articles/How-to-publish-your-package-to-PyPI-2018.md">edit this page yourself</a> and send <a href="http://ru.stackoverflow.com/a/598162/199934">pull request</a>.</li><li>Or write comment here. <a href="https://github.github.com/gfm/">Markdown GFM support in comments</a>. You can use <a href="https://github.com/GhostText/GhostText">GhostText</a>, that write issue in your preferred editor.<div class="wildfire_thread"></div></li></ol><p>I hate private communication, solely open support.</p><p>If you write in the style of <a href="https://kristinita.netlify.com/Smert-svobode/%D0%9D%D0%BE%D0%B2%D1%8B%D0%B5-%D0%BD%D0%B5%D0%B4%D0%BE%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B5">new disgruntled Russian</a> I reserve the right to dispose of my own discretion.</p><p>All rights reserved ©.</p></div><div class="WorkOnYourself">Работайте над собой</div></footer></article></main></body></html>
You can’t perform that action at this time.