Merge pull request #34198 from akhilnarang/python3.14
build: support python3.14
This commit is contained in:
commit
0be60be5dd
13 changed files with 41 additions and 23 deletions
2
.github/workflows/_base-server-tests.yml
vendored
2
.github/workflows/_base-server-tests.yml
vendored
|
|
@ -9,7 +9,7 @@ on:
|
|||
python-version:
|
||||
required: false
|
||||
type: string
|
||||
default: '3.13'
|
||||
default: '3.14'
|
||||
node-version:
|
||||
required: false
|
||||
type: number
|
||||
|
|
|
|||
2
.github/workflows/_base-type-check.yml
vendored
2
.github/workflows/_base-type-check.yml
vendored
|
|
@ -5,7 +5,7 @@ on:
|
|||
python-version:
|
||||
required: false
|
||||
type: string
|
||||
default: '3.13.0'
|
||||
default: '3.14.0'
|
||||
|
||||
jobs:
|
||||
typecheck:
|
||||
|
|
|
|||
2
.github/workflows/_base-ui-tests.yml
vendored
2
.github/workflows/_base-ui-tests.yml
vendored
|
|
@ -9,7 +9,7 @@ on:
|
|||
python-version:
|
||||
required: false
|
||||
type: string
|
||||
default: '3.13'
|
||||
default: '3.14'
|
||||
node-version:
|
||||
required: false
|
||||
type: number
|
||||
|
|
|
|||
2
.github/workflows/generate-pot-file.yml
vendored
2
.github/workflows/generate-pot-file.yml
vendored
|
|
@ -25,7 +25,7 @@ jobs:
|
|||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.13"
|
||||
python-version: "3.14"
|
||||
|
||||
- name: Run script to update POT file
|
||||
run: |
|
||||
|
|
|
|||
8
.github/workflows/linters.yml
vendored
8
.github/workflows/linters.yml
vendored
|
|
@ -41,7 +41,7 @@ jobs:
|
|||
- name: 'Setup Environment'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.13'
|
||||
python-version: '3.14'
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Validate Docs
|
||||
|
|
@ -60,7 +60,7 @@ jobs:
|
|||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.13'
|
||||
python-version: '3.14'
|
||||
cache: pip
|
||||
|
||||
- name: Download Semgrep rules
|
||||
|
|
@ -78,7 +78,7 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.13'
|
||||
python-version: '3.14'
|
||||
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
|
|
@ -106,6 +106,6 @@ jobs:
|
|||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.13'
|
||||
python-version: '3.14'
|
||||
cache: pip
|
||||
- uses: pre-commit/action@v3.0.1
|
||||
|
|
|
|||
2
.github/workflows/on_release.yml
vendored
2
.github/workflows/on_release.yml
vendored
|
|
@ -26,7 +26,7 @@ jobs:
|
|||
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.13'
|
||||
python-version: '3.14'
|
||||
- name: Set up bench and build assets
|
||||
run: |
|
||||
npm install -g yarn
|
||||
|
|
|
|||
2
.github/workflows/publish-assets-develop.yml
vendored
2
.github/workflows/publish-assets-develop.yml
vendored
|
|
@ -19,7 +19,7 @@ jobs:
|
|||
node-version: 22
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.13'
|
||||
python-version: '3.14'
|
||||
- name: Set up bench and build assets
|
||||
run: |
|
||||
npm install -g yarn
|
||||
|
|
|
|||
2
.github/workflows/run-indinvidual-tests.yml
vendored
2
.github/workflows/run-indinvidual-tests.yml
vendored
|
|
@ -74,7 +74,7 @@ jobs:
|
|||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.13'
|
||||
python-version: '3.14'
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v6
|
||||
|
|
|
|||
|
|
@ -176,6 +176,13 @@ class TestRQJob(IntegrationTestCase):
|
|||
if frappe.conf.use_mysqlclient:
|
||||
# TEMP: Add extra allowance for running two connectors, this should be rolled back before v16
|
||||
LAST_MEASURED_USAGE += 2
|
||||
|
||||
# Observed higher usage on 3.14. Temporarily raising the limit
|
||||
from sys import version_info
|
||||
|
||||
if version_info >= (3, 14):
|
||||
LAST_MEASURED_USAGE += 5
|
||||
|
||||
self.assertLessEqual(rss, LAST_MEASURED_USAGE * 1.05, msg)
|
||||
|
||||
def test_clear_failed_jobs(self):
|
||||
|
|
|
|||
|
|
@ -144,6 +144,8 @@ class TestConnectedApp(IntegrationTestCase):
|
|||
doc = frappe.get_doc("OAuth Authorization Code", code.name)
|
||||
doc.delete()
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
delete_if_exists("user")
|
||||
delete_if_exists("oauth_client")
|
||||
|
||||
|
|
|
|||
|
|
@ -193,14 +193,16 @@ class TestPerformance(IntegrationTestCase):
|
|||
"""
|
||||
|
||||
query = "select * from tabUser"
|
||||
expected_refcount = 1 if sys.version_info >= (3, 14) else 2
|
||||
for kwargs in ({}, {"as_dict": True}, {"as_list": True}):
|
||||
result = frappe.db.sql(query, **kwargs)
|
||||
self.assertEqual(sys.getrefcount(result), 2) # Note: This always returns +1
|
||||
self.assertEqual(sys.getrefcount(result), expected_refcount) # Note: This always returns +1
|
||||
self.assertFalse(gc.get_referrers(result))
|
||||
|
||||
def test_no_cyclic_references(self):
|
||||
doc = frappe.get_doc("User", "Administrator")
|
||||
self.assertEqual(sys.getrefcount(doc), 2) # Note: This always returns +1
|
||||
expected_refcount = 1 if sys.version_info >= (3, 14) else 2
|
||||
self.assertEqual(sys.getrefcount(doc), expected_refcount) # Note: This always returns +1
|
||||
|
||||
def test_get_doc_cache_calls(self):
|
||||
frappe.get_doc("User", "Administrator")
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import os
|
|||
import random
|
||||
import signal
|
||||
import socket
|
||||
import sys
|
||||
import time
|
||||
from collections import defaultdict
|
||||
from collections.abc import Callable
|
||||
|
|
@ -373,6 +374,7 @@ class FrappeWorker(Worker):
|
|||
def start_frappe_scheduler(self):
|
||||
from frappe.utils.scheduler import start_scheduler
|
||||
|
||||
# TODO: switch to multiprocessing.Process() after further investigating of fork -> forkserver
|
||||
Thread(target=start_scheduler, daemon=True).start()
|
||||
|
||||
|
||||
|
|
@ -418,7 +420,6 @@ def start_worker_pool(
|
|||
|
||||
WARNING: This feature is considered "EXPERIMENTAL".
|
||||
"""
|
||||
|
||||
_start_sentry()
|
||||
|
||||
# If gc.freeze is done then importing modules before forking allows us to share the memory
|
||||
|
|
@ -447,9 +448,15 @@ def start_worker_pool(
|
|||
logging_level = "WARNING"
|
||||
|
||||
# TODO: Make this true by default eventually. It's limited to RQ WorkerPool
|
||||
no_fork = sbool(os.environ.get("FRAPPE_BACKGROUND_WORKERS_NOFORK", False))
|
||||
if sbool(os.environ.get("FRAPPE_BACKGROUND_WORKERS_NOFORK", False)):
|
||||
worker_klass = FrappeWorkerNoFork
|
||||
else:
|
||||
if sys.version_info >= (3, 14):
|
||||
import multiprocessing
|
||||
|
||||
multiprocessing.set_start_method("fork", force=True)
|
||||
worker_klass = FrappeWorker
|
||||
|
||||
worker_klass = FrappeWorkerNoFork if no_fork else FrappeWorker
|
||||
pool = WorkerPool(
|
||||
queues=queues,
|
||||
connection=redis_connection,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ authors = [
|
|||
{ name = "Frappe Technologies Pvt Ltd", email = "developers@frappe.io"}
|
||||
]
|
||||
description = "Metadata driven, full-stack low code web framework"
|
||||
requires-python = ">=3.10,<3.14"
|
||||
requires-python = ">=3.10,<3.15"
|
||||
readme = "README.md"
|
||||
dynamic = ["version"]
|
||||
dependencies = [
|
||||
|
|
@ -21,11 +21,11 @@ dependencies = [
|
|||
# do NOT add loose requirements on PyMySQL versions.
|
||||
"PyMySQL==1.1.1",
|
||||
"pypdf~=6.1.3",
|
||||
"PyPika @ git+https://github.com/frappe/pypika@093984977ce157d35e048c51d9ff55a1f0f44570",
|
||||
"PyPika @ git+https://github.com/frappe/pypika@2c50e6142b2d61d2d243e466fdd5dc03b3d918f2",
|
||||
"mysqlclient==2.2.7",
|
||||
"PyQRCode~=1.2.1",
|
||||
"PyYAML~=6.0.2",
|
||||
"RestrictedPython~=8.0",
|
||||
"RestrictedPython~=8.1",
|
||||
"WeasyPrint==66.0",
|
||||
"pydyf==0.11.0",
|
||||
"Werkzeug==3.1.3",
|
||||
|
|
@ -35,7 +35,7 @@ dependencies = [
|
|||
"bleach[css]~=6.2.0",
|
||||
"chardet~=5.2.0",
|
||||
"croniter~=6.0.0",
|
||||
"cryptography~=45.0.4",
|
||||
"cryptography~=46.0.2",
|
||||
"cssutils~=2.11.1",
|
||||
"email-reply-parser~=0.5.12",
|
||||
"gunicorn @ git+https://github.com/frappe/gunicorn@bb554053bb87218120d76ab6676af7015680e8b6",
|
||||
|
|
@ -47,15 +47,15 @@ dependencies = [
|
|||
"num2words~=0.5.14",
|
||||
"oauthlib~=3.2.2",
|
||||
"openpyxl~=3.1.5",
|
||||
"orjson~=3.10.18",
|
||||
"orjson~=3.11.3",
|
||||
"passlib~=1.7.4",
|
||||
"pdfkit~=1.0.0",
|
||||
"phonenumbers~=9.0.7",
|
||||
"premailer~=3.10.0",
|
||||
"psutil~=7.0.0",
|
||||
"psycopg2-binary~=2.9.1",
|
||||
"pyOpenSSL~=25.1.0",
|
||||
"pydantic~=2.11.7",
|
||||
"pyOpenSSL~=25.3.0",
|
||||
"pydantic~=2.12.0",
|
||||
"pyotp~=2.9.0",
|
||||
"python-dateutil~=2.9.0",
|
||||
"pytz==2025.2",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue