Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5881c44

Browse files
authored
Merge pull requestpython3statement#55 from Carreau/practicalities
Start working on the practicalities section.
2 parents9a3c3b4 +f9ed6e8 commit5881c44

File tree

7 files changed

+420
-5
lines changed

7 files changed

+420
-5
lines changed

‎.gitignore‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
_site/
2-
.DS_Store
2+
.DS_Store
3+
*.swo

‎_config.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@ colors:
3535

3636
collections:
3737
-sections
38+
-practicalities
3839

‎_includes/css/base.css‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,16 @@
274274
width:90%;
275275
}
276276

277-
.highlightpre, .highlightcode {display:block;margin:0;padding:0;background: none;overflow:auto;word-wrap: normal; }
277+
.highlightpre, .highlightcode {
278+
display:block;
279+
margin:0;
280+
padding:0;
281+
background:
282+
none;
283+
overflow:auto;
284+
word-wrap: normal;
285+
white-space: pre;
286+
}
278287

279288
.highlight, .linenodiv {
280289
background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWPQ1dU1BgABzQC7XXMTYQAAAABJRU5ErkJggg==);

‎_includes/css/main.css‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ html { box-sizing: border-box; }
2525
#{{id}} .sectiondivider { color: {{ bg }}; }
2626
{% endfor %}
2727

28+
{% for node in site.practicalities %}
29+
{% capture id %}{{ node.id |remove:'/' |downcase }}{% endcapture %}
30+
{% capture bg %}{% if site.colors[node.bg] %}{{ site.colors[node.bg] }}{% else %}{{ node.bg }}{% endif %}{% endcapture %}
31+
{% capture fg %}{% if site.colors[node.color] %}{{ site.colors[node.color] }}{% else %}{{ node.color }}{% endif %}{% endcapture %}
32+
nav .p-{{id}} { border-color: {{ bg }}; }
33+
#{{id}} { background-color: {{ bg }}!important; color: {{ fg }}; }
34+
#{{id}} a { color: {{ fg }}; }
35+
#{{id}} .sectiondivider { color: {{ bg }}; }
36+
{% endfor %}
37+
2838

2939
/* ----- code, syntax highlighting, etc ----- */
3040

‎_practicalities/intro.md‎

