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/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/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 a1e0563..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"
diff --git a/_practicalities/intro.md b/_practicalities/intro.md
index 31e4281..a4c4cd5 100644
--- a/_practicalities/intro.md
+++ b/_practicalities/intro.md
@@ -11,7 +11,6 @@ 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.
@@ -29,10 +28,9 @@ least the main points -- should ease lots of the pain.
We gave a
[talk at PyCon 2017](https://www.youtube.com/watch?v=2DkfPzWWC2Q)
- ([slides](https://carreau.github.io/pycon2017/#/))
- , and at
- [pybay](https://www.youtube.com/watch?v=2DkfPzWWC2Q)
- ([slides](https://carreau.github.io/pycon2017/#/)).
+ ([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
@@ -60,7 +58,7 @@ upgrade.
## As a user
-### Install Pip 9.0
+### 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
@@ -130,7 +128,7 @@ version specifier.
[Warehouse](https://github.com/pypi/warehouse) and [Legacy
PyPI](https://github.com/pypa/legacy-pypi) have received various patches to
-insure they support this new functionality.
+ensure they support this new functionality.
# Preparing your library
@@ -173,7 +171,7 @@ 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
+# 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
@@ -183,7 +181,7 @@ install .` and `pip install -e .` for regular and developer installs, respectiv
Check in scripts and documentation that the correct installation command is
used.
-# Recommended Mitigations
+# Recommended mitigations
These are not mandatory but should make the transition seamless by warning your
users early enough _and_ providing useful error messages.
@@ -226,25 +224,25 @@ if sys.version_info < (3,):
raise ImportError(
"""You are running Frobulator 6.0 on Python 2
-Unfortunately Frobulator 6.0 and above are not compatible with Python 2
-anymore, and you still ended up with this version installed on your system.
-That's a bummer; sorry about that. It should not have happened. Make sure you
-have pip >= 9.0 to avoid this kind of issues, as well as setuptools >= 24.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
-You have various other choices
+Your choices:
-- install an older version of Frobulator:
+- Upgrade to Python 3.
- $ pip install 'frobulator<6.0'
+- Install an older version of Frobulator:
-- Upgrade your system to use Python 3.
+ $ 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:
+See the following URL for more up-to-date information:
https://i.am.an/url
@@ -274,7 +272,7 @@ The regular expression to check for validity of pep440 can be found below:
(\\.dev(0|[1-9]\\d*))?
-## fail early in setup.py
+## 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
@@ -285,6 +283,52 @@ Otherwise user code can fail at runtime arbitrarily later in the future, which c
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
@@ -297,7 +341,7 @@ 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.
-### Use a meta-package.
+### 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.
@@ -305,13 +349,13 @@ 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.
-## Depend on setuptools
+## 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 insure that during the next upgrade (when the packages drop python 2
+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 no break
+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
@@ -320,8 +364,7 @@ the update process broken.
Plus setuptools is rarely an actual dependency of your project but a
requirement to build wheels.
-
-### Multiple sdist files
+### 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
@@ -330,16 +373,16 @@ 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.
-### Wheel only ?
+### 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* ?!?
+# Why all *this*?!?
-You might wonder why all this, it's 2018 already, so how come this is still an
-issue? Python 3 has been out for 9+ years now !
+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.
@@ -355,10 +398,10 @@ 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 are still strong arguments in both
+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 inevitably some libraries
-will stop supporting for Python 2 and release Python 3 only library). Inevitably, some
+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 662e636..d40c439 100644
--- a/_sections/20-statement.md
+++ b/_sections/20-statement.md
@@ -12,33 +12,29 @@ 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 January 1, 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
+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, many of our projects will step down
-Python 2.7 support to only fixing bugs, and require Python 3 for all new
-feature releases. Some projects have already made this transition.
-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 including the Scientific
-Python stack, please start planning to move to Python 3.
+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 c3c0af9..640e417 100644
--- a/_sections/30-projects.md
+++ b/_sections/30-projects.md
@@ -10,49 +10,153 @@ style: center
These projects pledge to drop Python 2 support in or before 2020.
-- [pandas](http://pandas.pydata.org/)
-- [IPython](https://ipython.org)
-- [mitmproxy](https://mitmproxy.org/)
-- [Kivy](https://kivy.org/)
-- [Matplotlib](http://matplotlib.org/)
-- [NumPy](http://numpy.org)
-- [Zulip](https://zulip.org)
-- [SymPy](http://www.sympy.org/)
-- [Jupyter notebook](https://jupyter.org)
-- [PyMC3](https://github.com/pymc-devs/pymc3)
-- [xonsh](http://xon.sh)
-- [Astropy](http://www.astropy.org/)
-- [Biopython](http://biopython.org/)
-- [Pythran](https://github.com/serge-sans-paille/pythran)
-- [xarray](http://xarray.pydata.org/)
-- [PyStan](https://github.com/stan-dev/pystan)
-- [Software Carpentry](https://software-carpentry.org)
-- [scikit-bio](http://scikit-bio.org)
-- [SunPy](http://sunpy.org)
-- [Axelrod](https://github.com/Axelrod-Python/Axelrod)
-- [rpy2](https://rpy2.bitbucket.io)
-- [FEniCS](http://www.fenicsproject.org)
-- [RDKit](https://github.com/rdkit/rdkit)
-- [OpenQuake engine](https://github.com/gem/oq-engine)
-- [yt](http://yt-project.org)
-- [osBrain](https://github.com/opensistemas-hub/osbrain)
-- [PyMeasure](https://github.com/ralph-group/pymeasure)
-
-
+
+- [TensorFlow](https://www.tensorflow.org/)
+- [scikit-learn](https://scikit-learn.org/)
+- [PyTorch](https://pytorch.org/)
+- [Apache Spark](https://spark.apache.org/)
+- [pandas](https://pandas.pydata.org/)
+- [Tornado](http://www.tornadoweb.org/)
+- [Apache MXNet (Incubating)](http://mxnet.apache.org/)
+- [XGBoost](https://xgboost.ai/)
+- [mitmproxy](https://mitmproxy.org/)
+- [IPython](https://ipython.org)
+- [ccxt](https://github.com/ccxt/ccxt)
+- [NumPy](https://www.numpy.org/)
+- [SaltStack](https://github.com/saltstack/salt)
+- [Zulip](https://zulip.org)
+- [Bokeh](https://github.com/bokeh/bokeh)
+- [Matplotlib](https://matplotlib.org/)
+- [Kivy](https://kivy.org/)
+- [Pelican](https://getpelican.com/)
+- [Pillow](https://github.com/python-pillow/Pillow)
+- [PyInstaller](https://github.com/pyinstaller/pyinstaller)
+- [SciPy](https://www.scipy.org/)
+- [SymPy](https://www.sympy.org/)
+- [Jupyter notebook](https://jupyter.org)
+- [Dask](https://www.dask.org)
+- [Spyder](https://www.spyder-ide.org)
+- [pytest](https://docs.pytest.org/en/latest)
+- [Tensorpack](https://github.com/tensorpack/tensorpack)
+- [statsmodels](https://www.statsmodels.org/stable)
+- [PyMC3](https://github.com/pymc-devs/pymc3)
+- [Cython](https://cython.org/)
+- [marshmallow](https://github.com/marshmallow-code/marshmallow)
+- [Hypothesis](https://hypothesis.readthedocs.io/)
+- [Apache Beam](https://beam.apache.org/)
+- [xonsh](http://xon.sh)
+- [Scikit Image](http://scikit-image.org/)
+- [Sphinx](https://www.sphinx-doc.org/)
+- [geopy](https://geopy.readthedocs.io/)
+- [Neural Network Libraries](https://nnabla.org/)
+- [MISP](https://github.com/MISP/MISP)
+- [Astropy](https://www.astropy.org/)
+- [Biopython](https://biopython.org/)
+- [FontTools](https://github.com/fonttools/fonttools)
+- [Nikola](https://getnikola.com)
+- [xarray](https://xarray.pydata.org/)
+- [GluonNLP](https://gluon-nlp.mxnet.io/)
+- [Apache Libcloud](https://libcloud.apache.org/)
+- [Weblate](https://weblate.org/)
+- [Pythran](https://github.com/serge-sans-paille/pythran)
+- [dateutil](https://github.com/dateutil/dateutil)
+- [CherryPy](https://cherrypy.dev)
+- [Tryton](https://www.tryton.org/)
+- [MNE](https://www.martinos.org/mne/stable/index.html)
+- [Adversarial Robustness Toolbox](https://github.com/IBM/adversarial-robustness-toolbox)
+- [tikzplotlib](https://github.com/nschloe/tikzplotlib)
+- [stumpy](https://github.com/TDAmeritrade/stumpy)
+- [pydicom](https://github.com/pydicom/pydicom)
+- [PyStan](https://github.com/stan-dev/pystan)
+- [RDKit](https://github.com/rdkit/rdkit)
+- [Software Carpentry](https://software-carpentry.org)
+- [ADB-Enhanced](https://github.com/ashishb/adb-enhanced)
+- [Cartopy](https://scitools.org.uk/cartopy/docs/latest/)
+- [fecon235](https://github.com/rsvp/fecon235)
+- [scikit-bio](http://scikit-bio.org)
+- [MetPy](https://unidata.github.io/MetPy)
+- [Bottleneck](https://bottleneck.readthedocs.io/)
+- [SunPy](https://sunpy.org/)
+- [Nengo](https://www.nengo.ai/)
+- [Axelrod](https://github.com/Axelrod-Python/Axelrod)
+- [rpy2](https://rpy2.bitbucket.io)
+- [Toyplot](https://github.com/sandialabs/toyplot)
+- [Psi4](http://psicode.org/)
+- [pyLast](https://github.com/pylast/pylast)
+- [iris](https://scitools.org.uk/iris/docs/latest/)
+- [ESMValTool](https://esmvaltool.readthedocs.io/en/latest/)
+- [meshio](https://github.com/nschloe/meshio/)
+- [perfplot](https://github.com/nschloe/perfplot/)
+- [cmd2](https://github.com/python-cmd2/cmd2)
+- [yt](https://yt-project.org/)
+- [quadpy](https://github.com/nschloe/quadpy/)
+- [PySCIPOpt](https://github.com/SCIP-Interfaces/PySCIPOpt)
+- [betterbib](https://github.com/nschloe/betterbib)
+- [OpenQuake engine](https://github.com/gem/oq-engine)
+- [PyMeasure](https://github.com/ralph-group/pymeasure)
+- [Urduhack](https://github.com/urduhack/urduhack)
+- [osBrain](https://github.com/opensistemas-hub/osbrain)
+- [Cylc Workflow](https://cylc.github.io/)
+- [FEniCS](https://fenicsproject.org/)
+- [GSSAPI](https://github.com/pythongssapi/)
+- [colorio](https://github.com/nschloe/colorio)
+- [TatSu](https://tatsu.readthedocs.io/)
+- [Chaquopy](https://chaquo.com/chaquopy/)
+- [angr](http://angr.io/)
+- [BioBuilds](https://www.biobuilds.org/)
+- [orthopy](https://github.com/nschloe/orthopy)
+- [freud](https://github.com/glotzerlab/freud)
+- [signac](https://signac.io)
+- [Manticore](https://github.com/trailofbits/manticore)
+- [PLATON](https://github.com/ideasrule/platon)
+- [GSTools](https://github.com/GeoStat-Framework/GSTools)
+- [Cantor](https://cantor.kde.org)
+- [DocRaptor](https://docraptor.com)
+- [Connectome Mapper 3](https://connectome-mapper-3.readthedocs.io)
+- [lib3to6](https://github.com/mbarkhau/lib3to6)
+
+
-- [Altair](https://github.com/ellisonbg/altair)
+- [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)
-- [SPADE](https://github.com/javipalanca/spade)
+- [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)
-- [CIS](https://github.com/cedadev/cis)
-- [cual-id](https://github.com/johnchase/cual-id)
+- [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/assets/openquake.png b/assets/openquake.png
index a61c2fb..cf8baae 100644
Binary files a/assets/openquake.png 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
index 5aa2244..67411c5 100644
Binary files a/assets/pymc3.png 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
index 7a49710..701109a 100644
Binary files a/assets/pythran.png 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
index 00e70a6..efa4708 100644
Binary files a/assets/rdkit.png 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 @@
+
+
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
index dab0194..00a577a 100644
Binary files a/assets/xarray.png 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
index 67a3e3b..c8874ba 100644
Binary files a/assets/yt.png and b/assets/yt.png differ
diff --git a/assets/zulip.png b/assets/zulip.png
index e6fe8ab..e0c766c 100644
Binary files a/assets/zulip.png and b/assets/zulip.png differ
diff --git a/combo.css b/combo.css
index 4602a51..0f9195a 100644
--- a/combo.css
+++ b/combo.css
@@ -68,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/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/%7Borg%7D/%7Brepo%7D'
+ 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 d2ce955..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,15 +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},
{content:'Python 3.3', start: '2012-09-29', end: '2017-09-29'},
- // EOL for Python 3.4 - 3.7 not announced yet; project 5 years from initial release to follow CPython policy.
- {content:'Python 3.4', start: '2014-03-16', end: '2019-03-16'},
+ {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', start: '2016-12-23', end: '2021-12-23'},
- {content:'Python 3.7', start: '2018-06-15', end: '2023-06-01'},
+ {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},
@@ -116,15 +120,61 @@ $(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-04-19', 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'},
],
@@ -137,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},
@@ -148,37 +199,72 @@ $(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: '2017-07-29'},
+ {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'}
+ {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'}
- ],
+ {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-08-01', end: '2020-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},
@@ -191,30 +277,116 @@ $(document).ready(function (){
{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];