Skip to content

Commit 594f347

Browse files
committed
Validate [metadata].schema_version
It's okay to be missing, but if it's given it must be an expected version (i.e. currently, 1).
1 parent 1f697e6 commit 594f347

2 files changed

Lines changed: 30 additions & 2 deletions

File tree

Lib/site.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,14 @@ def _read_site_toml(sitedir, name):
207207
_trace(f"Error parsing {fullname!r}: {exc}")
208208
return None
209209

210-
metadata = data.get("metadata", [])
210+
metadata = data.get("metadata", {})
211+
# Validate the TOML schema version. PEP XXX defines schema_version == 1. Both the [metadata]
212+
# section and [metadata].schema_version are optional, but if missing, future compatibility
213+
# cannot be guaranteed.
214+
if (schema_version := metadata.get("schema_version")) is not None:
215+
if schema_version != 1:
216+
_trace(f"Unsupported [metadata].schema_version: {schema_version}")
217+
return None
211218

212219
# Validate [paths].dirs
213220
dirs = []

Lib/test/test_site.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,27 @@ def test_read_site_toml_basic(self):
961961
self.assertEqual(tomldata.dirs, ['subdir'])
962962
self.assertEqual(tomldata.init, ['os'])
963963

964+
def test_missing_schema_version_is_okay(self):
965+
# It's okay for the schema_version to be missing, or even the [metadata] section entirely
966+
# (which is tested below). A missing schema_version just means that no future compatibility
967+
# can be guaranteed.
968+
name = self._make_site_toml("""\
969+
[metadata]
970+
""")
971+
tomldata = site._read_site_toml(self.sitedir, name)
972+
self.assertIsNotNone(tomldata)
973+
self.assertEqual(tomldata.metadata, {})
974+
975+
def test_unexpected_schema_version_is_not_okay(self):
976+
# If [metadata].schema_version exists, but isn't a supported number, then the entire TOML
977+
# file is invalid and ignored.
978+
name = self._make_site_toml("""\
979+
[metadata]
980+
schema_version = 801
981+
""")
982+
tomldata = site._read_site_toml(self.sitedir, name)
983+
self.assertIsNone(tomldata)
984+
964985
def test_read_site_toml_parse_error(self):
965986
# Invalid pkg.site.toml content is skipped.
966987
name = self._make_site_toml("not valid [[[toml")
@@ -996,7 +1017,7 @@ def test_read_site_toml_empty_file(self):
9961017
# Empty .site.toml is a no-op.
9971018
name = self._make_site_toml("")
9981019
tomldata = site._read_site_toml(self.sitedir, name)
999-
self.assertEqual(tomldata.metadata, [])
1020+
self.assertEqual(tomldata.metadata, {})
10001021
self.assertEqual(tomldata.dirs, [])
10011022
self.assertEqual(tomldata.init, [])
10021023

0 commit comments

Comments
 (0)