Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/check_wheel_availability.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
matrix: arm
- name: Intel
matrix: intel
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
exclude:
- os:
matrix: windows
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ jobs:
- major_dot_minor: "3.10"
- major_dot_minor: "3.11"
- major_dot_minor: "3.12"
- major_dot_minor: "3.13"
exclude:
- os:
matrix: windows
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-install-scripts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ jobs:
# The behavior we follow in install.sh is unique with Arch in that
# we leave it to the user to install the appropriate version of python,
# so we need to install python here in order for the test to succeed.
pacman --noconfirm -U --needed https://archive.archlinux.org/packages/p/python/python-3.12.7-1-x86_64.pkg.tar.zst
pacman --noconfirm -U --needed https://archive.archlinux.org/packages/p/python/python-3.13.5-1-x86_64.pkg.tar.zst

- name: Prepare Debian
if: ${{ matrix.distribution.type == 'debian' }}
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/test-single.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@ jobs:
exclude_from:
limited: True
main: True
- name: "3.13"
file_name: "3.13"
action: "3.13"
apt: "3.13"
install_sh: "3.13"
matrix: "3.13"
exclude_from:
limited: True
main: True
exclude:
- arch:
matrix: arm
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/upload-pypi-source.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ jobs:
- major_dot_minor: "3.10"
- major_dot_minor: "3.11"
- major_dot_minor: "3.12"
- major_dot_minor: "3.13"
check:
- name: mypy
command: |
Expand Down
2 changes: 1 addition & 1 deletion Install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ if ($null -eq (Get-Command py -ErrorAction SilentlyContinue))
Exit 1
}

$supportedPythonVersions = "3.12", "3.11", "3.10", "3.9"
$supportedPythonVersions = "3.13", "3.12", "3.11", "3.10", "3.9"
if ("$env:INSTALL_PYTHON_VERSION" -ne "")
{
$pythonVersion = $env:INSTALL_PYTHON_VERSION
Expand Down
14 changes: 11 additions & 3 deletions chia/_tests/core/server/test_event_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ def test_base_event_loop_has_methods() -> None:
assert hasattr(base_selector_event_loop, "create_server")
method = getattr(base_selector_event_loop, "create_server")
assert inspect.ismethod(method)
if sys.version_info >= (3, 11):
if sys.version_info >= (3, 13):
expected_signature = "(protocol_factory, host=None, port=None, *, family=<AddressFamily.AF_UNSPEC: 0>, flags=<AddressInfo.AI_PASSIVE: 1>, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, keep_alive=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True)" # noqa: E501
elif sys.version_info >= (3, 11):
expected_signature = "(protocol_factory, host=None, port=None, *, family=<AddressFamily.AF_UNSPEC: 0>, flags=<AddressInfo.AI_PASSIVE: 1>, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True)" # noqa: E501
else:
expected_signature = "(protocol_factory, host=None, port=None, *, family=<AddressFamily.AF_UNSPEC: 0>, flags=<AddressInfo.AI_PASSIVE: 1>, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, ssl_handshake_timeout=None, start_serving=True)" # noqa: E501
Expand Down Expand Up @@ -103,7 +105,13 @@ async def main() -> None:

for func in ("_attach", "_detach"):
assert hasattr(base_server, func)
method = getattr(base_server, func)
assert str(inspect.signature(method)) == "()"
if sys.version_info >= (3, 13):
# https://github.com/python/cpython/blob/bcee1c322115c581da27600f2ae55e5439c027eb/Lib/asyncio/base_events.py#L296
method = getattr(base_server, func)
assert str(inspect.signature(method)) == "(transport)"
else:
method = getattr(base_server, func)
assert str(inspect.signature(method)) == "()"

finally:
selector_event_loop.close()
44 changes: 32 additions & 12 deletions chia/server/chia_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import ssl
import struct
import sys
import weakref

if sys.platform == "win32":
import _overlapped # type: ignore[import-not-found]
Expand Down Expand Up @@ -57,15 +58,26 @@ class BaseEventsServer(asyncio.base_events.Server):
else:
_loop: EventsAbstractEventLoop
_sockets: Iterable[socket.socket]
_active_count: int
if sys.version_info >= (3, 13):
# https://github.com/python/cpython/blob/v3.13.7/Lib/asyncio/base_events.py#L283
_clients: weakref.WeakSet[object]
else:
_active_count: int
_protocol_factory: _ProtocolFactory
_backlog: int
_ssl_context: _SSLContext
_ssl_handshake_timeout: Optional[float]

def _attach(self) -> None: ...
if sys.version_info >= (3, 13):
# https://github.com/python/cpython/blob/bcee1c322115c581da27600f2ae55e5439c027eb/Lib/asyncio/base_events.py#L296
def _attach(self, transport: object) -> None: ...

def _detach(self, transport: object) -> None: ...
else:

def _attach(self) -> None: ...

def _detach(self) -> None: ...
def _detach(self) -> None: ...

def _start_serving(self) -> None: ...

Expand Down Expand Up @@ -132,20 +144,22 @@ def __init__(
max_concurrent_connections if max_concurrent_connections is not None else global_max_concurrent_connections
)

def _attach(self) -> None:
super()._attach()
logging.getLogger(__name__).debug(f"New connection. Total connections: {self._active_count}")
if not self._paused and self._active_count >= self.max_concurrent_connections:
def _attach(self, *args: object, **kwargs: object) -> None:
super()._attach(*args, **kwargs)
active_connections = self._chia_active_connections()
logging.getLogger(__name__).debug(f"New connection. Total connections: {active_connections}")
if not self._paused and active_connections >= self.max_concurrent_connections:
self._chia_pause()

def _detach(self) -> None:
super()._detach()
logging.getLogger(__name__).debug(f"Connection lost. Total connections: {self._active_count}")
def _detach(self, *args: object, **kwargs: object) -> None:
super()._detach(*args, **kwargs)
active_connections = self._chia_active_connections()
logging.getLogger(__name__).debug(f"Connection lost. Total connections: {active_connections}")
if (
self._active_count > 0
active_connections > 0
and self._sockets is not None
and self._paused
and self._active_count < self.max_concurrent_connections
and active_connections < self.max_concurrent_connections
):
self._chia_resume()

Expand Down Expand Up @@ -180,6 +194,12 @@ def _chia_resume(self) -> None:
)
logging.getLogger(__name__).debug("Resumed accepting connections.")

