Maintaining Python 2 compatibility

Fellow plugin developers, has anyone dropped support for Python2 in their plugin yet?

OctoPi 0.18.0 (released two weeks ago) is now using Python3 and it seems like maintaining compatibility for both versions is getting difficult. I want to add a feature to the Firmware Update plugin, but making it backwards compatible is making life complicated.

Do we know when OctoPrint will drop support for Python2?

We have had a couple of discussions about this on Discord, and a good solution is yet to be agreed on.

Relevant conversation between and @kantlivelong and I: Discord

OctoPrint will drop Python 2 support with the release of 2.0, which while slated for this year has been delayed. No official word on a new date, if you watch OctoPrint on Air Gina gives a good explanation.

The thoughts we have come up with so far are:

  • Block update by specifying python_requires: >=3.6 in setup.py. Downside is that users will constantly be prompted for an update that they can't apply.
  • In a previous release, defined as the last that supports Python 2 remove the software update hook if users are on Python 2. Downside here is that bugs can't be fixed because Py 2 users can't update anymore
  • Similar to above, but swap the software update config to a Python 2 branch/repo that would allow for updates. Downside here is a lot more work from the maintainer.
  • Check the plugin repository on updates to check the Python compatibility string is still valid. Would require a change in OctoPrint, and wouldn't work for all plugins.

Yeah, it's a difficult one that we haven't really found a good way around. Python 3 users are currently at ~23%, see https://data.octoprint.org

Another option, not yet discussed on discord: do 1. and some magic with the software update overlays introduced in 1.5.x.

1 Like

Hmm, thanks for sharing that. The 2nd and 3rd options are interesting, and probably ones I can live with. Will need to think about it for a bit.

1 Like

I think it would be worth coming up with what we can think of as a 'good' solution, for both communication to users and updating itself, that can be set out as 'the way to do it' for plugin authors.

2 Likes

Certainly is more work if the author wants to actually maintain py2 but then why drop support in the first place?

I did do the first option recently with Google Drive Backup as an upstream dependency seemed to be causing me headaches in Python 2. I would be interested in seeing what could be done with overlays so that previous versions would still work but not get update notices for the users that aren't on board with upgrading their instances or migrate to python 3 right away.

It was more the option that you could still push necessary updates (eg. the update disabling the update hook set fire to everything) - I don't see that being a viable solution, just one that I remembered someone saying. Maybe I just thought it to myself.

Here's what I've cooked up if anyone wants to try.

Process:

  1. Install 0.0.1 zip on py2.7. You will notice it wants to upgrade to 0.0.3. Ignore as is expected here.
  2. Install 0.0.2 zip. After restarting it will mention there is another update with a commit hash from the py2 branch. Go ahead and upgrade.
  3. After upgraded the plugin will still be on 0.0.2 and if you check the sw update section it will show 0.0.2 w/ a commit hash.

Your software update hook doesn't match your plugin identifier....sorry couldn't resist plugin review...

Wuh? Where?

:man_facepalming: my bad, I wasn't looking at it right. You're good.

1 Like

2 Likes

Forget my overlay idea, I was too tired already it seems and completely forgot that that would also nuke access for Py3 :woman_facepalming:

It's a shame really that we can't attach meta fields to GitHub releases, that would make this trivial. If a plugin is hosted on PyPI and OctoPrint checks THAT for updates, it will already take the python compatibility flag into account (e.g. it will not prompt you to update to a pip version that ain't compatible already).

All things considered, I think the easiest way here is indeed to extend OctoPrint to pull in compatibility info from the repository. I've just pushed a new py2 only update check overlay to the plugin repo that gets generated to set

disabled: true
compatible: false

on Py3 only plugins. Py2 OctoPrint 1.6.x will fetch this overlay in addition to the normal one and apply it. That will make it so that plugins installed on OctoPrint under Py2 will switch to disabled update checks and also a new "disabled because of incompatibility" override once a Py3 only version gets pushed. By default at is. The overlay also allows to implement more specific actions here, like changing the version check and update url to e.g. a legacy repository, in case there should still be security updates or whatnot for Py2 instances. That should hopefully give us enough flexibility (also for OctoPrint itself btw) while being a sensible enough default behaviour that it doesn't cause unnecessary overhead for people all around.

2 Likes