Skip to content

Commit 11af006

Browse files
add script to retrieve supported Python versions, optionally from package source metadata
1 parent 0b56bf7 commit 11af006

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

.github/workflows/tox.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,17 @@ jobs:
123123
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
124124
with:
125125
python-version: '3.12'
126+
- if: inputs.envs == ''
127+
run: echo $SUPPORTED_PYTHONS_SCRIPT | base64 --decode > supported_pythons.py
128+
env:
129+
SUPPORTED_PYTHONS_SCRIPT: IyAvLy8gc2NyaXB0CiMgcmVxdWlyZXMtcHl0aG9uID0gIj49My4xMiIKIyBkZXBlbmRlbmNpZXMgPSBbCiMgICAgICJjbGljaz09OC4yLjEiLAojICAgICAicGVwcHlwcm9qZWN0PT0xLjAuMiIsCiMgICAgICJyZXF1ZXN0cz09Mi4zMi41IiwKIyAgICAgInBhY2thZ2luZz09MjUuMCIsCiMgXQojIC8vLwoKaW1wb3J0IGpzb24KaW1wb3J0IG9zCmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aAoKaW1wb3J0IGNsaWNrCmltcG9ydCByZXF1ZXN0cwpmcm9tIHBhY2thZ2luZy5zcGVjaWZpZXJzIGltcG9ydCBTcGVjaWZpZXJTZXQKZnJvbSBwYWNrYWdpbmcudmVyc2lvbiBpbXBvcnQgVmVyc2lvbgpmcm9tIHBlcHB5cHJvamVjdCBpbXBvcnQgUHlQcm9qZWN0Q29uZmlndXJhdGlvbgoKCkBjbGljay5jb21tYW5kKCkKQGNsaWNrLm9wdGlvbigiLS1zb3VyY2UiLCBkZWZhdWx0PU5vbmUpCkBjbGljay5vcHRpb24oIi0tZmxhZ3MiLCBkZWZhdWx0PU5vbmUpCkBjbGljay5vcHRpb24oIi0tbm8tZW9hcyIsIGlzX2ZsYWc9VHJ1ZSwgZGVmYXVsdD1GYWxzZSkKZGVmIHByaW50X3N1cHBvcnRlZF9weXRob25zKAogICAgc291cmNlOiBQYXRoID0gTm9uZSwKICAgIGZsYWdzOiBsaXN0W3N0cl0gPSBOb25lLAogICAgbm9fZW9hczogYm9vbCA9IEZhbHNlLAopOgogICAgIiIiZW51bWVyYXRlIHRveGVudnMgUHl0aG9uIGZyb20gYSBwYWNrYWdlIHNvdXJjZSIiIgoKICAgIHRveGVudnMgPSBzdXBwb3J0ZWRfcHl0aG9uX3RveGVudnMoc291cmNlLCBmbGFncywgbm9fZW9hcykKICAgIHByaW50KGpzb24uZHVtcHModG94ZW52cywgaW5kZW50PTIpKQogICAgd2l0aCBvcGVuKG9zLmVudmlyb25bIkdJVEhVQl9PVVRQVVQiXSwgImEiKSBhcyBmOgogICAgICAgIGYud3JpdGUoZiJlbnZzPXtqc29uLmR1bXBzKHRveGVudnMpfVxuIikKCgpkZWYgc3VwcG9ydGVkX3B5dGhvbl90b3hlbnZzKAogICAgc291cmNlOiBQYXRoID0gTm9uZSwKICAgIGZsYWdzOiBsaXN0W3N0cl0gPSBOb25lLAogICAgbm9fZW9hczogYm9vbCA9IEZhbHNlLAopIC0+IGxpc3Rbc3RyXToKICAgIHB5dGhvbnMgPSBjdXJyZW50X3B5dGhvbl92ZXJzaW9ucyhub19lb2FzPW5vX2VvYXMpCgogICAgaWYgc291cmNlIGlzIE5vbmUgb3Igc291cmNlID09ICIiOgogICAgICAgIHN1cHBvcnRlZF9weXRob25zID0gcHl0aG9ucwogICAgZWxzZToKICAgICAgICBjb25maWd1cmF0aW9uID0gUHlQcm9qZWN0Q29uZmlndXJhdGlvbi5mcm9tX2RpcmVjdG9yeShzb3VyY2UpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBweXRob25fcmVxdWlyZW1lbnRzID0gU3BlY2lmaWVyU2V0KGNvbmZpZ3VyYXRpb25bInByb2plY3QiXVsicmVxdWlyZXMtcHl0aG9uIl0pCgogICAgICAgICAgICBzdXBwb3J0ZWRfcHl0aG9ucyA9IFtweXRob24gZm9yIHB5dGhvbiBpbiBweXRob25zIGlmIHB5dGhvbiBpbiBweXRob25fcmVxdWlyZW1lbnRzXQogICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgc3VwcG9ydGVkX3B5dGhvbnMgPSBweXRob25zCgogICAgcmV0dXJuIFsKICAgICAgICBmInB5e3N0cihweXRob24pLnJlcGxhY2UoJy4nLCAnJyl9eyctJyArICctJy5qb2luKGZsYWdzKSBpZiBmbGFncyBpcyBub3QgTm9uZSBhbmQgbGVuKGZsYWdzKSA+IDAgZWxzZSAnJ30iCiAgICAgICAgZm9yIHB5dGhvbiBpbiBzdXBwb3J0ZWRfcHl0aG9ucwogICAgXQoKCmRlZiBjdXJyZW50X3B5dGhvbl92ZXJzaW9ucyhub19lb2FzOiBib29sID0gRmFsc2UpIC0+IGxpc3RbVmVyc2lvbl06CiAgICB1cmwgPSAiaHR0cHM6Ly9lbmRvZmxpZmUuZGF0ZS9hcGkvdjEvcHJvZHVjdHMvcHl0aG9uIgogICAgcmVzcG9uc2UgPSByZXF1ZXN0cy5nZXQoImh0dHBzOi8vZW5kb2ZsaWZlLmRhdGUvYXBpL3YxL3Byb2R1Y3RzL3B5dGhvbiIpCiAgICBpZiByZXNwb25zZS5zdGF0dXNfY29kZSA9PSAyMDA6CiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgVmVyc2lvbihweXRob25bIm5hbWUiXSkKICAgICAgICAgICAgZm9yIHB5dGhvbiBpbiByZXNwb25zZS5qc29uKClbInJlc3VsdCJdWyJyZWxlYXNlcyJdCiAgICAgICAgICAgIGlmIG5vdCBweXRob25bImlzRW9hcyIgaWYgbm9fZW9hcyBlbHNlICJpc0VvbCJdCiAgICAgICAgXQogICAgZWxzZToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKGYicmVxdWVzdCByZXR1cm5lZCBzdGF0dXMgY29kZSB7cmVzcG9uc2Uuc3RhdHVzX2NvZGV9IFt7dXJsfV0iKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBwcmludF9zdXBwb3J0ZWRfcHl0aG9ucygpCg==
130+
- if: inputs.envs == ''
131+
run: cat supported_pythons.py
132+
- id: get-envs
133+
run: |
134+
pipx run supported_pythons.py
135+
shell: sh
136+
- run: cat ${{ steps.get-envs.outputs.envs }}
126137
- run: echo $TOX_MATRIX_SCRIPT | base64 --decode > tox_matrix.py
127138
env:
128139
TOX_MATRIX_SCRIPT: IyAvLy8gc2NyaXB0CiMgcmVxdWlyZXMtcHl0aG9uID0gIj09My4xMiIKIyBkZXBlbmRlbmNpZXMgPSBbCiMgICAgICJjbGljaz09OC4yLjEiLAojICAgICAicHl5YW1sPT02LjAuMiIsCiMgXQojIC8vLwppbXBvcnQganNvbgppbXBvcnQgb3MKaW1wb3J0IHJlCgppbXBvcnQgY2xpY2sKaW1wb3J0IHlhbWwKCgpAY2xpY2suY29tbWFuZCgpCkBjbGljay5vcHRpb24oIi0tZW52cyIsIGRlZmF1bHQ9IiIpCkBjbGljay5vcHRpb24oIi0tbGlicmFyaWVzIiwgZGVmYXVsdD0iIikKQGNsaWNrLm9wdGlvbigiLS1wb3NhcmdzIiwgZGVmYXVsdD0iIikKQGNsaWNrLm9wdGlvbigiLS10b3hkZXBzIiwgZGVmYXVsdD0iIikKQGNsaWNrLm9wdGlvbigiLS10b3hhcmdzIiwgZGVmYXVsdD0iIikKQGNsaWNrLm9wdGlvbigiLS1weXRlc3QiLCBkZWZhdWx0PSJ0cnVlIikKQGNsaWNrLm9wdGlvbigiLS1weXRlc3QtcmVzdWx0cy1zdW1tYXJ5IiwgZGVmYXVsdD0iZmFsc2UiKQpAY2xpY2sub3B0aW9uKCItLWNvdmVyYWdlIiwgZGVmYXVsdD0iIikKQGNsaWNrLm9wdGlvbigiLS1jb25kYSIsIGRlZmF1bHQ9ImF1dG8iKQpAY2xpY2sub3B0aW9uKCItLXNldGVudiIsIGRlZmF1bHQ9IiIpCkBjbGljay5vcHRpb24oIi0tZGlzcGxheSIsIGRlZmF1bHQ9ImZhbHNlIikKQGNsaWNrLm9wdGlvbigiLS1jYWNoZS1wYXRoIiwgZGVmYXVsdD0iIikKQGNsaWNrLm9wdGlvbigiLS1jYWNoZS1rZXkiLCBkZWZhdWx0PSIiKQpAY2xpY2sub3B0aW9uKCItLWNhY2hlLXJlc3RvcmUta2V5cyIsIGRlZmF1bHQ9IiIpCkBjbGljay5vcHRpb24oIi0tYXJ0aWZhY3QtcGF0aCIsIGRlZmF1bHQ9IiIpCkBjbGljay5vcHRpb24oIi0tcnVucy1vbiIsIGRlZmF1bHQ9IiIpCkBjbGljay5vcHRpb24oIi0tZGVmYXVsdC1weXRob24iLCBkZWZhdWx0PSIiKQpAY2xpY2sub3B0aW9uKCItLXRpbWVvdXQtbWludXRlcyIsIGRlZmF1bHQ9IjM2MCIpCmRlZiBsb2FkX3RveF90YXJnZXRzKGVudnMsIGxpYnJhcmllcywgcG9zYXJncywgdG94ZGVwcywgdG94YXJncywgcHl0ZXN0LCBweXRlc3RfcmVzdWx0c19zdW1tYXJ5LAogICAgICAgICAgICAgICAgICAgICBjb3ZlcmFnZSwgY29uZGEsIHNldGVudiwgZGlzcGxheSwgY2FjaGVfcGF0aCwgY2FjaGVfa2V5LAogICAgICAgICAgICAgICAgICAgICBjYWNoZV9yZXN0b3JlX2tleXMsIGFydGlmYWN0X3BhdGgsIHJ1bnNfb24sIGRlZmF1bHRfcHl0aG9uLCB0aW1lb3V0X21pbnV0ZXMpOgogICAgIiIiU2NyaXB0IHRvIGxvYWQgdG94IHRhcmdldHMgZm9yIEdpdEh1YiBBY3Rpb25zIHdvcmtmbG93LiIiIgogICAgIyBMb2FkIGVudnMgY29uZmlnCiAgICBlbnZzID0geWFtbC5sb2FkKGVudnMsIExvYWRlcj15YW1sLkJhc2VMb2FkZXIpCiAgICBwcmludChqc29uLmR1bXBzKGVudnMsIGluZGVudD0yKSkKCiAgICAjIExvYWQgZ2xvYmFsIGxpYnJhcmllcyBjb25maWcKICAgIGdsb2JhbF9saWJyYXJpZXMgPSB7CiAgICAgICAgImJyZXciOiBbXSwKICAgICAgICAiYnJldy1jYXNrIjogW10sCiAgICAgICAgImFwdCI6IFtdLAogICAgICAgICJjaG9jbyI6IFtdLAogICAgfQogICAgbGlicmFyaWVzID0geWFtbC5sb2FkKGxpYnJhcmllcywgTG9hZGVyPXlhbWwuQmFzZUxvYWRlcikKICAgIGlmIGxpYnJhcmllcyBpcyBub3QgTm9uZToKICAgICAgICBnbG9iYWxfbGlicmFyaWVzLnVwZGF0ZShsaWJyYXJpZXMpCiAgICBwcmludChqc29uLmR1bXBzKGdsb2JhbF9saWJyYXJpZXMsIGluZGVudD0yKSkKCiAgICAjIERlZmF1bHQgaW1hZ2VzIHRvIHVzZSBmb3IgcnVubmVycwogICAgZGVmYXVsdF9ydW5zX29uID0gewogICAgICAgICJsaW51eCI6ICJ1YnVudHUtbGF0ZXN0IiwKICAgICAgICAibWFjb3MiOiAibWFjb3MtbGF0ZXN0IiwKICAgICAgICAid2luZG93cyI6ICJ3aW5kb3dzLWxhdGVzdCIsCiAgICB9CiAgICBjdXN0b21fcnVuc19vbiA9IHlhbWwubG9hZChydW5zX29uLCBMb2FkZXI9eWFtbC5CYXNlTG9hZGVyKQogICAgaWYgaXNpbnN0YW5jZShjdXN0b21fcnVuc19vbiwgZGljdCk6CiAgICAgICAgZGVmYXVsdF9ydW5zX29uLnVwZGF0ZShjdXN0b21fcnVuc19vbikKICAgIHByaW50KGpzb24uZHVtcHMoZGVmYXVsdF9ydW5zX29uLCBpbmRlbnQ9MikpCgogICAgIyBEZWZhdWx0IHN0cmluZyBwYXJhbWV0ZXJzIHdoaWNoIGNhbiBiZSBvdmVyd3JpdHRlbiBieSBlYWNoIGVudgogICAgc3RyaW5nX3BhcmFtZXRlcnMgPSB7CiAgICAgICAgInBvc2FyZ3MiOiBwb3NhcmdzLAogICAgICAgICJ0b3hkZXBzIjogdG94ZGVwcywKICAgICAgICAidG94YXJncyI6IHRveGFyZ3MsCiAgICAgICAgInB5dGVzdCI6IHB5dGVzdCwKICAgICAgICAicHl0ZXN0LXJlc3VsdHMtc3VtbWFyeSI6IHB5dGVzdF9yZXN1bHRzX3N1bW1hcnksCiAgICAgICAgImNvdmVyYWdlIjogY292ZXJhZ2UsCiAgICAgICAgImNvbmRhIjogY29uZGEsCiAgICAgICAgInNldGVudiI6IHNldGVudiwKICAgICAgICAiZGlzcGxheSI6IGRpc3BsYXksCiAgICAgICAgImNhY2hlLXBhdGgiOiBjYWNoZV9wYXRoLAogICAgICAgICJjYWNoZS1rZXkiOiBjYWNoZV9rZXksCiAgICAgICAgImNhY2hlLXJlc3RvcmUta2V5cyI6IGNhY2hlX3Jlc3RvcmVfa2V5cywKICAgICAgICAiYXJ0aWZhY3QtcGF0aCI6IGFydGlmYWN0X3BhdGgsCiAgICAgICAgInRpbWVvdXQtbWludXRlcyI6IHRpbWVvdXRfbWludXRlcywKICAgIH0KCiAgICAjIENyZWF0ZSBtYXRyaXgKICAgIG1hdHJpeCA9IHsiaW5jbHVkZSI6IFtdfQogICAgZm9yIGVudiBpbiBlbnZzOgogICAgICAgIG1hdHJpeFsiaW5jbHVkZSJdLmFwcGVuZChnZXRfbWF0cml4X2l0ZW0oCiAgICAgICAgICAgIGVudiwKICAgICAgICAgICAgZ2xvYmFsX2xpYnJhcmllcz1nbG9iYWxfbGlicmFyaWVzLAogICAgICAgICAgICBnbG9iYWxfc3RyaW5nX3BhcmFtZXRlcnM9c3RyaW5nX3BhcmFtZXRlcnMsCiAgICAgICAgICAgIHJ1bnNfb249ZGVmYXVsdF9ydW5zX29uLAogICAgICAgICAgICBkZWZhdWx0X3B5dGhvbj1kZWZhdWx0X3B5dGhvbiwKICAgICAgICApKQoKICAgICMgT3V0cHV0IG1hdHJpeAogICAgcHJpbnQoanNvbi5kdW1wcyhtYXRyaXgsIGluZGVudD0yKSkKICAgIHdpdGggb3Blbihvcy5lbnZpcm9uWyJHSVRIVUJfT1VUUFVUIl0sICJhIikgYXMgZjoKICAgICAgICBmLndyaXRlKGYibWF0cml4PXtqc29uLmR1bXBzKG1hdHJpeCl9XG4iKQoKCmRlZiBnZXRfbWF0cml4X2l0ZW0oZW52LCBnbG9iYWxfbGlicmFyaWVzLCBnbG9iYWxfc3RyaW5nX3BhcmFtZXRlcnMsCiAgICAgICAgICAgICAgICAgICAgcnVuc19vbiwgZGVmYXVsdF9weXRob24pOgoKICAgICMgZGVmaW5lIHNwZWMgZm9yIGVhY2ggbWF0cml4IGluY2x1ZGUgKCsgZ2xvYmFsX3N0cmluZ19wYXJhbWV0ZXJzKQogICAgaXRlbSA9IHsKICAgICAgICAib3MiOiBOb25lLAogICAgICAgICJ0b3hlbnYiOiBOb25lLAogICAgICAgICJweXRob25fdmVyc2lvbiI6IE5vbmUsCiAgICAgICAgIm5hbWUiOiBOb25lLAogICAgICAgICJweXRlc3RfZmxhZyI6IE5vbmUsCiAgICAgICAgImxpYnJhcmllc19icmV3IjogTm9uZSwKICAgICAgICAibGlicmFyaWVzX2JyZXdfY2FzayI6IE5vbmUsCiAgICAgICAgImxpYnJhcmllc19hcHQiOiBOb25lLAogICAgICAgICJsaWJyYXJpZXNfY2hvY28iOiBOb25lLAogICAgICAgICJjYWNoZS1wYXRoIjogTm9uZSwKICAgICAgICAiY2FjaGUta2V5IjogTm9uZSwKICAgICAgICAiY2FjaGUtcmVzdG9yZS1rZXlzIjogTm9uZSwKICAgICAgICAiYXJ0aWZhY3QtbmFtZSI6IE5vbmUsCiAgICAgICAgImFydGlmYWN0LXBhdGgiOiBOb25lLAogICAgICAgICJ0aW1lb3V0LW1pbnV0ZXMiOiBOb25lLAogICAgfQogICAgZm9yIHN0cmluZ19wYXJhbSwgZGVmYXVsdCBpbiBnbG9iYWxfc3RyaW5nX3BhcmFtZXRlcnMuaXRlbXMoKToKICAgICAgICBlbnZfdmFsdWUgPSBlbnYuZ2V0KHN0cmluZ19wYXJhbSkKICAgICAgICBpdGVtW3N0cmluZ19wYXJhbV0gPSBkZWZhdWx0IGlmIGVudl92YWx1ZSBpcyBOb25lIGVsc2UgZW52X3ZhbHVlCgogICAgIyBzZXQgb3MgYW5kIHRveGVudgogICAgZm9yIGssIHYgaW4gcnVuc19vbi5pdGVtcygpOgogICAgICAgIGlmIGsgaW4gZW52OgogICAgICAgICAgICBwbGF0Zm9ybSA9IGsKICAgICAgICAgICAgaXRlbVsib3MiXSA9IGVudi5nZXQoInJ1bnMtb24iLCB2KQogICAgICAgICAgICBpdGVtWyJ0b3hlbnYiXSA9IGVudltrXQogICAgYXNzZXJ0IGl0ZW1bIm9zIl0gaXMgbm90IE5vbmUgYW5kIGl0ZW1bInRveGVudiJdIGlzIG5vdCBOb25lCgogICAgIyBzZXQgcHl0aG9uX3ZlcnNpb24KICAgIHB5dGhvbl92ZXJzaW9uID0gZW52LmdldCgicHl0aG9uLXZlcnNpb24iKQogICAgbSA9IHJlLnNlYXJjaCgiXnB5KDJ8MykoWzAtOV0rdD8pIiwgaXRlbVsidG94ZW52Il0pCiAgICBpZiBweXRob25fdmVyc2lvbiBpcyBub3QgTm9uZToKICAgICAgICBpdGVtWyJweXRob25fdmVyc2lvbiJdID0gcHl0aG9uX3ZlcnNpb24KICAgIGVsaWYgbSBpcyBub3QgTm9uZToKICAgICAgICBtYWpvciwgbWlub3IgPSBtLmdyb3VwcygpCiAgICAgICAgaXRlbVsicHl0aG9uX3ZlcnNpb24iXSA9IGYie21ham9yfS57bWlub3J9IgogICAgZWxzZToKICAgICAgICBpdGVtWyJweXRob25fdmVyc2lvbiJdID0gZW52LmdldCgiZGVmYXVsdF9weXRob24iKSBvciBkZWZhdWx0X3B5dGhvbgoKICAgICMgc2V0IG5hbWUKICAgIGl0ZW1bIm5hbWUiXSA9IGVudi5nZXQoIm5hbWUiKSBvciBmJ3tpdGVtWyJ0b3hlbnYiXX0gKHtpdGVtWyJvcyJdfSknCgogICAgIyBzZXQgYXJ0aWZhY3QtbmFtZSAocmVwbGFjZSBpbnZhbGlkIHBhdGggY2hhcmFjdGVycykKICAgIGl0ZW1bImFydGlmYWN0LW5hbWUiXSA9IHJlLnN1YihyIltcXCAvOjw+fCo/XCInXSIsICItIiwgaXRlbVsibmFtZSJdKQogICAgaXRlbVsiYXJ0aWZhY3QtbmFtZSJdID0gcmUuc3ViKHIiLSsiLCAiLSIsIGl0ZW1bImFydGlmYWN0LW5hbWUiXSkKCiAgICAjIHNldCBweXRlc3RfZmxhZwogICAgaXRlbVsicHl0ZXN0X2ZsYWciXSA9ICIiCiAgICBzZXAgPSByIlxcIiBpZiBwbGF0Zm9ybSA9PSAid2luZG93cyIgZWxzZSAiLyIKICAgIGlmIGl0ZW1bInB5dGVzdCJdID09ICJ0cnVlIiBhbmQgImNvZGVjb3YiIGluIGl0ZW0uZ2V0KCJjb3ZlcmFnZSIsICIiKToKICAgICAgICBpdGVtWyJweXRlc3RfZmxhZyJdICs9ICgKICAgICAgICAgICAgcmYiLS1jb3YtcmVwb3J0PXhtbDoke3tHSVRIVUJfV09SS1NQQUNFfX17c2VwfWNvdmVyYWdlLnhtbCAiKQogICAgaWYgaXRlbVsicHl0ZXN0Il0gPT0gInRydWUiIGFuZCBpdGVtWyJweXRlc3QtcmVzdWx0cy1zdW1tYXJ5Il0gPT0gInRydWUiOgogICAgICAgIGl0ZW1bInB5dGVzdF9mbGFnIl0gKz0gcmYiLS1qdW5pdHhtbCAke3tHSVRIVUJfV09SS1NQQUNFfX17c2VwfXJlc3VsdHMueG1sICIKCiAgICAjIHNldCBsaWJyYXJpZXMKICAgIGVudl9saWJyYXJpZXMgPSBlbnYuZ2V0KCJsaWJyYXJpZXMiKQogICAgaWYgaXNpbnN0YW5jZShlbnZfbGlicmFyaWVzLCBzdHIpIGFuZCBsZW4oZW52X2xpYnJhcmllcy5zdHJpcCgpKSA9PSAwOgogICAgICAgIGVudl9saWJyYXJpZXMgPSB7fSAgIyBubyBsaWJyYXJpZXMgcmVxdWVzdGVkIGZvciBlbnZpcm9ubWVudAogICAgbGlicmFyaWVzID0gZ2xvYmFsX2xpYnJhcmllcyBpZiBlbnZfbGlicmFyaWVzIGlzIE5vbmUgZWxzZSBlbnZfbGlicmFyaWVzCiAgICBmb3IgbWFuYWdlciBpbiBbImJyZXciLCAiYnJld19jYXNrIiwgImFwdCIsICJjaG9jbyJdOgogICAgICAgIGl0ZW1bZiJsaWJyYXJpZXNfe21hbmFnZXJ9Il0gPSAiICIuam9pbihsaWJyYXJpZXMuZ2V0KG1hbmFnZXIsIFtdKSkKCiAgICAjIHNldCAiYXV0byIgY29uZGEgdmFsdWUKICAgIGlmIGl0ZW1bImNvbmRhIl0gPT0gImF1dG8iOgogICAgICAgIGl0ZW1bImNvbmRhIl0gPSAidHJ1ZSIgaWYgImNvbmRhIiBpbiBpdGVtWyJ0b3hlbnYiXSBlbHNlICJmYWxzZSIKCiAgICAjIGluamVjdCB0b3hkZXBzIGZvciBjb25kYQogICAgaWYgaXRlbVsiY29uZGEiXSA9PSAidHJ1ZSIgYW5kICJ0b3gtY29uZGEiIG5vdCBpbiBpdGVtWyJ0b3hkZXBzIl0ubG93ZXIoKToKICAgICAgICBpdGVtWyJ0b3hkZXBzIl0gPSAoInRveC1jb25kYSAiICsgaXRlbVsidG94ZGVwcyJdKS5zdHJpcCgpCgogICAgIyBtYWtlIHRpbWVvdXQtbWludXRlcyBhIG51bWJlcgogICAgaXRlbVsidGltZW91dC1taW51dGVzIl0gPSBpbnQoaXRlbVsidGltZW91dC1taW51dGVzIl0pCgogICAgIyB2ZXJpZnkgdmFsdWVzCiAgICBhc3NlcnQgaXRlbVsicHl0ZXN0Il0gaW4geyJ0cnVlIiwgImZhbHNlIn0KICAgIGFzc2VydCBpdGVtWyJjb25kYSJdIGluIHsidHJ1ZSIsICJmYWxzZSJ9CiAgICBhc3NlcnQgaXRlbVsiZGlzcGxheSJdIGluIHsidHJ1ZSIsICJmYWxzZSJ9CgogICAgcmV0dXJuIGl0ZW0KCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgbG9hZF90b3hfdGFyZ2V0cygpCg==

