diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d777f35ac208fd..54942f4b83ddaa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -200,10 +200,10 @@ jobs: strategy: fail-fast: false matrix: - # macos-14 is M1, macos-15-intel is Intel. + # macos-26 is Apple Silicon, macos-15-intel is Intel. # macos-15-intel only runs tests against the GIL-enabled CPython. os: - - macos-14 + - macos-26 - macos-15-intel free-threading: - false @@ -387,7 +387,7 @@ jobs: matrix: include: - arch: aarch64 - runs-on: macos-14 + runs-on: macos-26 - arch: x86_64 runs-on: ubuntu-24.04 @@ -404,7 +404,7 @@ jobs: needs: build-context if: needs.build-context.outputs.run-ios == 'true' timeout-minutes: 60 - runs-on: macos-14 + runs-on: macos-26 steps: - uses: actions/checkout@v6 with: @@ -417,10 +417,10 @@ jobs: # https://github.com/actions/runner-images/issues/12751. - name: Select Xcode version run: | - sudo xcode-select --switch /Applications/Xcode_15.4.app + sudo xcode-select --switch /Applications/Xcode.app - name: Build and test - run: python3 Apple ci iOS --fast-ci --simulator 'iPhone SE (3rd generation),OS=17.5' + run: python3 Apple ci iOS --fast-ci --simulator 'iPhone 17,OS=latest' build-wasi: name: 'WASI' diff --git a/.github/workflows/jit.yml b/.github/workflows/jit.yml index 9188839b26ee71..acf1df60817d58 100644 --- a/.github/workflows/jit.yml +++ b/.github/workflows/jit.yml @@ -86,7 +86,7 @@ jobs: runner: macos-15-intel - target: aarch64-apple-darwin/clang architecture: aarch64 - runner: macos-14 + runner: macos-26 - target: x86_64-unknown-linux-gnu/gcc architecture: x86_64 runner: ubuntu-24.04 diff --git a/.github/workflows/tail-call.yml b/.github/workflows/tail-call.yml index 32c6aa75e479f8..63ec5497b2c994 100644 --- a/.github/workflows/tail-call.yml +++ b/.github/workflows/tail-call.yml @@ -69,7 +69,7 @@ jobs: - target: x86_64-apple-darwin/clang runner: macos-15-intel - target: aarch64-apple-darwin/clang - runner: macos-14 + runner: macos-26 steps: - uses: actions/checkout@v6 with: diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 59e88be6aeec12..474da75a0baa16 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -171,7 +171,9 @@ typedef enum { DICT_KEYS_SPLIT = 2 } DictKeysKind; -/* See dictobject.c for actual layout of DictKeysObject */ +/* See dictobject.c for the full DictKeysObject memory layout. + * A PyDictKeysObject* points to the fixed-size header below. + */ struct _dictkeysobject { Py_ssize_t dk_refcnt; @@ -211,7 +213,8 @@ struct _dictkeysobject { - 4 bytes if dk_size <= 0xffffffff (int32_t*) - 8 bytes otherwise (int64_t*) - Dynamically sized, SIZEOF_VOID_P is minimum. */ + Dynamically sized. This is the start of the variable-sized tail that + immediately follows the fixed-size header. */ char dk_indices[]; /* char is required to avoid strict aliasing. */ /* "PyDictKeyEntry or PyDictUnicodeEntry dk_entries[USABLE_FRACTION(DK_SIZE(dk))];" array follows: diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 6c802ca569d48c..e53c6deeb62e7b 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -17,6 +17,7 @@ As of Python 3.6, this is compact and ordered. Basic idea is described here: layout: +---------------------+ +| struct _dictkeysobj | | dk_refcnt | | dk_log2_size | | dk_log2_index_bytes | @@ -25,13 +26,17 @@ As of Python 3.6, this is compact and ordered. Basic idea is described here: | dk_usable | | dk_nentries | +---------------------+ -| dk_indices[] | +| dk_indices[] | <-- starts at &dk->dk_indices[0] | | +---------------------+ -| dk_entries[] | +| dk_entries[] | <-- starts at DK_ENTRIES(dk) | | +---------------------+ +A PyDictKeysObject* points to the start of the fixed-size header. +The variable-sized part begins at dk_indices and is followed immediately by +the entry array. + dk_indices is actual hashtable. It holds index in entries, or DKIX_EMPTY(-1) or DKIX_DUMMY(-2). Size of indices is dk_size. Type of each index in indices varies with dk_size: