Selected changesmerged Sep 27, 2026
fix: Stop shared ESM watchers when unusedPython · 165 + / 29 −
Introduces 11 new declarations in panel/io/watcher.py.
Adds new core implementation rather than adjusting what was there. Tests changed with it, with code of their own.
panel/io/watcher.py ↗ · 3 files
@@ -0,0 +1,157 @@+"""+Shared file watching for the autoreload development loop.++Components that render from the same file, e.g. every component compiled+into a shared ESM bundle, would otherwise each start their own watcher+task. This module hands out one watcher per path and notifies all its+subscribers when the file changes.+"""+from __future__ import annotations++import asyncio+import os+import pathlib+import typing as t+import weakref++from .state import state++_watchers: dict[pathlib.Path, PathWatcher] = {}+++class PathWatcher:+ """+ Watches a single path on behalf of any number of subscribers.++ Subscribers are held weakly, so subscribing does not keep a component+ alive; each is notified by calling the method it subscribed with.+ """++ def __init__(self, path: pathlib.Path):+ self.path = path+ self._subscribers: weakref.WeakKeyDictionary[t.Any, set[str]] = weakref.WeakKeyDictionary()+ self._stop_event: asyncio.Event | None = None
Use focused npm advisories and nudge only for ready upgradesTypeScript · 106 + / 350 −
Introduces 4 new declarations in packages/next/src/lib/upgrade/prepare-upgrade.ts.
Adds new framework internals rather than adjusting what was there. Tests changed with it, with code of their own.
packages/next/src/lib/upgrade/prepare-upgrade.ts ↗ · 6 files
@@ -533,136 +426,55 @@ async function readNpmAdvisories(versions: string[]): Promise<Advisory[]> { throw new Error('Could not check for security updates.') } - const advisories: Advisory[] = data.next.map((finding) => {- if (!finding || typeof finding.vulnerable_versions !== 'string') {+ return data.next.map((finding) => {+ if (+ !finding ||+ typeof finding.vulnerable_versions !== 'string' ||+ !finding.vulnerable_versions.trim()+ ) { throw new Error('Could not check for security updates.') }-- return {- // npm's active advisory feed does not expose withdrawal metadata.- withdrawn_at: null,- vulnerabilities: [- {- package: { ecosystem: 'npm', name: 'next' },- vulnerable_version_range: finding.vulnerable_versions,- },- ],+ const range = finding.vulnerable_versions.replace(/,\s*/g, ' ')+ if (!semver.validRange(range)) {+ throw new Error('Could not check for security updates.') }+ return range })- return advisories-}--function advisoryVersions(value: unknown, checkedVersion: string): string[] {
ENH: infer read_excel engine from a workbook object (GH#46352)Python · 65 + / 49 −
Introduces 2 new declarations in pandas/io/excel/_base.py.
Adds new core implementation rather than adjusting what was there. Tests changed with it, with code of their own.
pandas/io/excel/_base.py ↗ · 3 files
@@ -1645,53 +1672,42 @@ def __init__( self._io = stringify_path(path_or_buffer) if engine is None:- # Only determine ext if it is needed- ext: str | None = None-- # GH#56692 - avoid importing xlrd; a Book only exists if the caller- # already imported it. GH#68086 - must precede inspect_excel_format,- # which seeks.- xlrd = sys.modules.get("xlrd")- if xlrd is not None and isinstance(path_or_buffer, xlrd.Book):- ext = "xls"- engine = "xlrd"+ # GH#68086 - must precede inspect_excel_format, which seeks.+ engine = _infer_engine_from_workbook(path_or_buffer) + if engine is None:+ ext = inspect_excel_format(+ content_or_path=path_or_buffer, storage_options=storage_options+ ) if ext is None:- ext = inspect_excel_format(- content_or_path=path_or_buffer, storage_options=storage_options+ raise ValueError(+ "Excel file format cannot be determined, you must specify "+ "an engine manually." )- if ext is None:- raise ValueError(- "Excel file format cannot be determined, you must specify "- "an engine manually."- )
http: cache parser callbacksC++ · 37 + / 7 −
Introduces 1 new declaration in src/node_http_parser.cc.
Adds new language design rather than adjusting what was there. Tests changed with it, with code of their own.
src/node_http_parser.cc ↗ · 2 files
@@ -980,12 +989,33 @@ class Parser : public AsyncWrap, public StreamListener { have_flushed_ = true; } + void ClearCachedCallbacks() {+ Local<Value> undefined = Undefined(env()->isolate());+ object()->SetInternalField(kOnHeadersCompleteCallback, undefined);+ object()->SetInternalField(kOnBodyCallback, undefined);+ object()->SetInternalField(kOnMessageCompleteCallback, undefined);+ }++ // Keep cached callbacks on the JS object so they do not keep the parser+ // alive when a callback closes over it.+ Local<Value> CachedCallback(uint32_t index, int field) {+ Local<Object> obj = object();+ Local<Value> cb = obj->GetInternalField(field).As<Value>();+ if (cb->IsFunction()) return cb;++ cb = obj->Get(env()->context(), index).ToLocalChecked();+ if (cb->IsFunction()) obj->SetInternalField(field, cb);+ return cb;+ }+ void Init(llhttp_type_t type, uint64_t max_http_header_size, uint32_t lenient_flags, size_t max_header_pairs) { llhttp_init(&parser_, type, &settings); + ClearCachedCallbacks();+ if (lenient_flags & kLenientHeaders) { llhttp_set_lenient_headers(&parser_, 1); }
Fix introsort heap fallback ignoring range boundariesPython · 25 + / 12 −
Introduces 1 new declaration in sorts/intro_sort.py.
Adds new core implementation rather than adjusting what was there. Tests changed with it, with code of their own.
sorts/intro_sort.py ↗ · 2 files
@@ -44,29 +44,40 @@ def insertion_sort[T: Comparable]( def heapify[T: Comparable](- array: list[T], index: int, heap_size: int+ array: list[T], index: int, heap_size: int, start: int = 0 ) -> None: # Max Heap """+ Restore the max heap rooted at an index relative to start.+ heap_size is the number of elements in the heap beginning at start.+ >>> array = [4, 2, 6, 8, 1, 7, 8, 22, 14, 56, 27, 79, 23, 45, 14, 12] >>> heapify(array, len(array) // 2, len(array)) """ largest = index left_index = 2 * index + 1 # Left Node right_index = 2 * index + 2 # Right Node - if left_index < heap_size and array[largest] < array[left_index]:+ if left_index < heap_size and array[start + largest] < array[start + left_index]: largest = left_index - if right_index < heap_size and array[largest] < array[right_index]:+ if right_index < heap_size and array[start + largest] < array[start + right_index]: largest = right_index if largest != index:- array[index], array[largest] = array[largest], array[index]- heapify(array, largest, heap_size)+ array[start + index], array[start + largest] = (+ array[start + largest],+ array[start + index],+ )+ heapify(array, largest, heap_size, start)