tools/supported_pythons.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# /// script
2+
# requires-python = ">=3.12"
3+
# dependencies = [
4+
# "click==8.2.1",
5+
# "peppyproject==1.0.2",
6+
# "requests==2.32.5",
7+
# "packaging==25.0",
8+
# ]
9+
# ///
10+
11+
import json
12+
import os
13+
from pathlib import Path
14+
15+
import click
16+
import requests
17+
from packaging.specifiers import SpecifierSet
18+
from packaging.version import Version
19+
from peppyproject import PyProjectConfiguration
20+
21+
22+
@click.command()
23+
@click.option("--source", default=None)
24+
@click.option("--flags", default=None)
25+
@click.option("--no-eoas", is_flag=True, default=False)
26+
def print_supported_pythons(
27+
source: Path = None,
28+
flags: list[str] = None,
29+
no_eoas: bool = False,
30+
):
31+
"""enumerate toxenvs Python from a package source"""
32+
33+
toxenvs = supported_python_toxenvs(source, flags, no_eoas)
34+
print(json.dumps(toxenvs, indent=2))
35+
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
36+
f.write(f"envs={json.dumps(toxenvs)}\n")
37+
38+
39+
def supported_python_toxenvs(
40+
source: Path = None,
41+
flags: list[str] = None,
42+
no_eoas: bool = False,
43+
) -> list[str]:
44+
pythons = current_python_versions(no_eoas=no_eoas)
45+
46+
if source is None or source == "":
47+
supported_pythons = pythons
48+
else:
49+
configuration = PyProjectConfiguration.from_directory(source)
50+
try:
51+
python_requirements = SpecifierSet(configuration["project"]["requires-python"])
52+
53+
supported_pythons = [python for python in pythons if python in python_requirements]
54+
except KeyError:
55+
supported_pythons = pythons
56+
57+
return [
58+
f"py{str(python).replace('.', '')}{'-' + '-'.join(flags) if flags is not None and len(flags) > 0 else ''}"
59+
for python in supported_pythons
60+
]
61+
62+
63+
def current_python_versions(no_eoas: bool = False) -> list[Version]:
64+
url = "https://endoflife.date/api/v1/products/python"
65+
response = requests.get("https://endoflife.date/api/v1/products/python")
66+
if response.status_code == 200:
67+
return [
68+
Version(python["name"])
69+
for python in response.json()["result"]["releases"]
70+
if not python["isEoas" if no_eoas else "isEol"]
71+
]
72+
else:
73+
raise ValueError(f"request returned status code {response.status_code} [{url}]")
74+
75+
76+
if __name__ == "__main__":
77+
print_supported_pythons()

update_scripts_in_yml.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ def base64_encode_into(script, yml_file, env_var):
3232
base64_encode_into('set_env.py', 'tox.yml', 'SET_ENV_SCRIPT')
3333
base64_encode_into('set_env.py', 'publish.yml', 'SET_ENV_SCRIPT')
3434
base64_encode_into('set_env.py', 'publish_pure_python.yml', 'SET_ENV_SCRIPT')
35+
base64_encode_into('supported_pythons.py', 'tox.yml', 'SUPPORTED_PYTHONS_SCRIPT')

0 commit comments

Comments
 (0)