Skip to content
Merged
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
10 changes: 6 additions & 4 deletions .github/workflows/reusable-emscripten.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,17 @@ jobs:
run: python3 Platforms/emscripten configure-build-python -- --config-cache --with-pydebug
- name: "Make build Python"
run: python3 Platforms/emscripten make-build-python
- name: "Display build info of the build Python"
run: python3 Platforms/emscripten pythoninfo-build
- name: "Make dependencies"
run: >-
python3 Platforms/emscripten make-dependencies
${{ steps.emsdk-cache.outputs.cache-hit == 'true' && '--check-up-to-date' || '' }}
- name: "Configure host Python"
- name: "Configure host/Emscripten Python"
run: python3 Platforms/emscripten configure-host --host-runner node -- --config-cache
- name: "Make host Python"
- name: "Make host/Emscripten Python"
run: python3 Platforms/emscripten make-host
- name: "Display build info"
run: python3 Platforms/emscripten run --pythoninfo
- name: "Display build info of the host/Emscripten Python"
run: python3 Platforms/emscripten pythoninfo-host
- name: "Test"
run: python3 Platforms/emscripten run --test
11 changes: 6 additions & 5 deletions .github/workflows/reusable-wasi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ jobs:
timeout-minutes: 60
env:
WASMTIME_VERSION: 38.0.3
CROSS_BUILD_PYTHON: cross-build/build
CROSS_BUILD_WASI: cross-build/wasm32-wasip1
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand Down Expand Up @@ -54,14 +53,16 @@ jobs:
run: python3 Platforms/WASI configure-build-python -- --config-cache --with-pydebug
- name: "Make build Python"
run: python3 Platforms/WASI make-build-python
- name: "Configure host"
- name: "Display build info of the build Python"
run: python3 Platforms/WASI pythoninfo-build
- name: "Configure host/WASI Python"
# `--with-pydebug` inferred from configure-build-python
run: python3 Platforms/WASI configure-host -- --config-cache
env:
WASI_SDK_PATH: ${{ steps.install-wasi-sdk.outputs.wasi-sdk-path }}
- name: "Make host"
- name: "Make host/WASI Python"
run: python3 Platforms/WASI make-host
- name: "Display build info"
run: make --directory "${CROSS_BUILD_WASI}" pythoninfo
- name: "Display build info of the host/WASI Python"
run: python3 Platforms/WASI pythoninfo-host
- name: "Test"
run: make --directory "${CROSS_BUILD_WASI}" test
10 changes: 10 additions & 0 deletions Doc/deprecations/pending-removal-in-3.17.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,13 @@ Pending removal in Python 3.17

See :pep:`PEP 688 <688#current-options>` for more details.
(Contributed by Shantanu Jain in :gh:`91896`.)

* :mod:`tkinter`:

- The :class:`!tkinter.Variable` methods :meth:`!trace_variable`,
:meth:`!trace` (an alias of :meth:`!trace_variable`),
:meth:`!trace_vdelete` and :meth:`!trace_vinfo`, deprecated since
Python 3.14, are scheduled for removal in Python 3.17.
Use :meth:`!trace_add`, :meth:`!trace_remove` and :meth:`!trace_info`
instead.
(Contributed by Serhiy Storchaka in :gh:`120220`.)
120 changes: 93 additions & 27 deletions Lib/test/pythoninfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import warnings


MS_WINDOWS = (sys.platform == "win32")


def normalize_text(text):
if text is None:
return None
Expand Down Expand Up @@ -906,8 +909,30 @@ def collect_subprocess(info_add):
copy_attributes(info_add, subprocess, 'subprocess.%s', ('_USE_POSIX_SPAWN',))


def winreg_query(path):
try:
import winreg
except ImportError:
return None

key, path = path.split('\\', 1)
sub_key, value = path.rsplit('\\', 1)
if key == "HKEY_LOCAL_MACHINE":
key = winreg.HKEY_LOCAL_MACHINE
else:
raise ValueError(f"unknown key {key!r}")

try:
access = winreg.KEY_READ | winreg.KEY_WOW64_64KEY
with winreg.OpenKey(key, sub_key, access=access) as key_handle:
result, _ = winreg.QueryValueEx(key_handle, value)
return result
except OSError:
return None


def collect_windows(info_add):
if sys.platform != "win32":
if not MS_WINDOWS:
# Code specific to Windows
return

Expand Down Expand Up @@ -999,19 +1024,10 @@ def collect_windows(info_add):
info_add('windows.ver', line)

# windows.developer_mode: get AllowDevelopmentWithoutDevLicense registry
import winreg
try:
key = winreg.OpenKey(
winreg.HKEY_LOCAL_MACHINE,
r"SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock")
subkey = "AllowDevelopmentWithoutDevLicense"
try:
value, value_type = winreg.QueryValueEx(key, subkey)
finally:
winreg.CloseKey(key)
except OSError:
pass
else:
value = winreg_query(r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows"
r"\CurrentVersion\AppModelUnlock"
r"\AllowDevelopmentWithoutDevLicense")
if value is not None:
info_add('windows.developer_mode', "enabled" if value else "disabled")


Expand Down Expand Up @@ -1044,38 +1060,88 @@ def collect_libregrtest_utils(info_add):
info_add('libregrtests.build_info', ' '.join(utils.get_build_info()))


def linux_get_uptime():
# Use CLOCK_BOOTTIME if available
def uptime_boottime():
# Use CLOCK_BOOTTIME
import time
try:
return time.clock_gettime(time.CLOCK_BOOTTIME)
except (AttributeError, OSError):
pass
return None

# Otherwise, parse the first member of /proc/uptime
uptime = read_first_line("/proc/uptime")
if not uptime:

def uptime_linux():
# Parse the first member of /proc/uptime
line = read_first_line("/proc/uptime")
if not line:
return
try:
parts = uptime.split()
parts = line.split()
if not parts:
return
return float(parts[0])
except ValueError:
return


def uptime_bsd():
# Get sysctlbyname("kern.boottime")
try:
import _testcapi
except ImportError:
return None
try:
return _testcapi.uptime_bsd()
except (AttributeError, OSError):
return None


def uptime_windows():
try:
import _winapi
except ImportError:
return None
else:
return _winapi.GetTickCount64() / 1000.


def get_uptime():
for func in (uptime_boottime, uptime_linux, uptime_bsd, uptime_windows):
uptime = func()
if uptime is not None:
return uptime
return None


def get_machine_id():
if MS_WINDOWS:
machine_guid = winreg_query(r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft"
r"\Cryptography\MachineGuid")
if machine_guid:
return machine_guid

for filename in (
# https://www.freedesktop.org/software/systemd/man/latest/machine-id.html
"/etc/machine-id",
# BSD
"/etc/hostid",
):
machine_id = read_first_line(filename)
if machine_id:
return machine_id

return None


def collect_linux(info_add):
boot_id = read_first_line("/proc/sys/kernel/random/boot_id")
if boot_id:
info_add('linux.boot_id', boot_id)
info_add('system.boot_id', boot_id)

# https://www.freedesktop.org/software/systemd/man/latest/machine-id.html
machine_id = read_first_line("/etc/machine-id")
machine_id = get_machine_id()
if machine_id:
info_add('linux.machine_id', machine_id)
info_add('system.machine_id', machine_id)

uptime = linux_get_uptime()
uptime = get_uptime()
if uptime is not None:
# truncate microseconds
uptime = int(uptime)
Expand All @@ -1084,7 +1150,7 @@ def collect_linux(info_add):
uptime = str(datetime.timedelta(seconds=uptime))
except ImportError:
uptime = f'{uptime} sec'
info_add('linux.uptime', uptime)
info_add('system.uptime', uptime)


def collect_info(info):
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_bigmem.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from test import support
from test.support import bigmemtest, _1G, _2G, _4G, import_helper
_testcapi = import_helper.import_module('_testcapi')

import unittest
import operator
Expand Down Expand Up @@ -1264,6 +1263,7 @@ class ImmortalityTest(unittest.TestCase):
def test_stickiness(self, size):
"""Check that immortality is "sticky", so that
once an object is immortal it remains so."""
_testcapi = import_helper.import_module('_testcapi')
if size < _2G:
# Not enough memory to cause immortality on overflow
return
Expand Down
3 changes: 2 additions & 1 deletion Lib/test/test_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@
from test.support import threading_helper, import_helper
from test.support.bytecode_helper import instructions_with_positions
from opcode import opmap, opname
from _testcapi import code_offset_to_line
try:
import _testinternalcapi
except ModuleNotFoundError:
Expand Down Expand Up @@ -1491,6 +1490,8 @@ async def async_func():
rc, out, err = assert_python_ok('-OO', '-c', code)

def test_co_branches(self):
_testcapi = import_helper.import_module("_testcapi")
code_offset_to_line = _testcapi.code_offset_to_line

def get_line_branches(func):
code = func.__code__
Expand Down
24 changes: 15 additions & 9 deletions Lib/tkinter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,12 +505,14 @@ def trace_variable(self, mode, callback):
Return the name of the callback.

