Download index.html from getreadystack/python-310-eol-pin-check: direct link, hf CLI and curl.
- Browser
- Download file 58.6 kB
-
https://huggingface.co/spaces/getreadystack/python-310-eol-pin-check/resolve/main/index.html
- Command line
-
hf download hf://spaces/getreadystack/python-310-eol-pin-check/index.html
-
curl -L -o index.html https://huggingface.co/spaces/getreadystack/python-310-eol-pin-check/resolve/main/index.html
58.6 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width,initial-scale=1"> | |
| <title>Python 3.10 End of Life — find pins and show the fix</title> | |
| <meta name="description" content="This tool finds Python 3.10 pins in project and cloud configuration files and shows the dated end-of-life fact and a Python 3.13 fix."> | |
| <style> | |
| :root{color-scheme:light}body{margin:0;font:15px/1.55 system-ui,-apple-system,"Segoe UI",sans-serif;background:#faf9f5;color:#1a1512} | |
| .wrap{max-width:960px;margin:0 auto;padding:28px 18px 60px}h1{font-size:26px;margin:0 0 6px}.lede{color:#4a403a;margin:0 0 16px} | |
| textarea{width:100%;min-height:260px;font:13px/1.45 ui-monospace,Menlo,Consolas,monospace;padding:12px;border:1px solid #d9d0c4;border-radius:8px;box-sizing:border-box} | |
| .bar{display:flex;gap:10px;align-items:center;margin:12px 0}button{font:600 15px system-ui;padding:10px 18px;border:0;border-radius:8px;background:#1a1512;color:#fff;cursor:pointer} | |
| input[type=date]{font:14px system-ui;padding:8px;border:1px solid #d9d0c4;border-radius:6px} | |
| table{border-collapse:collapse;width:100%;font-size:14px;margin-top:10px}th,td{text-align:left;padding:8px 10px;border-bottom:1px solid #eee;vertical-align:top}th{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:#7a6e65} | |
| .sev.error{color:#a8551f;font-weight:700}.sev.warn,.sev.warning{color:#96691f}.ok{color:#2a6446;font-weight:600}.sum{font-weight:600} | |
| .note{font-size:13px;color:#7a6e65;margin-top:18px}#paid{margin-top:22px;padding:14px 16px;border:1px solid #e2d8cb;border-radius:10px;background:#fffdfa} | |
| </style> | |
| <script data-grow-initializer="">!(function(){window.growMe||((window.growMe=function(e){window.growMe._.push(e);}),(window.growMe._=[]));var e=document.createElement("script");(e.type="text/javascript"),(e.src="https://faves.grow.me/main.js"),(e.defer=!0),e.setAttribute("data-grow-faves-site-id","U2l0ZTphZjljMzgyMC0yMmU5LTRhYjgtYTIxNS03OTRhMGY1N2ExYzM=");var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t);})();</script> | |
| <style data-yj-mfit="1">#out{max-width:100%}#out td,#out th{overflow-wrap:break-word}#out th{white-space:nowrap}#out pre{white-space:pre-wrap;overflow-wrap:anywhere}#out code{white-space:pre-wrap;overflow-wrap:break-word}@media (max-width:640px){#out td,#out th{overflow-wrap:anywhere}#out th{white-space:normal}table{display:block;max-width:100%;overflow-x:auto}pre{max-width:100%;overflow-x:auto}code,a{overflow-wrap:anywhere}img,svg,video,canvas,iframe{max-width:100%}textarea,input,select{max-width:100%;box-sizing:border-box}.yj-lgbar{position:static;justify-content:flex-end;margin:0 0 10px}h1,h2,h3,h4,p,li,dd,dt,blockquote,figcaption,summary,label,.res,.lead{overflow-wrap:anywhere}label{max-width:100%;box-sizing:border-box}#out table:not(:has(tr>:nth-child(4))){display:table;table-layout:fixed;width:100%}#out table:has(tr>:nth-child(4)),#out table:has(tr>:nth-child(4)) tbody,#out table:has(tr>:nth-child(4)) tr,#out table:has(tr>:nth-child(4)) td{display:block;width:auto;overflow:visible}#out table:has(tr>:nth-child(4)) thead{display:none}#out table:has(tr>:nth-child(4)) tr{padding:10px 0;border-bottom:1px solid rgba(128,128,128,.28)}#out table:has(tr>:nth-child(4)) td{border:0;padding:1px 0}#out table:has(tr>:nth-child(4)) td:nth-child(-n+3){display:inline-block;margin-right:10px;font-size:12px;opacity:.78}}</style> | |
| <!--yj-canon-s101--><link rel="canonical" href="https://getreadystack.com/tools/python-310-eol-pin-check"><!--yj-trust-org-s191--><script type="application/ld+json" data-yj="yj-trust-org">{"@context": "https://schema.org", "@type": "Organization", "name": "ReadyStack", "url": "https://getreadystack.com/", "logo": "https://getreadystack.com/branding/readystack_profile.png", "email": "support@getreadystack.com", "contactPoint": {"@type": "ContactPoint", "contactType": "customer support", "email": "support@getreadystack.com", "availableLanguage": ["English", "German", "Japanese", "Spanish", "Portuguese"]}}</script><!--/yj-trust-org-s191--></head> | |
| <body> | |
| <div class="wrap"> | |
| <h1>Python 3.10 End of Life — find pins and show the fix</h1> | |
| <p class="lede">Python 3.10 end of life was 2026-10-01. Finds every 3.10 pin — Dockerfile, GitHub Actions, tox, .python-version, Lambda, Cloud Run functions, Azure — with file:line, the dated fact and the 3.13 fix. Runs entirely in your browser — nothing is uploaded.</p> | |
| <textarea id="src" spellcheck="false">name: deploy | |
| on: | |
| push: | |
| branches: [main] | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ['3.10', '3.11', '3.12'] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - run: pip install -r requirements.txt && pytest | |
| build: | |
| runs-on: ubuntu-latest | |
| container: python:3.10-slim | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - run: pip wheel . -w dist | |
| deploy: | |
| needs: [test, build] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.10' | |
| - run: aws lambda update-function-configuration --function-name billing-export --runtime python3.10 | |
| - run: gcloud functions deploy invoice-webhook --gen2 --runtime python310 --region europe-west1 --trigger-http | |
| - run: az functionapp config set --name reports-fn --resource-group ops --linux-fx-version "PYTHON|3.10"</textarea> | |
| <div class="bar"><button id="go">Check</button><label>as of <input type="date" id="today"></label></div> | |
| <div id="out" aria-live="polite"></div> | |
| <div id="paid"><strong>Free here:</strong> Check the open file: every Python 3.10 pin with its line, the dated end-of-life or cloud-runtime fact for that place, and the one-line fix (Quick Fix applies it).. <strong>In the editor:</strong> Fix all lines in every file at once with a preview and a dated change record ($29 once); team key adds the company exposure report and a CI gate on new 3.10 pins. — that part asks for a licence key.</div> | |
| <p class="note"><a href="https://getreadystack.com/api/buy/cl/polar_cl_T5u1TmZEv7E3AJdUtY7kLZzZUsO5PxXsXz7vh1auiYI">Fix all 3.10 pins in every file at once (VS Code, preview + dated record) — $29 once</a></p> | |
| <p class="note">Same engine as the VS Code extension, byte for byte.</p> | |
| </div> | |
| <script>var PY310_RULES = [ | |
| {"id": "docker_image", "sev": "error", "title": "Docker image python:3.10", "where": "Dockerfile FROM · compose image: · CI container: · Lambda base image", "fact": "psf", "fix": "python:3.13 with the same tail (-slim, -alpine, -bookworm)", "auto": true, | |
| "facts": { | |
| "psf": {"text": "Python 3.10 reached end of life on 2026-10-01; 3.10.22 was the final release and the PSF ships no further security patches.", "date": "2026-10-01", "source": "https://endoflife.date/api/python.json"}, | |
| "aws_lambda": {"text": "AWS Lambda python3.10 (Amazon Linux 2): deprecation 2026-10-31 · block function create 2027-07-29 · block function update 2027-08-31.", "date": "2026-10-31", "source": "https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html"}, | |
| "gcp_functions": {"text": "Google Cloud Run functions python310: deprecation 2026-10-04 · decommission 2027-04-04.", "date": "2026-10-04", "source": "https://cloud.google.com/functions/docs/runtime-support"}, | |
| "azure_functions": {"text": "Azure Functions Python 3.10: expected end of support October 2026. Python 3.12 is the last version supported on the Linux Consumption plan.", "date": "2026-10", "source": "https://learn.microsoft.com/en-us/azure/azure-functions/supported-languages"}, | |
| "replacement": {"text": "Python 3.13 gets security support until 2029-10-31; Python 3.12 until 2028-10-31.", "date": "2029-10-31", "source": "https://endoflife.date/api/python.json"} | |
| }}, | |
| {"id": "docker_old_debian", "sev": "error", "title": "python:3.10 on Debian buster/bullseye", "where": "Dockerfile FROM · compose image:", "fact": "psf", "fix": "by hand: there is no python:3.13 buster/bullseye image — move to python:3.13-bookworm and re-test apt packages", "auto": false}, | |
| {"id": "gha_python_version", "sev": "warning", "title": "setup-python python-version 3.10", "where": ".github/workflows/*.yml", "fact": "psf", "fix": "python-version: '3.13'", "auto": true}, | |
| {"id": "gha_matrix", "sev": "warning", "title": "3.10 in a CI matrix", "where": ".github/workflows/*.yml matrix", "fact": "psf", "fix": "replace '3.10' with '3.13' in the matrix", "auto": true}, | |
| {"id": "gha_matrix_has_313", "sev": "warning", "title": "3.10 in a matrix that already has 3.13", "where": ".github/workflows/*.yml matrix", "fact": "psf", "fix": "by hand: drop '3.10' from the matrix (3.13 is already there) or keep it on purpose for library users", "auto": false}, | |
| {"id": "tox_env", "sev": "warning", "title": "tox env py310", "where": "tox.ini envlist · [testenv:py310] · basepython", "fact": "psf", "fix": "by hand: add py313 to envlist; drop py310 only if you no longer support 3.10", "auto": false}, | |
| {"id": "nox_python", "sev": "warning", "title": "nox session python 3.10", "where": "noxfile.py", "fact": "psf", "fix": "by hand: add \"3.13\" to the session list; drop \"3.10\" only if you no longer support it", "auto": false}, | |
| {"id": "python_version_file", "sev": "warning", "title": ".python-version / .tool-versions on 3.10", "where": ".python-version · .tool-versions", "fact": "psf", "fix": "3.13 (python 3.13 in .tool-versions)", "auto": true}, | |
| {"id": "runtime_txt", "sev": "error", "title": "runtime.txt python-3.10", "where": "runtime.txt", "fact": "psf", "fix": "python-3.13", "auto": true}, | |
| {"id": "pipfile_python", "sev": "warning", "title": "Pipfile python_version 3.10", "where": "Pipfile [requires]", "fact": "psf", "fix": "python_version = \"3.13\" (python_full_version by hand)", "auto": true}, | |
| {"id": "requires_python_cap", "sev": "warning", "title": "requires-python capped at 3.10", "where": "pyproject.toml requires-python · setup.cfg python_requires", "fact": "psf", "fix": "by hand: widen the cap (for example \u003e=3.10,\u003c3.14) — a library may keep 3.10 support on purpose", "auto": false}, | |
| {"id": "classifier_310", "sev": "info", "title": "classifier Python :: 3.10", "where": "pyproject.toml · setup.cfg classifiers", "fact": "psf", "fix": "by hand: keep it if you still test 3.10; add Python :: 3.13", "auto": false}, | |
| {"id": "conda_python", "sev": "warning", "title": "conda python=3.10", "where": "environment.yml · conda create", "fact": "psf", "fix": "python=3.13", "auto": true}, | |
| {"id": "aws_lambda_runtime", "sev": "error", "title": "AWS Lambda runtime python3.10", "where": "SAM/CloudFormation Runtime: · serverless.yml runtime: · Terraform runtime = · aws lambda --runtime · CDK Runtime.PYTHON_3_10", "fact": "aws_lambda", "fix": "python3.13 (CDK: Runtime.PYTHON_3_13)", "auto": true}, | |
| {"id": "gcp_runtime", "sev": "error", "title": "Google Cloud runtime python310", "where": "gcloud functions deploy --runtime · Terraform google_cloudfunctions runtime · app.yaml runtime:", "fact": "gcp_functions", "fix": "python313", "auto": true}, | |
| {"id": "azure_linuxfx", "sev": "error", "title": "Azure linuxFxVersion Python|3.10", "where": "Bicep/ARM linuxFxVersion · az functionapp --linux-fx-version", "fact": "azure_functions", "fix": "Python|3.12 (the last version on the Linux Consumption plan)", "auto": true}, | |
| {"id": "precommit_python", "sev": "warning", "title": "pre-commit language_version python3.10", "where": ".pre-commit-config.yaml", "fact": "psf", "fix": "python3.13", "auto": true} | |
| ] | |
| ;</script> | |
| <script>// Python 3.10 End of Life — pin check. Finds every place a project PINS Python 3.10 (not stdlib API use). | |
| // Every dated sentence comes from rules[0].facts (each with its source URL) — ⛔no date is computed from a rule. | |
| (function () { | |
| 'use strict'; | |
| var RULES = (typeof module !== 'undefined') ? require('./rules.json') : window.PY310_RULES; | |
| var BY = {}; RULES.forEach(function (r) { BY[r.id] = r; }); | |
| var FACTS = RULES[0].facts; | |
| var RX = { | |
| docker: /\bpython:3\.10(?![\d])((?:\.\d+)?)((?:-[\w.]+)*)/, | |
| gha_one: /^\s*-?\s*python-version\s*:\s*(['"]?)3\.10(?:\.\d+|\.x)?\1\s*(?:#.*)?$/, | |
| arr: /^\s*-?\s*(?:python-version|python|python_version|py|pyver)\s*:\s*\[([^\]]*)\]/, | |
| arr310: /(['"]?)3\.10(?:\.\d+|\.x)?\1(?=\s*(?:,|$))/, | |
| arr313: /(['"]?)3\.13(?:\.\d+|\.x)?\1(?=\s*(?:,|$))/, | |
| key: /^(\s*)-?\s*(?:python-version|python|python_version)\s*:\s*(?:#.*)?$/, | |
| item: /^(\s*)-\s*(['"]?)3\.(1\d)(?:\.\d+|\.x)?\2\s*(?:#.*)?$/, | |
| tox: /^\s*(?:env_?list\s*=.*\bpy310\b|\[testenv:[^\]]*\bpy310\b|basepython\s*=\s*python3\.10(?![\d]))/, | |
| nox: /(?:@nox\.session\(|^\s*PYTHON\w*\s*=)[^#\n]*['"]3\.10['"]/, | |
| pyver: /^\s*(?:cpython-)?3\.10(?:\.\d+)?\s*$/, | |
| toolv: /^\s*python\s+(?:[\d.]+\s+)*3\.10(?:\.\d+)?\b/, | |
| rtxt: /^\s*python-3\.10(?:\.\d+)?\s*$/, | |
| pipfile: /^\s*python_(?:full_)?version\s*=\s*["']3\.10(?:\.\d+)?["']/, | |
| reqpy: /^\s*["']?(?:requires-python|python_requires)["']?\s*[=:]\s*["']?([^"'\n#]*)/, | |
| cap: /(?:==\s*3\.10(?![\d])|~=\s*3\.10(?![\d])|<\s*3\.11(?![\d])|<=\s*3\.10(?![\d]))/, | |
| classifier: /Programming Language :: Python :: 3\.10(?![\d])/, | |
| conda: /(?:^|[\s"'-])python\s*={1,2}\s*3\.10(?![\d])/, | |
| lambda: /(?:\b[Rr]untime["']?\s*[:=]\s*["']?python3\.10(?![\d])|--runtime[ =]["']?python3\.10(?![\d])|\bRuntime\.PYTHON_3_10\b)/, | |
| gcp: /(?:\b[Rr]untime["']?\s*[:=]\s*["']?python310\b|--runtime[ =]["']?python310\b)/, | |
| azure: /python\|3\.10(?![\d])/i, | |
| precommit: /^\s*(?:language_version|python)\s*:\s*["']?python3\.10(?![\d])/ | |
| }; | |
| function base(p) { return String(p || '').replace(/\\/g, '/').split('/').pop(); } | |
| function days(a, b) { | |
| if (!/^\d{4}-\d{2}-\d{2}$/.test(String(a || '')) || !/^\d{4}-\d{2}-\d{2}$/.test(String(b || ''))) return ''; | |
| var d = Math.round((Date.parse(b + 'T00:00:00Z') - Date.parse(a + 'T00:00:00Z')) / 86400000); | |
| return d > 0 ? ' (' + d + ' days from ' + a + ')' : d < 0 ? ' (' + (-d) + ' days ago, counted from ' + a + ')' : ' (that is today)'; | |
| } | |
| function fact(id, today) { | |
| var f = FACTS[id]; return f.text + (id === 'aws_lambda' ? ' Next: deprecation 2026-10-31' + days(today, '2026-10-31') + '.' : '') + ' Source: ' + f.source; | |
| } | |
| function check(text, opts) { | |
| opts = opts || {}; | |
| var today = String(opts.today || new Date().toISOString().slice(0, 10)).slice(0, 10), bn = base(opts.path); | |
| var L = String(text == null ? '' : text).split(/\r?\n/), out = []; | |
| var real = L.filter(function (s) { return s.trim() && !/^\s*#/.test(s); }); | |
| var isPyver = bn === '.python-version' || (!bn && real.length > 0 && real.length <= 2); | |
| var isApp = /^app\.ya?ml$/.test(bn); | |
| var block = null; // a YAML key `python-version:` followed by a list of versions | |
| var toxc = false; // s188 G5 — inside a multi-line tox value (envlist = / [gh-actions] python =): indented lines that name py310 are pins too | |
| function add(id, i, extra) { | |
| var r = BY[id]; | |
| out.push({ check: id, sev: r.sev, line: i + 1, | |
| msg: r.title + ' — ' + fact(r.fact, today) + (extra || '') + ' Fix: ' + r.fix + '. ' + FACTS.replacement.text }); | |
| } | |
| for (var i = 0; i < L.length; i++) { | |
| var s = L[i], m; | |
| if (block && s.trim() !== '' && !/^\s*-/.test(s)) block = null; | |
| if (/^\s*(?:#|\/\/)/.test(s)) continue; | |
| if (toxc && s.trim() && !/^\s/.test(s)) toxc = false; | |
| if (toxc && /^\s/.test(s)) { if (/\bpy310\b/.test(s)) add('tox_env', i); continue; } | |
| if (/^(?:env_?list|python)\s*=/.test(s)) toxc = true; | |
| if (block && (m = RX.item.exec(s))) { if (m[3] === '10') add(block.has313 ? 'gha_matrix_has_313' : 'gha_matrix', i); continue; } | |
| if ((m = RX.key.exec(s))) { | |
| var ind = m[1].length, has = false; | |
| for (var j = i + 1; j < L.length && j < i + 20; j++) { var mm = RX.item.exec(L[j]); if (!mm) break; if (mm[3] === '13') has = true; } | |
| block = { ind: ind, has313: has }; continue; | |
| } | |
| if ((m = RX.docker.exec(s))) { add(/(?:buster|bullseye)/.test(m[2]) ? 'docker_old_debian' : 'docker_image', i, /lambda\/python:3\.10/.test(s) ? ' ' + FACTS.aws_lambda.text : ''); continue; } | |
| if ((m = RX.arr.exec(s))) { | |
| var parts = m[1].split(',').map(function (x) { return x.trim(); }); | |
| if (parts.some(function (x) { return /^['"]?3\.10(?:\.\d+|\.x)?['"]?$/.test(x); })) { | |
| add(parts.some(function (x) { return /^['"]?3\.13(?:\.\d+|\.x)?['"]?$/.test(x); }) ? 'gha_matrix_has_313' : 'gha_matrix', i); continue; | |
| } | |
| } | |
| if (RX.gha_one.test(s)) { add('gha_python_version', i); continue; } | |
| if (RX.lambda.test(s)) { add('aws_lambda_runtime', i); continue; } | |
| if (RX.gcp.test(s)) { add('gcp_runtime', i, isApp ? ' (app.yaml is App Engine: its runtimes follow the App Engine support schedule — the PSF end of life on 2026-10-01 still applies.)' : ''); continue; } | |
| if (RX.azure.test(s)) { add('azure_linuxfx', i); continue; } | |
| if (RX.precommit.test(s)) { add('precommit_python', i); continue; } | |
| if (RX.tox.test(s)) { add('tox_env', i); continue; } | |
| if (RX.nox.test(s) && (bn === 'noxfile.py' || /nox/.test(s))) { add('nox_python', i); continue; } | |
| if (RX.rtxt.test(s)) { add('runtime_txt', i); continue; } | |
| if (RX.toolv.test(s)) { add('python_version_file', i); continue; } | |
| if (isPyver && RX.pyver.test(s)) { add('python_version_file', i); continue; } | |
| if (RX.pipfile.test(s)) { add('pipfile_python', i); continue; } | |
| if ((m = RX.reqpy.exec(s)) && RX.cap.test(m[1])) { add('requires_python_cap', i); continue; } | |
| if (RX.classifier.test(s)) { add('classifier_310', i); continue; } | |
| if (RX.conda.test(s)) { add('conda_python', i); continue; } | |
| } | |
| return { findings: out, today: today, rules: RULES.length }; | |
| } | |
| var API = { engine: { check: check }, RULES: RULES, RULE_COUNT: RULES.length, FACTS: FACTS }; | |
| if (typeof module !== 'undefined' && module.exports) module.exports = API; | |
| if (typeof window !== 'undefined') window.PY310ENGINE = API; | |
| })(); | |
| </script> | |
| <script>// ⛔뼈대 — kit/scaffold.py 가 찍는다 (s143). findings [{check,sev,msg,line?}] → 글/HTML. 같은 파일이 Node 와 브라우저에서 산다. | |
| ; | |
| function escapeHtml(s) { return String(s == null ? '' : s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); } | |
| function summaryLine(res) { | |
| const f = (res && res.findings) || []; const e = f.filter(function (x) { return String(x.sev || 'error').toLowerCase().startsWith('err'); }).length; | |
| return f.length ? (f.length + ' finding' + (f.length === 1 ? '' : 's') + ' (' + e + ' error' + (e === 1 ? '' : 's') + ')') : 'Clean — no findings.'; | |
| } | |
| function toText(res, label) { | |
| const f = (res && res.findings) || []; | |
| const lines = ['== ' + (label || '') + ' — ' + summaryLine(res)]; | |
| f.forEach(function (x) { lines.push(' ' + String(x.sev || 'error').toUpperCase().slice(0, 4) + ' ' + (x.line ? 'L' + x.line + ' ' : '') + (x.check || x.id || '') + ' ' + (x.msg || x.message || '')); }); | |
| return lines.join('\n'); | |
| } | |
| function toHtml(res) { | |
| const f = (res && res.findings) || []; | |
| if (!f.length) return '<p class="ok">' + escapeHtml(summaryLine(res)) + '</p>'; | |
| const rows = f.map(function (x) { return '<tr><td class="sev ' + escapeHtml(String(x.sev || 'error')) + '">' + escapeHtml(String(x.sev || 'error')) + '</td><td>' + (x.line ? 'L' + escapeHtml(x.line) : '') + '</td><td><code>' + escapeHtml(x.check || x.id || '') + '</code></td><td>' + escapeHtml(x.msg || x.message || '') + '</td></tr>'; }).join(''); | |
| return '<p class="sum">' + escapeHtml(summaryLine(res)) + '</p><table><thead><tr><th>Level</th><th>Line</th><th>Check</th><th>What</th></tr></thead><tbody>' + rows + '</tbody></table>'; | |
| } | |
| var PY310REPORT = { escapeHtml: escapeHtml, summaryLine: summaryLine, toText: toText, toHtml: toHtml }; | |
| if (typeof module !== 'undefined' && module.exports) module.exports = PY310REPORT; | |
| else window.PY310REPORT = PY310REPORT; | |
| </script> | |
| <script> | |
| (function(){ | |
| var src=document.getElementById('src'), out=document.getElementById('out'), go=document.getElementById('go'), today=document.getElementById('today'); | |
| today.value=new Date().toISOString().slice(0,10); | |
| function run(){ try { var res=window.PY310ENGINE.engine.check(src.value,{today:today.value}); out.innerHTML=window.PY310REPORT.toHtml(res); } catch(e){ out.innerHTML='<p class="sev error">Could not run: '+String(e.message||e)+'</p>'; } } | |
| go.onclick=run; if (src.value.trim()) run(); | |
| })(); | |
| </script> | |
| <section data-yj-install="free" style="margin:2rem auto 1rem;max-width:46rem;padding:1.25rem 1.25rem;border:1px solid #cfe3d6;border-radius:12px;background:#f6fbf8;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .4rem;font-size:1.2rem">Install free</h2><p style="margin:0 0 .8rem;color:#41505f">Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.</p><a href="https://marketplace.visualstudio.com/items?itemName=ReadyStack.python-310-eol-pin-check" rel="noopener" data-yj-install-door="mp" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'python-310-eol-pin-check',src:'mp',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">VS Code Marketplace</a><a href="https://open-vsx.org/extension/readystack/python-310-eol-pin-check" rel="noopener" data-yj-install-door="ovsx" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'python-310-eol-pin-check',src:'ovsx',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Open VSX (Cursor, VSCodium)</a><pre style="margin:.5rem 0 0;padding:.6rem .8rem;background:#f3f5f8;border-radius:8px;font-size:.9rem;overflow:auto">ext install ReadyStack.python-310-eol-pin-check</pre><p style="margin:.6rem 0 0;font-size:.92rem;color:#41505f"><a href="https://getreadystack.com/api/buy/team" rel="nofollow" style="color:#0f7b3f;text-decoration:underline">Team? One key for every ReadyStack linter, 5 seats, $149 once</a></p></section> | |
| <section data-yj-alert="rule" style="margin:1rem auto 1.5rem;max-width:46rem;padding:1.1rem 1.25rem;border:1px solid #d9dee6;border-radius:12px;background:#fbfcfd;font:15px/1.55 system-ui,-apple-system,Segoe UI,sans-serif"><b style="font-size:1.05rem">Get one email when this rule changes</b><div style="opacity:.78;margin:.35rem 0 .8rem">We watch the regulation and vendor sources behind Python 3.10 End of Life — Pin Check & Fix every day. When a rule changes, you get a single email with what changed and the updated check. No newsletter.</div><div style="display:flex;gap:8px;flex-wrap:wrap"><input id="yjae" type="email" placeholder="you@example.com" style="flex:1;min-width:210px;padding:11px 13px;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:#fff;color:inherit"><button id="yjab" style="padding:11px 18px;border-radius:8px;border:0;cursor:pointer;background:#0f7b3f;color:#fff;font:600 15px system-ui,sans-serif">Notify me</button></div><div id="yjao" hidden style="margin-top:.6rem;color:#0f7b3f">You're on the list. One email when it changes.</div><script>(function(){var b=document.getElementById("yjab"),e=document.getElementById("yjae");if(!b||!e)return;b.addEventListener("click",function(){var v=e.value.trim();if(!/.+@.+\..+/.test(v))return;try{localStorage.setItem("yj_em","1");}catch(_){}fetch(location.origin+"/api/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:v,slug:"python-310-eol-pin-check",lang:"en",source:"rule_alert"+((b.closest&&b.closest("section")&&b.closest("section").getAttribute("data-yj-moved"))?"_at_result":"")})}).then(function(r){var o=document.getElementById("yjao");o.hidden=false;if(!r.ok){o.textContent="Could not save - please try again.";}}).catch(function(){var o=document.getElementById("yjao");o.hidden=false;o.textContent="Could not save - please try again.";});});})();</script><script>(function(){var e=document.getElementById("yjae"),s=e&&e.closest?e.closest("section"):null,o=document.getElementById("out");if(!s||!o)return;var d=false;function mv(ev){if(d)return;if(ev&&ev.target&&s.contains(ev.target))return;d=true;var b=o;while(b.parentNode&&b.parentNode!==document.body&&b.parentNode.tagName!=="MAIN"&&b.parentNode.tagName!=="ARTICLE")b=b.parentNode;if(!b.parentNode||b===s||b.contains(s))return;try{b.parentNode.insertBefore(s,b.nextSibling);s.setAttribute("data-yj-moved","1");}catch(_){}}document.addEventListener("input",mv,true);document.addEventListener("change",mv,true);document.addEventListener("click",function(ev){var b=ev.target&&ev.target.closest?ev.target.closest("button,input[type=submit]"):null;if(b&&!b.closest("[data-yj],[data-yj-cta],[data-yj-install],[data-yj-alert],.yj-find,.yj-related,#yj-ask,.yjp"))mv(ev);},true);})();</script></section> | |
| <section data-yj-cta="paid" style="margin:3rem auto;max-width:46rem;padding:1.5rem 1.25rem;border:1px solid #d8dee9;border-radius:12px;background:#fbfcfe;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .5rem;font-size:1.25rem">Get the full version <span class="yj-price">$29</span></h2><p class="yj-cta-paid" style="margin:.25rem 0 .6rem;color:#1f2a37">Fix all lines in every file at once with a preview and a dated change record ($29 once); team key adds the company exposure report and a CI gate on new 3.10 pins.</p><p class="yj-cta-pay" style="margin:.25rem 0 1rem;color:#5b6b7c;font-size:.94rem">One payment, one licence key for this tool. The key is shown right after payment.</p><p class="yj-cta-anchor" style="margin:0 0 1rem;color:#5b6b7c;font-size:.94rem">Upwork's own hiring page lists software developers at $10–$100 an hour; finding every 3.10 pin across Dockerfiles, CI, tox and cloud runtimes is billed at that rate.</p><a href="https://getreadystack.com/api/buy/cl/polar_cl_T5u1TmZEv7E3AJdUtY7kLZzZUsO5PxXsXz7vh1auiYI" rel="nofollow" style="display:inline-block;padding:.7rem 1.3rem;border-radius:8px;background:#1b64f2;color:#fff;text-decoration:none;font-weight:600">Buy the full version — $29</a></section><!--yj-trust-strip-s191--><aside data-yj="yj-trust-strip" style="max-width:46rem;margin:-1.8rem auto 2.4rem;padding:.9rem 1.2rem;border:1px solid #d8dee9;border-radius:12px;background:#f6f8fb;font:14.5px/1.55 system-ui,-apple-system,Segoe UI,sans-serif;color:#2b3640"><p style="margin:0 0 .3rem;font-weight:600">Buying here, plainly</p><ul style="margin:0;padding-left:1.2rem"><li style="margin:.25rem 0">Payment runs on Whop’s checkout: your card details go to Whop, not to us, and Whop emails you the receipt.</li><li style="margin:.25rem 0">Your licence key shows on the next page right after payment and stays in your Whop account (Your purchases).</li><li style="margin:.25rem 0">Chose a subscription? Cancel any time in your Whop account (Orders → Cancel membership); access lasts until the end of the period you paid.</li><li style="margin:.25rem 0">Your inputs are calculated in your browser and are not sent to us (unless you ask for the result by email).</li><li style="margin:.25rem 0">Questions before buying? support@getreadystack.com — we answer within 2 business days.</li></ul></aside><!--/yj-trust-strip-s191--> | |
| <!--yj-embed-s178--><details id="embed" data-yj="yj-embed" style="max-width:46rem;margin:1.6rem auto;padding:.85rem 1.1rem;border:1px solid #8884;border-radius:10px"><summary style="cursor:pointer;font-weight:600">Embed this tool on your site (free)</summary><p style="margin:.6rem 0;opacity:.85">Paste this code into your page. It runs in your visitor’s browser and stays up to date. Nothing your visitors type is stored.</p><textarea readonly rows="6" style="width:100%;font:12px/1.4 ui-monospace,Menlo,Consolas,monospace;border:1px solid #8886;border-radius:7px;padding:.5rem"><iframe src="https://getreadystack.com/embed/python-310-eol-pin-check/" title="Python 3.10 End of Life — Pin Check &amp; Fix — free online check" loading="lazy" data-rs-embed="en-python-310-eol-pin-check" style="width:100%;max-width:760px;height:640px;border:1px solid #e3e3e3;border-radius:10px"></iframe> | |
| <p style="font-size:13px;margin:6px 0 0"><a href="https://getreadystack.com/tools/python-310-eol-pin-check">Python 3.10 End of Life — Pin Check &amp; Fix — free online check</a> by <a href="https://getreadystack.com/">ReadyStack</a></p> | |
| <script>window.addEventListener("message",function(e){if(e.origin!=="https://getreadystack.com"||!e.data||e.data.type!=="readystack-embed")return;var f=document.querySelectorAll("iframe[data-rs-embed]");for(var i=0;i<f.length;i++){if(f[i].contentWindow===e.source)f[i].style.height=Math.min(e.data.h+6,8000)+"px";}});</script></textarea><p style="margin:.5rem 0 0"><button type="button" data-yj="yj-embed-copy" style="font:inherit;padding:8px 14px;border:1px solid #8884;border-radius:9px;background:transparent;cursor:pointer">Copy code</button> <a href="/embed/">All embeddable tools</a></p><p style="margin:.7rem 0 0;font-size:.92em;opacity:.9">For businesses: your name and logo instead of ours, and each visitor’s result + e-mail in your inbox (only when they tick consent) — Pro from $19/month. <a href="/embed/pro/?ref=embed_box">See Pro →</a></p></details><script data-yj="yj-embed">(function(){var b=document.querySelector("[data-yj=yj-embed-copy]");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var a=b.closest("details").querySelector("textarea");var v=a.value;function d(){b.textContent="Copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(v).then(d,function(){a.select();});}else{a.select();}});})();</script><!--yj-share-s101--><div style="margin:28px 0 8px;text-align:center"><button id="yjcp" type="button" style="font:inherit;padding:10px 18px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Copy link</button><button id="yjimg" type="button" style="font:inherit;padding:10px 18px;margin-left:8px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Save result as image</button></div><script>(function(){var b=document.getElementById("yjimg");if(!b)return;b.addEventListener("click",function(){var o=document.getElementById("out");var txt=(o&&(o.innerText||o.textContent)||"").trim();if(!txt){b.textContent="(no result yet)";setTimeout(function(){b.textContent="Save result as image";},1500);return;}var lines=txt.split(String.fromCharCode(10)).filter(function(x){return x.trim();}).slice(0,10);var W=1200,P=56,c=document.createElement("canvas");c.width=W;var lh=38,H=P*2+70+lines.length*lh+60;c.height=H;var x=c.getContext("2d");x.fillStyle="#1a1512";x.fillRect(0,0,W,H);x.fillStyle="#f3e9d2";x.font="600 34px system-ui,Segoe UI,Arial";var t=(document.title||"").split("|")[0].trim();x.fillText(t.slice(0,54),P,P+34);x.font="22px ui-monospace,Menlo,Consolas,monospace";x.fillStyle="#e8dcc4";for(var i=0;i<lines.length;i++){x.fillText(lines[i].slice(0,88),P,P+70+i*lh+22);}x.font="600 22px system-ui,Segoe UI,Arial";x.fillStyle="#c9a227";var d=location.hostname.replace("www.","");x.fillText(d,W-P-x.measureText(d).width,H-P+6);c.toBlob(function(bl){var u=URL.createObjectURL(bl),a=document.createElement("a");a.href=u;a.download=(t||"result").replace(/[^a-z0-9]+/gi,"-").toLowerCase()+"-"+d+".png";document.body.appendChild(a);a.click();setTimeout(function(){URL.revokeObjectURL(u);a.remove();},2000);},"image/png");});})();</script><script>(function(){var b=document.getElementById("yjcp");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var u=location.href.split("#")[0];function d(){b.textContent="Link copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(u).then(d,function(){prompt("",u);});}else{prompt("",u);}});})();</script> | |
| <script data-yj="yj-view-beacon">(function(){try{var p=location.pathname;var k='yjv:'+p;if(sessionStorage.getItem(k))return;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",ref:(document.referrer||''),src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}catch(e){}})();</script> | |
| <script data-yj="yj-use-beacon">(function(){try{var o=document.getElementById('out');if(!o)return;var p=location.pathname,k='yju:'+p,sent=false;function fire(){if(sent||sessionStorage.getItem(k))return;if(!(o.textContent||'').replace(/\s+/g,'').length)return;sent=true;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",t:'use',src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}var mo=new MutationObserver(function(){fire();if(sent)mo.disconnect();});mo.observe(o,{childList:true,characterData:true,subtree:true});}catch(e){}})();</script> | |
| <script data-yj="yj-prefill-s181 v1">(function(){try{var q=new URLSearchParams(location.search);if(!q.toString())return;var P={"R": {"employee": ["employee|w-?2\\b|arbeitnehmer|angestellt|会社員|従業員|給与所得|trabajador|asalariad|empregad|clt\\b|salari", "Employee"], "self": ["self-?employ|freelanc|sole (trader|prop)|selbst(ä|ae)ndig|freiberuf|個人事業|フリーランス|aut(ó|o)nom|\\bmei\\b", "Freelancer / self-employed"], "landlord": ["landlord|rental|vermiet|大家|不動産|arrendador|alquiler|locador|aluguel", "Landlord"], "investor": ["invest|trader|anleger|投資|inversor|investidor", "Investor / trader"], "employer": ["employer|arbeitgeber|雇用主|事業主|empleador|empregador", "Employer"], "seller": ["seller|online shop|h(ä|ae)ndler|販売|vendedor|e-?commerce", "Online seller"]}, "C": {"US": "^(us|usa)$|united states|estados unidos|vereinigte staaten|アメリカ|米国", "UK": "^(uk|gb)$|united kingdom|great britain|reino unido|vereinigtes k|イギリス|英国", "DE": "^de$|germany|deutschland|alemania|alemanha|ドイツ", "JP": "^jp$|japan|jap(ó|ã|o)n?|日本", "ES": "^es$|spain|españa|espana|espanha|spanien|スペイン", "BR": "^br$|brazil|brasil|ブラジル"}, "B": "your 2027 dates", "L": "en"};function ours(el){return !!(el&&el.closest&&el.closest("[data-yj],[data-yj-cta],[data-yj-cal],.yj-email-gate,.yj-find,.yj-related,#yj-ask,#yjgo,#yjr,header,footer,nav"));}function fields(){var r=document.querySelector("main")||document.body;return [].filter.call(r.querySelectorAll("input,select,textarea"),function(el){var t=(el.type||"").toLowerCase();return !ours(el)&&!el.disabled&&["email","hidden","search","password","file","submit","button","reset","image"].indexOf(t)<0;});}function key(el){return el.getAttribute("data-k")||el.id||el.name||"";}function fire(el){["input","change"].forEach(function(n){try{el.dispatchEvent(new Event(n,{bubbles:true}))}catch(e){}});}function setv(el,v){v=String(v).slice(0,80);var t=(el.type||"").toLowerCase(),tg=el.tagName;if(tg=="SELECT"){var o=[].filter.call(el.options,function(o){return o.value==v||o.text.trim()==v})[0];if(!o)return false;el.value=o.value;}else if(t=="checkbox"||t=="radio"){if(!/^(1|0|true|false|on|off|yes|no)$/i.test(v))return false;el.checked=/^(1|true|on|yes)$/i.test(v);}else if(t=="number"||t=="range"){var n=parseFloat(v.replace(/\s/g,"").replace(",","."));if(!isFinite(n))return false;el.value=String(n);}else if(t=="date"){if(!/^\d{4}-\d{2}-\d{2}$/.test(v))return false;el.value=v;}else{if(/[<>]/.test(v))return false;el.value=v;}fire(el);return true;}function pick(el,rx){if(el.tagName!="SELECT")return false;var re=new RegExp(rx,"i");var o=[].filter.call(el.options,function(o){return re.test(o.value)||re.test(o.text)})[0];if(!o||el.value==o.value)return false;el.value=o.value;fire(el);return true;}function run(){var F=fields(),done={},n=0;q.forEach(function(v,k){if(n>=20||/^(ref|role|cc|utm_.*|fbclid|gclid)$/.test(k)||!/^[A-Za-z0-9_-]{1,40}$/.test(k))return;F.forEach(function(el){if(key(el)===k&&!done[k]&&setv(el,v)){done[k]=1;n++;}});});var cc=(q.get("cc")||"").toUpperCase().replace(/[^A-Z]/g,"");if(P.C[cc])F.forEach(function(el){var k=key(el);if(!done[k]&&/country|land|pa(i|í)s|pays|国/i.test(k+" "+(el.id||""))&&pick(el,P.C[cc])){done[k]=1;n++;}});var ro=(q.get("role")||"").replace(/[^a-z]/g,""),R=P.R[ro];if(R)F.forEach(function(el){var k=key(el);if(!done[k]&&el.tagName=="SELECT"&&[].some.call(el.options,function(o){return [].some.call(Object.keys(P.R),function(x){return new RegExp(P.R[x][0],"i").test(o.text)})})&&pick(el,R[0])){done[k]=1;n++;}});if(q.get("ref")=="calendar"){var h=document.querySelector("main h1")||document.querySelector("h1");var d=document.createElement("div");d.setAttribute("data-yj","yj-prefill-back");d.style.cssText="margin:.4rem 0 .8rem;font:15px/1.5 system-ui,sans-serif;opacity:.9";var a=document.createElement("a");a.href="/"+P.L+"/calendar/?ref=tool"+(R?"&role="+ro:"")+(P.C[cc]?"&cc="+cc:"");a.textContent=(R?R[1]+" \u00b7 ":"")+P.B+" \u2192";d.appendChild(a);if(h&&h.parentNode)h.parentNode.insertBefore(d,h.nextSibling);}document.documentElement.setAttribute("data-yj-prefilled",String(n));}if(document.readyState=="loading")document.addEventListener("DOMContentLoaded",run);else run();}catch(e){}})();</script><div class="yj-home-find"><div class="yj-lgbar"><a href="/" class="yj-lg on">EN</a><a href="/de/" class="yj-lg">DE</a><a href="/ja/" class="yj-lg">JA</a><a href="/es/" class="yj-lg">ES</a><a href="/pt/" class="yj-lg">PT</a></div><section class="yj-find"><h2>Find a tool</h2><input id="yjq" type="search" autocomplete="off" placeholder="Type a product name, format or task"><div id="yjr"></div></section><style>.yj-lgbar{position:absolute;top:14px;right:18px;display:flex;gap:6px;z-index:60}.yj-lg{font:600 12px/1 system-ui,sans-serif;padding:6px 9px;border-radius:4px;text-decoration:none;color:#8b96a3;border:1px solid rgba(140,150,165,.28)}.yj-lg:hover{color:#e8eaed;border-color:rgba(160,175,195,.6)}.yj-lg.on{color:#0e1116;background:#cfd6de;border-color:#cfd6de}.yj-find{max-width:760px;margin:34px auto 8px;padding:0 20px}.yj-find h2{font:600 20px/1.3 system-ui,sans-serif;margin:0 0 10px}#yjq{width:100%;box-sizing:border-box;padding:13px 15px;font:400 15.5px system-ui,sans-serif;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:rgba(255,255,255,.04);color:inherit}#yjq:focus{outline:none;border-color:#7FD1C4}#yjr{margin-top:10px;display:flex;flex-direction:column;gap:6px}#yjr a{display:flex;justify-content:space-between;gap:12px;padding:11px 14px;border:1px solid rgba(140,150,165,.22);border-radius:6px;text-decoration:none;font:400 14.5px/1.4 system-ui,sans-serif;color:inherit}#yjr a:hover{border-color:#7FD1C4}#yjr .pr{font:600 13px system-ui,sans-serif;color:#5fbf9a;white-space:nowrap}</style><script>(function(){var q=document.getElementById("yjq"),r=document.getElementById("yjr"),D=null;function load(){if(D)return Promise.resolve(D);return fetch("/search-index.json").then(function(x){return x.json();}).then(function(j){D=j;return j;}).catch(function(){D=[];return D;});}function esc(t){return String(t).replace(/[&<>"]/g,function(c){return {"&":"&","<":"<",">":">",'"':"""}[c];});}function run(){var v=q.value.trim().toLowerCase();if(v.length<2){r.innerHTML="";return;}load().then(function(j){var w=v.split(/\s+/),o=[];for(var i=0;i<j.length&&o.length<12;i++){var t=j[i].t.toLowerCase();var ok=true;for(var k=0;k<w.length;k++){if(t.indexOf(w[k])<0){ok=false;break;}}if(ok)o.push(j[i]);}r.innerHTML=o.length?o.map(function(x){return "<a href=\""+esc(x.u)+"\">"+"<span>"+esc(x.t)+"</span>"+(x.p?"<span class=\"pr\">$"+x.p+"</span>":"")+"</a>";}).join(""):"";});}q.addEventListener("input",run);q.addEventListener("focus",load);})();</script></div><section data-yj="yj-facts-v1" style="max-width:920px;margin:48px auto 0;padding:0 20px;font-family:system-ui,sans-serif"><style>.yj-article p{font:400 15.5px/1.7 system-ui,sans-serif;color:#26313b;margin:0 0 12px;max-width:72ch}.yj-article h2,.yj-article h3,.yj-article h4{font:600 17px/1.35 system-ui,sans-serif;color:#1b1f24;margin:22px 0 8px}.yj-article table{border-collapse:collapse;margin:10px 0 16px;font:14px/1.45 system-ui,sans-serif}.yj-article th,.yj-article td{border:1px solid #e2e6ea;padding:6px 10px;text-align:left}.yj-article th{background:#f4f6f8}.yj-article pre{background:#0f1720;color:#e6edf3;padding:12px 14px;border-radius:8px;overflow:auto;font:13px/1.5 ui-monospace,Menlo,monospace}.yj-article code{font:13px ui-monospace,Menlo,monospace;background:#f1f3f5;padding:1px 4px;border-radius:3px}.yj-article pre code{background:none;padding:0}.yj-article ul,.yj-article ol{font:15px/1.6 system-ui,sans-serif;color:#26313b}</style><p style="font:400 13px/1.5 system-ui,sans-serif;color:#6b7680;margin:0 0 14px"><time datetime="2026-10-11">Updated 2026-10-11</time> · ReadyStack</p><script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","dateModified":"2026-10-11","author":{"@type":"Organization","name":"ReadyStack"}}</script><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Worked example</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 16px;color:#5b6570">Real numbers from this tool, line by line.</p><div class="yj-article"><p><img src="https://getreadystack.com/img/promo/sku598551_result_card.jpg" alt="Six end-of-life Python pins in deploy.yml" loading="lazy" style="max-width:100%;border-radius:6px"></p> | |
| <p>Six end-of-life Python pins sat in a single deploy.yml for a Python team shipping to AWS Lambda, Google Cloud Run functions and Azure Functions — 4 errors and 2 warnings, each with its line and its fix:</p> | |
| <table><thead><tr><th>Pinned line</th><th>Fix</th></tr></thead><tbody><tr><td>L10 python-version: ['3.10', '3.11', '3.12']</td><td>'3.13' in the matrix</td></tr><tr><td>L19 container: python:3.10-slim</td><td>python:3.13-slim</td></tr><tr><td>L30 python-version: '3.10'</td><td>python-version: '3.13'</td></tr><tr><td>L31 aws lambda --runtime python3.10</td><td>python3.13 · deprecation Oct 31, 2026</td></tr><tr><td>L32 gcloud functions --runtime python310</td><td>python313 · decommission Apr 4, 2027</td></tr><tr><td>L33 --linux-fx-version "PYTHON\</td><td>3.10"</td><td>PYTHON\</td><td>3.12 · Linux Consumption</td></tr></tbody></table> | |
| <p>Two of them are in the test job, one is the build container, and three are deploy flags that hand python3.10 straight to a cloud runtime. The Lambda line is the closest deadline: AWS deprecates python3.10 on Oct 31, 2026.</p> | |
| <h3>The dates, one per place</h3> | |
| <p>Python 3.10 reached end of life on Oct 1, 2026. 3.10.22 was the final release; the PSF ships no further security patches (endoflife.date). From then on, the date that matters depends on where the pin lives:</p> | |
| <ul><li><strong>AWS Lambda python3.10</strong> (Amazon Linux 2): deprecation Oct 31, 2026 · block function create Jul 29, 2027 · block function update Aug 31, 2027 (AWS Lambda runtimes page).</li><li><strong>Google Cloud Run functions python310</strong>: deprecation Oct 4, 2026 · decommission Apr 4, 2027 (Google runtime support page).</li><li><strong>Azure Functions Python 3.10</strong>: expected end of support October 2026. Python 3.12 is the last version supported on the Linux Consumption plan, so the Azure fix is PYTHON|3.12, not 3.13 (Azure supported languages page).</li><li><strong>Docker images and CI</strong>: no cloud block date, but python:3.10 images get no more interpreter security fixes after the PSF end of life.</li></ul> | |
| <p>The replacement has room: Python 3.13 gets security support until Oct 31, 2029 and Python 3.12 until Oct 31, 2028.</p> | |
| <h3>Why grep is not enough</h3> | |
| <p>grep for "3.10" finds the matrix and the container line. It misses python310 (Google), PYTHON_3_10 (AWS CDK) and py310 (tox), it matches unrelated version strings, and it tells you nothing about which date applies to the line it found. A chatbot gives one end-of-life date — some guides still print 31 October — not the Lambda, Google and Azure dates for each line in your own files.</p> | |
| <h3>What the check reads</h3> | |
| <p>17 rules across the places a project pins its interpreter: Dockerfile FROM and compose image lines, CI container images, setup-python python-version and matrices, tox envlist and testenv sections, nox sessions, .python-version, .tool-versions, runtime.txt, Pipfile python_version, conda python=3.10, pre-commit language_version, SAM and CloudFormation Runtime, serverless.yml, Terraform runtime, aws lambda --runtime, CDK Runtime.PYTHON_3_10, gcloud --runtime python310, app.yaml, and Azure linuxFxVersion.</p> | |
| <p>Some lines are never rewritten for you. python:3.10-bullseye and -buster have no 3.13 image, so they are listed with the how-to (move to bookworm). A matrix that already lists 3.13 is left to you. tox envs, nox sessions, requires-python caps and the Python :: 3.10 classifier get the date only — a library may keep 3.10 support on purpose.</p> | |
| <h3>Free first</h3> | |
| <p>Open the file and run the check: every pin, its date and source, and a Quick Fix for that line, with no key. Fixing all pins in every file at once, with a preview and a dated record of each change, is the paid step. Upwork's own hiring page lists software developers at $10–$100 an hour for the same sweep by hand.</p></div><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:30px 0 10px;color:#1b1f24">15 seconds — what it actually does</h2><video controls muted playsinline preload="none" poster="/img/promo/sku598551_result_card.jpg" style="width:100%;max-width:360px;border-radius:10px;display:block;margin:0 auto"><source src="/media/sku598551_short.mp4" type="video/mp4"></video><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:34px 0 6px;color:#1b1f24">Questions people ask</h2><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What does Python 3.10 End of Life — Pin Check & Fix do?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">It reads Dockerfiles, GitHub Actions workflows, tox.ini, noxfile.py, .python-version, runtime.txt, Pipfile, conda files, SAM, serverless, Terraform, app.yaml and Azure templates and lists every line that pins Python 3.10. Each finding gives the line, the dated fact for that place (PSF end of life 2026-10-01, Lambda deprecation 2026-10-31) with its source URL, and the one-line replacement.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Who is the Python 3.10 pin check for?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Python teams and platform engineers who ship to AWS Lambda, Google Cloud Run functions or Azure Functions, or build Docker images on python:3.10, and must move off 3.10 after its end of life on 2026-10-01. It also helps library maintainers see which CI matrix entries, tox envs and classifiers still name 3.10.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Why not grep or ask a chatbot about Python 3.10 end of life?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">grep for 3.10 misses python310, PYTHON_3_10 and py310 and matches unrelated version strings. A chatbot gives one end-of-life date, and some guides still print 31 October. Neither maps each line in your files to its own date: Lambda deprecation 2026-10-31, Cloud Run functions decommission 2027-04-04, Azure end of support October 2026.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What is free and what needs a licence key?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Free and without a key: check any open file, see every 3.10 pin with its date and source, and apply the Quick Fix for that line. The $29 key, paid once, fixes all pins in every workspace file at once with a preview and a dated change record. The $149 team key adds a company exposure report and a CI gate.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What does a manual Python 3.10 audit cost?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Upwork's own hiring page lists software developers at $10–$100 an hour. A manual sweep has to open Dockerfiles, every workflow, tox, nox, version files and each cloud template, then look up the Lambda, Google and Azure dates for each. The extension does that check for free and fixes all safe lines for $29 once.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">When is the next Python 3.10 deadline?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">AWS Lambda deprecates the python3.10 runtime on 2026-10-31, then blocks function create on 2027-07-29 and function update on 2027-08-31. Google Cloud Run functions decommissions python310 on 2027-04-04. Azure Functions lists end of support for Python 3.10 in October 2026. Sources: AWS Lambda runtimes page, Google runtime support page, Azure supported languages page.</p></details><script type="application/ld+json" data-yj="yj-faq-ld">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What does Python 3.10 End of Life — Pin Check & Fix do?", "acceptedAnswer": {"@type": "Answer", "text": "It reads Dockerfiles, GitHub Actions workflows, tox.ini, noxfile.py, .python-version, runtime.txt, Pipfile, conda files, SAM, serverless, Terraform, app.yaml and Azure templates and lists every line that pins Python 3.10. Each finding gives the line, the dated fact for that place (PSF end of life 2026-10-01, Lambda deprecation 2026-10-31) with its source URL, and the one-line replacement."}}, {"@type": "Question", "name": "Who is the Python 3.10 pin check for?", "acceptedAnswer": {"@type": "Answer", "text": "Python teams and platform engineers who ship to AWS Lambda, Google Cloud Run functions or Azure Functions, or build Docker images on python:3.10, and must move off 3.10 after its end of life on 2026-10-01. It also helps library maintainers see which CI matrix entries, tox envs and classifiers still name 3.10."}}, {"@type": "Question", "name": "Why not grep or ask a chatbot about Python 3.10 end of life?", "acceptedAnswer": {"@type": "Answer", "text": "grep for 3.10 misses python310, PYTHON_3_10 and py310 and matches unrelated version strings. A chatbot gives one end-of-life date, and some guides still print 31 October. Neither maps each line in your files to its own date: Lambda deprecation 2026-10-31, Cloud Run functions decommission 2027-04-04, Azure end of support October 2026."}}, {"@type": "Question", "name": "What is free and what needs a licence key?", "acceptedAnswer": {"@type": "Answer", "text": "Free and without a key: check any open file, see every 3.10 pin with its date and source, and apply the Quick Fix for that line. The $29 key, paid once, fixes all pins in every workspace file at once with a preview and a dated change record. The $149 team key adds a company exposure report and a CI gate."}}, {"@type": "Question", "name": "What does a manual Python 3.10 audit cost?", "acceptedAnswer": {"@type": "Answer", "text": "Upwork's own hiring page lists software developers at $10–$100 an hour. A manual sweep has to open Dockerfiles, every workflow, tox, nox, version files and each cloud template, then look up the Lambda, Google and Azure dates for each. The extension does that check for free and fixes all safe lines for $29 once."}}, {"@type": "Question", "name": "When is the next Python 3.10 deadline?", "acceptedAnswer": {"@type": "Answer", "text": "AWS Lambda deprecates the python3.10 runtime on 2026-10-31, then blocks function create on 2027-07-29 and function update on 2027-08-31. Google Cloud Run functions decommissions python310 on 2027-04-04. Azure Functions lists end of support for Python 3.10 in October 2026. Sources: AWS Lambda runtimes page, Google runtime support page, Azure supported languages page."}}]}</script><div id="yj-ask" style="margin:36px 0 0;padding:18px 18px 16px;border:1px solid #e2e6ea;border-radius:10px;background:#fbfbfc"><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:0 0 4px;color:#1b1f24">Ask about this tool</h2><p style="font:400 13.5px/1.5 system-ui,sans-serif;margin:0 0 12px;color:#5b6570">One question, answered by the person who built it. Your email only if you want the answer sent.</p><form onsubmit="return yjAsk(event)" style="display:grid;gap:8px"><textarea name="question" required minlength="10" maxlength="2000" rows="3" placeholder="Your question" style="font:14px/1.5 system-ui,sans-serif;padding:10px;border:1px solid #cfd6dd;border-radius:6px"></textarea><div style="display:flex;gap:8px;flex-wrap:wrap"><input type="email" name="email" placeholder="Email (optional)" style="flex:1;min-width:200px;font:14px system-ui,sans-serif;padding:9px 10px;border:1px solid #cfd6dd;border-radius:6px"><button type="submit" style="font:600 14px system-ui,sans-serif;padding:9px 18px;border:0;border-radius:6px;background:#1b1f24;color:#fff;cursor:pointer">Send</button></div><p id="yj-ask-msg" style="font:13px system-ui,sans-serif;margin:2px 0 0;color:#0a6238;min-height:1em"></p></form><script>function yjAsk(e){e.preventDefault();var f=e.target,m=document.getElementById("yj-ask-msg");m.style.color="#0a6238";fetch(location.origin+"/api/ask",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sku:598551,slug:"python-310-eol-pin-check",lang:"en",question:f.question.value,email:f.email.value,page:location.pathname})}).then(function(r){if(!r.ok)throw 0;m.textContent="Thanks \u2014 noted. Answers land on this page and, if you left an email, in your inbox.";f.question.value="";}).catch(function(){m.style.color="#a8551f";m.textContent="Could not send. Please try again in a minute.";});return false;}</script></div></section><section class="yj-related" style="max-width:920px;margin:56px auto 40px;padding:0 20px"><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Same job, next tool</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 20px;color:#5b6570">Free in the browser. The full version is a one-time licence.</p><div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px"><a class="yj-rel-c" href="https://getreadystack.com/tools/runtime-eol-deploy-block-audit?ref=related"><span class="yj-rel-t">Runtime EOL and Deploy-Block Audit for Docker, CI and AWS Lambda</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/base-image-eol-lint?ref=related"><span class="yj-rel-t">Base Image EOL Lint - Dockerfile and CI end-of-life check</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/skills/dockerfile-base-image-eol-check/?ref=related"><span class="yj-rel-t">Dockerfile EOL skill for Claude Code — end-of-life base images and FROM fixes</span><span class="yj-rel-p">$12</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/docker-image-for-data-science?ref=related"><span class="yj-rel-t">Docker Image for Data Science — Reproducible JupyterLab + MLflow Stack (Python</span><span class="yj-rel-p">$19.99</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/dotnet-eol-support-gate?ref=related"><span class="yj-rel-t">.NET EOL & CRA Support Window Gate</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/actions-deprecation-lint-2026?ref=related"><span class="yj-rel-t">GitHub Actions Deprecation Lint: the 2026 runner and action EOL dates</span><span class="yj-rel-p">$29</span></a></div><style>.yj-rel-c{display:flex;flex-direction:column;gap:8px;padding:15px 16px;border:1px solid #e2e6ea;border-radius:6px;text-decoration:none;background:#fff}.yj-rel-c:hover{border-color:#b9c2cb;background:#fafbfc}.yj-rel-t{font:500 14.5px/1.42 system-ui,sans-serif;color:#1b1f24}.yj-rel-p{font:600 13px system-ui,sans-serif;color:#0a6238}</style></section><!--yj-trust-foot-s191--><footer data-yj="yj-trust-foot" style="margin:3rem auto 0;padding:1.2rem 1rem 2rem;border-top:1px solid rgba(128,128,128,.28);max-width:60rem;font:14px/1.6 system-ui,-apple-system,Segoe UI,sans-serif;color:#5b6570;text-align:center"><nav aria-label="ReadyStack" style="display:flex;gap:.4rem 1.1rem;justify-content:center;flex-wrap:wrap"><a href="/about" style="color:inherit">About</a><a href="/verify/" style="color:inherit">How we verify</a><a href="/privacy" style="color:inherit">Privacy</a><a href="/terms" style="color:inherit">Terms</a><a href="/contact.html" style="color:inherit">Contact</a><a href="mailto:support@getreadystack.com" style="color:inherit">support@getreadystack.com</a></nav><p style="margin:.6rem 0 0">🔒 Secure checkout by Whop · © 2026 ReadyStack</p></footer><!--/yj-trust-foot-s191--></body> | |
| </html> | |