diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..79243f7 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,8 @@ +If you're adding a project to the Python 3 statement, please ensure you have: + +- [ ] Discussed dropping Python 2 support with all maintainers +- [ ] Discussed signing the statement with all maintainers +- [ ] Added a suitable logo if the project has one + - [ ] Approximately square logos generally fit better than banners + - [ ] Compressed the logo to save bandwidth (run `scripts/squash-images.sh` on it) +- [ ] Checked the Netlify preview made from the pull request diff --git a/.gitignore b/.gitignore index f11e635..a406e93 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ _site/ -.DS_Store \ No newline at end of file +.DS_Store +*.swo diff --git a/CNAME b/CNAME deleted file mode 100644 index a365dac..0000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -www.python3statement.org \ No newline at end of file diff --git a/COPYING.md b/COPYING.md new file mode 100644 index 0000000..4fa7b5f --- /dev/null +++ b/COPYING.md @@ -0,0 +1,33 @@ +The logos of projects which have endorsed the statement are used with the +permission of the projects they represent. They are not covered by any of the +licenses granted by this project. + +The project uses the [SinglePaged template](https://github.com/t413/SinglePaged), +which is under the MIT license: + + Copyright (c) 2014 Tim O'Brien (t413) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +Any example computer code created for this project is published under a +[CC0 license](https://creativecommons.org/publicdomain/zero/1.0/), meaning it +can be used with no conditions. + +Content not mentioned above (principally the text of the website), is published +under the [CC-BY license](https://creativecommons.org/licenses/by/4.0/). diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..e401321 --- /dev/null +++ b/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' +gem 'github-pages' +gem "jekyll" +gem "jekyll-redirect-from" +gem "jekyll-paginate" +gem "jekyll-sitemap" +gem "jekyll-feed" diff --git a/README.md b/README.md index b875056..9587d0c 100755 --- a/README.md +++ b/README.md @@ -3,7 +3,36 @@ This is the main website for a pledge to stop supporting Python 2 for free in open source software. -# Run locally +## History + +This page is now an archive of part of the transition from Python 2 to 3. + +By around 2015, when Python 2 support was originally planned to end, many +important Python libraries and tools supported Python 3. But Python 2 still had +a lot of users, and projects needed to support both major versions. The end of +Python 2 support was postponed to 2020, and some people argued that development +of Python 2 should resume. It seemed like a real possibility that the end date +would be postponed again, and we'd need to support two versions of the language +indefinitely. + +The Python 3 statement was drawn up around 2016. Projects pledged to require +Python 3 by 2020, giving other projects confidence that they could plan a similar +transition, and allowing downstream users to figure out their options without a +nasty surprise. We didn't force people to move to Python 3, but if they wanted +to stick with Python 2, they would stop getting new versions of our projects. +The focus was originally on the scientific Python ecosystem, with Jupyter and +matplotlib among the first projects involved, but in late 2017 it was expanded +to any Python projects. +A rapidly growing number of projects signed up as we approached 2020. + +The long-term transition we hoped for has succeeded: in 2024 it is entirely +normal for projects to support only Python 3, simplifying maintainers' lives +and letting us take full advantage of newer language features. + +Thank-you to all of the people, in projects big and small, who contributed +their support to the statement! + +## Run locally Install Jekyll : `gem install jekyll`, `gem install github-pages` @@ -15,7 +44,9 @@ Modify the various files, refresh your browser and enjoy. PRs welcomed. -# Add your project +## Add your project + +We're no longer adding new projects - see the history section above. If you just want to add your project to the list of participating projects, add a line in [the list of participating projects](_sections/30-projects.md). It's @@ -23,7 +54,9 @@ markdown so feel free to just list your project name or add a link, and make a pull request. You should even be able to [edit it online](https://github.com/python3statement/python3statement.github.io/edit/master/_sections/30-projects.md). -## Add timeline information +There is no need to install Jekyll: A check creating a preview will be run on your pull request. Please check this preview. + +### Add timeline information The front page also has a timeline chart, with past release dates and future (planned) releases. You can also add your project there, if you have a specific @@ -33,7 +66,7 @@ See [site.js](site.js) around [line 100](https://github.com/python3statement/python3statement.github.io/blob/master/site.js#L103) to see how to add this kind of data. -# Base template +## Base template This site is based on [github.com/t413/SinglePaged](https://github.com/t413/SinglePaged). diff --git a/_config.yml b/_config.yml index fdb01cf..925e282 100755 --- a/_config.yml +++ b/_config.yml @@ -14,9 +14,9 @@ markdown: kramdown ### content configuration ### -title: "Sunsetting Python 2 support in scientific Python projects" +title: "Sunsetting Python 2 support" keywords: "Python 3, support, Jupyter, IPython, matplotlib, Python 2, Legacy Python" -description: "Scientific Python projects will drop Python 2 support by 2020." +description: "A pledge to drop Python 2 support by 2020." source_link: "https://github.com/python3statement/python3statement.github.io" favicon: #put a path like: "img/favicon.ico" touch_icon: #put a path like: "img/apple-touch-icon.png" @@ -35,4 +35,5 @@ colors: collections: - sections +- practicalities diff --git a/_includes/css/base.css b/_includes/css/base.css index bdc9578..5cacd6b 100644 --- a/_includes/css/base.css +++ b/_includes/css/base.css @@ -52,7 +52,7 @@ ================================================== */ body { background: #fff; - font: 14px/21px "Raleway", "HelveticaNeue-Light", Arial, sans-serif; + font: 14px/21px "Raleway", "HelveticaNeue", Arial, sans-serif; color: #444; -webkit-font-smoothing: antialiased; /* Fix for webkit rendering */ -webkit-text-size-adjust: 100%; @@ -274,7 +274,16 @@ width:90%; } -.highlight pre, .highlight code { display:block; margin:0; padding:0; background: none; overflow:auto; word-wrap: normal; } +.highlight pre, .highlight code { + display:block; + margin:0; + padding:0; + background: + none; + overflow:auto; + word-wrap: normal; + white-space: pre; +} .highlight, .linenodiv { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWPQ1dU1BgABzQC7XXMTYQAAAABJRU5ErkJggg==); diff --git a/_includes/css/main.css b/_includes/css/main.css index f511a0f..8424c97 100644 --- a/_includes/css/main.css +++ b/_includes/css/main.css @@ -25,6 +25,16 @@ html { box-sizing: border-box; } #{{id}} .sectiondivider { color: {{ bg }}; } {% endfor %} +{% for node in site.practicalities %} + {% capture id %}{{ node.id | remove:'/' | downcase }}{% endcapture %} + {% capture bg %}{% if site.colors[node.bg] %}{{ site.colors[node.bg] }}{% else %}{{ node.bg }}{% endif %}{% endcapture %} + {% capture fg %}{% if site.colors[node.color] %}{{ site.colors[node.color] }}{% else %}{{ node.color }}{% endif %}{% endcapture %} + nav .p-{{id}} { border-color: {{ bg }}; } + #{{id}} { background-color: {{ bg }} !important; color: {{ fg }}; } + #{{id}} a { color: {{ fg }}; } + #{{id}} .sectiondivider { color: {{ bg }}; } +{% endfor %} + /* ----- code, syntax highlighting, etc ----- */ diff --git a/_practicalities/intro.md b/_practicalities/intro.md new file mode 100644 index 0000000..a4c4cd5 --- /dev/null +++ b/_practicalities/intro.md @@ -0,0 +1,407 @@ +--- +bg: '#4da45e' +color: white +title: practicalities +fa-icon: pencil +id: bar +--- + +We do not discourage authors to release software on Python 2. While this guide +is mostly written with the assumption that software are going to stop Python 2 +support, it does perfectly apply to a package that wishes to not support Python 3, +or is stopping support for any minor version. + +This page gathers information and links to resources allowing a library +to stop supporting an older version of Python without causing too +much disruption for users who haven't upgraded to this new version. + +Whether you are a user or a developer, being aware of the issue listed here -- at +least the main points -- should ease lots of the pain. + +# Too long, did not read: + + - Help and encourage users to install **pip 9.0+** + - Help and encourage users to install **setuptools 24.3+** + - As maintainer, use the new `setup(..., python_requires='>=3.4')` option. + - Use `pip install [-e] .` and do **not** invoke `setup.py` directly. + - **Fail** early at **install time** if user is on Python 2. + +We gave a + [talk at PyCon 2017](https://www.youtube.com/watch?v=2DkfPzWWC2Q) + ([slides](https://speakerdeck.com/pycon2017/py3-compatibility-in-a-user-friendly-manner)), and at + [PyBay](https://www.youtube.com/watch?v=3i6n1RwqQCo) + ([slides](https://speakerdeck.com/pybay/2017-building-bridges-stopping-python-2-without-damages)). + +## The problem + +Up until December 2016 it was hard to publish a new major version of a library +that changed requirements in Python version and mark it as such so that a user's +system will not try to upgrade said library. + +With the recent changes in Python packaging this is now possible. + +As an example let's look at a non-existent `fictitious` library. + +- `fictitious` 1.1, 1.2, 1.3, 1.4 are compatible Python 2.7 and 3.3+ +- `fictitious` 2.0 has been released and is python 3.4+ only. + +As a Python 2.7 user, if I don't pay attention, or if the library is not +correctly tagged, there can be issues when you try to update the library: + + $ python -c 'import fictitious; print(fictitious.__version__)' + 1.3.2 + $ pip install fictitious --upgrade + +Either my system will install 2.0, which will not work -- the worst case +scenario -- or fail to install, in which case I will not get the critical 1.4 +upgrade. + +## As a user + +### Install pip 9.0 + +If you are already a Python 3 user, you should not encounter a lot of +disruption. Please still check that the libraries you use follow best practices +not to break for Python 2 users. Python is a community regardless of which +python version you have to (or decided to) run, making sure that everything +works makes the community strong. + +Make sure you have Pip ≥ 9.0, this is especially important if you have Python +2 installations. Having pip 9.0+ is not a guarantee of a flawless upgrade. But pip +9.0+ does have a number of safety check not available in previous versions. + +Having a version of pip < 9.0 can lead your system to try to upgrade to +non-compatible versions of Python packages even if these are marked as +non-compatible. + +Help as many other _users_ as possible to install pip ≥ 9.0. For the +transition, it is the slowest part of the ecosystem to update, and is the only +piece that requires action of all Python users. + +The simplest way to make sure all is up to date is to run the following for +each installation of Python: + + $ pip install --upgrade setuptools pip + +This will install the latest version of pip and setuptools. + +You can issue the following to see the version of pip: + + $ pip --version + 9.0.0 + +All good. + + + +## Setuptools + +If you are on a system for which no wheel is available, pip will try to +install a source distribution (aka `sdist`). + +Installing an `sdist` will require setuptools, so make sure you have setuptools +≥ 24.2.0 or building Python 3-only libraries will likely fail. In particular +if library authors have taken time to mark their library as Python 3 only, the +`python_requires` argument to `setup()` may not be recognized and installation +will fail. + +Use the following to check your setuptools version : + + $ python -c 'import setuptools; print(setuptools.__version__)' + 24.2.0 + +Again make sure to upgrade pip and setuptools to make sure you have an up to +date system: + + $ pip install --upgrade setuptools pip + +## Local package index + +If you are using a custom local package index, for example if you are working +at a company with private packages, make sure it correctly implements +[pep-503](https://www.python.org/dev/peps/pep-0503/) to let pip know about +the `python_requires` field. This _mostly_ mean that the HTML you are exposing +should get a `data-python-requires` data attribute with the (html escaped) +version specifier. + +## The state of PyPI + +[Warehouse](https://github.com/pypi/warehouse) and [Legacy +PyPI](https://github.com/pypa/legacy-pypi) have received various patches to +ensure they support this new functionality. + +# Preparing your library + + +As a library author one of the most important factors in a smooth transition is +planning and communication, letting your user base know in advance that the +transition is happening and what step to take is critical for a transition. + +For your library code here the steps you need to take to ensure that +installation will fail in the least number of cases: + +You need to release your package's new version with +[setuptools](https://pypi.python.org/pypi/setuptools) version 24.2.0 or above. +You can also use one of the alternate package managers that can set the +[Requires-Python](https://www.python.org/dev/peps/pep-0345/#requires-python) +metadata field. Without this, pip 9.0 **will try** to install a non-compatible +version of your software on Python 2. This version of setuptools is recent +(July 20, 2016) and this is all possible thanks to the [work of Xavier +Fernandez](https://github.com/pypa/setuptools/pull/631) + +Add the following to your `setup.py` + +``` +setup( + ... + python_requires='>=3.3' + ... +) +``` + +Change `>=3.3` accordingly depending on what version your library decides to +support. In particular you can use `>=2.6` or `>=3.5` ! Note that this also +support the _compatible with_ syntax: `~=2.5` (meaning, `>=2.5` and `<3`). + +This will make [PyPI aware](https://github.com/pypa/warehouse/pull/1448) that +your package is Python 3.3+ only, and [allow +pip](https://github.com/pypa/pip/pull/3877) to be [made aware of +this](https://github.com/pypa/pypi-legacy/pull/506). + +Thus as long as your user have recent enough versions of pip and setuptools +they will get the right version of your library. + +# Unit testing and documentation + +It is recommended **not** to invoke `setup.py` directly either with `install` or +`develop` subcommands. These may not correctly resolve dependencies, and can +install incompatible versions of dependencies. Please recommend and use `pip +install .` and `pip install -e .` for regular and developer installs, respectively. + +Check in scripts and documentation that the correct installation command is +used. + +# Recommended mitigations + +These are not mandatory but should make the transition seamless by warning your +users early enough _and_ providing useful error messages. + +## Runtime warning on master + +Add a warning at _runtime_ that triggers early on master +(before switching to Python 3 only) + +``` +import warnings +import sys +if sys.version_info < (3,): + warnings.warn('You are using master of `Frobulator` with Python 2. ' + 'Frobulator will soon be Python 3 only. ' + 'See this issue to know more.', + UserWarning) +``` + +Your Python 2 users will have a chance to upgrade, or get off master, +(for example on the LTS branch). + +## Fail early at import time + +Add an error early through import at runtime with a clear error message, leave the +early import compatible Python 2 as users will not feel welcomed with a useless +`SyntaxError` due to their Python 2 usage. Don't hesitate to use multi-line strings +in error messages. + +Error at import time _will_ happen on systems with old version of pip and +setuptools. Keep in mind that saying the package is Python 3 only is not a lot +more helpful than a `SyntaxError`. The most reasonable reason would be +out-of-date pip and setuptools: + + +``` +import sys + +if sys.version_info < (3,): + raise ImportError( + """You are running Frobulator 6.0 on Python 2 + +Frobulator 6.0 and above are no longer compatible with Python 2, and you still +ended up with this version installed. That's unfortunate; sorry about that. +It should not have happened. Make sure you have pip >= 9.0 to avoid this kind +of issue, as well as setuptools >= 24.2: + + $ pip install pip setuptools --upgrade + +Your choices: + +- Upgrade to Python 3. + +- Install an older version of Frobulator: + + $ pip install 'frobulator<6.0' + +It would be great if you can figure out how this version ended up being +installed, and try to check how to prevent that for future users. + +See the following URL for more up-to-date information: + +https://i.am.an/url + +""") + +``` + +## Watch out for beta releases + + +Make sure your version number matches +[PEP 440](https://www.python.org/dev/peps/pep-0440/) or you will get surprises +during beta, in particular as the `sdist` and `wheel` will appear as being +different versions (the sdist (during beta/rc/post) can appear with +a greater version number than wheels). Pip thus will try to install the sdist +instead of the wheel, which has more chance of failing, in particular with +pre-24.2 versions of setuptools. + +The regular expression to check for validity of pep440 can be found below: + + ^ + ([1-9]\\d*!)? + (0|[1-9]\\d*) + (\\.(0|[1-9]\\d*))* + ((a|b|rc)(0|[1-9]\\d*))? + (\\.post(0|[1-9]\\d*))? + (\\.dev(0|[1-9]\\d*))? + + +## Fail early in setup.py + +Leave `setup.py` python 2 compatible and fail early. If you detect Python 2 +raise a clear error message and ask the user to make sure they have pip > 9.0 (or +migrate to Python 3). You can (try to) conditionally import pip and check for +its version but this might not be the same pip. Failing early is important to +make sure the Python installation does not install an incompatible version. +Otherwise user code can fail at runtime arbitrarily later in the future, which can +be a difficult to debug and fix. Get inspiration from the message of failure at +runtime, and adapt for installation time. + + +Here is for a simple version of how IPython handle old versions of Python and +Pip that still try to install IPython 7.0+ on Python `< (3,4)`. + +```python +if sys.version_info < (3, 4): + + error = """ + IPython 7.0+ supports Python 3.4 and above. + When using Python 2.7, please install IPython 5.x LTS Long Term Support version. + Python 3.3 was supported up to IPython 6.x. + + See IPython `README.rst` file for more information: + + https://github.com/ipython/ipython/blob/master/README.rst + + Python {py} detected. + + Try upgrading pip and retry. + """.format(py='.'.join([str(v) for v in sys.version_info[:3]])) + + print(error, file=sys.stderr) + sys.exit(1) +``` + +You can look at the [full +check](https://github.com/ipython/ipython/blob/6a3e2db0c299dc05e636653c4a43d0aa756fb1c8/setup.py#L23-L58) +that attempt to detect which version of pip is in used. + +## If your users absolutely need Py2.7 but you want to move on + +If you have users that still depend on Python 2.7 and you cannot drop support yet, +it may nonetheless be possible to start using Python 3 in your codebase. +Through automatic conversion using [lib3to6](https://pypi.org/project/lib3to6/) +(similar to Babel for JavaScript) +you can generate distribution files that will work on both Python 2 and Python 3. +Lib3to6 is also useful if your project needs to support older versions of Python 3 +such as 3.5 but you want to use the latest Python syntax. + +## Upload with Twine + +You _must_ upload your package with ``twine`` and NOT with ``setup.py upload``. +If you have an old version of setuptools or ``distutils``, even if +``python_requires`` is set, metadata may not be uploaded correctly. See [This +issue](https://github.com/pypa/warehouse/issues/3889) on PyPI repository + +## Fix dependant libraries + +If you control dependant packages, Make sure to include conditional dependencies +depending on the version of Python. + +# Non-recommended mitigations + +This is a collection of "mitigation" or "solutions" you will find on the web +and that you will hear about. This is an attempt to acknowledge them, and +explain why they can't work and what are their drawbacks before you attempt to +implement them. + +### Don't use a meta-package + +It is possible to release a meta-package that has _virtually_ no code and relies +on a conditional dependency to install its actual core code on the user system. +For example, Frob-6.0 could be a meta-package which depends on +Frob-real-py2 on Python < 3.0, and Frob-real-py3 on Python ≥ 3.4. While +this approach is _doable_ this can make imports confusing. + +## Don't depend on setuptools (unless version >=24.3) + +You can mark your library as dependent on setuptools greater than 24.3 as this +will ensure that during the next upgrade (when the packages drop python 2 +support) will have the right version of setuptools. + +Of course regardless of all the care you will take for your library to not break +and to install only on python 2, you will likely have cases where it will still +end up being installed on incompatible versions of Python. Simply because users +upgrade rarely and only an old version of pip or setuptools is enough to make +the update process broken. + +Plus setuptools is rarely an actual dependency of your project but a +requirement to build wheels. + +### Don't write multiple sdist files + +Pip (used to) support a "feature" where a sdist ending in `-pyX.Y.tar.gz` would +only be seen as compatible on Python X.Y, thus it used to be possible to +publish multiple sdist of a package targeting various python version. + +It is not possible anymore to upload multiple sdist files on PyPI, so this +solution is no longer tenable. + +### Don't release wheel only + +Releasing a package only using wheels for a given python version is doable, but +this will break downstream packages that may require the original source to +reproduce their build. + +# Why all *this*?!? + +You might wonder why all this, it's 2020 already, so how come this is still an +issue? Python 3 has been out for 11+ years now! + +Well there are many reasons for this. First of all, this issue mostly affects +libraries that are currently python 2 and Python 3 compatible at the same time. +Many libraries have transitioned from Python 2-only to Python 2 + 3. And the +issue of transitioning to Python 3 only is relatively recent. Technically it +can also apply to libraries that are only stopping support for 2.6, or are even +already Python 3 only, but are starting to stop supporting earlier versions of +Python (for example a library releasing a Python 3.4+ only version). + +Python 3.3 was released at the end of 2012, and was the first version to +support (again) `u` as a prefix for Unicode string. It was one of the first +minor versions of Python 3 that saw a majority of single-source projects working +both on Python 2 and Python 3. These are the projects that will likely be +affected by this issue. + +The introduction of Python 3 was chaotic; there were strong arguments in both +the Python 2 and Python 3 camps. Regardless of what side you take, the ones suffering +the most from this are users (starting with the fact that some libraries +have stopped supporting for Python 2 and released Python 3 only versions). Inevitably, some +systems and people will not be upgraded to Python 3, so this document hopefully +helps to _ensure_ that users get the _least_ breakage as possible and what are the best +practices are to follow. diff --git a/_sections/10-archive.md b/_sections/10-archive.md new file mode 100644 index 0000000..f6fe0b1 --- /dev/null +++ b/_sections/10-archive.md @@ -0,0 +1,33 @@ +--- +title: archive +bg: 'white' +--- + +# History + +This page is now an archive of part of the transition from Python 2 to 3. + +By around 2015, when Python 2 support was originally planned to end, many +important Python libraries and tools supported Python 3. But Python 2 still had +a lot of users, and projects needed to support both major versions. The end of +Python 2 support was postponed to 2020, and some people argued that development +of Python 2 should resume. It seemed like a real possibility that the end date +would be postponed again, and we'd need to support two versions of the language +indefinitely. + +The Python 3 statement was drawn up around 2016. Projects pledged to require +Python 3 by 2020, giving other projects confidence that they could plan a similar +transition, and allowing downstream users to figure out their options without a +nasty surprise. We didn't force people to move to Python 3, but if they wanted +to stick with Python 2, they would stop getting new versions of our projects. +The focus was originally on the scientific Python ecosystem, with Jupyter and +matplotlib among the first projects involved, but in late 2017 it was expanded +to any Python projects. +A rapidly growing number of projects signed up as we approached 2020. + +The long-term transition we hoped for has succeeded: in 2024 it is entirely +normal for projects to support only Python 3, simplifying maintainers' lives +and letting us take full advantage of newer language features. + +Thank-you to all of the people, in projects big and small, who contributed +their support to the statement! diff --git a/_sections/20-statement.md b/_sections/20-statement.md index 1dcbbf3..d40c439 100644 --- a/_sections/20-statement.md +++ b/_sections/20-statement.md @@ -6,38 +6,35 @@ color: white # Moving to require Python 3 -All of the major projects making up the Scientific Python stack now support +Almost all major open source Python packages now support both Python 3.x and Python 2.7, and many projects have been supporting these two versions of the language for several years. While we have developed tools and techniques to maintain compatibility efficiently, it is a small but constant friction in the development of a lot of code. -We are keen to use Python 3 to its full potential, and we currently accept the -cost of writing cross-compatible code to allow a smooth transition, but we -don’t intend to maintain this compatibility indefinitely. Although the -transition has not been as quick as we hoped, we do see it taking place, with +We are keen to use Python 3 to its full potential, and though +we accepted the cost of writing cross-compatible +code to allow a smooth transition, we +did not intend to maintain this compatibility indefinitely. Although the +transition was not as quick as we hoped, it is taking place, with more and more people using, teaching and recommending Python 3. The developers of the Python language extended support of Python 2.7 from 2015 -to 2020, recognising that many people were still using Python 2. We believe -that the extra 5 years is sufficient to transition off of Python 2, and our -projects plan to stop supporting Python 2 when upstream support ends in 2020, -if not before. We will then be able to simplify our code and take advantage of +to January 1, 2020, recognising that many people were still using Python 2. We believe +that the extra 5 years was sufficient to transition off of Python 2, and +now that upstream support has ended, our +projects have stopped supporting Python 2 or will do so before the end of 2020. +We will thus be able to simplify our code and take advantage of the many new features in the current version of the Python language and standard library. -In addition, significantly before 2020, some of our projects will step down -Python 2.7 support to only fixing bugs, and make new feature releases which -require Python 3. This too parallels support for the language itself, as Python -2.7 releases only include bugfixes and security improvements. - Third parties may offer paid support for our projects on old Python versions for longer than we support them ourselves. We won’t obstruct this, and it is a core principle of free and open source software that this is possible. However, -if you enjoy the free, first party support for many projects in the Scientific -Python stack, please start planning to move to Python 3. +if you enjoy the free, first party support for many projects including the Scientific +Python stack, please move to Python 3. For all of these reasons, the following projects have pledged to **drop support -for Python 2.7 no later than 2020**, coinciding with the Python development -team's [timeline for dropping support for Python -2.7](https://www.python.org/dev/peps/pep-0373/#update). +for Python 2.7 no later than 2020**, following the [end of support for Python +2.7 itself](https://www.python.org/dev/peps/pep-0373/#update) at the start of +the year. diff --git a/_sections/30-projects.md b/_sections/30-projects.md index 1ee733f..640e417 100644 --- a/_sections/30-projects.md +++ b/_sections/30-projects.md @@ -10,28 +10,154 @@ style: center These projects pledge to drop Python 2 support in or before 2020. -- [![](assets/ipython.png)IPython](https://ipython.org) -- [![](assets/jupyter.png)Jupyter notebook](https://jupyter.org) -- [![](assets/pandas.png)pandas](http://pandas.pydata.org/) -- [![](assets/matplotlib.png)Matplotlib](http://matplotlib.org/) -- [![](assets/sympy.png)SymPy](http://www.sympy.org/) -- [![](assets/astropy.png)Astropy](http://www.astropy.org/) -- [![](assets/swcarpentry.png)Software Carpentry](https://software-carpentry.org) -- [![](assets/sunpy.png)SunPy](http://sunpy.org) -- [![](assets/xonsh.png)xonsh](http://xon.sh) -- [![](assets/skbio.png)scikit-bio](http://scikit-bio.org) -- [![](assets/pystan.png)PyStan](https://github.com/stan-dev/pystan) -- [![](assets/axelrod.png)Axelrod](https://github.com/Axelrod-Python/Axelrod) -- [![](assets/osbrain.png)osBrain](https://github.com/opensistemas-hub/osbrain) -- [![](assets/pymeasure.png)PyMeasure](https://github.com/ralph-group/pymeasure) -- [![](assets/rpy2_logo_64x64.png)rpy2](https://rpy2.bitbucket.io) + + +- [![](assets/tensorflow.png)TensorFlow](https://www.tensorflow.org/) +- [![](assets/scikit-learn.png)scikit-learn](https://scikit-learn.org/) +- [![](assets/pytorch.png)PyTorch](https://pytorch.org/) +- [![](assets/apache_spark.png)Apache Spark](https://spark.apache.org/) +- [![](assets/pandas.png)pandas](https://pandas.pydata.org/) +- [![](assets/tornado.png)Tornado](http://www.tornadoweb.org/) +- [![](assets/mxnet.png)Apache MXNet (Incubating)](http://mxnet.apache.org/) +- [![](assets/xgboost.png)XGBoost](https://xgboost.ai/) +- [![](assets/mitmproxy.png)mitmproxy](https://mitmproxy.org/) +- [![](assets/ipython.png)IPython](https://ipython.org) +- [![](assets/ccxt.png)ccxt](https://github.com/ccxt/ccxt) +- [![](assets/numpylogoicon.png)NumPy](https://www.numpy.org/) +- [![](assets/saltstack.png)SaltStack](https://github.com/saltstack/salt) +- [![](assets/zulip.png)Zulip](https://zulip.org) +- [![](assets/bokeh.png)Bokeh](https://github.com/bokeh/bokeh) +- [![](assets/matplotlib.png)Matplotlib](https://matplotlib.org/) +- [![](assets/kivy.png)Kivy](https://kivy.org/) +- [![](assets/pelican.png)Pelican](https://getpelican.com/) +- [![](assets/pillow.png)Pillow](https://github.com/python-pillow/Pillow) +- [![](assets/pyinstaller.png)PyInstaller](https://github.com/pyinstaller/pyinstaller) +- [![](assets/scipyshiny_small.png)SciPy](https://www.scipy.org/) +- [![](assets/sympy.png)SymPy](https://www.sympy.org/) +- [![](assets/jupyter.png)Jupyter notebook](https://jupyter.org) +- [![](assets/dask.svg)Dask](https://www.dask.org) +- [![](assets/spyder.png)Spyder](https://www.spyder-ide.org) +- [![](assets/pytest1.png)pytest](https://docs.pytest.org/en/latest) +- [![](assets/tensorpack.png)Tensorpack](https://github.com/tensorpack/tensorpack) +- [![](assets/statsmodels.svg)statsmodels](https://www.statsmodels.org/stable) +- [![](assets/pymc3.png)PyMC3](https://github.com/pymc-devs/pymc3) +- [![](https://cython.org/logo/cython-logo-C.svg)Cython](https://cython.org/) +- [![](assets/marshmallow.png)marshmallow](https://github.com/marshmallow-code/marshmallow) +- [![](assets/hypothesis.png)Hypothesis](https://hypothesis.readthedocs.io/) +- [![](assets/apache_beam.png)Apache Beam](https://beam.apache.org/) +- [![](assets/xonsh.png)xonsh](http://xon.sh) +- [![](assets/scikit-image.png)Scikit Image](http://scikit-image.org/) +- [![](assets/sphinx-doc.png)Sphinx](https://www.sphinx-doc.org/) +- [![](assets/geopy.png)geopy](https://geopy.readthedocs.io/) +- [![](https://nnabla.org/logos/logo3.png)Neural Network Libraries](https://nnabla.org/) +- [![](assets/misp.png)MISP](https://github.com/MISP/MISP) +- [![](assets/astropy.png)Astropy](https://www.astropy.org/) +- [![](assets/biopython.png)Biopython](https://biopython.org/) +- [![](assets/fonttools.png)FontTools](https://github.com/fonttools/fonttools) +- [![](assets/nikola.png)Nikola](https://getnikola.com) +- [![](assets/xarray.png)xarray](https://xarray.pydata.org/) +- [![](assets/gluonnlp.png)GluonNLP](https://gluon-nlp.mxnet.io/) +- [![](assets/libcloud.png)Apache Libcloud](https://libcloud.apache.org/) +- [![](assets/weblate.png)Weblate](https://weblate.org/) +- [![](assets/pythran.png)Pythran](https://github.com/serge-sans-paille/pythran) +- [![](assets/dateutil.png)dateutil](https://github.com/dateutil/dateutil) +- [![](https://cherrypy.dev/images/cherrypy.png)CherryPy](https://cherrypy.dev) +- [![](assets/tryton.png)Tryton](https://www.tryton.org/) +- [![](assets/mne.png)MNE](https://www.martinos.org/mne/stable/index.html) +- [![](assets/art_logo.png)Adversarial Robustness Toolbox](https://github.com/IBM/adversarial-robustness-toolbox) +- [![](assets/tikzplotlib.png)tikzplotlib](https://github.com/nschloe/tikzplotlib) +- [![](assets/stumpy_logo_small.png)stumpy](https://github.com/TDAmeritrade/stumpy) +- [![](assets/pydicom.png)pydicom](https://github.com/pydicom/pydicom) +- [![](assets/pystan.png)PyStan](https://github.com/stan-dev/pystan) +- [![](assets/rdkit.png)RDKit](https://github.com/rdkit/rdkit) +- [![](assets/swcarpentry.png)Software Carpentry](https://software-carpentry.org) +- [![](assets/adb_enhanced.png)ADB-Enhanced](https://github.com/ashishb/adb-enhanced) +- [![](assets/cartopy.png)Cartopy](https://scitools.org.uk/cartopy/docs/latest/) +- [![](assets/fecon235.png)fecon235](https://github.com/rsvp/fecon235) +- [![](assets/skbio.png)scikit-bio](http://scikit-bio.org) +- [![](assets/metpy.png)MetPy](https://unidata.github.io/MetPy) +- [![](assets/bottleneck.png)Bottleneck](https://bottleneck.readthedocs.io/) +- [![](assets/sunpy.png)SunPy](https://sunpy.org/) +- [![](assets/nengo.png)Nengo](https://www.nengo.ai/) +- [![](assets/axelrod.png)Axelrod](https://github.com/Axelrod-Python/Axelrod) +- [![](assets/rpy2_logo_64x64.png)rpy2](https://rpy2.bitbucket.io) +- [![](assets/toyplot-256x256.png)Toyplot](https://github.com/sandialabs/toyplot) +- [![](assets/psi4square.png)Psi4](http://psicode.org/) +- [![](assets/pylast.png)pyLast](https://github.com/pylast/pylast) +- [![](assets/iris.png)iris](https://scitools.org.uk/iris/docs/latest/) +- [![](assets/esmvaltool.png)ESMValTool](https://esmvaltool.readthedocs.io/en/latest/) +- [![](assets/meshio.png)meshio](https://github.com/nschloe/meshio/) +- [![](assets/perfplot.png)perfplot](https://github.com/nschloe/perfplot/) +- [![](assets/cmd2.png)cmd2](https://github.com/python-cmd2/cmd2) +- [![](assets/yt.png)yt](https://yt-project.org/) +- [![](assets/quadpy.png)quadpy](https://github.com/nschloe/quadpy/) +- [![](assets/pyscipopt.png)PySCIPOpt](https://github.com/SCIP-Interfaces/PySCIPOpt) +- [![](assets/betterbib.png)betterbib](https://github.com/nschloe/betterbib) +- [![](assets/openquake.png)OpenQuake engine](https://github.com/gem/oq-engine) +- [![](assets/pymeasure.png)PyMeasure](https://github.com/ralph-group/pymeasure) +- [![](https://urduhack.readthedocs.io/en/stable/_static/urduhack.png)Urduhack](https://github.com/urduhack/urduhack) +- [![](assets/osbrain.png)osBrain](https://github.com/opensistemas-hub/osbrain) +- [![](assets/cylc.png)Cylc Workflow](https://cylc.github.io/) +- [![](assets/fenics.png)FEniCS](https://fenicsproject.org/) +- [![](assets/gssapi.png)GSSAPI](https://github.com/pythongssapi/) +- [![](assets/colorio.png)colorio](https://github.com/nschloe/colorio) +- [![](assets/tatsu.png)TatSu](https://tatsu.readthedocs.io/) +- [![](assets/chaquopy.png)Chaquopy](https://chaquo.com/chaquopy/) +- [![](assets/angr.png)angr](http://angr.io/) +- [![](assets/biobuilds.png)BioBuilds](https://www.biobuilds.org/) +- [![](assets/orthopy.png)orthopy](https://github.com/nschloe/orthopy) +- [![](assets/freud.png)freud](https://github.com/glotzerlab/freud) +- [![](assets/signac.png)signac](https://signac.io) +- [![](assets/manticore.png)Manticore](https://github.com/trailofbits/manticore) +- [![](assets/platon.png)PLATON](https://github.com/ideasrule/platon) +- [![](https://raw.githubusercontent.com/GeoStat-Framework/GSTools/master/docs/source/pics/gstools.png)GSTools](https://github.com/GeoStat-Framework/GSTools) +- [![](assets/cantor.png)Cantor](https://cantor.kde.org) +- [![](assets/docraptor.svg)DocRaptor](https://docraptor.com) +- [![](assets/cmp.png)Connectome Mapper 3](https://connectome-mapper-3.readthedocs.io) +- [![](assets/lib3to6.png)lib3to6](https://github.com/mbarkhau/lib3to6) + +   -- [An Introduction to Applied Bioinformatics](http://readiab.org) +- [NetworkX](https://github.com/networkx/networkx) +- [folium](https://github.com/python-visualization/folium) +- [PyQt5](https://www.riverbankcomputing.com/software/pyqt/download5) +- [better-exceptions](https://github.com/qix-/better-exceptions) +- [umap-learn](https://github.com/lmcinnes/umap) +- [hdbscan](https://github.com/scikit-learn-contrib/hdbscan) +- [h5py](https://github.com/h5py/h5py/) +- [python-gitlab](https://github.com/python-gitlab/python-gitlab) +- [python-chess](https://github.com/niklasf/python-chess) +- [awslimitchecker](https://github.com/jantman/awslimitchecker) +- [Altair](https://github.com/ellisonbg/altair) - [music21](http://web.mit.edu/music21/) +- [imageio](https://imageio.github.io) +- [An Introduction to Applied Bioinformatics](http://readiab.org) +- [pyfakefs](https://github.com/jmcgeheeiv/pyfakefs) +- [pvlib-python](https://github.com/pvlib/pvlib-python) - [QIIME](http://qiime.org) -- [Altair](https://github.com/ellisonbg/altair) +- [Py-ART](https://arm-doe.github.io/pyart/) +- [SPADE](https://github.com/javipalanca/spade) +- [Plyara](https://plyara.readthedocs.io/en/latest/) - [gala](https://gala.readthedocs.io) -- [cual-id](https://github.com/johnchase/cual-id) -- [CIS](https://github.com/cedadev/cis) +- [stomp.py](https://github.com/jasonrbriggs/stomp.py) +- [CIS](https://github.com/cedadev/cis) +- [cual-id](https://github.com/johnchase/cual-id) +- [tinytext](https://github.com/hugovk/tinytext) +- [fino](https://github.com/hugovk/fino) +- [OSMViz](https://github.com/hugovk/osmviz) +- [MambuPy](https://github.com/jstitch/MambuPy) +- [Pyramid](https://trypyramid.com) +- [eml_parser](https://github.com/GOVCERT-LU/eml_parser) +- [odin](https://github.com/python-odin/odin) +- [jenkinsflow](https://github.com/lhupfeldt/jenkinsflow) +- [multiconf](https://github.com/lhupfeldt/multiconf) +- [pyApp](https://github.com/timsavage/pyapp) +- [python-daemon](https://pagure.io/python-daemon/) + + diff --git a/_sections/50-why.md b/_sections/50-why.md index 86ccfc7..257e094 100644 --- a/_sections/50-why.md +++ b/_sections/50-why.md @@ -11,9 +11,11 @@ style: center Here are some resources on why Python 3 was created, and how and why to update code to use Python 3: -- [Why Python 3 exists](http://www.snarky.ca/why-python-3-exists) (Brett Cannon) +- [Why Python 3 exists](https://snarky.ca/why-python-3-exists/) (Brett Cannon) - [How to add Python 3 support to your code](https://docs.python.org/3/howto/pyporting.html) -- [Stop supporting Python 2.6 for free](http://www.curiousefficiency.org/posts/2015/04/stop-supporting-python26.html) (Nick Coghlan) -- [Why Python 4.0 won't be like Python 3.0](http://www.curiousefficiency.org/posts/2014/08/python-4000.html) (Nick Coghlan) +- [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) +- [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) +- [Stop supporting Python 2.6 for free](https://www.curiousefficiency.org/posts/2015/04/stop-supporting-python26/) (Alyssa Coghlan) +- [Why Python 4.0 won't be like Python 3.0](https://www.curiousefficiency.org/posts/2014/08/python-4000/) (Alyssa Coghlan) - [Python 3 for scientists](https://python-3-for-scientists.readthedocs.io/en/latest/) - [scikit-bio py3-only RFC](https://github.com/biocore/scikit-bio-rfcs/blob/master/accepted/002-py3-only.md) diff --git a/_sections/70-discuss.md b/_sections/70-discuss.md index 91e74a2..527fdec 100644 --- a/_sections/70-discuss.md +++ b/_sections/70-discuss.md @@ -8,8 +8,8 @@ style: center # Discuss -While the above statement is close to final form, it is still open for -discussion. Feel free to [open an +While the above statement has been signed by dozens of developers, +it is still open for discussion. Feel free to [open an issue](https://github.com/python3statement/python3statement.github.io/issues) on our GitHub repository or browse the open and closed ones. diff --git a/_sections/80-update-my-project.md b/_sections/80-update-my-project.md index b59e159..a4844b1 100644 --- a/_sections/80-update-my-project.md +++ b/_sections/80-update-my-project.md @@ -15,9 +15,10 @@ encountered both by developers and users during this process. We are thus collecting a list of things to be aware of for when transitioning that are less obvious. For example : as a developer, how to make sure that your package manager like pip does not upgrade your libraries to incompatible -versions on Python 2. Check [our -repository](https://github.com/python3statement/python3statement.github.io) for -more information. +versions on Python 2. See the [Practicality Page](/practicalities/) for +information and check [our +repository](https://github.com/python3statement/python3statement.github.io) to +contribute. diff --git a/assets/adb_enhanced.png b/assets/adb_enhanced.png new file mode 100644 index 0000000..7a6ddab Binary files /dev/null and b/assets/adb_enhanced.png differ diff --git a/assets/angr.png b/assets/angr.png new file mode 100644 index 0000000..be049aa Binary files /dev/null and b/assets/angr.png differ diff --git a/assets/apache_beam.png b/assets/apache_beam.png new file mode 100644 index 0000000..b349592 Binary files /dev/null and b/assets/apache_beam.png differ diff --git a/assets/apache_spark.png b/assets/apache_spark.png new file mode 100644 index 0000000..21bbfaa Binary files /dev/null and b/assets/apache_spark.png differ diff --git a/assets/art_logo.png b/assets/art_logo.png new file mode 100644 index 0000000..0b2ee0d Binary files /dev/null and b/assets/art_logo.png differ diff --git a/assets/astropy.png b/assets/astropy.png index 7154327..86f7a84 100644 Binary files a/assets/astropy.png and b/assets/astropy.png differ diff --git a/assets/axelrod.png b/assets/axelrod.png index a594ccb..add7886 100644 Binary files a/assets/axelrod.png and b/assets/axelrod.png differ diff --git a/assets/betterbib.png b/assets/betterbib.png new file mode 100644 index 0000000..415dc33 Binary files /dev/null and b/assets/betterbib.png differ diff --git a/assets/biobuilds.png b/assets/biobuilds.png new file mode 100644 index 0000000..2ba6481 Binary files /dev/null and b/assets/biobuilds.png differ diff --git a/assets/biopython.png b/assets/biopython.png new file mode 100644 index 0000000..23de7e1 Binary files /dev/null and b/assets/biopython.png differ diff --git a/assets/bokeh.png b/assets/bokeh.png new file mode 100644 index 0000000..79c2f6c Binary files /dev/null and b/assets/bokeh.png differ diff --git a/assets/bottleneck.png b/assets/bottleneck.png new file mode 100644 index 0000000..8dda6a7 Binary files /dev/null and b/assets/bottleneck.png differ diff --git a/assets/cantor.png b/assets/cantor.png new file mode 100644 index 0000000..ddbfc06 Binary files /dev/null and b/assets/cantor.png differ diff --git a/assets/cartopy.png b/assets/cartopy.png new file mode 100644 index 0000000..be19e48 Binary files /dev/null and b/assets/cartopy.png differ diff --git a/assets/ccxt.png b/assets/ccxt.png new file mode 100644 index 0000000..f3a27a0 Binary files /dev/null and b/assets/ccxt.png differ diff --git a/assets/chaquopy.png b/assets/chaquopy.png new file mode 100644 index 0000000..1a1b97a Binary files /dev/null and b/assets/chaquopy.png differ diff --git a/assets/cmd2.png b/assets/cmd2.png new file mode 100644 index 0000000..a9ca5a0 Binary files /dev/null and b/assets/cmd2.png differ diff --git a/assets/cmp.png b/assets/cmp.png new file mode 100644 index 0000000..a7cdb4b Binary files /dev/null and b/assets/cmp.png differ diff --git a/assets/colorio.png b/assets/colorio.png new file mode 100644 index 0000000..1aeddf1 Binary files /dev/null and b/assets/colorio.png differ diff --git a/assets/cylc.png b/assets/cylc.png new file mode 100644 index 0000000..57c10b6 Binary files /dev/null and b/assets/cylc.png differ diff --git a/assets/dask.svg b/assets/dask.svg new file mode 100644 index 0000000..8999ed4 --- /dev/null +++ b/assets/dask.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + Dask + + + + + diff --git a/assets/dateutil.png b/assets/dateutil.png new file mode 100644 index 0000000..9ef4c17 Binary files /dev/null and b/assets/dateutil.png differ diff --git a/assets/docraptor.svg b/assets/docraptor.svg new file mode 100644 index 0000000..2cdf6c9 --- /dev/null +++ b/assets/docraptor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/esmvaltool.png b/assets/esmvaltool.png new file mode 100644 index 0000000..a97d3b4 Binary files /dev/null and b/assets/esmvaltool.png differ diff --git a/assets/fecon235.png b/assets/fecon235.png new file mode 100644 index 0000000..56f91bc Binary files /dev/null and b/assets/fecon235.png differ diff --git a/assets/fenics.png b/assets/fenics.png new file mode 100644 index 0000000..2819733 Binary files /dev/null and b/assets/fenics.png differ diff --git a/assets/fonttools.png b/assets/fonttools.png new file mode 100644 index 0000000..9c83892 Binary files /dev/null and b/assets/fonttools.png differ diff --git a/assets/freud.png b/assets/freud.png new file mode 100644 index 0000000..c75dd33 Binary files /dev/null and b/assets/freud.png differ diff --git a/assets/geopy.png b/assets/geopy.png new file mode 100644 index 0000000..e79e425 Binary files /dev/null and b/assets/geopy.png differ diff --git a/assets/gluonnlp.png b/assets/gluonnlp.png new file mode 100644 index 0000000..d3e6dd1 Binary files /dev/null and b/assets/gluonnlp.png differ diff --git a/assets/gssapi.png b/assets/gssapi.png new file mode 100644 index 0000000..c818deb Binary files /dev/null and b/assets/gssapi.png differ diff --git a/assets/hypothesis.png b/assets/hypothesis.png new file mode 100644 index 0000000..d9d0ca7 Binary files /dev/null and b/assets/hypothesis.png differ diff --git a/assets/ipython.png b/assets/ipython.png index 2473054..7bb1d79 100644 Binary files a/assets/ipython.png and b/assets/ipython.png differ diff --git a/assets/iris.png b/assets/iris.png new file mode 100644 index 0000000..6d4460d Binary files /dev/null and b/assets/iris.png differ diff --git a/assets/jupyter.png b/assets/jupyter.png index 3446780..96856d6 100644 Binary files a/assets/jupyter.png and b/assets/jupyter.png differ diff --git a/assets/kivy.png b/assets/kivy.png new file mode 100644 index 0000000..5560906 Binary files /dev/null and b/assets/kivy.png differ diff --git a/assets/lib3to6.png b/assets/lib3to6.png new file mode 100644 index 0000000..1c555cc Binary files /dev/null and b/assets/lib3to6.png differ diff --git a/assets/libcloud.png b/assets/libcloud.png new file mode 100644 index 0000000..e8f3ab9 Binary files /dev/null and b/assets/libcloud.png differ diff --git a/assets/manticore.png b/assets/manticore.png new file mode 100644 index 0000000..8505e71 Binary files /dev/null and b/assets/manticore.png differ diff --git a/assets/marshmallow.png b/assets/marshmallow.png new file mode 100644 index 0000000..61edafc Binary files /dev/null and b/assets/marshmallow.png differ diff --git a/assets/matplotlib.png b/assets/matplotlib.png index 2704f25..c1870bc 100644 Binary files a/assets/matplotlib.png and b/assets/matplotlib.png differ diff --git a/assets/meshio.png b/assets/meshio.png new file mode 100644 index 0000000..c2e8b6c Binary files /dev/null and b/assets/meshio.png differ diff --git a/assets/metpy.png b/assets/metpy.png new file mode 100644 index 0000000..7a0ef4d Binary files /dev/null and b/assets/metpy.png differ diff --git a/assets/misp.png b/assets/misp.png new file mode 100644 index 0000000..9b781f8 Binary files /dev/null and b/assets/misp.png differ diff --git a/assets/mitmproxy.png b/assets/mitmproxy.png new file mode 100644 index 0000000..479aacd Binary files /dev/null and b/assets/mitmproxy.png differ diff --git a/assets/mne.png b/assets/mne.png new file mode 100644 index 0000000..4e5a740 Binary files /dev/null and b/assets/mne.png differ diff --git a/assets/mxnet.png b/assets/mxnet.png new file mode 100644 index 0000000..27ff67b Binary files /dev/null and b/assets/mxnet.png differ diff --git a/assets/nengo.png b/assets/nengo.png new file mode 100644 index 0000000..cb2b43f Binary files /dev/null and b/assets/nengo.png differ diff --git a/assets/nikola.png b/assets/nikola.png new file mode 100644 index 0000000..af12d93 Binary files /dev/null and b/assets/nikola.png differ diff --git a/assets/numpylogoicon.png b/assets/numpylogoicon.png new file mode 100644 index 0000000..90be79b Binary files /dev/null and b/assets/numpylogoicon.png differ diff --git a/assets/openquake.png b/assets/openquake.png new file mode 100644 index 0000000..cf8baae Binary files /dev/null and b/assets/openquake.png differ diff --git a/assets/orthopy.png b/assets/orthopy.png new file mode 100644 index 0000000..964f0d8 Binary files /dev/null and b/assets/orthopy.png differ diff --git a/assets/osbrain.png b/assets/osbrain.png index fa3e07e..97bdb3b 100644 Binary files a/assets/osbrain.png and b/assets/osbrain.png differ diff --git a/assets/pandas.png b/assets/pandas.png index cb3898a..67ee682 100644 Binary files a/assets/pandas.png and b/assets/pandas.png differ diff --git a/assets/pelican.png b/assets/pelican.png new file mode 100644 index 0000000..06b7a87 Binary files /dev/null and b/assets/pelican.png differ diff --git a/assets/perfplot.png b/assets/perfplot.png new file mode 100644 index 0000000..b83fc04 Binary files /dev/null and b/assets/perfplot.png differ diff --git a/assets/pillow.png b/assets/pillow.png new file mode 100644 index 0000000..0fa6c54 Binary files /dev/null and b/assets/pillow.png differ diff --git a/assets/platon.png b/assets/platon.png new file mode 100644 index 0000000..ec9387a Binary files /dev/null and b/assets/platon.png differ diff --git a/assets/psi4square.png b/assets/psi4square.png new file mode 100644 index 0000000..58f5454 Binary files /dev/null and b/assets/psi4square.png differ diff --git a/assets/pydicom.png b/assets/pydicom.png new file mode 100644 index 0000000..91fe921 Binary files /dev/null and b/assets/pydicom.png differ diff --git a/assets/pyinstaller.png b/assets/pyinstaller.png new file mode 100644 index 0000000..f35e608 Binary files /dev/null and b/assets/pyinstaller.png differ diff --git a/assets/pylast.png b/assets/pylast.png new file mode 100644 index 0000000..921d230 Binary files /dev/null and b/assets/pylast.png differ diff --git a/assets/pymc3.png b/assets/pymc3.png new file mode 100644 index 0000000..67411c5 Binary files /dev/null and b/assets/pymc3.png differ diff --git a/assets/pymeasure.png b/assets/pymeasure.png index 92a9618..3ee2823 100644 Binary files a/assets/pymeasure.png and b/assets/pymeasure.png differ diff --git a/assets/pyscipopt.png b/assets/pyscipopt.png new file mode 100644 index 0000000..c5c09e9 Binary files /dev/null and b/assets/pyscipopt.png differ diff --git a/assets/pystan.png b/assets/pystan.png index c5310a0..47df03b 100644 Binary files a/assets/pystan.png and b/assets/pystan.png differ diff --git a/assets/pytest1.png b/assets/pytest1.png new file mode 100644 index 0000000..2a875f2 Binary files /dev/null and b/assets/pytest1.png differ diff --git a/assets/pythran.png b/assets/pythran.png new file mode 100644 index 0000000..701109a Binary files /dev/null and b/assets/pythran.png differ diff --git a/assets/pytorch.png b/assets/pytorch.png new file mode 100644 index 0000000..f994c0d Binary files /dev/null and b/assets/pytorch.png differ diff --git a/assets/quadpy.png b/assets/quadpy.png new file mode 100644 index 0000000..5518198 Binary files /dev/null and b/assets/quadpy.png differ diff --git a/assets/rdkit.png b/assets/rdkit.png new file mode 100644 index 0000000..efa4708 Binary files /dev/null and b/assets/rdkit.png differ diff --git a/assets/requests.png b/assets/requests.png new file mode 100644 index 0000000..70d83dd Binary files /dev/null and b/assets/requests.png differ diff --git a/assets/rpy2_logo_64x64.png b/assets/rpy2_logo_64x64.png index cd13ae5..91ad272 100644 Binary files a/assets/rpy2_logo_64x64.png and b/assets/rpy2_logo_64x64.png differ diff --git a/assets/saltstack.png b/assets/saltstack.png new file mode 100644 index 0000000..17e0ae8 Binary files /dev/null and b/assets/saltstack.png differ diff --git a/assets/scikit-image.png b/assets/scikit-image.png new file mode 100644 index 0000000..a9245ed Binary files /dev/null and b/assets/scikit-image.png differ diff --git a/assets/scikit-learn.png b/assets/scikit-learn.png new file mode 100644 index 0000000..cba0638 Binary files /dev/null and b/assets/scikit-learn.png differ diff --git a/assets/scipyshiny_small.png b/assets/scipyshiny_small.png new file mode 100644 index 0000000..d0e7098 Binary files /dev/null and b/assets/scipyshiny_small.png differ diff --git a/assets/signac.png b/assets/signac.png new file mode 100644 index 0000000..c4c3eb4 Binary files /dev/null and b/assets/signac.png differ diff --git a/assets/skbio.png b/assets/skbio.png index dbc475d..8eaf616 100644 Binary files a/assets/skbio.png and b/assets/skbio.png differ diff --git a/assets/sphinx-doc.png b/assets/sphinx-doc.png new file mode 100644 index 0000000..6256d8d Binary files /dev/null and b/assets/sphinx-doc.png differ diff --git a/assets/spyder.png b/assets/spyder.png new file mode 100644 index 0000000..fea385d Binary files /dev/null and b/assets/spyder.png differ diff --git a/assets/statsmodels.svg b/assets/statsmodels.svg new file mode 100644 index 0000000..a103da8 --- /dev/null +++ b/assets/statsmodels.svg @@ -0,0 +1,105 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/assets/stumpy_logo_small.png b/assets/stumpy_logo_small.png new file mode 100644 index 0000000..3a221c9 Binary files /dev/null and b/assets/stumpy_logo_small.png differ diff --git a/assets/sunpy.png b/assets/sunpy.png index f39a552..2ff1859 100644 Binary files a/assets/sunpy.png and b/assets/sunpy.png differ diff --git a/assets/swcarpentry.png b/assets/swcarpentry.png index 3d648f6..a9f3221 100644 Binary files a/assets/swcarpentry.png and b/assets/swcarpentry.png differ diff --git a/assets/sympy.png b/assets/sympy.png index 732662f..b8c9bd6 100644 Binary files a/assets/sympy.png and b/assets/sympy.png differ diff --git a/assets/tatsu.png b/assets/tatsu.png new file mode 100644 index 0000000..df11182 Binary files /dev/null and b/assets/tatsu.png differ diff --git a/assets/tensorflow.png b/assets/tensorflow.png new file mode 100644 index 0000000..babf1f0 Binary files /dev/null and b/assets/tensorflow.png differ diff --git a/assets/tensorpack.png b/assets/tensorpack.png new file mode 100644 index 0000000..945f16d Binary files /dev/null and b/assets/tensorpack.png differ diff --git a/assets/tikzplotlib.png b/assets/tikzplotlib.png new file mode 100644 index 0000000..aa0edb5 Binary files /dev/null and b/assets/tikzplotlib.png differ diff --git a/assets/tornado.png b/assets/tornado.png new file mode 100644 index 0000000..55a205a Binary files /dev/null and b/assets/tornado.png differ diff --git a/assets/toyplot-256x256.png b/assets/toyplot-256x256.png new file mode 100644 index 0000000..dc57c35 Binary files /dev/null and b/assets/toyplot-256x256.png differ diff --git a/assets/tryton.png b/assets/tryton.png new file mode 100644 index 0000000..089f32f Binary files /dev/null and b/assets/tryton.png differ diff --git a/assets/weblate.png b/assets/weblate.png new file mode 100644 index 0000000..38b15da Binary files /dev/null and b/assets/weblate.png differ diff --git a/assets/xarray.png b/assets/xarray.png new file mode 100644 index 0000000..00a577a Binary files /dev/null and b/assets/xarray.png differ diff --git a/assets/xgboost.png b/assets/xgboost.png new file mode 100644 index 0000000..254b050 Binary files /dev/null and b/assets/xgboost.png differ diff --git a/assets/xonsh.png b/assets/xonsh.png index d8288d2..9349a53 100644 Binary files a/assets/xonsh.png and b/assets/xonsh.png differ diff --git a/assets/yt.png b/assets/yt.png new file mode 100644 index 0000000..c8874ba Binary files /dev/null and b/assets/yt.png differ diff --git a/assets/zulip.png b/assets/zulip.png new file mode 100644 index 0000000..e0c766c Binary files /dev/null and b/assets/zulip.png differ diff --git a/combo.css b/combo.css index 73421fb..0f9195a 100644 --- a/combo.css +++ b/combo.css @@ -17,6 +17,10 @@ div.vis-item.py2, p.py2 { } +p { + font-weight: 300; +} + p.py2:first-child, p.py3:first-child{ margin-top: 0px; margin-bottom: 5px; @@ -64,6 +68,7 @@ div.vis-item.vis-selected { margin: 10px; padding: 20px; font-size: 19px; + min-width: 105px; } diff --git a/img/bgnoise.png b/img/bgnoise.png index 2912433..fef22f5 100644 Binary files a/img/bgnoise.png and b/img/bgnoise.png differ diff --git a/practicalities/index.html b/practicalities/index.html new file mode 100644 index 0000000..f0e0dc1 --- /dev/null +++ b/practicalities/index.html @@ -0,0 +1,41 @@ +--- +--- + + + + + + {{ site.title }} + + + + + + + + {% if site.favicon %}{% endif %} + {% if site.touch_icon %}{% endif %} + + +
+ + + + + {% for page in site.practicalities %} + {% capture id %}{{ page.id | remove:'/' | downcase }}{% endcapture %} +
+ +
+ {{ page.content }} +
+
+ {% endfor %} +
+ + diff --git a/scripts/reorder.py b/scripts/reorder.py new file mode 100644 index 0000000..c4dc044 --- /dev/null +++ b/scripts/reorder.py @@ -0,0 +1,43 @@ +with open('_sections/30-projects.md') as f: + data = f.read() + + + +import re +import sys +import requests +import requests_cache + + +match = re.compile('sg:(\d+)') +def make_groups(lines): + # assume first line does not match + matching = True + groups = [] + loc = [] + for l in lines: + if (len(match.findall(l)) == 0) != matching: + matching = not matching + if loc: + groups.append((matching, loc)) + loc = [] + loc.append(l) + if loc: + groups.append((not matching, loc)) + return groups + + +with open('_sections/30-projects.md','w') as f: + + groups = make_groups(data.splitlines()) + for m,g in groups: + if m: + g = sorted(g, key=lambda s:int(match.findall(s)[0]), reverse=True) + for l in g: + f.write(l + '\n') + + + + + + diff --git a/scripts/restar.py b/scripts/restar.py new file mode 100644 index 0000000..b70af95 --- /dev/null +++ b/scripts/restar.py @@ -0,0 +1,56 @@ +with open('_sections/30-projects.md') as f: + data = f.read() + + + +import re +import sys +import requests +import requests_cache + +requests_cache.install_cache('cache') + +token = None +if len(sys.argv) == 2: + token = sys.argv[1] + + +headers = {} +if token: + headers = { + "Authorization": f"token {token}" + } + +match = re.compile('github.com/([a-zA-Z0-9-]+)/([0-9a-zA-Z-._]+)/?') + +with open('_sections/30-projects.md','w') as f: + + for line in data.splitlines(): + if not 'github' in line: + f.write(line+'\n') + continue + + m = match.findall(line) + if m: + print('.', end='') + sys.stdout.flush() + org,repo = m[-1] + url = f'https://api.github.com/repos/{org}/{repo}' + info = requests.get(url, headers=headers).json() + llll = line.split(' \n") + # continue + count = info.get('stargazers_count', None) + if count: + f.write(llll + f" \n") + else: + print('skip', m, info) + f.write(line+'\n') + else: + f.write(line+'\n') + + + diff --git a/scripts/squash-images.sh b/scripts/squash-images.sh new file mode 100755 index 0000000..83a800f --- /dev/null +++ b/scripts/squash-images.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -e + +# pip install pillow +if [ ! -z $1 ] +then + python3 scripts/thumbnail-images.py --file $1 +else + python3 scripts/thumbnail-images.py +fi + +# http://optipng.sourceforge.net/ +# On Mac: brew install optipng + +# Optimization levels: +# -o7 -zm1-9 <=> -zc1-9 -zm1-9 -zs0-3 -f0-5 (1080 trials) + +if [ ! -z $1 ] +then + pngcrush -ow -brute $1 + optipng -o7 -zm1-9 $1 +else + optipng -o7 -zm1-9 assets/*.png +fi diff --git a/scripts/thumbnail-images.py b/scripts/thumbnail-images.py new file mode 100644 index 0000000..dedd89a --- /dev/null +++ b/scripts/thumbnail-images.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +# encoding: utf-8 +""" +Thumbnail images to a maximum of 320px wide and 160px high +""" +import argparse +import glob + +from PIL import Image # pip install pillow + +max_size = 320, 160 + +parser = argparse.ArgumentParser( + description="Thumbnail images to a maximum size", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, +) +parser.add_argument("--file", default="assets/*.png", help="Input file specification") +args = parser.parse_args() + +for infile in glob.glob(args.file): + im = Image.open(infile) + if im.width <= max_size[0] and im.height <= max_size[1]: + continue + + size_before = im.size + im.thumbnail(max_size) + im.save(infile) + + print(f"Resized {infile} from {size_before} to {im.size}") diff --git a/site.js b/site.js index db67e26..7b3cb27 100644 --- a/site.js +++ b/site.js @@ -26,18 +26,18 @@ $.extend($.easing, navItems = this; //attatch click listeners - navItems.on('click', function(event){ - event.preventDefault(); + navItems.on('click', function(event){ + event.preventDefault(); var navID = $(this).attr("href").substring(1); disableScrollFn = true; activateNav(navID); populateDestinations(); //recalculate these! - $('html,body').animate({scrollTop: sections[navID] - settings.scrollToOffset}, + $('html,body').animate({scrollTop: sections[navID] - settings.scrollToOffset}, settings.scrollSpeed, "easeInOutExpo", function(){ disableScrollFn = false; } ); - }); + }); //populate lookup of clicable elements and destination sections populateDestinations(); //should also be run on browser resize, btw @@ -75,21 +75,21 @@ $(document).ready(function (){ $('nav li a').navScroller(); //section divider icon click gently scrolls to reveal the section - $(".sectiondivider").on('click', function(event) { - $('html,body').animate({scrollTop: $(event.target.parentNode).offset().top - 50}, 400, "linear"); - }); + $(".sectiondivider").on('click', function(event) { + $('html,body').animate({scrollTop: $(event.target.parentNode).offset().top - 50}, 400, "linear"); + }); //links going to other sections nicely scroll - $(".container a").each(function(){ + $(".container a").each(function(){ if ($(this).attr("href").charAt(0) == '#'){ $(this).on('click', function(event) { - event.preventDefault(); + event.preventDefault(); var target = $(event.target).closest("a"); var targetHight = $(target.attr("href")).offset().top - $('html,body').animate({scrollTop: targetHight - 170}, 800, "easeInOutExpo"); + $('html,body').animate({scrollTop: targetHight - 170}, 800, "easeInOutExpo"); }); } - }); + }); // DOM element where the Timeline will be attached var container = document.getElementById('visualization'); @@ -100,14 +100,19 @@ $(document).ready(function (){ // { content:'', start: , end: , py2:}, // ... // ] + // + // The placement of projects in the data does not matter. + // They will be sorted alphabetically + // var data = { 'CPython':[ {content:'Python 2.7', start: '2010-07-03', end: '2020-01-01', py2:true}, - // EOL for Python 3.3 - 3.6 not announced yet; project 5 years from initial release to follow CPython policy. {content:'Python 3.3', start: '2012-09-29', end: '2017-09-29'}, - {content:'Python 3.4', start: '2014-03-14', end: '2019-03-14'}, + {content:'Python 3.4', start: '2014-03-16', end: '2019-03-19'}, + // EOL for Python 3.5 - 3.7 not announced yet; project 5 years from initial release to follow CPython policy. {content:'Python 3.5', start: '2015-09-13', end: '2020-09-13'}, - {content:'Python 3.6 (scheduled)', start: '2016-12-16', end: '2021-12-16'}, + {content:'Python 3.6', start: '2016-12-23', end: '2021-12-23'}, + {content:'Python 3.7', start: '2018-06-27', end: '2023-06-27'}, ], 'IPython':[ {content: '1.x', start: '2013-08-08', end:'2014-03-31', py2:true}, @@ -115,9 +120,60 @@ $(document).ready(function (){ {content: '3.x', start: '2015-02-27', end:'2015-08-10', py2:true}, {content: '4.x', start: '2015-08-11', end:'2016-07-07', py2:true}, {content: 'IPython 5.x LTS', start: '2016-07-08', end:'2019-06-01', py2:true}, - {content: '6.x', start: '2017-01-01', end:'2018-01-01'}, - {content: '7.x', start: '2018-01-01', end:'2019-06-12'}, - {content: '8.x', start: '2019-06-12', end:'2020-06-01'}, + {content: '6.x', start: '2017-04-19', end:'2018-09-27'}, + {content: '7.x', start: '2018-09-27', end:'2019-12-12'}, + {content: '8.x', start: '2019-12-12', end:'2020-12-01'}, + ], + 'pandas':[ + {content: 'Python 2 & 3', start: '2011-10-10', end:'2018-12-31', py2:true}, + {content: 'Python 3 only', start: '2019-01-01', end:'2021-12-16'}, + ], + 'scikit-learn':[ + {content: 'Python 2 & 3', start: '2010-03-25', end:'2019-03-18', py2:true}, + {content: 'Python 3 only', start: '2019-03-19', end:'2023-12-31'}, + ], + 'XGBoost':[ + {content: 'Python 2 & 3', start: '2016-01-14', end:'2019-05-15', py2:true}, + {content: 'Python 3 only', start: '2019-05-15', end:'2023-12-31'}, + ], + 'ccxt':[ + {content: 'Python 2 & 3', start: '2017-05-14', end:'2019-12-31', py2:true}, + {content: 'Python 3 only', start: '2020-01-01', end:'2023-12-31'}, + ], + 'Numpy':[ + {content: 'Py 2 & 3 full', start: '2010-08-31', end:'2018-12-31', py2:true}, + {content: 'Py 2 bug fix', start: '2019-01-01', end:'2019-12-31', py2:true}, + {content: 'Py 3 full', start: '2019-01-01', end:'2021-12-16'}, + ], + 'Pillow':[ + {content: 'Python 2 & 3', start: '2013-03-15', end:'2019-12-31', py2:true}, + {content: 'Python 3 only', start: '2020-01-01', end:'2023-12-31'}, + ], + 'PyInstaller':[ + {content: 'Python 2.7', start: '2011-05-05', end:'2019-12-31', py2:true}, + {content: 'Python 3.3', start: '2015-10-04', end:'2018-09-09'}, + {content: 'Python 3.4', start: '2015-10-04', end:'2019-07-09'}, + // EOL for Python 3.5 - 3.7 not announced yet; project 5 years + // from initial release to follow CPython policy. + {content: 'Python 3.5', start: '2015-10-04', end:'2020-09-30'}, + {content: 'Python 3.6', start: '2017-09-21', end:'2021-12-31'}, + {content: 'Python 3.7', start: '2018-09-09', end:'2023-06-30'}, + ], + 'Scipy':[ + {content: 'Py 2 & 3 full', start: '2010-08-31', end:'2018-12-31', py2:true}, + {content: 'Py 2 bug fix', start: '2019-01-01', end:'2019-12-31', py2:true}, + {content: 'Py 3 full', start: '2019-01-01', end:'2021-12-16'}, + ], + 'Matplotlib':[ + {content: '2.2 LTS', start: '2018-03-05', end: '2020-01-10', py2:true}, + {content: '3.0', start: '2018-07-01', end: '2019-01-01'}, + {content: '3.1', start: '2019-01-01', end: '2019-07-01'}, + {content: '3.2', start: '2019-07-01', end: '2020-01-01'} + ], + 'Spyder':[ + {content: '3', start: '2016-09-24', end: '2019-01-15', py2:true}, + {content: '4', start: '2019-01-15', end: '2020-01-01', py2:true}, + {content: '5', start: '2019-12-31', end: '2021-12-16'} ], 'Xonsh':[ {content: '0.x series – Python 3.4+', start: '2015-03-09', end: '2021-12-16'}, @@ -131,10 +187,11 @@ $(document).ready(function (){ {content: '2.x+', start: '2016-07-11', end: '2021-12-16'}, ], 'SunPy':[ - {content: '0.7', start: '2016-05-24', end: '2017-06-01', py2:true}, - {content: '0.8', start: '2016-12-01', end: '2017-12-01', py2:true}, - {content: '0.9', start: '2017-06-01', end: '2018-06-01', py2:true}, - {content: '0.10', start: '2017-12-01', end: '2018-12-01'}, + {content: '0.7', start: '2016-05-24', end: '2017-08-07', py2:true}, + {content: '0.8', start: '2017-08-07', end: '2018-04-23', py2:true}, + {content: '0.9', start: '2018-04-23', end: '2020-01-01', py2:true}, + {content: '1.0', start: '2019-01-01', end: '2020-01-01'}, + {content: '1.1', start: '2020-01-01', end: '2020-06-01'}, ], 'Astropy':[ {content: '1.0 LTS', start: '2015-02-19', end: '2017-06-01', py2:true}, @@ -142,43 +199,194 @@ $(document).ready(function (){ {content: '1.2', start: '2016-06-23', end: '2016-12-16', py2:true}, {content: '1.3', start: '2016-12-16', end: '2017-06-01', py2:true}, {content: '2.0 LTS', start: '2017-06-01', end: '2019-12-31', py2:true}, - {content: '3.0', start: '2017-12-01', end: '2018-06-01'}, - {content: '3.1', start: '2018-06-01', end: '2018-12-01'}, - {content: '3.2', start: '2018-12-01', end: '2019-06-01'}, - {content: '3.3', start: '2019-06-01', end: '2019-12-01'}, - {content: '4.0 LTS', start: '2019-12-01', end: '2021-12-01'}, + {content: '3.0', start: '2018-02-19', end: '2018-11-30'}, + {content: '3.1', start: '2018-11-30', end: '2019-05-01'}, + {content: '3.2', start: '2019-05-01', end: '2019-11-30'}, + {content: '4.0 LTS', start: '2019-11-30', end: '2021-12-01'}, + ], + 'Sphinx':[ + {content: '0.1 - 1.0 (Py2)', start: '2008-03-22', end:'2011-10-09', py2:true}, + {content: '1.1 - 1.8 (Py2,Py3)', start: '2011-10-10', end:'2019-03-28', py2:true}, + {content: '2.0 - (Py3)', start: '2019-03-29', end:'2023-12-31'}, + ], + 'Apache Libcloud':[ + {content: 'Python 2 & 3', start: '2011-12-09', end:'2020-01-01', py2:true}, + {content: 'Python 3 only', start: '2020-01-01', end:'2023-12-31'}, + ], + 'geopy':[ + {content: '1.x', start: '2014-09-07', end:'2019-04-01', py2:true}, + {content: '2.x', start: '2019-04-01', end:'2023-12-31'}, + ], + 'Weblate':[ + {content: '0.1 - 2.4 (Py2)', start: '2008-03-22', end:'2016-03-10', py2:true}, + {content: '2.5 - 3.11 (Py2,Py3)', start: '2016-03-10', end:'2020-04-01', py2:true}, + {content: '4.0 - (Py3)', start: '2020-04-01', end:'2023-12-31'}, + ], + 'Tryton':[ + {content: '4.0', start: '2016-05-02', end: '2018-10-01', py2:true}, + {content: '4.2', start: '2016-11-28', end: '2019-05-01', py2:true}, + {content: '4.4', start: '2017-05-01', end: '2019-10-01', py2:true}, + {content: '4.6', start: '2017-10-30', end: '2020-05-01', py2:true}, + {content: '4.8', start: '2018-04-23', end: '2020-10-01', py2:true}, + {content: '5.0', start: '2018-10-01', end: '2023-10-01'}, + {content: '5.2', start: '2019-05-01', end: '2020-05-01'}, ], 'osBrain':[ {content: '0.x', start: '2016-07-01', end: '2021-12-16'}, ], 'PyMeasure':[ - {content: '0.2', start: '2015-12-16', end: '2016-04-08'}, - {content: '0.3', start: '2016-04-08', end: '2016-07-29'}, - {content: '0.4', start: '2016-07-29', end: '2016-12-16'}, + {content: '0.4', start: '2016-07-29', end: '2017-10-18'}, + {content: '0.5', start: '2017-10-18', end: '2019-01-14'}, + {content: '0.6', start: '2019-01-14', end: '2020-01-01'}, + ], + 'TatSu':[ + {content: 'Python 2 & 3', start: '2017-01-01', end:'2019-04-01', py2:true}, + {content: 'Python 2 & 3 fixes', start: '2019-04-01', end:'2020-01-01', py2:true}, + {content: 'Python 3 only', start: '2019-04-01', end:'2023-12-31'}, + ], + 'rpy2':[ + {content: '2.8.x', start: '2016-12-21', end:'2018-12-21', py2:true}, + {content: '2.9.x', start: '2017-07-14', end:'2018-07-14'}, + ], + 'FEniCS':[ + {content: '2017.1.0', start: '2017-05-12', end: '2017-12-31', py2:true}, + {content: '2018.1.0', start: '2018-01-01', end: '2018-06-01'} + ], + 'RDKit':[ + {content: '2014.9.1 - 2019.03.1', start: '2014-09-1', end: '2019-09-1', py2:true}, + {content: '2019.9.1 -' , start: '2019-09-01', end: '2021-03-01'} + ], + 'Toyplot':[ + {content: 'Python 2 & 3', start: '2014-11-05', end:'2018-12-31', py2:true}, + {content: 'Python 3 only', start: '2019-01-01', end:'2021-12-31'}, ], + 'music21':[ + {content: 'v3', start: '2016-08-22', end: '2017-08-06', py2:true}, + {content: 'v4', start: '2017-08-22', end: '2019-06-01', py2:true}, + {content: 'v5', start: '2018-03-17', end: '2019-08-01'}, + {content: 'v6', start: '2019-06-01', end: '2020-08-01'}, + ], + 'mitmproxy':[ + {content: '0.18.x', start: '2016-10-16', end: '2017-10-16', py2:true}, + {content: '1.0.x -', start: '2016-12-26', end: '2021-12-23'} + ], + 'SPADE':[ + {content: '2.0', start: '2010-08-01', end: '2012-11-09', py2:true}, + {content: '2.1', start: '2012-11-09', end: '2013-05-27', py2:true}, + {content: '2.2', start: '2013-05-27', end: '2017-06-09', py2:true}, + {content: '2.3', start: '2017-06-09', end: '2018-12-31', py2:true}, + {content: '3.x -', start: '2018-09-15', end: '2020-12-31', py2:false} + ], + 'dateutil': [ + {content: '2.x', start: '2011-12-01', end: '2018-09-01', py2:true}, + {content: '3.x', start: '2018-09-01', end: '2019-07-01', py2:true}, + {content: '4.x', start: '2019-01-01', end: '2020-07-01', py2:false}, + ], + 'CherryPy': [ + {content: '3.2-17.x', start: '2011-02-25', end: '2019-12-31', py2: true}, + {content: '18.x+', start: '2018-09-01', end: '2023-12-31', py2: false}, + ], + 'stomp.py':[ + {content: '3.x', start: '2010-04-01', end: '2013-09-30', py2:true}, + {content: '4.x', start: '2013-10-01', end: '2020-01-09', py2:true}, + {content: '5.x+', start: '2020-01-10', end: '2023-12-31', py2:false}, + ], + 'cmd2':[ + {content: '0.7.x', start: '2017-02-23', end: '2018-01-04', py2:true}, + {content: '0.8.x', start: '2018-02-01', end: '2018-08-31', py2:true}, + {content: '0.9.x', start: '2018-05-28', end: '2023-12-31', py2:false}, + ], + 'angr':[ + {content: '7.x', start: '2017-09-09', end: '2018-09-26', py2: true}, + {content: '8.x', start: '2018-09-28', end: '2023-12-31', py2: false}, + ], + 'FontTools':[ + {content: 'Py 2 & 3 full', start: '2014-09-24', end:'2018-12-31', py2:true}, + {content: 'Py 2 bug fix', start: '2019-01-01', end:'2019-06-30', py2:true}, + {content: 'Py 3 full', start: '2019-01-01', end:'2023-12-31'}, + ], + 'plyara':[ + {content: '2.x', start: '2019-02-01', end:'2020-01-01'}, + ], + 'marshmallow':[ + {content: '2.x', start: '2015-09-25', end:'2020-01-01', py2:true}, + {content: '3.x', start: '2019-05-05', end:'2023-12-31'}, + ], + 'eml_parser':[ + {content: '2.x', start: '2014-12-08', end:'2017-05-08', py2:true}, + {content: '3.x', start: '2014-12-08', end:'2023-12-31'}, + ], + 'pyapp': [ + {content: '0.1-3.x', start: '2017-01-28', end: '2020-01-01', py2:true}, + {content: '4.x', start: '2019-05-28', end: '2024-05-28', py2:false}, + ], + 'odin': [ + {content: '0.4-1.x', start: '2013-11-30', end: '2020-01-01', py2:true}, + {content: '2.x', start: '2019-11-30', end: '2024-11-30', py2:false}, + ], + 'Apache Spark': [ + {content: 'Python 2 & 3', start: '2015-07-15', end: '2020-04-01', py2:true}, + {content: 'Python 3 only', start: '2020-04-01', end: '2023-12-31'}, + ], + 'Iris': [ + {content: '1.x', start: '2015-12-10', end: '2018-02-14', py2:true}, + {content: '2.x', start: '2018-02-14', end: '2019-12-31', py2:true}, + {content: '3.x', start: '2019-11-05', end: '2023-12-31', py2:false}, + ], + 'ESMValTool': [ + {content: '2.x', start: '2017-09-14', end: '2019-03-07', py2:true}, + {content: '2.x', start: '2019-03-07', end: '2023-12-31', py2:false}, + ], + 'Dask': [ + {content: '1', start: '2014-12-21', end: '2019-07-01', py2:true}, + {content: '2', start: '2019-11-30', end: '2024-11-30', py2:false}, + ], + 'Cylc': [ + {content: 'cylc-3.0.x - cylc-7.8.x', start: '2011-05-26', end: '2020-06-30', py2:true}, + {content: '8-α', start: '2019-12-01', end: '2020-12-31', py2:false}, + {content: '8.x', start: '2020-06-30', end: '2021-12-31', py2:false}, + {content: '9.x', start: '2021-06-30', end: '2022-12-31', py2:false}, + ], + 'Neural Network Libraries': [ + { content:'Python 2 & 3', start: '2017-07-22', end: '2019-12-31', py2:true}, + { content:'Python 3 only', start: '2020-01-01', end: '2023-12-31', py2:false}, + ], + 'lib3to6': [ + { content:'Python 3 only', start: '2018-09-01', end: '2023-12-31', py2:false}, + ], + 'Connectome Mapper 3':[ + {content: 'v3.x beta series (Py2 only)', start: '2019-04-24', end:'2020-08-24', py2:true}, + {content: 'v3.x series (Py3 only)', start: '2020-08-24', end:'2023-12-31'}, + ] + // for tests, rando example //'matplotlib':[ // {content: 'matplotlib 2.x', start: '2015-06-01', end:'2018-06-01', py2:true}, - // {content: 'matplotlib 3.x', start: '2018-6-12', end:'2019-12-01'}, + // {content: 'matplotlib 3.x', start: '2018-06-12', end:'2019-12-01'}, //], //'scikit-bio':[ // {content: '0.18', start: '2016-05-01', end:'2016-11-01', py2:true}, // {content: '0.19', start: '2016-11-02', end:'2017-12-01'}, //] - } // Create a DataSet (allows two way data-binding) - var items = new vis.DataSet([ - ]); - + var items = new vis.DataSet([]); + // put the data in alphabetical order, except CPython at top. + var ordered = {}; + Object.keys(data).sort(function (a, b) { + if (a == 'CPython') return -1; + if (b == 'CPython') return 1; + return a.toLowerCase().localeCompare(b.toLowerCase()); + }).forEach(function(key) { ordered[key] = data[key] }); + data = ordered; var groups = new vis.DataSet(); var g=0; var i=0; - for (var gname in data) { + for (var gname in data) { g++; groups.add({id: g, content: gname}); gr = data[gname];