def _chia_active_connections(self) -> int:
if sys.version_info >= (3, 13):
return len(self._clients)
else:
return self._active_count


async def _chia_create_server(
cls: Any,
Expand Down
6 changes: 3 additions & 3 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ OPENSSL_VERSION_INT=
find_python() {
set +e
unset BEST_VERSION
for V in 312 3.12 311 3.11 310 3.10 39 3.9 3; do
for V in 313 3.13 312 3.12 311 3.11 310 3.10 39 3.9 3; do
if command -v python$V >/dev/null; then
if [ "$BEST_VERSION" = "" ]; then
BEST_VERSION=$V
Expand Down Expand Up @@ -135,8 +135,8 @@ if ! command -v "$INSTALL_PYTHON_PATH" >/dev/null; then
exit 1
fi

if [ "$PYTHON_MAJOR_VER" -ne "3" ] || [ "$PYTHON_MINOR_VER" -lt "7" ] || [ "$PYTHON_MINOR_VER" -ge "13" ]; then
echo "Chia requires Python version >= 3.9 and < 3.13.0" >&2
if [ "$PYTHON_MAJOR_VER" -ne "3" ] || [ "$PYTHON_MINOR_VER" -lt "7" ] || [ "$PYTHON_MINOR_VER" -ge "14" ]; then
echo "Chia requires Python version >= 3.9 and < 3.14.0" >&2
echo "Current Python version = $INSTALL_PYTHON_VERSION" >&2
# If Arch, direct to Arch Wiki
if type pacman >/dev/null 2>&1 && [ -f "/etc/arch-release" ]; then
Expand Down
14 changes: 7 additions & 7 deletions poetry.lock
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ description = "Python graph (network) package"
optional = true
python-versions = "*"
groups = ["main"]
markers = "extra == \"dev\" and python_version <= \"3.12\""
markers = "extra == \"dev\" and python_version < \"3.14\""
files = [
{file = "altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"},
{file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"},
Expand Down Expand Up @@ -1917,7 +1917,7 @@ description = "Mach-O header analysis and editing"
optional = true
python-versions = "*"
groups = ["main"]
markers = "extra == \"dev\" and sys_platform == \"darwin\" and python_version <= \"3.12\""
markers = "extra == \"dev\" and sys_platform == \"darwin\" and python_version < \"3.14\""
files = [
{file = "macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c"},
{file = "macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30"},
Expand Down Expand Up @@ -2381,7 +2381,7 @@ description = "Python PE parsing module"
optional = true
python-versions = ">=3.6.0"
groups = ["main"]
markers = "extra == \"dev\" and sys_platform == \"win32\" and python_version <= \"3.12\""
markers = "extra == \"dev\" and sys_platform == \"win32\" and python_version < \"3.14\""
files = [
{file = "pefile-2023.2.7-py3-none-any.whl", hash = "sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6"},
{file = "pefile-2023.2.7.tar.gz", hash = "sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc"},
Expand Down Expand Up @@ -2712,7 +2712,7 @@ description = "PyInstaller bundles a Python application and all its dependencies
optional = true
python-versions = "<3.15,>=3.8"
groups = ["main"]
markers = "extra == \"dev\" and python_version <= \"3.12\""
markers = "extra == \"dev\" and python_version < \"3.14\""
files = [
{file = "pyinstaller-6.15.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:9f00c71c40148cd1e61695b2c6f1e086693d3bcf9bfa22ab513aa4254c3b966f"},
{file = "pyinstaller-6.15.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:cbcc8eb77320c60722030ac875883b564e00768fe3ff1721c7ba3ad0e0a277e9"},
Expand Down Expand Up @@ -2749,7 +2749,7 @@ description = "Community maintained hooks for PyInstaller"
optional = true
python-versions = ">=3.8"
groups = ["main"]
markers = "extra == \"dev\" and python_version <= \"3.12\""
markers = "extra == \"dev\" and python_version < \"3.14\""
files = [
{file = "pyinstaller_hooks_contrib-2025.8-py3-none-any.whl", hash = "sha256:8d0b8cfa0cb689a619294ae200497374234bd4e3994b3ace2a4442274c899064"},
{file = "pyinstaller_hooks_contrib-2025.8.tar.gz", hash = "sha256:3402ad41dfe9b5110af134422e37fc5d421ba342c6cb980bd67cb30b7415641c"},
Expand Down Expand Up @@ -3799,7 +3799,7 @@ description = "ZSTD Bindings for Python"
optional = false
python-versions = "*"
groups = ["main"]
markers = "python_version == \"3.12\""
markers = "python_version >= \"3.12\""
files = [
{file = "zstd-1.5.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b5cd20afab8d13c52d2b2219bf18cc765eae87b8219343bce20647007890adab"},
{file = "zstd-1.5.5.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:0f467ab9b57ab8b4b874e6974d38b802f20406803bb7ec9308df923553cd48f7"},
Expand Down Expand Up @@ -3862,4 +3862,4 @@ upnp = ["miniupnpc"]
[metadata]
lock-version = "2.1"
python-versions = ">=3.9, <4, !=3.9.0, !=3.9.1"
content-hash = "650f0c98ff03cf897ee793ebb1e26bee8ae7b3c99bab5295fee7736bc19e346f"
content-hash = "b7d446b58d0bc30a0f35c407a90e167c2f79550d5216399c090db6fe2cc802f4"
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ typing-extensions = ">=4.12.2" # typing backports like Protocol and TypedDict
watchdog = ">=4.0.1" # Filesystem event watching - watches keyring.yaml
zstd = [
{version=">=1.5.5.1", python = "<3.12"},
{version=">=1.5.5.1", python = "3.12", source="chia"},
{version=">=1.5.5.1", python = ">=3.12", source="chia"},
]
importlib-resources = ">=6.4.5"
hsms = ">=0.3.1"
Expand All @@ -92,7 +92,7 @@ diff-cover = { version = ">=9.2.0", optional = true }
mypy = { version = ">=1.11.1", optional = true }
pre-commit = { version = ">=3.7.1", optional = true }
py3createtorrent = { version = ">=1.2.1", optional = true }
pyinstaller = { version = ">=6.9.0", python = "<3.13", optional = true }
pyinstaller = { version = ">=6.9.0", python = "<3.14", optional = true }
pytest = { version = ">=8.3.3", optional = true }
pytest-cov = { version = ">=5.0.0", optional = true }
pytest-mock = { version = ">=3.14.0", optional = true }
Expand Down
Loading