├── CNAME
├── .gitignore
├── assets
├── angr.png
├── ccxt.png
├── cmd2.png
├── kivy.png
├── mne.png
├── yt.png
├── fenics.png
├── geopy.png
├── metpy.png
├── nikola.png
├── pandas.png
├── pylast.png
├── pymc3.png
├── pystan.png
├── rdkit.png
├── skbio.png
├── spyder.png
├── sunpy.png
├── sympy.png
├── tryton.png
├── xarray.png
├── xonsh.png
├── zulip.png
├── astropy.png
├── axelrod.png
├── biobuilds.png
├── biopython.png
├── chaquopy.png
├── dateutil.png
├── fecon235.png
├── fonttools.png
├── ipython.png
├── jupyter.png
├── mitmproxy.png
├── openquake.png
├── osbrain.png
├── pymeasure.png
├── pytest1.png
├── pythran.png
├── tornado.png
├── matplotlib.png
├── psi4square.png
├── swcarpentry.png
├── tensorpack.png
├── adb_enhanced.png
├── scikit-image.png
├── scikit-learn.png
├── rpy2_logo_64x64.png
├── scipyshiny_small.png
└── toyplot-256x256.png
├── img
└── bgnoise.png
├── Gemfile
├── _includes
├── footer.md
├── analytics.html
└── css
│ ├── skeleton.css
│ ├── main.css
│ └── base.css
├── _sections
├── 60-sign.md
├── 70-discuss.md
├── 80-update-my-project.md
├── 40-timeline.md
├── 50-why.md
├── 20-statement.md
└── 30-projects.md
├── _config.yml
├── README.md
├── combo.css
├── practicalities
└── index.html
├── COPYING.md
├── index.html
├── site.js
└── _practicalities
└── intro.md
/CNAME:
--------------------------------------------------------------------------------
1 | www.python3statement.org
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | _site/
2 | .DS_Store
3 | *.swo
4 |
--------------------------------------------------------------------------------
/assets/angr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/angr.png
--------------------------------------------------------------------------------
/assets/ccxt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/ccxt.png
--------------------------------------------------------------------------------
/assets/cmd2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/cmd2.png
--------------------------------------------------------------------------------
/assets/kivy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/kivy.png
--------------------------------------------------------------------------------
/assets/mne.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/mne.png
--------------------------------------------------------------------------------
/assets/yt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/yt.png
--------------------------------------------------------------------------------
/img/bgnoise.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/img/bgnoise.png
--------------------------------------------------------------------------------
/assets/fenics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/fenics.png
--------------------------------------------------------------------------------
/assets/geopy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/geopy.png
--------------------------------------------------------------------------------
/assets/metpy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/metpy.png
--------------------------------------------------------------------------------
/assets/nikola.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/nikola.png
--------------------------------------------------------------------------------
/assets/pandas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/pandas.png
--------------------------------------------------------------------------------
/assets/pylast.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/pylast.png
--------------------------------------------------------------------------------
/assets/pymc3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/pymc3.png
--------------------------------------------------------------------------------
/assets/pystan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/pystan.png
--------------------------------------------------------------------------------
/assets/rdkit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/rdkit.png
--------------------------------------------------------------------------------
/assets/skbio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/skbio.png
--------------------------------------------------------------------------------
/assets/spyder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/spyder.png
--------------------------------------------------------------------------------
/assets/sunpy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/sunpy.png
--------------------------------------------------------------------------------
/assets/sympy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/sympy.png
--------------------------------------------------------------------------------
/assets/tryton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/tryton.png
--------------------------------------------------------------------------------
/assets/xarray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/xarray.png
--------------------------------------------------------------------------------
/assets/xonsh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/xonsh.png
--------------------------------------------------------------------------------
/assets/zulip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/zulip.png
--------------------------------------------------------------------------------
/assets/astropy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/astropy.png
--------------------------------------------------------------------------------
/assets/axelrod.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/axelrod.png
--------------------------------------------------------------------------------
/assets/biobuilds.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/biobuilds.png
--------------------------------------------------------------------------------
/assets/biopython.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/biopython.png
--------------------------------------------------------------------------------
/assets/chaquopy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/chaquopy.png
--------------------------------------------------------------------------------
/assets/dateutil.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/dateutil.png
--------------------------------------------------------------------------------
/assets/fecon235.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/fecon235.png
--------------------------------------------------------------------------------
/assets/fonttools.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/fonttools.png
--------------------------------------------------------------------------------
/assets/ipython.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/ipython.png
--------------------------------------------------------------------------------
/assets/jupyter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/jupyter.png
--------------------------------------------------------------------------------
/assets/mitmproxy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/mitmproxy.png
--------------------------------------------------------------------------------
/assets/openquake.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/openquake.png
--------------------------------------------------------------------------------
/assets/osbrain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/osbrain.png
--------------------------------------------------------------------------------
/assets/pymeasure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/pymeasure.png
--------------------------------------------------------------------------------
/assets/pytest1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/pytest1.png
--------------------------------------------------------------------------------
/assets/pythran.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/pythran.png
--------------------------------------------------------------------------------
/assets/tornado.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/tornado.png
--------------------------------------------------------------------------------
/assets/matplotlib.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/matplotlib.png
--------------------------------------------------------------------------------
/assets/psi4square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/psi4square.png
--------------------------------------------------------------------------------
/assets/swcarpentry.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/swcarpentry.png
--------------------------------------------------------------------------------
/assets/tensorpack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/tensorpack.png
--------------------------------------------------------------------------------
/assets/adb_enhanced.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/adb_enhanced.png
--------------------------------------------------------------------------------
/assets/scikit-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/scikit-image.png
--------------------------------------------------------------------------------
/assets/scikit-learn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/scikit-learn.png
--------------------------------------------------------------------------------
/assets/rpy2_logo_64x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/rpy2_logo_64x64.png
--------------------------------------------------------------------------------
/assets/scipyshiny_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/scipyshiny_small.png
--------------------------------------------------------------------------------
/assets/toyplot-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lmcinnes/python3statement.github.io/master/assets/toyplot-256x256.png
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 | gem 'github-pages'
3 | gem "jekyll"
4 | gem "jekyll-redirect-from"
5 | gem "jekyll-paginate"
6 | gem "jekyll-sitemap"
7 | gem "jekyll-feed"
8 |
--------------------------------------------------------------------------------
/_includes/footer.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | Design by Tim O'Brien [t413.com](http://t413.com/)
4 | —
5 | [SinglePaged theme](https://github.com/t413/SinglePaged)
6 | —
7 | this site is [open source]({{ site.source_link }})
8 |
9 |
--------------------------------------------------------------------------------
/_sections/60-sign.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: sign
3 | fa-icon: pencil
4 | bg: '#4da45e'
5 | color: 'white'
6 | style: center
7 | ---
8 |
9 | # Sign the statement
10 |
11 | Do you want to sign the statement for your project?
12 | Open an [issue](https://github.com/python3statement/python3statement.github.io/issues) with your project information,
13 | or directly submit a [pull-request](https://github.com/python3statement/python3statement.github.io/pulls).
14 |
--------------------------------------------------------------------------------
/_sections/70-discuss.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: discuss
3 | fa-icon: comment
4 | bg: '#a066f3'
5 | color: 'white'
6 | style: center
7 | ---
8 |
9 | # Discuss
10 |
11 | While the above statement is close to final form, it is still open for
12 | discussion. Feel free to [open an
13 | issue](https://github.com/python3statement/python3statement.github.io/issues)
14 | on our GitHub repository or browse the open and closed ones.
15 |
16 | If you think some information is missing or inaccurate, please let us know as
17 | well.
18 |
--------------------------------------------------------------------------------
/_includes/analytics.html:
--------------------------------------------------------------------------------
1 | {% if site.google_analytics_key %}
2 |
15 | {% endif %}
--------------------------------------------------------------------------------
/_sections/80-update-my-project.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Practicalities
3 | fa-icon: arrow-circle-up
4 | bg: '#49a7e9'
5 | color: 'white'
6 | style: center
7 | ---
8 |
9 | # Practicalities
10 |
11 | While most of the projects that have signed up above are migrating to Python 3
12 | only code bases, we are gathering information about the difficulties that can be
13 | encountered both by developers and users during this process.
14 |
15 | We are thus collecting a list of things to be aware of for when transitioning that
16 | are less obvious. For example : as a developer, how to make sure that
17 | your package manager like pip does not upgrade your libraries to incompatible
18 | versions on Python 2. See the [Practicality Page](/practicalities/) for
19 | information and check [our
20 | repository](https://github.com/python3statement/python3statement.github.io) to
21 | contribute.
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/_sections/40-timeline.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: timeline
3 | bg: 'white'
4 | fa-icon: calendar
5 | style: center
6 | ---
7 |
8 | # Projects Timeline
9 |
10 | In the following chart, you can see many projects that have decided to stop
11 | supporting Python 2 before 2020. The chart is a guideline to show what
12 | versions of each project support Python 2, or not, their release timelines, and
13 | extended support. (Python's own timeline is available
14 | [here](https://docs.python.org/devguide/#status-of-python-branches)).
15 |
16 |
17 |
18 |
19 |
Compatible with Python 2 and Python 3.
20 |
Compatible with Python 3 only.
21 |
22 | See how to [add your project to the list of participating projects](https://github.com/python3statement/python3statement.github.io#add-your-project) and to [this timeline](https://github.com/python3statement/python3statement.github.io#add-timeline-information)
23 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | port: 4000
4 | host: 0.0.0.0
5 | safe: false
6 |
7 |
8 | ### site serving configuration ###
9 | exclude: [CNAME, README.md, .gitignore]
10 | permalink: /:title ## disables post output
11 | timezone: null
12 | lsi: false
13 | markdown: kramdown
14 |
15 |
16 | ### content configuration ###
17 | title: "Sunsetting Python 2 support"
18 | keywords: "Python 3, support, Jupyter, IPython, matplotlib, Python 2, Legacy Python"
19 | description: "A pledge to drop Python 2 support by 2020."
20 | source_link: "https://github.com/python3statement/python3statement.github.io"
21 | favicon: #put a path like: "img/favicon.ico"
22 | touch_icon: #put a path like: "img/apple-touch-icon.png"
23 | google_analytics_key: ## put YOUR key here to enable tracking! (blank to disable)
24 |
25 |
26 | ### template colors, used site-wide via css ###
27 | colors:
28 | black: '#111111'
29 | white: '#f8f8f8'
30 | blue: '#49a7e9'
31 | green: '#9bcf2f'
32 | purple: '#c869bf'
33 | orange: '#fab125'
34 | turquoise: '#0fbfcf'
35 |
36 | collections:
37 | - sections
38 | - practicalities
39 |
40 |
--------------------------------------------------------------------------------
/_sections/50-why.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: why
3 | color: 'white'
4 | bg: '#49a7e9 '
5 | fa-icon: 'question'
6 | style: center
7 | ---
8 |
9 | # Why switch to Python 3?
10 |
11 | Here are some resources on why Python 3 was created, and how and why to update
12 | code to use Python 3:
13 |
14 | - [Why Python 3 exists](https://snarky.ca/why-python-3-exists/) (Brett Cannon)
15 | - [How to add Python 3 support to your code](https://docs.python.org/3/howto/pyporting.html)
16 | - [Python FAQ: Why should I use Python 3?](https://eev.ee/blog/2016/07/31/python-faq-why-should-i-use-python-3/) (lexy munroe)
17 | - [Python FAQ: How do I port to Python 3?](https://eev.ee/blog/2016/07/31/python-faq-how-do-i-port-to-python-3/) (lexy munroe)
18 | - [Stop supporting Python 2.6 for free](https://www.curiousefficiency.org/posts/2015/04/stop-supporting-python26.html) (Nick Coghlan)
19 | - [Why Python 4.0 won't be like Python 3.0](https://www.curiousefficiency.org/posts/2014/08/python-4000.html) (Nick Coghlan)
20 | - [Python 3 for scientists](https://python-3-for-scientists.readthedocs.io/en/latest/)
21 | - [scikit-bio py3-only RFC](https://github.com/biocore/scikit-bio-rfcs/blob/master/accepted/002-py3-only.md)
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # A pledge to migrate to Python 3.
2 |
3 | This is the main website for a pledge to stop supporting Python 2 for free in
4 | open source software.
5 |
6 | # Run locally
7 |
8 | Install Jekyll : `gem install jekyll`, `gem install github-pages`
9 |
10 | Clone this locally, `cd` in the newly created directory.
11 |
12 | Run `jekyll serve -w` in one terminal, open your browser to `localhost:4000`.
13 |
14 | Modify the various files, refresh your browser and enjoy.
15 |
16 | PRs welcomed.
17 |
18 | # Add your project
19 |
20 | If you just want to add your project to the list of participating projects, add
21 | a line in [the list of participating projects](_sections/30-projects.md). It's
22 | markdown so feel free to just list your project name or add a link, and make a
23 | pull request. You should even be able to [edit it
24 | online](https://github.com/python3statement/python3statement.github.io/edit/master/_sections/30-projects.md).
25 |
26 | ## Add timeline information
27 |
28 | The front page also has a timeline chart, with past release dates and future
29 | (planned) releases. You can also add your project there, if you have a specific
30 | date where you plan to drop Python 2 support.
31 |
32 | See [site.js](site.js) around [line
33 | 100](https://github.com/python3statement/python3statement.github.io/blob/master/site.js#L103)
34 | to see how to add this kind of data.
35 |
36 | # Base template
37 |
38 | This site is based on
39 | [github.com/t413/SinglePaged](https://github.com/t413/SinglePaged).
40 |
--------------------------------------------------------------------------------
/combo.css:
--------------------------------------------------------------------------------
1 | ---
2 | ---
3 | {% include css/base.css %}
4 | {% include css/skeleton.css %}
5 | {% include css/main.css %}
6 |
7 | div.vis-item , p.py3{
8 | background-color:#03acf6;
9 | color: white;
10 | }
11 |
12 |
13 | div.vis-item.py2, p.py2 {
14 | background-color: #3dbf18;
15 | border-color: #3dbf18;
16 | color:white;
17 |
18 | }
19 |
20 | p {
21 | font-weight: 300;
22 | }
23 |
24 | p.py2:first-child, p.py3:first-child{
25 | margin-top: 0px;
26 | margin-bottom: 5px;
27 |
28 | }
29 |
30 | div.vis-item.vis-selected {
31 | background-color: #e8aa2c;
32 | border-color: #bf8a1e;
33 | }
34 |
35 | /* create a custom sized dot at the bottom of the red item */
36 | .vis-item.red {
37 | background-color: red;
38 | border-color: darkred;
39 | color: white;
40 | font-family: monospace;
41 | box-shadow: 0 0 10px gray;
42 | }
43 |
44 | .center ul {
45 | list-style: none;
46 | }
47 |
48 | .vis-timeline {
49 | text-align: left;
50 | }
51 |
52 | /* hardcode the calendar which is on a clear background to a darker gray that matches the font color.*/
53 | .fa-calendar {
54 | color: #868686;
55 | }
56 |
57 | .subtlecircle .fa-stack-1x{
58 | font-size: 80%;
59 | }
60 |
61 | #sections30-projects ul:nth-child(2) a {
62 | text-decoration: none;
63 | }
64 |
65 |
66 | #sections30-projects li {
67 | display: inline-block;
68 | margin: 10px;
69 | padding: 20px;
70 | font-size: 19px;
71 | }
72 |
73 |
74 | #sections30-projects li a > img{
75 | margin: auto;
76 | margin-bottom:10px;
77 | display: block;
78 | max-height: 80px;
79 | max-width: 160px;
80 | vertical-align: middle;
81 | }
82 |
--------------------------------------------------------------------------------
/practicalities/index.html:
--------------------------------------------------------------------------------
1 | ---
2 | ---
3 |
4 |
5 |
6 |
7 |
8 | {{ site.title }}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {% if site.favicon %} {% endif %}
17 | {% if site.touch_icon %} {% endif %}
18 |
19 |
20 |
21 |
22 |
23 | {% for node in site.sections %}
24 | {% capture id %}{{ node.id | remove:'/' | downcase }}{% endcapture %}
25 | {{node.title}}
26 | {% endfor %}
27 |
28 |
29 |
30 | {% for page in site.practicalities %}
31 | {% capture id %}{{ page.id | remove:'/' | downcase }}{% endcapture %}
32 |
33 |
34 |
35 | {{ page.content }}
36 |
37 |
38 | {% endfor %}
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/COPYING.md:
--------------------------------------------------------------------------------
1 | The logos of projects which have endorsed the statement are used with the
2 | permission of the projects they represent. They are not covered by any of the
3 | licenses granted by this project.
4 |
5 | The project uses the [SinglePaged template](https://github.com/t413/SinglePaged),
6 | which is under the MIT license:
7 |
8 | Copyright (c) 2014 Tim O'Brien (t413)
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining a copy
11 | of this software and associated documentation files (the "Software"), to deal
12 | in the Software without restriction, including without limitation the rights
13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | copies of the Software, and to permit persons to whom the Software is
15 | furnished to do so, subject to the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included in all
18 | copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 | SOFTWARE.
27 |
28 | Any example computer code created for this project is published under a
29 | [CC0 license](https://creativecommons.org/publicdomain/zero/1.0/), meaning it
30 | can be used with no conditions.
31 |
32 | Content not mentioned above (principally the text of the website), is published
33 | under the [CC-BY license](https://creativecommons.org/licenses/by/4.0/).
34 |
--------------------------------------------------------------------------------
/_sections/20-statement.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: statement
3 | bg: '#4da45e'
4 | color: white
5 | ---
6 |
7 | # Moving to require Python 3
8 |
9 | Almost all major open source Python packages now support
10 | both Python 3.x and Python 2.7, and many projects have been supporting these
11 | two versions of the language for several years. While we have developed tools
12 | and techniques to maintain compatibility efficiently, it is a small but
13 | constant friction in the development of a lot of code.
14 |
15 | We are keen to use Python 3 to its full potential, and we currently accept the
16 | cost of writing cross-compatible code to allow a smooth transition, but we
17 | don’t intend to maintain this compatibility indefinitely. Although the
18 | transition has not been as quick as we hoped, we do see it taking place, with
19 | more and more people using, teaching and recommending Python 3.
20 |
21 | The developers of the Python language extended support of Python 2.7 from 2015
22 | to January 1, 2020, recognising that many people were still using Python 2. We believe
23 | that the extra 5 years is sufficient to transition off of Python 2, and our
24 | projects plan to stop supporting Python 2 when upstream support ends in 2020,
25 | if not before. We will then be able to simplify our code and take advantage of
26 | the many new features in the current version of the Python language and
27 | standard library.
28 |
29 | In addition, significantly before 2020, many of our projects will step down
30 | Python 2.7 support to only fixing bugs, and require Python 3 for all new
31 | feature releases. Some projects have already made this transition.
32 | This too parallels support for the language itself, as Python
33 | 2.7 releases only include bugfixes and security improvements.
34 |
35 | Third parties may offer paid support for our projects on old Python versions
36 | for longer than we support them ourselves. We won’t obstruct this, and it is a
37 | core principle of free and open source software that this is possible. However,
38 | if you enjoy the free, first party support for many projects including the Scientific
39 | Python stack, please start planning to move to Python 3.
40 |
41 | For all of these reasons, the following projects have pledged to **drop support
42 | for Python 2.7 no later than 2020**, coinciding with the Python development
43 | team's [timeline for dropping support for Python
44 | 2.7](https://www.python.org/dev/peps/pep-0373/#update).
45 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 | ---
2 | ---
3 |
4 |
5 |
6 |
7 |
8 | {{ site.title }}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {% if site.favicon %} {% endif %}
17 | {% if site.touch_icon %} {% endif %}
18 |
19 |
20 |
21 |
22 |
23 | {% for node in site.sections %}
24 | {% capture id %}{{ node.id | remove:'/' | downcase }}{% endcapture %}
25 | {{node.title}}
26 | {% endfor %}
27 |
28 |
29 |
30 | {% for page in site.sections %}
31 | {% capture id %}{{ page.id | remove:'/' | downcase }}{% endcapture %}
32 |
33 | {% if page.icon %}
34 |
35 |
36 |
{{ page.title }}
37 |
38 | {% elsif page.fa-icon %}
39 |
40 |
41 |
42 |
43 |
44 |
{{ page.title }}
45 |
46 | {% endif %}
47 |
48 | {{ page.content }}
49 |
50 |
51 | {% endfor %}
52 |
53 |
54 |
60 |
61 |
62 | {% include analytics.html %}
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/_includes/css/skeleton.css:
--------------------------------------------------------------------------------
1 |
2 | /* -----------------------------------*/
3 | /* ----- 960px wide fancy grid! ----- */
4 | /* -----------------------------------*/
5 |
6 | /* by tim o'brien, t413.com
7 | * based on getskeleton.com
8 | */
9 |
10 |
11 | /* ----- base grid----- */
12 |
13 | .container { position: relative; width: 960px; margin: 0 auto; padding: 0; }
14 | .container .column { float: left; display: inline; margin-left: 10px; margin-right: 10px; }
15 | .row { margin-bottom: 20px; }
16 |
17 | .container .small.column { width: 300px; }
18 | .container .half.column { width: 460px; }
19 | .container .big.column { width: 620px; }
20 | .container .full.column { width: 940px; }
21 |
22 |
23 | /* ----- Tablet (Portrait) -- 768px ----- */
24 | @media only screen and (min-width: 768px) and (max-width: 959px) {
25 | .container { width: 768px; }
26 |
27 | .container .small.column { width: 236px; }
28 | .container .half.column { width: 364px; }
29 | .container .big.column { width: 488px; }
30 | .container .full.column { width: 748px; }
31 | }
32 |
33 |
34 | /* ----- Mobile (Portrait) ----- */
35 | @media only screen and (max-width: 767px) {
36 | .container { width: 96%; }
37 | .container .column { margin: 1%; }
38 |
39 | .container .small.column { width: 48%; }
40 | .container .half.column { width: 48%; }
41 | .container .big.column { width: 98%; }
42 | .container .full.column { width: 98%; }
43 | }
44 |
45 |
46 | /* ----- Mobile (Landscape) -- 480px ----- */
47 | @media only screen and (min-width: 480px) and (max-width: 767px) {
48 | .container { width: 92%; }
49 | .container .column { margin: 2%; }
50 |
51 | .container .small.column { width: 46%; }
52 | .container .half.column { width: 46%; }
53 | .container .big.column { width: 96%; }
54 | .container .full.column { width: 96%; }
55 | }
56 |
57 |
58 |
59 | /* ----- Clearing ----- */
60 |
61 | /* Self Clearing Goodness */
62 | .container:after { content: "\0020"; display: block; height: 0; clear: both; visibility: hidden; }
63 |
64 | /* Use clearfix class on parent to clear nested columns,
65 | or wrap each row of columns in a */
66 | .clearfix:before,
67 | .clearfix:after,
68 | .row:before,
69 | .row:after {
70 | content: '\0020';
71 | display: block;
72 | overflow: hidden;
73 | visibility: hidden;
74 | width: 0;
75 | height: 0; }
76 | .row:after,
77 | .clearfix:after {
78 | clear: both; }
79 | .row,
80 | .clearfix {
81 | zoom: 1; }
82 |
83 | /* You can also use a to clear columns */
84 | .clear {
85 | clear: both;
86 | display: block;
87 | overflow: hidden;
88 | visibility: hidden;
89 | width: 0;
90 | height: 0;
91 | }
92 |
--------------------------------------------------------------------------------
/_sections/30-projects.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Projects
3 | bg: '#7ec4ea'
4 | fa-icon: group
5 | color: black
6 | style: center
7 | ---
8 |
9 | # Participating Projects
10 |
11 | These projects pledge to drop Python 2 support in or before 2020.
12 |
13 | - [pandas](https://pandas.pydata.org/)
14 | - [scikit-learn](https://scikit-learn.org/)
15 | - [Tornado](http://www.tornadoweb.org/)
16 | - [IPython](https://ipython.org)
17 | - [mitmproxy](https://mitmproxy.org/)
18 | - [Kivy](https://kivy.org/)
19 | - [Matplotlib](https://matplotlib.org/)
20 | - [NumPy](https://www.numpy.org/)
21 | - [SciPy](https://www.scipy.org/)
22 | - [ccxt](https://github.com/ccxt/ccxt)
23 | - [Zulip](https://zulip.org)
24 | - [SymPy](https://www.sympy.org/)
25 | - [Jupyter notebook](https://jupyter.org)
26 | - [Spyder](https://www.spyder-ide.org)
27 | - [Scikit Image](http://scikit-image.org/)
28 | - [PyMC3](https://github.com/pymc-devs/pymc3)
29 | - [Tensorpack](https://github.com/tensorpack/tensorpack)
30 | - [pytest](https://docs.pytest.org/en/latest)
31 | - [xonsh](http://xon.sh)
32 | - [Astropy](https://www.astropy.org/)
33 | - [geopy](https://geopy.readthedocs.io/)
34 | - [Biopython](https://biopython.org/)
35 | - [Nikola](https://getnikola.com)
36 | - [FontTools](https://github.com/fonttools/fonttools)
37 | - [Pythran](https://github.com/serge-sans-paille/pythran)
38 | - [xarray](https://xarray.pydata.org/)
39 | - [dateutil](https://github.com/dateutil/dateutil)
40 | - [CherryPy](https://cherrypy.org/)
41 | - [Tryton](https://www.tryton.org/)
42 | - [PyStan](https://github.com/stan-dev/pystan)
43 | - [MNE](https://www.martinos.org/mne/stable/index.html)
44 | - [Software Carpentry](https://software-carpentry.org)
45 | - [ADB-Enhanced](https://github.com/ashishb/adb-enhanced)
46 | - [scikit-bio](http://scikit-bio.org)
47 | - [fecon235](https://github.com/rsvp/fecon235)
48 | - [SunPy](https://sunpy.org/)
49 | - [Axelrod](https://github.com/Axelrod-Python/Axelrod)
50 | - [rpy2](https://rpy2.bitbucket.io)
51 | - [FEniCS](https://fenicsproject.org/)
52 | - [RDKit](https://github.com/rdkit/rdkit)
53 | - [Toyplot](https://github.com/sandialabs/toyplot)
54 | - [MetPy](https://unidata.github.io/MetPy)
55 | - [pyLast](https://github.com/pylast/pylast)
56 | - [Psi4](http://psicode.org/)
57 | - [OpenQuake engine](https://github.com/gem/oq-engine)
58 | - [yt](https://yt-project.org/)
59 | - [cmd2](https://github.com/python-cmd2/cmd2)
60 | - [osBrain](https://github.com/opensistemas-hub/osbrain)
61 | - [PyMeasure](https://github.com/ralph-group/pymeasure)
62 | - [Chaquopy](https://chaquo.com/chaquopy/)
63 | - [angr](http://angr.io/)
64 | - [BioBuilds](https://www.biobuilds.org/)
65 |
66 |
69 |
70 |
71 |
72 | - [Hypothesis](https://github.com/HypothesisWorks/hypothesis)
73 | - [better-exceptions](https://github.com/qix-/better-exceptions)
74 | - [python-chess](https://github.com/niklasf/python-chess)
75 | - [Altair](https://github.com/ellisonbg/altair)
76 | - [music21](http://web.mit.edu/music21/)
77 | - [imageio](https://imageio.github.io)
78 | - [An Introduction to Applied Bioinformatics](http://readiab.org)
79 | - [pvlib-python](https://github.com/pvlib/pvlib-python)
80 | - [QIIME](http://qiime.org)
81 | - [PySCIPOpt](https://github.com/SCIP-Interfaces/PySCIPOpt)
82 | - [SPADE](https://github.com/javipalanca/spade)
83 | - [gala](https://gala.readthedocs.io)
84 | - [CIS](https://github.com/cedadev/cis)
85 | - [cual-id](https://github.com/johnchase/cual-id)
86 | - [stomp.py](https://github.com/jasonrbriggs/stomp.py)
87 | - [tinytext](https://github.com/hugovk/tinytext)
88 | - [OSMViz](https://github.com/hugovk/osmviz)
89 | - [fino](https://github.com/hugovk/fino)
90 | - [MambuPy](https://github.com/jstitch/MambuPy)
91 | - [Pyramid](https://trypyramid.com)
92 |
93 |
96 |
--------------------------------------------------------------------------------
/_includes/css/main.css:
--------------------------------------------------------------------------------
1 | html { box-sizing: border-box; }
2 | *, *:before, *:after { box-sizing: inherit; }
3 |
4 | /* ---------------------------*/
5 | /* ----- Special Styles ----- */
6 | /* ---------------------------*/
7 |
8 | /* ----- colors (autogenerated from _config.yml)----- */
9 |
10 | {% for c in site.colors %}
11 | .border-{{c[0]}} { border-color: {{ c[1] }} !important; }
12 | .text-{{c[0]}} { color: {{ c[1] }}; }
13 | .text-{{c[0]}} a { color: {{ c[1] }}; }
14 | .bg-{{c[0]}} { background-color: {{ c[1] }} !important; }
15 | {% endfor %}
16 |
17 | /* ----- per-post colors! ----- */
18 | {% for node in site.sections %}
19 | {% capture id %}{{ node.id | remove:'/' | downcase }}{% endcapture %}
20 | {% capture bg %}{% if site.colors[node.bg] %}{{ site.colors[node.bg] }}{% else %}{{ node.bg }}{% endif %}{% endcapture %}
21 | {% capture fg %}{% if site.colors[node.color] %}{{ site.colors[node.color] }}{% else %}{{ node.color }}{% endif %}{% endcapture %}
22 | nav .p-{{id}} { border-color: {{ bg }}; }
23 | #{{id}} { background-color: {{ bg }} !important; color: {{ fg }}; }
24 | #{{id}} a { color: {{ fg }}; }
25 | #{{id}} .sectiondivider { color: {{ bg }}; }
26 | {% endfor %}
27 |
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 |
38 |
39 | /* ----- code, syntax highlighting, etc ----- */
40 |
41 | code, pre { font-family: Monaco, Menlo, Consolas, "Courier New", monospace; }
42 |
43 | /* spesifically inline code */
44 | code, pre {
45 | background: rgba(255,255,255,0.2);
46 | display: inline;
47 | word-wrap: break-word;
48 | }
49 |
50 | /* block code */
51 | pre code { background: none; display: block; }
52 | pre {
53 | display: block;
54 | margin: 20px 5%;
55 | padding: 4px 8px;
56 | background: rgba(255,255,255,0.1);
57 | word-wrap: break-word;
58 | }
59 |
60 | .highlight { margin:20px 5%; }
61 |
62 |
63 | /* ----- base elements ----- */
64 |
65 | img {
66 | max-width:100%;
67 | height:auto;
68 | vertical-align:middle;
69 | }
70 |
71 | hr {
72 | margin:60px auto;
73 | width:50%;
74 | border-color: {{ site.colors.black }};
75 | }
76 |
77 | .container { word-wrap: break-word; }
78 | .center { text-align: center; }
79 | .left, .container .left { text-align: left; }
80 |
81 | .container h1, .container h2, .container h3, .container h4 {
82 | margin-bottom: 20px;
83 | text-align: center;
84 | padding: 0 4%;
85 | }
86 | .container p, .container ol, .container ul {
87 | font-size: 17px;
88 | padding: 0 5%;
89 | }
90 | .container ol, .container ul { padding: 0 8%; }
91 | .container p:first-of-type {
92 | margin-top: 40px;
93 | }
94 |
95 | /* keep embedded videos fluid! */
96 | .icontain {
97 | position: relative;
98 | height: 0;
99 | overflow: hidden;
100 | padding-bottom: 56.25%; /* keep 16x9 Aspect Ratio */
101 | }
102 | .i4x3 { padding-bottom: 75.00%; } /* keep 4x3 Aspect Ratio */
103 | .icontain iframe {
104 | position: absolute;
105 | top:0;
106 | left: 0;
107 | width: 100%;
108 | height: 100%;
109 | }
110 |
111 | .inlineblock {
112 | display:-moz-inline-stack;
113 | display:inline-block;
114 | zoom:1;
115 | *display:inline;
116 | }
117 |
118 | /* ---------------------------*/
119 | /* ----- Main Structure ----- */
120 | /* ---------------------------*/
121 |
122 | /* ----- top menu ----- */
123 |
124 | {% assign navborder = 3 %}
125 | {% assign navborder_active = 6 %}
126 |
127 | nav {
128 | font-size:15px;
129 | width:100%;
130 | position:fixed;
131 | z-index:100;
132 | top:0;
133 | left:0;
134 | background:#2e2e2e;
135 | }
136 |
137 | nav ul {
138 | list-style:none;
139 | text-align:center;
140 | padding:0;
141 | margin:0;
142 | letter-spacing:-4px;
143 | }
144 |
145 | nav ul li {
146 | display:inline-block;
147 | border-top:{{navborder}}px solid;
148 | padding: {{navborder}}px 0;
149 | *display:inline;
150 | zoom:1;
151 | line-height:normal;
152 | letter-spacing:normal;
153 | text-transform:uppercase;
154 | min-width:110px;
155 | line-height:60px;
156 | margin:0;
157 | }
158 |
159 | nav ul li a, nav ul li a:visited {
160 | display:block;
161 | color:#fff;
162 | text-decoration:none;
163 | font-weight:600;
164 | opacity:.75;
165 | }
166 |
167 | nav ul li a:hover {
168 | opacity:1
169 | }
170 | nav ul li:hover, nav ul li.active {
171 | border-top-width: {{navborder_active}}px;
172 | padding-top: 0;
173 | }
174 |
175 |
176 | /* ----- sections/articles ----- */
177 |
178 | .section {
179 | position:relative;
180 | display:block;
181 | width:100%;
182 | min-height:300px;
183 | padding:210px 0;
184 | background:url(img/bgnoise.png);
185 | /* generated noise from noisetexturegenerator.com */
186 | }
187 |
188 | .section:first-of-type {
189 | padding-top: 140px;
190 | }
191 |
192 |
193 | #footer {
194 | padding: 8px 0;
195 | min-height:0;
196 | text-align:center;
197 | background-color:#2e2e2e;
198 | background-image:none;
199 | }
200 | #footer .container p { font-size:13px; margin:0; }
201 |
202 | .subtlecircle {
203 | text-align:center;
204 | z-index:3;
205 | border-radius:50%;
206 | -moz-border-radius:50%;
207 | -webkit-border-radius:50%;
208 | box-shadow: 0px 1px 15px rgba(0,0,0,0.05);
209 | background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAF0lEQVQIHWP8//+/MQMaYELjg7kUCgIASm8DOqGzfp8AAAAASUVORK5CYII=);
210 | }
211 |
212 | .sectiondivider {
213 | width:270px;
214 | height:270px;
215 | padding:15px;
216 | position:absolute;
217 | top:-135px;
218 | left:50%;
219 | margin-left:-135px;
220 | }
221 |
222 | .sectiondivider img {
223 | width:200px;
224 | height:240px;
225 | position: static;
226 | margin-top: -20px;
227 | }
228 |
229 | .sectiondivider .fa-stack {
230 | font-size: 130px;
231 | position: static;
232 | margin-top: -8px;
233 | }
234 | .sectiondivider .fa-circle { color: #fff; }
235 |
236 | .sectiondivider h5 {
237 | font-size:15px;
238 | font-weight:700;
239 | text-transform:uppercase;
240 | position:absolute;
241 | bottom:50px;
242 | left:auto;
243 | text-align:center;
244 | display:block;
245 | z-index:6;
246 | width:240px;
247 | }
248 |
249 | .sectiondivider.imaged {
250 | text-shadow: 1px 1px 3px #333;
251 | }
252 |
253 |
254 | .columned {
255 | -webkit-column-count: 3;
256 | -moz-column-count: 3;
257 | column-count: 3;
258 |
259 | -webkit-column-gap: 40px;
260 | -moz-column-gap: 40px;
261 | column-gap: 40px;
262 |
263 | -webkit-column-rule: 1px outset rgba(255,255,255,0.5);
264 | -moz-column-rule: 1px outset rgba(255,255,255,0.5);
265 | column-rule: 1px outset rgba(255,255,255,0.5);
266 | }
267 | .longlist { font-size: 14px !important; }
268 | .longlist li { margin-bottom: 3px; }
269 |
270 |
271 |
272 | /* ----- fork on github banner ----- */
273 | #forkongithub a {
274 | color:#fff;
275 | text-decoration:none;
276 | font-family:arial,sans-serif;
277 | text-align:center;
278 | font-weight:700;
279 | font-size:1rem;
280 | line-height:2rem;
281 | position:relative;
282 | transition:.5s;
283 | padding:5px 40px;
284 | }
285 | #forkongithub a::before, #forkongithub a::after {
286 | content:""; width:100%; display:block; position:absolute;
287 | top:1px; left:0; height:1px; background:#fff;
288 | }
289 | #forkongithub a::after { bottom:1px; top:auto; }
290 | @media screen and (min-width:800px) {
291 | #forkongithub {
292 | position:fixed;
293 | display:block;
294 | top:0;
295 | right:0;
296 | width:200px;
297 | overflow:hidden;
298 | height:200px;
299 | z-index:9999;
300 | }
301 | #forkongithub a {
302 | width:200px;
303 | position:absolute;
304 | top:60px;
305 | right:-60px;
306 | transform:rotate(45deg);
307 | -webkit-transform:rotate(45deg);
308 | -ms-transform:rotate(45deg);
309 | -moz-transform:rotate(45deg);
310 | -o-transform:rotate(45deg);
311 | box-shadow:4px 4px 10px rgba(0,0,0,0.8);
312 | box-sizing: content-box;
313 | }
314 | }
315 |
316 |
317 |
318 | /* mid size (tablets, landscapes) */
319 | @media only screen and (max-width: 679px) {
320 | nav { font-size:11px; }
321 | nav ul li {
322 | min-width:60px;
323 | line-height:40px;
324 | }
325 | }
326 |
327 | /* tiny size (phones) */
328 | @media only screen and (max-width: 380px) {
329 | nav ul li { min-width:90px; line-height:20px; }
330 | }
331 |
332 | /* anything not desktop */
333 | @media only screen and (max-width: 767px) {
334 | .container h1 { font-size: 30px; }
335 | .container h2 { font-size: 24px; }
336 | .container h3 { font-size: 20px; }
337 | .container h4 { font-size: 18px; }
338 |
339 |
340 | .section { padding:130px 0; }
341 | .sectiondivider {
342 | width:200px;
343 | height:200px;
344 | padding:15px;
345 | top:-100px;
346 | margin-left:-100px;
347 | }
348 | .sectiondivider img {
349 | width:150px;
350 | height:180px;
351 | }
352 | .sectiondivider .fa-stack {
353 | font-size: 100px;
354 | margin-top: -14px;
355 | }
356 | .sectiondivider h5 {
357 | font-size:15px;
358 | bottom:30px;
359 | width:170px
360 | }
361 |
362 | .columned {
363 | -webkit-column-count: 2;
364 | -moz-column-count: 2;
365 | column-count: 2;
366 | }
367 | }
368 |
--------------------------------------------------------------------------------
/site.js:
--------------------------------------------------------------------------------
1 |
2 | $.extend($.easing,
3 | {
4 | def: 'easeOutQuad',
5 | easeInOutExpo: function (x, t, b, c, d) {
6 | if (t==0) return b;
7 | if (t==d) return b+c;
8 | if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
9 | return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
10 | }
11 | });
12 |
13 | (function( $ ) {
14 |
15 | var settings;
16 | var disableScrollFn = false;
17 | var navItems;
18 | var navs = {}, sections = {};
19 |
20 | $.fn.navScroller = function(options) {
21 | settings = $.extend({
22 | scrollToOffset: 170,
23 | scrollSpeed: 800,
24 | activateParentNode: true,
25 | }, options );
26 | navItems = this;
27 |
28 | //attatch click listeners
29 | navItems.on('click', function(event){
30 | event.preventDefault();
31 | var navID = $(this).attr("href").substring(1);
32 | disableScrollFn = true;
33 | activateNav(navID);
34 | populateDestinations(); //recalculate these!
35 | $('html,body').animate({scrollTop: sections[navID] - settings.scrollToOffset},
36 | settings.scrollSpeed, "easeInOutExpo", function(){
37 | disableScrollFn = false;
38 | }
39 | );
40 | });
41 |
42 | //populate lookup of clicable elements and destination sections
43 | populateDestinations(); //should also be run on browser resize, btw
44 |
45 | // setup scroll listener
46 | $(document).scroll(function(){
47 | if (disableScrollFn) { return; }
48 | var page_height = $(window).height();
49 | var pos = $(this).scrollTop();
50 | for (i in sections) {
51 | if ((pos + settings.scrollToOffset >= sections[i]) && sections[i] < pos + page_height){
52 | activateNav(i);
53 | }
54 | }
55 | });
56 | };
57 |
58 | function populateDestinations() {
59 | navItems.each(function(){
60 | var scrollID = $(this).attr('href').substring(1);
61 | navs[scrollID] = (settings.activateParentNode)? this.parentNode : this;
62 | sections[scrollID] = $(document.getElementById(scrollID)).offset().top;
63 | });
64 | }
65 |
66 | function activateNav(navID) {
67 | for (nav in navs) { $(navs[nav]).removeClass('active'); }
68 | $(navs[navID]).addClass('active');
69 | }
70 | })( jQuery );
71 |
72 |
73 | $(document).ready(function (){
74 |
75 | $('nav li a').navScroller();
76 |
77 | //section divider icon click gently scrolls to reveal the section
78 | $(".sectiondivider").on('click', function(event) {
79 | $('html,body').animate({scrollTop: $(event.target.parentNode).offset().top - 50}, 400, "linear");
80 | });
81 |
82 | //links going to other sections nicely scroll
83 | $(".container a").each(function(){
84 | if ($(this).attr("href").charAt(0) == '#'){
85 | $(this).on('click', function(event) {
86 | event.preventDefault();
87 | var target = $(event.target).closest("a");
88 | var targetHight = $(target.attr("href")).offset().top
89 | $('html,body').animate({scrollTop: targetHight - 170}, 800, "easeInOutExpo");
90 | });
91 | }
92 | });
93 |
94 | // DOM element where the Timeline will be attached
95 | var container = document.getElementById('visualization');
96 |
97 | // add your project here with the following format
98 | //
99 | // ' : [
100 | // { content:'', start: , end: , py2:},
101 | // ...
102 | // ]
103 | var data = {
104 | 'CPython':[
105 | {content:'Python 2.7', start: '2010-07-03', end: '2020-01-01', py2:true},
106 | {content:'Python 3.3', start: '2012-09-29', end: '2017-09-29'},
107 | // EOL for Python 3.4 - 3.7 not announced yet; project 5 years from initial release to follow CPython policy.
108 | {content:'Python 3.4', start: '2014-03-16', end: '2019-03-16'},
109 | {content:'Python 3.5', start: '2015-09-13', end: '2020-09-13'},
110 | {content:'Python 3.6', start: '2016-12-23', end: '2021-12-23'},
111 | {content:'Python 3.7', start: '2018-06-15', end: '2023-06-01'},
112 | ],
113 | 'IPython':[
114 | {content: '1.x', start: '2013-08-08', end:'2014-03-31', py2:true},
115 | {content: '2.x', start: '2014-04-01', end:'2015-02-26', py2:true},
116 | {content: '3.x', start: '2015-02-27', end:'2015-08-10', py2:true},
117 | {content: '4.x', start: '2015-08-11', end:'2016-07-07', py2:true},
118 | {content: 'IPython 5.x LTS', start: '2016-07-08', end:'2019-06-01', py2:true},
119 | {content: '6.x', start: '2017-04-19', end:'2018-09-27'},
120 | {content: '7.x', start: '2018-09-27', end:'2019-12-12'},
121 | {content: '8.x', start: '2019-12-12', end:'2020-12-01'},
122 | ],
123 | 'pandas':[
124 | {content: 'Python 2 & 3', start: '2011-10-10', end:'2018-12-31', py2:true},
125 | {content: 'Python 3 only', start: '2019-01-01', end:'2021-12-16'},
126 | ],
127 | 'scikit-learn':[
128 | {content: 'Python 2 & 3', start: '2010-03-25', end:'2019-03-18', py2:true},
129 | {content: 'Python 3 only', start: '2019-03-19', end:'2023-12-31'},
130 | ],
131 | 'ccxt':[
132 | {content: 'Python 2 & 3', start: '2017-05-14', end:'2019-12-31', py2:true},
133 | {content: 'Python 3 only', start: '2020-01-01', end:'2023-12-31'},
134 | ],
135 | 'Numpy':[
136 | {content: 'Py 2 & 3 full', start: '2010-08-31', end:'2018-12-31', py2:true},
137 | {content: 'Py 2 bug fix', start: '2019-01-01', end:'2019-12-31', py2:true},
138 | {content: 'Py 3 full', start: '2019-01-01', end:'2021-12-16'},
139 | ],
140 | 'Scipy':[
141 | {content: 'Py 2 & 3 full', start: '2010-08-31', end:'2018-12-31', py2:true},
142 | {content: 'Py 2 bug fix', start: '2019-01-01', end:'2019-12-31', py2:true},
143 | {content: 'Py 3 full', start: '2019-01-01', end:'2021-12-16'},
144 | ],
145 | 'Matplotlib':[
146 | {content: '2.2 LTS', start: '2018-03-05', end: '2020-01-10', py2:true},
147 | {content: '3.0', start: '2018-07-01', end: '2019-01-01'},
148 | {content: '3.1', start: '2019-01-01', end: '2019-07-01'},
149 | {content: '3.2', start: '2019-07-01', end: '2020-01-01'}
150 | ],
151 | 'Spyder':[
152 | {content: '3', start: '2016-09-24', end: '2019-01-15', py2:true},
153 | {content: '4', start: '2019-01-15', end: '2020-01-01', py2:true},
154 | {content: '5', start: '2019-12-31', end: '2021-12-16'}
155 | ],
156 | 'Xonsh':[
157 | {content: '0.x series – Python 3.4+', start: '2015-03-09', end: '2021-12-16'},
158 | ],
159 | 'scikit-bio':[
160 | {content: '0.1.1 - 0.4.2', start: '2014-05-16', end: '2016-05-30', py2:true},
161 | {content: '0.5.0+', start: '2016-05-31', end: '2021-12-16'},
162 | ],
163 | 'QIIME':[
164 | {content: '1.x', start: '2010-04-09', end: '2017-12-31', py2:true},
165 | {content: '2.x+', start: '2016-07-11', end: '2021-12-16'},
166 | ],
167 | 'SunPy':[
168 | {content: '0.7', start: '2016-05-24', end: '2017-08-07', py2:true},
169 | {content: '0.8', start: '2017-08-07', end: '2018-04-23', py2:true},
170 | {content: '0.9', start: '2018-04-23', end: '2020-01-01', py2:true},
171 | {content: '1.0', start: '2019-01-01', end: '2020-01-01'},
172 | {content: '1.1', start: '2020-01-01', end: '2020-06-01'},
173 | ],
174 | 'Astropy':[
175 | {content: '1.0 LTS', start: '2015-02-19', end: '2017-06-01', py2:true},
176 | {content: '1.1', start: '2015-12-11', end: '2016-06-23', py2:true},
177 | {content: '1.2', start: '2016-06-23', end: '2016-12-16', py2:true},
178 | {content: '1.3', start: '2016-12-16', end: '2017-06-01', py2:true},
179 | {content: '2.0 LTS', start: '2017-06-01', end: '2019-12-31', py2:true},
180 | {content: '3.0', start: '2018-02-19', end: '2018-11-30'},
181 | {content: '3.1', start: '2018-11-30', end: '2019-05-01'},
182 | {content: '3.2', start: '2019-05-01', end: '2019-11-30'},
183 | {content: '4.0 LTS', start: '2019-11-30', end: '2021-12-01'},
184 | ],
185 | 'geopy':[
186 | {content: '1.x', start: '2014-09-07', end:'2019-04-01', py2:true},
187 | {content: '2.x', start: '2019-04-01', end:'2023-12-31'},
188 | ],
189 | 'Tryton':[
190 | {content: '4.0', start: '2016-05-02', end: '2018-10-01', py2:true},
191 | {content: '4.2', start: '2016-11-28', end: '2019-05-01', py2:true},
192 | {content: '4.4', start: '2017-05-01', end: '2019-10-01', py2:true},
193 | {content: '4.6', start: '2017-10-30', end: '2020-05-01', py2:true},
194 | {content: '4.8', start: '2018-04-23', end: '2020-10-01', py2:true},
195 | {content: '5.0', start: '2018-10-01', end: '2023-10-01'},
196 | {content: '5.2', start: '2019-05-01', end: '2020-05-01'},
197 | ],
198 | 'osBrain':[
199 | {content: '0.x', start: '2016-07-01', end: '2021-12-16'},
200 | ],
201 | 'PyMeasure':[
202 | {content: '0.4', start: '2016-07-29', end: '2017-10-18'},
203 | {content: '0.5', start: '2017-10-18', end: '2019-01-14'},
204 | {content: '0.6', start: '2019-01-14', end: '2020-01-01'},
205 | ],
206 | 'rpy2':[
207 | {content: '2.8.x', start: '2016-12-21', end:'2018-12-21', py2:true},
208 | {content: '2.9.x', start: '2017-07-14', end:'2018-07-14'},
209 | ],
210 | 'FEniCS':[
211 | {content: '2017.1.0', start: '2017-05-12', end: '2017-12-31', py2:true},
212 | {content: '2018.1.0', start: '2018-01-01', end: '2018-06-01'}
213 | ],
214 | 'RDKit':[
215 | {content: '2014.9.1 - 2019.03.1', start: '2014-09-1', end: '2019-09-1', py2:true},
216 | {content: '2019.9.1 -' , start: '2019-09-01', end: '2021-03-01'}
217 | ],
218 | 'Toyplot':[
219 | {content: 'Python 2 & 3', start: '2014-11-05', end:'2018-12-31', py2:true},
220 | {content: 'Python 3 only', start: '2019-01-01', end:'2021-12-31'},
221 | ],
222 | 'music21':[
223 | {content: 'v3', start: '2016-08-22', end: '2017-08-06', py2:true},
224 | {content: 'v4', start: '2017-08-22', end: '2019-06-01', py2:true},
225 | {content: 'v5', start: '2018-03-17', end: '2019-08-01'},
226 | {content: 'v6', start: '2019-08-01', end: '2020-08-01'},
227 | ],
228 | 'mitmproxy':[
229 | {content: '0.18.x', start: '2016-10-16', end: '2017-10-16', py2:true},
230 | {content: '1.0.x -', start: '2016-12-26', end: '2021-12-23'}
231 | ],
232 | 'SPADE':[
233 | {content: '2.0', start: '2010-08-01', end: '2012-11-09', py2:true},
234 | {content: '2.1', start: '2012-11-09', end: '2013-05-27', py2:true},
235 | {content: '2.2', start: '2013-05-27', end: '2017-06-09', py2:true},
236 | {content: '2.3', start: '2017-06-09', end: '2018-12-31', py2:true},
237 | {content: '3.x -', start: '2018-09-15', end: '2020-12-31', py2:false}
238 | ],
239 | 'dateutil': [
240 | {content: '2.x', start: '2011-12-01', end: '2018-09-01', py2:true},
241 | {content: '3.x', start: '2018-09-01', end: '2019-07-01', py2:true},
242 | {content: '4.x', start: '2019-01-01', end: '2020-07-01', py2:false},
243 | ],
244 | 'CherryPy': [
245 | {content: '3.2-17.x', start: '2011-02-25', end: '2019-12-31', py2: true},
246 | {content: '18.x+', start: '2018-09-01', end: '2023-12-31', py2: false},
247 | ],
248 | 'stomp.py':[
249 | {content: '3.x', start: '2010-04-01', end: '2013-09-30', py2:true},
250 | {content: '4.x', start: '2013-10-01', end: '2020-01-09', py2:true},
251 | {content: '5.x+', start: '2020-01-10', end: '2023-12-31', py2:false},
252 | ],
253 | 'cmd2':[
254 | {content: '0.7.x', start: '2017-02-23', end: '2018-01-04', py2:true},
255 | {content: '0.8.x', start: '2018-02-01', end: '2018-08-31', py2:true},
256 | {content: '0.9.x', start: '2018-05-28', end: '2023-12-31', py2:false},
257 | ],
258 | 'angr':[
259 | {content: '7.x', start: '2017-09-09', end: '2018-09-26', py2: true},
260 | {content: '8.x', start: '2018-09-28', end: '2023-12-31', py2: false},
261 | ],
262 | 'FontTools':[
263 | {content: 'Py 2 & 3 full', start: '2014-09-24', end:'2018-12-31', py2:true},
264 | {content: 'Py 2 bug fix', start: '2019-01-01', end:'2019-06-30', py2:true},
265 | {content: 'Py 3 full', start: '2019-01-01', end:'2023-12-31'},
266 | ],
267 |
268 | // for tests, rando example
269 | //'matplotlib':[
270 | // {content: 'matplotlib 2.x', start: '2015-06-01', end:'2018-06-01', py2:true},
271 | // {content: 'matplotlib 3.x', start: '2018-6-12', end:'2019-12-01'},
272 | //],
273 | //'scikit-bio':[
274 | // {content: '0.18', start: '2016-05-01', end:'2016-11-01', py2:true},
275 | // {content: '0.19', start: '2016-11-02', end:'2017-12-01'},
276 | //]
277 |
278 |
279 | }
280 |
281 | // Create a DataSet (allows two way data-binding)
282 | var items = new vis.DataSet([
283 | ]);
284 |
285 |
286 |
287 | var groups = new vis.DataSet();
288 | var g=0;
289 | var i=0;
290 | for (var gname in data) {
291 | g++;
292 | groups.add({id: g, content: gname});
293 | gr = data[gname];
294 | for(var k in gr){
295 | i++;
296 | gr[k].id = i;
297 | gr[k].group = g;
298 | if(gr[k].py2) gr[k].className ='py2'
299 | items.add(gr[k])
300 | }
301 | }
302 |
303 | // Configuration for the Timeline
304 | var options = {};
305 |
306 | var options = {
307 | clickToUse: true,
308 | groupOrder: 'group'
309 | };
310 |
311 | // Create a Timeline
312 | var timeline = new vis.Timeline(container, items, options);
313 | timeline.setGroups(groups);
314 | timeline.setItems(items);
315 | timeline.addCustomTime(Date.parse('2020-01-01'))
316 |
317 | });
318 |
--------------------------------------------------------------------------------
/_includes/css/base.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Skeleton V1.2
3 | * Copyright 2011, Dave Gamache
4 | * www.getskeleton.com
5 | * Free to use under the MIT license.
6 | * http://www.opensource.org/licenses/mit-license.php
7 | * 6/20/2012
8 | */
9 |
10 |
11 | /* Table of Content
12 | ==================================================
13 | #Reset & Basics
14 | #Basic Styles
15 | #Site Styles
16 | #Typography
17 | #Links
18 | #Lists
19 | #Images
20 | #Buttons
21 | #Forms
22 | #Misc */
23 |
24 |
25 | /* #Reset & Basics (Inspired by E. Meyers)
26 | ================================================== */
27 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
28 | margin: 0;
29 | padding: 0;
30 | border: 0;
31 | font-size: 100%;
32 | font: inherit;
33 | vertical-align: baseline; }
34 | article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
35 | display: block; }
36 | body {
37 | line-height: 1; }
38 | ol, ul {
39 | list-style: none; }
40 | blockquote, q {
41 | quotes: none; }
42 | blockquote:before, blockquote:after,
43 | q:before, q:after {
44 | content: '';
45 | content: none; }
46 | table {
47 | border-collapse: collapse;
48 | border-spacing: 0; }
49 |
50 |
51 | /* #Basic Styles
52 | ================================================== */
53 | body {
54 | background: #fff;
55 | font: 14px/21px "Raleway", "HelveticaNeue", Arial, sans-serif;
56 | color: #444;
57 | -webkit-font-smoothing: antialiased; /* Fix for webkit rendering */
58 | -webkit-text-size-adjust: 100%;
59 | }
60 |
61 |
62 | /* #Typography
63 | ================================================== */
64 | h1, h2, h3, h4, h5, h6 {
65 | font-weight: 300; }
66 | h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; }
67 | h1 { font-size: 46px; line-height: 50px; margin-bottom: 14px;}
68 | h2 { font-size: 35px; line-height: 40px; margin-bottom: 10px; }
69 | h3 { font-size: 28px; line-height: 34px; margin-bottom: 8px; }
70 | h4 { font-size: 21px; line-height: 30px; margin-bottom: 4px; }
71 | h5 { font-size: 17px; line-height: 24px; }
72 | h6 { font-size: 14px; line-height: 21px; }
73 | .subheader { color: #777; }
74 |
75 | p { margin: 0 0 20px 0; }
76 | p img { margin: 0; }
77 | p.lead { font-size: 21px; line-height: 27px; color: #777; }
78 |
79 | em { font-style: italic; }
80 | strong { font-weight: bold; }
81 | small { font-size: 80%; }
82 |
83 | /* Blockquotes */
84 | blockquote, blockquote p { font-size: 17px; line-height: 24px; color: #777; font-style: italic; }
85 | blockquote { margin: 0 0 20px; padding: 9px 20px 0 19px; border-left: 1px solid #ddd; }
86 | blockquote cite { display: block; font-size: 12px; color: #555; }
87 | blockquote cite:before { content: "\2014 \0020"; }
88 | blockquote cite a, blockquote cite a:visited, blockquote cite a:visited { color: #555; }
89 |
90 | hr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 10px 0 30px; height: 0; }
91 |
92 |
93 | /* #Links
94 | ================================================== */
95 | a, a:visited { text-decoration: underline; outline: 0; }
96 | a:hover, a:focus { }
97 | p a, p a:visited { line-height: inherit; }
98 |
99 |
100 | /* #Lists
101 | ================================================== */
102 | ul, ol { margin-bottom: 20px; }
103 | ul { list-style: none outside; }
104 | ol { list-style: decimal; }
105 | ul, ul.square { list-style: square outside; }
106 | ul ul, ul.circle { list-style: circle outside; }
107 | ul ul ul, ul.disc { list-style: disc outside; }
108 | ul ul li, ul ol li,
109 | ol ol li, ol ul li { margin-bottom: 6px; }
110 | li { line-height: 18px; margin-bottom: 12px; }
111 | ul.large li { line-height: 21px; }
112 | li p { line-height: 21px; }
113 |
114 | /* #Images
115 | ================================================== */
116 |
117 | img.scale-with-grid {
118 | max-width: 100%;
119 | height: auto; }
120 |
121 |
122 | /* #Buttons
123 | ================================================== */
124 |
125 | .button,
126 | button,
127 | input[type="submit"],
128 | input[type="reset"],
129 | input[type="button"] {
130 | background: #eee; /* Old browsers */
131 | background: #eee -moz-linear-gradient(top, rgba(255,255,255,.2) 0%, rgba(0,0,0,.2) 100%); /* FF3.6+ */
132 | background: #eee -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.2)), color-stop(100%,rgba(0,0,0,.2))); /* Chrome,Safari4+ */
133 | background: #eee -webkit-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Chrome10+,Safari5.1+ */
134 | background: #eee -o-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Opera11.10+ */
135 | background: #eee -ms-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* IE10+ */
136 | background: #eee linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* W3C */
137 | border: 1px solid #aaa;
138 | border-top: 1px solid #ccc;
139 | border-left: 1px solid #ccc;
140 | -moz-border-radius: 3px;
141 | -webkit-border-radius: 3px;
142 | border-radius: 3px;
143 | color: #444;
144 | display: inline-block;
145 | font-size: 11px;
146 | font-weight: bold;
147 | text-decoration: none;
148 | text-shadow: 0 1px rgba(255, 255, 255, .75);
149 | cursor: pointer;
150 | margin-bottom: 20px;
151 | line-height: normal;
152 | padding: 8px 10px;
153 | font-family: "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; }
154 |
155 | .button:hover,
156 | button:hover,
157 | input[type="submit"]:hover,
158 | input[type="reset"]:hover,
159 | input[type="button"]:hover {
160 | color: #222;
161 | background: #ddd; /* Old browsers */
162 | background: #ddd -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); /* FF3.6+ */
163 | background: #ddd -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.3)), color-stop(100%,rgba(0,0,0,.3))); /* Chrome,Safari4+ */
164 | background: #ddd -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Chrome10+,Safari5.1+ */
165 | background: #ddd -o-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Opera11.10+ */
166 | background: #ddd -ms-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* IE10+ */
167 | background: #ddd linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* W3C */
168 | border: 1px solid #888;
169 | border-top: 1px solid #aaa;
170 | border-left: 1px solid #aaa; }
171 |
172 | .button:active,
173 | button:active,
174 | input[type="submit"]:active,
175 | input[type="reset"]:active,
176 | input[type="button"]:active {
177 | border: 1px solid #666;
178 | background: #ccc; /* Old browsers */
179 | background: #ccc -moz-linear-gradient(top, rgba(255,255,255,.35) 0%, rgba(10,10,10,.4) 100%); /* FF3.6+ */
180 | background: #ccc -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.35)), color-stop(100%,rgba(10,10,10,.4))); /* Chrome,Safari4+ */
181 | background: #ccc -webkit-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Chrome10+,Safari5.1+ */
182 | background: #ccc -o-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Opera11.10+ */
183 | background: #ccc -ms-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* IE10+ */
184 | background: #ccc linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* W3C */ }
185 |
186 | .button.full-width,
187 | button.full-width,
188 | input[type="submit"].full-width,
189 | input[type="reset"].full-width,
190 | input[type="button"].full-width {
191 | width: 100%;
192 | padding-left: 0 !important;
193 | padding-right: 0 !important;
194 | text-align: center; }
195 |
196 | /* Fix for odd Mozilla border & padding issues */
197 | button::-moz-focus-inner,
198 | input::-moz-focus-inner {
199 | border: 0;
200 | padding: 0;
201 | }
202 |
203 |
204 | /* #Forms
205 | ================================================== */
206 |
207 | form {
208 | margin-bottom: 20px; }
209 | fieldset {
210 | margin-bottom: 20px; }
211 | input[type="text"],
212 | input[type="password"],
213 | input[type="email"],
214 | textarea,
215 | select {
216 | border: 1px solid #ccc;
217 | padding: 6px 4px;
218 | outline: none;
219 | -moz-border-radius: 2px;
220 | -webkit-border-radius: 2px;
221 | border-radius: 2px;
222 | font: 13px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
223 | color: #777;
224 | margin: 0;
225 | width: 210px;
226 | max-width: 100%;
227 | display: block;
228 | margin-bottom: 20px;
229 | background: #fff; }
230 | select {
231 | padding: 0; }
232 | input[type="text"]:focus,
233 | input[type="password"]:focus,
234 | input[type="email"]:focus,
235 | textarea:focus {
236 | border: 1px solid #aaa;
237 | color: #444;
238 | -moz-box-shadow: 0 0 3px rgba(0,0,0,.2);
239 | -webkit-box-shadow: 0 0 3px rgba(0,0,0,.2);
240 | box-shadow: 0 0 3px rgba(0,0,0,.2); }
241 | textarea {
242 | min-height: 60px; }
243 | label,
244 | legend {
245 | display: block;
246 | font-weight: bold;
247 | font-size: 13px; }
248 | select {
249 | width: 220px; }
250 | input[type="checkbox"] {
251 | display: inline; }
252 | label span,
253 | legend span {
254 | font-weight: normal;
255 | font-size: 13px;
256 | color: #444; }
257 |
258 | /* #Misc
259 | ================================================== */
260 | .remove-bottom { margin-bottom: 0 !important; }
261 | .half-bottom { margin-bottom: 10px !important; }
262 | .add-bottom { margin-bottom: 20px !important; }
263 |
264 |
265 |
266 | /* #Syntax highlighting
267 | ================================================== */
268 |
269 |
270 | .highlight {
271 | color: #f8f8f2;
272 | table-layout: fixed;
273 | white-space: nowrap;
274 | width:90%;
275 | }
276 |
277 | .highlight pre, .highlight code {
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 | }
287 |
288 | .highlight, .linenodiv {
289 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWPQ1dU1BgABzQC7XXMTYQAAAABJRU5ErkJggg==);
290 | display:block;
291 | padding: 10px;
292 | margin-bottom:20px;
293 | }
294 | .gutter, .lineno { color: #ccc; }
295 |
296 | td.gl { width: 40px; }
297 |
298 | .gutter {
299 | border-right: none;
300 | padding: 10px;
301 | text-align: right;
302 | }
303 | span.lineno {
304 | display: block;
305 | float: left;
306 | width: 40px;
307 | padding-right: 8px;
308 | text-align: right;
309 | }
310 |
311 |
312 | .hll { background-color: #49483e }
313 | .c { color: #75715e } /* Comment */
314 | .err { color: #960050; background-color: #1e0010 } /* Error */
315 | .k { color: #66d9ef } /* Keyword */
316 | .l { color: #ae81ff } /* Literal */
317 | .n { color: #f8f8f2 } /* Name */
318 | .o { color: #f92672 } /* Operator */
319 | .p { color: #f8f8f2 } /* Punctuation */
320 | .cm { color: #75715e } /* Comment.Multiline */
321 | .cp { color: #75715e } /* Comment.Preproc */
322 | .c1 { color: #75715e } /* Comment.Single */
323 | .cs { color: #75715e } /* Comment.Special */
324 | .ge { font-style: italic } /* Generic.Emph */
325 | .gs { font-weight: bold } /* Generic.Strong */
326 | .kc { color: #66d9ef } /* Keyword.Constant */
327 | .kd { color: #66d9ef } /* Keyword.Declaration */
328 | .kn { color: #f92672 } /* Keyword.Namespace */
329 | .kp { color: #66d9ef } /* Keyword.Pseudo */
330 | .kr { color: #66d9ef } /* Keyword.Reserved */
331 | .kt { color: #66d9ef } /* Keyword.Type */
332 | .ld { color: #e6db74 } /* Literal.Date */
333 | .m { color: #ae81ff } /* Literal.Number */
334 | .s { color: #e6db74 } /* Literal.String */
335 | .na { color: #a6e22e } /* Name.Attribute */
336 | .nb { color: #f8f8f2 } /* Name.Builtin */
337 | .nc { color: #a6e22e } /* Name.Class */
338 | .no { color: #66d9ef } /* Name.Constant */
339 | .nd { color: #a6e22e } /* Name.Decorator */
340 | .ni { color: #f8f8f2 } /* Name.Entity */
341 | .ne { color: #a6e22e } /* Name.Exception */
342 | .nf { color: #a6e22e } /* Name.Function */
343 | .nl { color: #f8f8f2 } /* Name.Label */
344 | .nn { color: #f8f8f2 } /* Name.Namespace */
345 | .nx { color: #a6e22e } /* Name.Other */
346 | .py { color: #f8f8f2 } /* Name.Property */
347 | .nt { color: #f92672 } /* Name.Tag */
348 | .nv { color: #f8f8f2 } /* Name.Variable */
349 | .ow { color: #f92672 } /* Operator.Word */
350 | .w { color: #f8f8f2 } /* Text.Whitespace */
351 | .mf { color: #ae81ff } /* Literal.Number.Float */
352 | .mh { color: #ae81ff } /* Literal.Number.Hex */
353 | .mi { color: #ae81ff } /* Literal.Number.Integer */
354 | .mo { color: #ae81ff } /* Literal.Number.Oct */
355 | .sb { color: #e6db74 } /* Literal.String.Backtick */
356 | .sc { color: #e6db74 } /* Literal.String.Char */
357 | .sd { color: #e6db74 } /* Literal.String.Doc */
358 | .s2 { color: #e6db74 } /* Literal.String.Double */
359 | .se { color: #ae81ff } /* Literal.String.Escape */
360 | .sh { color: #e6db74 } /* Literal.String.Heredoc */
361 | .si { color: #e6db74 } /* Literal.String.Interpol */
362 | .sx { color: #e6db74 } /* Literal.String.Other */
363 | .sr { color: #e6db74 } /* Literal.String.Regex */
364 | .s1 { color: #e6db74 } /* Literal.String.Single */
365 | .ss { color: #e6db74 } /* Literal.String.Symbol */
366 | .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
367 | .vc { color: #f8f8f2 } /* Name.Variable.Class */
368 | .vg { color: #f8f8f2 } /* Name.Variable.Global */
369 | .vi { color: #f8f8f2 } /* Name.Variable.Instance */
370 | .il { color: #ae81ff } /* Literal.Number.Integer.Long */
371 |
372 | .gh { } /* Generic Heading & Diff Header */
373 | .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */
374 | .gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */
375 | .gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */
376 |
--------------------------------------------------------------------------------
/_practicalities/intro.md:
--------------------------------------------------------------------------------
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 wishes to not support Python 3,
12 | or is stopping support for any minor version.
13 |
14 |
15 | This page gathers information and links to resources allowing a library
16 | to 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 the new `setup(..., python_requires='>=3.4')` option.
27 | - Use `pip install [-e] .` and do **not** invoke `setup.py` directly.
28 | - **Fail** early at **install time** if user is on Python 2.
29 |
30 | We gave a
31 | [talk at PyCon 2017](https://www.youtube.com/watch?v=2DkfPzWWC2Q)
32 | ([slides](https://speakerdeck.com/pycon2017/py3-compatibility-in-a-user-friendly-manner)), and at
33 | [PyBay](https://www.youtube.com/watch?v=3i6n1RwqQCo)
34 | ([slides](https://speakerdeck.com/pybay/2017-building-bridges-stopping-python-2-without-damages)).
35 |
36 | ## The problem
37 |
38 | Up until December 2016 it was hard to publish a new major version of a library
39 | that changed requirements in Python version and mark it as such so that a user's
40 | system will not try to upgrade said library.
41 |
42 | With the recent changes in Python packaging this is now possible.
43 |
44 | As an example let's look at a non-existent `fictitious` library.
45 |
46 | - `fictitious` 1.1, 1.2, 1.3, 1.4 are compatible Python 2.7 and 3.3+
47 | - `fictitious` 2.0 has been released and is python 3.4+ only.
48 |
49 | As a Python 2.7 user, if I don't pay attention, or if the library is not
50 | correctly tagged, there can be issues when you try to update the library:
51 |
52 | $ python -c 'import fictitious; print(fictitious.__version__)'
53 | 1.3.2
54 | $ pip install fictitious --upgrade
55 |
56 | Either my system will install 2.0, which will not work -- the worst case
57 | scenario -- or fail to install, in which case I will not get the critical 1.4
58 | upgrade.
59 |
60 | ## As a user
61 |
62 | ### Install pip 9.0
63 |
64 | If you are already a Python 3 user, you should not encounter a lot of
65 | disruption. Please still check that the libraries you use follow best practices
66 | not to break for Python 2 users. Python is a community regardless of which
67 | python version you have to (or decided to) run, making sure that everything
68 | works makes the community strong.
69 |
70 | Make sure you have Pip ≥ 9.0, this is especially important if you have Python
71 | 2 installations. Having pip 9.0+ is not a guarantee of a flawless upgrade. But pip
72 | 9.0+ does have a number of safety check not available in previous versions.
73 |
74 | Having a version of pip < 9.0 can lead your system to try to upgrade to
75 | non-compatible versions of Python packages even if these are marked as
76 | non-compatible.
77 |
78 | Help as many other _users_ as possible to install pip ≥ 9.0. For the
79 | transition, it is the slowest part of the ecosystem to update, and is the only
80 | piece that requires action of all Python users.
81 |
82 | The simplest way to make sure all is up to date is to run the following for
83 | each installation of Python:
84 |
85 | $ pip install --upgrade setuptools pip
86 |
87 | This will install the latest version of pip and setuptools.
88 |
89 | You can issue the following to see the version of pip:
90 |
91 | $ pip --version
92 | 9.0.0
93 |
94 | All good.
95 |
96 |
97 |
98 | ## Setuptools
99 |
100 | If you are on a system for which no wheel is available, pip will try to
101 | install a source distribution (aka `sdist`).
102 |
103 | Installing an `sdist` will require setuptools, so make sure you have setuptools
104 | ≥ 24.2.0 or building Python 3-only libraries will likely fail. In particular
105 | if library authors have taken time to mark their library as Python 3 only, the
106 | `python_requires` argument to `setup()` may not be recognized and installation
107 | will fail.
108 |
109 | Use the following to check your setuptools version :
110 |
111 | $ python -c 'import setuptools; print(setuptools.__version__)'
112 | 24.2.0
113 |
114 | Again make sure to upgrade pip and setuptools to make sure you have an up to
115 | date system:
116 |
117 | $ pip install --upgrade setuptools pip
118 |
119 | ## Local package index
120 |
121 | If you are using a custom local package index, for example if you are working
122 | at a company with private packages, make sure it correctly implements
123 | [pep-503](https://www.python.org/dev/peps/pep-0503/) to let pip know about
124 | the `python_requires` field. This _mostly_ mean that the HTML you are exposing
125 | should get a `data-python-requires` data attribute with the (html escaped)
126 | version specifier.
127 |
128 | ## The state of PyPI
129 |
130 | [Warehouse](https://github.com/pypi/warehouse) and [Legacy
131 | PyPI](https://github.com/pypa/legacy-pypi) have received various patches to
132 | insure they support this new functionality.
133 |
134 | # Preparing your library
135 |
136 |
137 | As a library author one of the most important factors in a smooth transition is
138 | planning and communication, letting your user base know in advance that the
139 | transition is happening and what step to take is critical for a transition.
140 |
141 | For your library code here the steps you need to take to ensure that
142 | installation will fail in the least number of cases:
143 |
144 | You need to release your package's new version with
145 | [setuptools](https://pypi.python.org/pypi/setuptools) version 24.2.0 or above.
146 | You can also use one of the alternate package managers that can set the
147 | [Requires-Python](https://www.python.org/dev/peps/pep-0345/#requires-python)
148 | metadata field. Without this, pip 9.0 **will try** to install a non-compatible
149 | version of your software on Python 2. This version of setuptools is recent
150 | (July 20, 2016) and this is all possible thanks to the [work of Xavier
151 | Fernandez](https://github.com/pypa/setuptools/pull/631)
152 |
153 | Add the following to your `setup.py`
154 |
155 | ```
156 | setup(
157 | ...
158 | python_requires='>=3.3'
159 | ...
160 | )
161 | ```
162 |
163 | Change `>=3.3` accordingly depending on what version your library decides to
164 | support. In particular you can use `>=2.6` or `>=3.5` ! Note that this also
165 | support the _compatible with_ syntax: `~=2.5` (meaning, `>=2.5` and `<3`).
166 |
167 | This will make [PyPI aware](https://github.com/pypa/warehouse/pull/1448) that
168 | your package is Python 3.3+ only, and [allow
169 | pip](https://github.com/pypa/pip/pull/3877) to be [made aware of
170 | this](https://github.com/pypa/pypi-legacy/pull/506).
171 |
172 | Thus as long as your user have recent enough versions of pip and setuptools
173 | they will get the right version of your library.
174 |
175 | # Unit testing and documentation
176 |
177 | It is recommended **not** to invoke `setup.py` directly either with `install` or
178 | `develop` subcommands. These may not correctly resolve dependencies, and can
179 | install incompatible versions of dependencies. Please recommend and use `pip
180 | install .` and `pip install -e .` for regular and developer installs, respectively.
181 |
182 | Check in scripts and documentation that the correct installation command is
183 | used.
184 |
185 | # Recommended mitigations
186 |
187 | These are not mandatory but should make the transition seamless by warning your
188 | users early enough _and_ providing useful error messages.
189 |
190 | ## Runtime warning on master
191 |
192 | Add a warning at _runtime_ that triggers early on master
193 | (before switching to Python 3 only)
194 |
195 | ```
196 | import warnings
197 | import sys
198 | if sys.version_info < (3,):
199 | warnings.warn('You are using master of `Frobulator` with Python 2. '
200 | 'Frobulator will soon be Python 3 only. '
201 | 'See this issue to know more.',
202 | UserWarning)
203 | ```
204 |
205 | Your Python 2 users will have a chance to upgrade, or get off master,
206 | (for example on the LTS branch).
207 |
208 | ## Fail early at import time
209 |
210 | Add an error early through import at runtime with a clear error message, leave the
211 | early import compatible Python 2 as users will not feel welcomed with a useless
212 | `SyntaxError` due to their Python 2 usage. Don't hesitate to use multi-line strings
213 | in error messages.
214 |
215 | Error at import time _will_ happen on systems with old version of pip and
216 | setuptools. Keep in mind that saying the package is Python 3 only is not a lot
217 | more helpful than a `SyntaxError`. The most reasonable reason would be
218 | out-of-date pip and setuptools:
219 |
220 |
221 | ```
222 | import sys
223 |
224 | if sys.version_info < (3,):
225 | raise ImportError(
226 | """You are running Frobulator 6.0 on Python 2
227 |
228 | Frobulator 6.0 and above are no longer compatible with Python 2, and you still
229 | ended up with this version installed. That's unfortunate; sorry about that.
230 | It should not have happened. Make sure you have pip >= 9.0 to avoid this kind
231 | of issue, as well as setuptools >= 24.2:
232 |
233 | $ pip install pip setuptools --upgrade
234 |
235 | Your choices:
236 |
237 | - Upgrade to Python 3.
238 |
239 | - Install an older version of Frobulator:
240 |
241 | $ pip install 'frobulator<6.0'
242 |
243 | It would be great if you can figure out how this version ended up being
244 | installed, and try to check how to prevent that for future users.
245 |
246 | See the following URL for more up-to-date information:
247 |
248 | https://i.am.an/url
249 |
250 | """)
251 |
252 | ```
253 |
254 | ## Watch out for beta releases
255 |
256 |
257 | Make sure your version number matches
258 | [PEP 440](https://www.python.org/dev/peps/pep-0440/) or you will get surprises
259 | during beta, in particular as the `sdist` and `wheel` will appear as being
260 | different versions (the sdist (during beta/rc/post) can appear with
261 | a greater version number than wheels). Pip thus will try to install the sdist
262 | instead of the wheel, which has more chance of failing, in particular with
263 | pre-24.2 versions of setuptools.
264 |
265 | The regular expression to check for validity of pep440 can be found below:
266 |
267 | ^
268 | ([1-9]\\d*!)?
269 | (0|[1-9]\\d*)
270 | (\\.(0|[1-9]\\d*))*
271 | ((a|b|rc)(0|[1-9]\\d*))?
272 | (\\.post(0|[1-9]\\d*))?
273 | (\\.dev(0|[1-9]\\d*))?
274 |
275 |
276 | ## Fail early in setup.py
277 |
278 | Leave `setup.py` python 2 compatible and fail early. If you detect Python 2
279 | raise a clear error message and ask the user to make sure they have pip > 9.0 (or
280 | migrate to Python 3). You can (try to) conditionally import pip and check for
281 | its version but this might not be the same pip. Failing early is important to
282 | make sure the Python installation does not install an incompatible version.
283 | Otherwise user code can fail at runtime arbitrarily later in the future, which can
284 | be a difficult to debug and fix. Get inspiration from the message of failure at
285 | runtime, and adapt for installation time.
286 |
287 |
288 | Here is for a simple version of how IPython handle old versions of Python and
289 | Pip that still try to install IPython 7.0+ on Python `< (3,4)`.
290 |
291 | ```python
292 | if sys.version_info < (3, 4):
293 |
294 | error = """
295 | IPython 7.0+ supports Python 3.4 and above.
296 | When using Python 2.7, please install IPython 5.x LTS Long Term Support version.
297 | Python 3.3 was supported up to IPython 6.x.
298 |
299 | See IPython `README.rst` file for more information:
300 |
301 | https://github.com/ipython/ipython/blob/master/README.rst
302 |
303 | Python {py} detected.
304 |
305 | Try upgrading pip and retry.
306 | """.format(py='.'.join([str(v) for v in sys.version_info[:3]]))
307 |
308 | print(error, file=sys.stderr)
309 | sys.exit(1)
310 | ```
311 |
312 | You can look at the [full
313 | check](https://github.com/ipython/ipython/blob/6a3e2db0c299dc05e636653c4a43d0aa756fb1c8/setup.py#L23-L58)
314 | that attempt to detect which version of pip is in used.
315 |
316 | ## Upload with Twine.
317 |
318 | You _must_ upload your package with ``twine`` and NOT with ``setup.py upload``.
319 | If you have an old version of setuptools or ``distutils``, even if
320 | ``python_requires`` is set, metadata may not be uploaded correctyl. See [This
321 | issue](https://github.com/pypa/warehouse/issues/3889) on PyPI repository
322 |
323 | ## Fix dependant libraries
324 |
325 | If you control dependant packages, Make sure to include conditional dependencies
326 | depending on the version of Python.
327 |
328 | # Non-recommended mitigations
329 |
330 | This is a collection of "mitigation" or "solutions" you will find on the web
331 | and that you will hear about. This is an attempt to acknowledge them, and
332 | explain why they can't work and what are their drawbacks before you attempt to
333 | implement them.
334 |
335 | ### Use a meta-package
336 |
337 | It is possible to release a meta-package that has _virtually_ no code and relies
338 | on a conditional dependency to install its actual core code on the user system.
339 | For example, Frob-6.0 could be a meta-package which depends on
340 | Frob-real-py2 on Python < 3.0, and Frob-real-py3 on Python ≥ 3.4. While
341 | this approach is _doable_ this can make imports confusing.
342 |
343 | ## Depend on setuptools
344 |
345 | You can mark your library as dependent on setuptools greater than 24.3 as this
346 | will insure that during the next upgrade (when the packages drop python 2
347 | support) will have the right version of setuptools.
348 |
349 | Of course regardless of all the care you will take for your library to no break
350 | and to install only on python 2, you will likely have cases where it will still
351 | end up being installed on incompatible versions of Python. Simply because users
352 | upgrade rarely and only an old version of pip or setuptools is enough to make
353 | the update process broken.
354 |
355 | Plus setuptools is rarely an actual dependency of your project but a
356 | requirement to build wheels.
357 |
358 |
359 | ### Multiple sdist files
360 |
361 | Pip (used to) support a "feature" where a sdist ending in `-pyX.Y.tar.gz` would
362 | only be seen as compatible on Python X.Y, thus it used to be possible to
363 | publish multiple sdist of a package targeting various python version.
364 |
365 | It is not possible anymore to upload multiple sdist files on PyPI, so this
366 | solution is no longer tenable.
367 |
368 | ### Wheel only?
369 |
370 | Releasing a package only using wheels for a given python version is doable, but
371 | this will break downstream packages that may require the original source to
372 | reproduce their build.
373 |
374 | # Why all *this*?!?
375 |
376 | You might wonder why all this, it's 2018 already, so how come this is still an
377 | issue? Python 3 has been out for 9+ years now!
378 |
379 | Well there are many reasons for this. First of all, this issue mostly affects
380 | libraries that are currently python 2 and Python 3 compatible at the same time.
381 | Many libraries have transitioned from Python 2-only to Python 2 + 3. And the
382 | issue of transitioning to Python 3 only is relatively recent. Technically it
383 | can also apply to libraries that are only stopping support for 2.6, or are even
384 | already Python 3 only, but are starting to stop supporting earlier versions of
385 | Python (for example a library releasing a Python 3.4+ only version).
386 |
387 | Python 3.3 was released at the end of 2012, and was the first version to
388 | support (again) `u` as a prefix for Unicode string. It was one of the first
389 | minor versions of Python 3 that saw a majority of single-source projects working
390 | both on Python 2 and Python 3. These are the projects that will likely be
391 | affected by this issue.
392 |
393 | The introduction of Python 3 was chaotic; there are still strong arguments in both
394 | the Python 2 and Python 3 camps. Regardless of what side you take, the ones suffering
395 | the most from this are users (starting with the fact that inevitably some libraries
396 | will stop supporting for Python 2 and release Python 3 only library). Inevitably, some
397 | systems and people will not be upgraded to Python 3, so this document hopefully
398 | helps to _ensure_ that users get the _least_ breakage as possible and what are the best
399 | practices are to follow.
400 |
--------------------------------------------------------------------------------