This deprecated method wraps a deprecated Tcl method removed
in Tcl 9.0. Use trace_add() instead.
in Tcl 9.0 and will be removed in Python 3.17. Use trace_add()
instead.
"""
import warnings
warnings.warn(
"trace_variable() is deprecated and not supported with Tcl 9; "
"use trace_add() instead.",
"trace_variable() is deprecated and will be removed in Python "
"3.17; use trace_add() instead. It is not supported with "
"Tcl 9.",
DeprecationWarning, stacklevel=2)
cbname = self._register(callback)
self._tk.call("trace", "variable", self._name, mode, cbname)
Expand All @@ -525,12 +527,14 @@ def trace_vdelete(self, mode, cbname):
CBNAME is the name of the callback returned from trace_variable or trace.

This deprecated method wraps a deprecated Tcl method removed
in Tcl 9.0. Use trace_remove() instead.
in Tcl 9.0 and will be removed in Python 3.17. Use trace_remove()
instead.
"""
import warnings
warnings.warn(
"trace_vdelete() is deprecated and not supported with Tcl 9; "
"use trace_remove() instead.",
"trace_vdelete() is deprecated and will be removed in Python "
"3.17; use trace_remove() instead. It is not supported with "
"Tcl 9.",
DeprecationWarning, stacklevel=2)
self._tk.call("trace", "vdelete", self._name, mode, cbname)
cbname = self._tk.splitlist(cbname)[0]
Expand All @@ -548,12 +552,14 @@ def trace_vinfo(self):
"""Return all trace callback information.

This deprecated method wraps a deprecated Tcl method removed
in Tcl 9.0. Use trace_info() instead.
in Tcl 9.0 and will be removed in Python 3.17. Use trace_info()
instead.
"""
import warnings
warnings.warn(
"trace_vinfo() is deprecated and not supported with Tcl 9; "
"use trace_info() instead.",
"trace_vinfo() is deprecated and will be removed in Python "
"3.17; use trace_info() instead. It is not supported with "
"Tcl 9.",
DeprecationWarning, stacklevel=2)
return [self._tk.splitlist(x) for x in self._tk.splitlist(
self._tk.call("trace", "vinfo", self._name))]
Expand Down
29 changes: 12 additions & 17 deletions Lib/zipfile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,15 @@ def _sanitize_filename(filename):
filename = filename.replace(os.altsep, "/")
return filename

def _read_local_file_header(fp):
fheader = fp.read(sizeFileHeader)
if len(fheader) != sizeFileHeader:
raise BadZipFile("Truncated file header")
fheader = struct.unpack(structFileHeader, fheader)
if fheader[_FH_SIGNATURE] != stringFileHeader:
raise BadZipFile("Bad magic number for file header")
return fheader


class ZipInfo:
"""Class with attributes describing each file in the ZIP archive."""
Expand Down Expand Up @@ -1648,7 +1657,7 @@ def _validate_local_file_entry_sequence(self, fp, start_offset, end_offset, chec
def _validate_local_file_entry(self, fp, offset, end_offset):
fp.seek(offset)
try:
fheader = self._read_local_file_header(fp)
fheader = _read_local_file_header(fp)
except BadZipFile:
return None

Expand Down Expand Up @@ -1714,15 +1723,6 @@ def _validate_local_file_entry(self, fp, offset, end_offset):

return entry_size

def _read_local_file_header(self, fp):
fheader = fp.read(sizeFileHeader)
if len(fheader) != sizeFileHeader:
raise BadZipFile("Truncated file header")
fheader = struct.unpack(structFileHeader, fheader)
if fheader[_FH_SIGNATURE] != stringFileHeader:
raise BadZipFile("Bad magic number for file header")
return fheader

def _scan_data_descriptor(self, fp, offset, end_offset, zip64):
dd_fmt = '<LLQQ' if zip64 else '<LLLL'
dd_size = struct.calcsize(dd_fmt)
Expand Down Expand Up @@ -1825,7 +1825,7 @@ def _trace_compressed_block_end(self, fp, offset, end_offset, decompressor,

def _calc_local_file_entry_size(self, fp, zinfo):
fp.seek(zinfo.header_offset)
fheader = self._read_local_file_header(fp)
fheader = _read_local_file_header(fp)

if zinfo.flag_bits & _MASK_USE_DATA_DESCRIPTOR:
zip64 = fheader[_FH_UNCOMPRESSED_SIZE] == 0xffffffff
Expand Down Expand Up @@ -2215,12 +2215,7 @@ def open(self, name, mode="r", pwd=None, *, force_zip64=False):
self._fpclose, self._lock, lambda: self._writing)
try:
# Skip the file header:
fheader = zef_file.read(sizeFileHeader)
if len(fheader) != sizeFileHeader:
raise BadZipFile("Truncated file header")
fheader = struct.unpack(structFileHeader, fheader)
if fheader[_FH_SIGNATURE] != stringFileHeader:
raise BadZipFile("Bad magic number for file header")
fheader = _read_local_file_header(zef_file)

fname = zef_file.read(fheader[_FH_FILENAME_LENGTH])
if fheader[_FH_EXTRA_FIELD_LENGTH]:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix build error if specialization is disabled.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
The deprecated :class:`tkinter.Variable` methods :meth:`!trace_variable`,
:meth:`!trace`, :meth:`!trace_vdelete` and :meth:`!trace_vinfo` are now
scheduled for removal in Python 3.17.
Loading
Loading