Lines changed: 352 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
---
2+
bg:'#4da45e'
3+
color:white
4+
title:practicalities
5+
fa-icon:pencil
6+
id:bar
7+
---
8+
9+
We do not discourage authors to release software on Python 2. While this guide
10+
is mostly written with the assumption that software are going to stop Python 2
11+
support, it does perfectly apply to a package that wish to not support Python 3,
12+
or is stopping support for any minor version.
13+
14+
15+
This page gather information and links to resources allowing to release a
16+
library that stop supporting an older version of Python without causing too
17+
much disruption for users who haven't upgraded to this new version.
18+
19+
Whether you are a user, or a developer, being aware of the issue listed here, at
20+
least the main points should ease lots of the pain.
21+
22+
#Too long, did not read:
23+
24+
- Help and encourage users to install**pip 9.0+**
25+
- Help and encourage users to install**setuptools 24.3+**
26+
- As maintainer use`setup(..., python_requires='>=3.4')` new option.
27+
- do use`pip install [-e] .` and do**not** invoke`setup.py` directly.
28+
-**Fail** early at**install time** if on Python 2.
29+
- We are giving a talk at PyCon 2017 (likely recorded), add link here.
30+
31+
##The problem
32+
33+
Up until December 2016 it was hard to publish a new major version of library
34+
that changed requirements in Python version and mark it as such so that user
35+
system will not try to upgrade said library.
36+
37+
With the recent changes in Python packaging this is now possible.
38+
39+
As an example let's look at the example of the`fictitious` library.
40+
41+
-`fictitious` 1.1, 1.2, 1.3, 1.4 are compatible Python 2.7 and 3.3+
42+
-`fictitious` 2.0 has been released and is python 3.4+ only.
43+
44+
As a Python 2.7 user, if I don't pay attention, or if the library is not
45+
correctly tagged, if I issue the following:
46+
47+
$ python -c 'import fictitious; print(fictitious.__version__)'
48+
1.3.2
49+
$ pip install fiction --upgrade
50+
51+
Either my system will install 2.0, which will not work, on the worst case
52+
scenario, or fail to install, in which case I will not get the critical 1.4
53+
upgrade.
54+
55+
##As a user
56+
57+
###Install Pip 9.0
58+
59+
If you are already a Python 3 user, you should not encounter a lot of
60+
disruption. Please still check that the libraries you use follow best practices
61+
not to break for Python 2 users. Python is a community regardless of which
62+
python version you have to (or decided to) run, making sure that everything
63+
works make the community strong.
64+
65+
Make sure you have Pip >= 9.0, this is especially important if you have Python
66+
2 installations. Having pip 9.0+ is not a guaranty to flawless upgrade. But pip
67+
9.0+ does have a number of safety check not available on previous versions.
68+
69+
Having a version of pip < 9.0 can lead your system to try to upgrade to
70+
non-compatible versions of Python packages even if these are marked as
71+
non-compatible.
72+
73+
Help as many other_users_ as possible to install pip >=9.0, for the
74+
transition, it is the slowest part of the ecosystem to update, and is the only
75+
piece that requires action of all Python users.
76+
77+
The simplest way to make sure all is up to date is to run the following for
78+
each installation of Python:
79+
80+
$ pip install --upgrade setuptools pip
81+
82+
This will install the latest version of pip and setuptools.
83+
84+
You can issue the following to see the version of pip:
85+
86+
$ pip --version
87+
9.0.0
88+
89+
All good.
90+
91+
92+
93+
##Setuptools
94+
95+
If you are on a system for which no wheel is available, pip will try to
96+
install a source distribution (aka`sdist`).
97+
98+
Installing an`sdist` will require setuptools make sure you have setuptools
99+
`>=24.2.0` or building Python 3 only libraries is likely to fail. In particular
100+
if library authors have taken time to mark their library as Python 3 only, the
101+
`python_requires` argument to`setup()` may not be recognized and installation
102+
will fail.
103+
104+
Use the following to check setuptools version :
105+
106+
$ python -c 'import setuptools; print(setuptools.__version__)
107+
24.2.0
108+
109+
Again make sure to upgrade pip and setuptools to make sure you have an up to
110+
date system:
111+
112+
$ pip install --upgrade setuptools pip
113+
114+
##Local package index
115+
116+
If you are using a custom local package index, for example if you are working
117+
at a company with private packages, make sure it implement correctly
118+
[pep-503](https://www.python.org/dev/peps/pep-0503/) and let pip knows about
119+
the`python_requires` field. This_mostly_ mean that the html you are exposing
120+
should get a`data-python-requires` data attribute with the (html escaped)
121+
version specifier.
122+
123+
##The state of PyPI
124+
125+
Note that at the time of this writing the patches to`pypi.python.org` are not
126+
deployed yet but should hopefully be deployed soon.
127+
128+
[Warehouse](https://github.com/pypi/warehouse) and[Legacy
129+
PyPI](https://github.com/pypa/legacy-pypi) have received various patches to
130+
insure they support this new functionality.
131+
132+
#Preparing your library
133+
134+
135+
As a library author one of the most important factor in a smooth transition is
136+
planning and communication, letting your user base know in advance that the
137+
transition is happening and what step to take is critical for a transition.
138+
139+
For your library code here the steps you need to take to ensure that
140+
installation will fail in the least number of case:
141+
142+
You need to release your new packages version with
143+
[setuptools](https://pypi.python.org/pypi/setuptools) version 24.2.0 or above.
144+
You can also use one of the alternate package manager that can set the
145+
[Requires-Python](https://www.python.org/dev/peps/pep-0345/#requires-python)
146+
metadata field. Without this, pip 9.0**will try** to install non-compatible
147+
version of your software on Python 2. This version of setuptools is recent
148+
(July 20, 2016) and this possible thank to the[work of Xavier
149+
Fernandez](https://github.com/pypa/setuptools/pull/631)
150+
151+
Add the following to your`setup.py`
152+
153+
```
154+
setup(
155+
...
156+
python_requires='>=3.3'
157+
...
158+
)
159+
```
160+
161+
Change`>=3.3` accordingly depending on what version your library decides to
162+
support. In particular you can use`>=2.6` or`>=3.5` ! Note that this also
163+
support the_compable with_ syntax:`~=2.5` (meaning,`>=2.5` and`<3`).
164+
165+
This will make[PyPI aware](https://github.com/pypa/warehouse/pull/1448) that
166+
your package is Python 3.3+ only, and[allow
167+
pip](https://github.com/pypa/pip/pull/3877) to be[made aware of
168+
this](https://github.com/pypa/pypi-legacy/pull/506).
169+
170+
Thus as long as your user have recent enough versions of pip and setuptools
171+
they will get the right version of your library.
172+
173+
#Unit Testing and documentation
174+
175+
It is recommended**not** to invoke`setup.py` directly either with`install` or
176+
`develop` subcommands. These may not correctly resolve dependencies, and can
177+
install incompatible versions of dependencies. Please recommend and use `pip
178+
install .` and`pip install -e .` for regular and developer install.
179+
180+
Check in scripts, and documentation that the correct installation command is
181+
used.
182+
183+
#Recommended Mitigations
184+
185+
These are not mandatory but should make the transition seamless by warning your
186+
user early enough_and_ providing useful error messages.
187+
188+
##Runtime warning on master
189+
190+
Add a warning at_runtime_ early on master (before switching to Python 3
191+
only)
192+
193+
```
194+
import warnings
195+
import sys
196+
if sys.version_info < (3,):
197+
warnings.warn('You are using master of `Frobulator` with Python 2. '
198+
'Frobulator will soon be Python 3 only. '
199+
'See this issue to know more.',
200+
UserWarning)
201+
```
202+
203+
Your Python 2 user have a chance to upgrade, or get off master, (for example on
204+
the LTS branch).
205+
206+
##Fail early at import time
207+
208+
Add an error early at import at runtime with a clear error message, leave the
209+
early import compatible Python 2 for users to not be welcomed with a useless
210+
`SyntaxError`. Don't hesitate to use multi-line strings in error messages.
211+
212+
Error at import time_will_ happen on system with old version of pip and
213+
setuptools. Keep in mind that saying the package is Python 3 only is not a lot
214+
more helpful than a Syntax error. The most reasonable reason would be out of
215+
data pip and setuptools:
216+
217+
218+
```
219+
import sys
220+
221+
if sys.version_info < (3,):
222+
raise ImportError(
223+
"""You are running Frobulator 6.0 on Python 2
224+
225+
Unfortunately Frobulator 6.0 and above are not compatible with Python 2
226+
anymore, and you still ended up with this version installed on your system.
227+
That's a bummer. Sorry about that. It should not have happened. Make sure you
228+
have pip >= 9.0 to avoid this kind of issues, as well as setuptools >= 24.2:
229+
230+
$ pip install pip setuptools --upgrade
231+
232+
You have various other choices
233+
234+
- install an older version of Frobulator:
235+
236+
$ pip install 'frobulator<6.0'
237+
238+
- Upgrade your system to use Python 3.
239+
240+
It would be great if you can figure out how this version ended up being
241+
installed, and try to check how to prevent that for future users.
242+
243+
See the following url for more up to date informations:
244+
245+
https://i.am.an/url
246+
247+
""")
248+
249+
```
250+
251+
##Watch out for beta releases
252+
253+
254+
Make sure your version number match pep 440 or you will get surprises during
255+
beta in particular as the`sdist` and`wheel` will appear as being different
256+
versions, in particular sdist (during beta/rc/post) can appear with a greater
257+
version number than wheels. Pip thus try to install the sdist instead of the
258+
wheel, which have more chance of failing, in particular with pre 24.2 versions
259+
of setuptools.
260+
261+
The regular expression to check for validity of pep440 can be find below:
262+
263+
`^([1-9]\\d*!)?(0|[1-9]\\d*)(\\.(0|[1-9]\\d*))*((a|b|rc)(0|[1-9]\\d*))?(\\.post(0|[1-9]\\d*))?(\\.dev(0|[1-9]\\d*))?`
264+
265+
266+
##fail early in setup.py
267+
268+
Leave`setup.py` python 2 compatible and fail early. If you detect Python 2
269+
raise a clear error message and ask user to make sure they have pip >9.0 (or
270+
migrate to Python 3). You can (try to) conditionally import pip and check for
271+
its version but this might not be the same pip. Failing early is important to
272+
make sure the Python installation does not install an incompatible version.
273+
Otherwise user code can fail at runtime arbitrary later in the future, which can
274+
be a difficult to debug and fix. Get inspiration from the message of failure at
275+
runtime, and adapt for installation time.
276+
277+
##Fix dependant libraries
278+
279+
If you control dependant packages, Make sure to include conditional dependencies
280+
depending on the version of Python.
281+
282+
#Non recommended mitigations
283+
284+
This is a collection of "mitigation" or "solutions" you will find on the web
285+
and that you will hear about. This is an attempt to acknowledge them, and
286+
explain why they can't work and what are their drawbacks before you attempt to
287+
implement them.
288+
289+
###Use a meta-package.
290+
291+
It is possible to release a meta-package that has_virtually_ no code and rely
292+
on conditional dependency to install its actual core code on the user system.
293+
For example, Frob-6.0 could be a meta-package which depends on
294+
Frob-real-py2 on Python <3.0, and Frob-real-py3 on Python >= 3.4. While
295+
this approach is_doable_ this can make imports confusing.
296+
297+
##Depend on setuptools
298+
299+
You can mark your library as dependent on setuptools greater than 24.3 this
300+
will insure that during the next upgrade (when the packages drop python 2
301+
support) will have the right version of setuptools.
302+
303+
Of course regardless of all the care you will take for your library to no break
304+
and to install only on python 2, you will likely have cases where it still end
305+
up being installed on incompatible versions of Python. Simply because users
306+
upgrades rarely and only an old version of pip or setuptools is enough to make
307+
the all update process broken.
308+
309+
Plus setuptools is rarely an actual dependency of your project but a
310+
requirement to build wheels.
311+
312+
313+
###Multiple Sdist.
314+
315+
Pip (used to) support a "feature" where a sdist ending in`-pyX.Y.tar.gz` would
316+
only be seen as compatible on Python X.Y, thus it used to be possible to
317+
publish multiple sdist of a package targeting various python version.
318+
319+
Though it is not possible anymore to upload multiple sdist on PyPI. This
320+
solution is thus not possible.
321+
322+
###Wheel only ?
323+
324+
Releasing a package only using wheel for a given python version is doable, but
325+
this will break downstream packages that may require the original source to
326+
reproduce the build.
327+
328+
#Why all that ?
329+
330+
You might wonder why all this, it's 2016 already, so how come all these
331+
issues ? Python 3 has been out for 8+ years now !
332+
333+
Well there are many reasons to this, first of all, this issue mostly affect
334+
libraries that are currently python 2 and Python 3 compatible at the same time.
335+
Many libraries have transitioned from Python 2-only to Python 2 + 3. And the
336+
issue of transitioning to Python 3 only is relatively recent. Technically it
337+
can also apply to libraries that are only stopping support for 2.6, or even are
338+
already Python 3 only, but are starting to stop support for earlier versions of
339+
Python. For example a library releasing a Python 3.4+ only version.
340+
341+
Python 3.3 was release at the end of 2012, and was the first version to
342+
support (again)`u` as a prefix for Unicode string. It was one of the first
343+
minor version of Python 3 that saw a majority of single-source project working
344+
both on Python 2 and Python 3. These are the Project that will likely be
345+
affected by this issue.
346+
347+
The introduction of Python 3 was chaotic, there are still strong argument both
348+
in Python 2 and Python 3 camps. In the one suffering the most from this are
349+
users. Starting with the fact that inevitably some libraries will stop support
350+
for Python 2 and release Python 3 only library. And that inevitably some system
351+
will will not be upgraded to Python 3 how can we_ensure_ that users get the
352+
_least_ breakage as possible ? And what are the best practices to follow.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp