Skip to main content

The Python 3.1 problem

Or, a variation on the Norway problem #

Short version: put quotes around version numbers in YAML.

The Norway problem #

The Norway problem is when you put this in YAML:

countries:
  - GB
  - IE
  - FR
  - DE
  - NO

But get this out:

>>> import yaml
>>> with open("countries.yml") as f:
...     yaml.safe_load(f)
...
{'countries': ['GB', 'IE', 'FR', 'DE', False]}

😱

The Norway fix #

Use quotes:

countries:
  - "GB"
  - "IE"
  - "FR"
  - "DE"
  - "NO"
>>> with open("countries.yml") as f:
...     yaml.safe_load(f)
...
{'countries': ['GB', 'IE', 'FR', 'DE', 'NO']}

🇳🇴 ✅

The Python 3.1 problem #

A similar problem will affect the Python community in October 2021, when Python 3.10 comes out.

Why?

When 3.10 is added to YAML, for example in CI test matrix config, it’s interpreted as a float. This:

python-version: [3.6, 3.7, 3.8, 3.9, 3.10, pypy3]

Turns into this:

>>> import yaml
>>> with open("versions.yml") as f:
...     yaml.safe_load(f)
...
{'python-version': [3.6, 3.7, 3.8, 3.9, 3.1, 'pypy3']}

CI failed! It’s not 2009! Python 3.1 not found!

😱

Relatedly, 3.10-dev without quotes works because it’s interpreted as a string. But when deleting -dev, 3.10 is interpreted as a float.

The Python 3.10 fix #

Version numbers are strings, not floats. Use quotes:

python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "pypy3"]
>>> import yaml
>>> with open("versions.yml") as f:
...     yaml.safe_load(f)
...
{'python-version': ['3.6', '3.7', '3.8', '3.9', '3.10', 'pypy3']}

🐍 ✅

See also #

flake8-2020 is a useful Flake8 plugin to find Python 3.10 and other bugs caused by assumptions about the length of version numbers when using sys.version and sys.version_info.


Header photo: “zero” by Leo Reynolds is licensed under CC BY-NC-SA 2.0.