Skip to content
Closed
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
32 changes: 0 additions & 32 deletions .github/dependabot.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
workflow_dispatch:
push:
branches:
- 'main'
- 'meta/main'
- '3.*'
pull_request:
branches:
Expand Down
11 changes: 6 additions & 5 deletions .github/workflows/mypy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ jobs:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.15"
activate-environment: true
cache-dependency-glob: Tools/requirements-dev.txt
- run: uv pip install -r Tools/requirements-dev.txt
allow-prereleases: true
cache: pip
cache-dependency-path: Tools/requirements-dev.txt
- run: pip install -r Tools/requirements-dev.txt
- run: python3 Misc/mypy/make_symlinks.py --symlink
- run: mypy --num-workers 4 --config-file ${{ matrix.target }}/mypy.ini
- run: mypy --config-file ${{ matrix.target }}/mypy.ini
16 changes: 2 additions & 14 deletions Doc/c-api/sentinel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,8 @@ Sentinel objects

.. c:function:: int PySentinel_Check(PyObject *o)

Return true if *o* is a :class:`sentinel` object or a subtype.
The :class:`sentinel` type does not currently allow subclasses,
so this check is exact.
Future Python versions may choose to allow subtyping.
This function always succeeds.

.. versionadded:: 3.15

.. c:function:: int PySentinel_CheckExact(PyObject *o)

Return true if *o* is a :class:`sentinel` object, but not a subtype.
The :class:`sentinel` type does not currently allow subclasses.
Future Python versions may choose to allow subtyping.
This function always succeeds.
Return true if *o* is a :class:`sentinel` object. The :class:`sentinel` type
does not allow subclasses, so this check is exact.

.. versionadded:: 3.15

Expand Down
8 changes: 3 additions & 5 deletions Doc/library/mimetypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,9 @@ than one MIME-type database; it provides an interface similar to the one of the
When *strict* is ``True`` (the default), the mapping will be added to the
official MIME types, otherwise to the non-standard ones.

.. deprecated:: 3.14
*ext* values that do not start with ``'.'`` are deprecated.

.. versionchanged:: next
*ext* now must start with ``'.'``. Otherwise :exc:`ValueError` is raised.
.. deprecated-removed:: 3.14 3.16
Invalid, undotted extensions will raise a
:exc:`ValueError` in Python 3.16.


.. _mimetypes-cli:
Expand Down
11 changes: 4 additions & 7 deletions Include/cpython/sentinelobject.h
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
/* Sentinel object interface */

#ifndef Py_LIMITED_API
#ifndef _Py_SENTINELOBJECT_H
#define _Py_SENTINELOBJECT_H
#ifndef Py_SENTINELOBJECT_H
#define Py_SENTINELOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif

PyAPI_DATA(PyTypeObject) PySentinel_Type;

#define PySentinel_CheckExact(op) Py_IS_TYPE((op), &PySentinel_Type)

/* Alias as long as subclasses are not allowed. */
#define PySentinel_Check(op) PySentinel_CheckExact(op)
#define PySentinel_Check(op) Py_IS_TYPE((op), &PySentinel_Type)

PyAPI_FUNC(PyObject *) PySentinel_New(
const char *name,
Expand All @@ -21,5 +18,5 @@ PyAPI_FUNC(PyObject *) PySentinel_New(
#ifdef __cplusplus
}
#endif
#endif /* !_Py_SENTINELOBJECT_H */
#endif /* !Py_SENTINELOBJECT_H */
#endif /* !Py_LIMITED_API */
2 changes: 1 addition & 1 deletion Include/cpython/sliceobject.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef _Py_CPYTHON_SLICEOBJECT_H
#ifndef Py_CPYTHON_SLICEOBJECT_H
# error "this header file must not be included directly"
#endif

Expand Down
2 changes: 1 addition & 1 deletion Include/cpython/structseq.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef _Py_CPYTHON_STRUCTSEQ_H
#ifndef Py_CPYTHON_STRUCTSEQ_H
# error "this header file must not be included directly"
#endif

Expand Down
49 changes: 49 additions & 0 deletions Include/internal/pycore_gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,55 @@ extern void _PyGC_VisitObjectsWorldStopped(PyInterpreterState *interp,
gcvisitobjects_t callback, void *arg);
#endif

struct _Ci_PyGCImpl;

/*
* Collect cyclic garbage.
*
* impl - Pointer to the collection implementation.
* tstate - Indirectly specifies (via tstate->interp) the interpreter
for which collection should be performed.
* generation - Collect generations <= this value
* reason - Why we're collecting
*/
typedef Py_ssize_t (*Ci_gc_collect_t)(struct _Ci_PyGCImpl *impl, PyThreadState* tstate,
int generation, _PyGC_Reason reason);

// Free a collector
typedef void (*Ci_gc_finalize_t)(struct _Ci_PyGCImpl *impl);

// An implementation of cyclic garbage collection
typedef struct _Ci_PyGCImpl {
Ci_gc_collect_t collect;
Ci_gc_finalize_t finalize;
} _Ci_PyGCImpl;

struct _gc_runtime_state;

/*
* Set the collection implementation.
*
* The callee takes ownership of impl.
*
* Returns a pointer to the previous impl, which the caller is responsible for freeing
* using the returned impl's finalize().
*/
PyAPI_FUNC(_Ci_PyGCImpl *) _Ci_PyGC_SetImpl(struct _gc_runtime_state *gc_state, _Ci_PyGCImpl *impl);

/*
* Returns a pointer to the current GC implementation but does not transfer
* ownership to the caller.
*/
PyAPI_FUNC(_Ci_PyGCImpl *) _Ci_PyGC_GetImpl(struct _gc_runtime_state *gc_state);

/*
* Clear free lists (e.g. frames, tuples, etc.) for the given interpreter.
*
* This should be called by GC implementations after collecting the highest
* generation.
*/
PyAPI_FUNC(void) _Ci_PyGC_ClearFreeLists(PyInterpreterState* interp);

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion Include/internal/pycore_jit_unwind.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#if defined(_Py_JIT) && defined(__linux__) && defined(__ELF__)
# define PY_HAVE_JIT_GDB_UNWIND
# if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
defined(_Py_HAVE_LIBGCC_EH_FRAME_REGISTRATION)
defined(HAVE_LIBGCC_EH_FRAME_REGISTRATION)
# define PY_HAVE_JIT_GNU_BACKTRACE_UNWIND
# endif
#endif
Expand Down
4 changes: 2 additions & 2 deletions Include/internal/pycore_mmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ extern "C" {

#include "pycore_pystate.h"

#if defined(_Py_HAVE_PR_SET_VMA_ANON_NAME) && defined(__linux__)
#if defined(HAVE_PR_SET_VMA_ANON_NAME) && defined(__linux__)
# include <linux/prctl.h>
# include <sys/prctl.h>
#endif

#if defined(_Py_HAVE_PR_SET_VMA_ANON_NAME) && defined(__linux__)
#if defined(HAVE_PR_SET_VMA_ANON_NAME) && defined(__linux__)
static inline int
_PyAnnotateMemoryMap(void *addr, size_t size, const char *name)
{
Expand Down
6 changes: 6 additions & 0 deletions Include/internal/pycore_pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,13 @@ _Py_ThreadCanHandleSignals(PyInterpreterState *interp)
and interpreter state */

#if !defined(Py_BUILD_CORE_MODULE)
# if defined(Py_ENABLE_SHARED) && _Py__has_attribute(tls_model)
__attribute__((tls_model("initial-exec")))
# endif
extern _Py_thread_local PyThreadState *_Py_tss_tstate;
# if defined(Py_ENABLE_SHARED) && _Py__has_attribute(tls_model)
__attribute__((tls_model("initial-exec")))
# endif
extern _Py_thread_local PyInterpreterState *_Py_tss_interp;
#endif

Expand Down
2 changes: 1 addition & 1 deletion Include/patchlevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#define PY_RELEASE_SERIAL 0

/* Version as a string */
#define PY_VERSION "3.16.0a0"
#define PY_VERSION "3.16.0a0+meta"
/*--end constants--*/


Expand Down
2 changes: 2 additions & 0 deletions Include/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ PyAPI_FUNC(void) PyGILState_Release(PyGILState_STATE);
*/
PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void);

// Sets the thread state for multi-threaded GC
PyAPI_FUNC(void) Ci_SetTStateForGC(PyThreadState *tstate);

/* PEP 788 -- Protection against interpreter finalization */

Expand Down
4 changes: 2 additions & 2 deletions Include/sliceobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ PyAPI_FUNC(Py_ssize_t) PySlice_AdjustIndices(Py_ssize_t length,
#endif

#ifndef Py_LIMITED_API
# define _Py_CPYTHON_SLICEOBJECT_H
# define Py_CPYTHON_SLICEOBJECT_H
# include "cpython/sliceobject.h"
# undef _Py_CPYTHON_SLICEOBJECT_H
# undef Py_CPYTHON_SLICEOBJECT_H
#endif

#ifdef __cplusplus
Expand Down
4 changes: 2 additions & 2 deletions Include/structseq.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ PyAPI_FUNC(void) PyStructSequence_SetItem(PyObject*, Py_ssize_t, PyObject*);
PyAPI_FUNC(PyObject*) PyStructSequence_GetItem(PyObject*, Py_ssize_t);

#ifndef Py_LIMITED_API
# define _Py_CPYTHON_STRUCTSEQ_H
# define Py_CPYTHON_STRUCTSEQ_H
# include "cpython/structseq.h"
# undef _Py_CPYTHON_STRUCTSEQ_H
# undef Py_CPYTHON_STRUCTSEQ_H
#endif

#ifdef __cplusplus
Expand Down
11 changes: 1 addition & 10 deletions Lib/ftplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -883,16 +883,7 @@ def ftpcp(source, sourcename, target, targetname = '', type = 'I'):
type = 'TYPE ' + type
source.voidcmd(type)
target.voidcmd(type)
# Don't trust the IPv4 address the source server advertises in its PASV
# reply: a malicious source could otherwise point the target's data
# connection at an arbitrary host (SSRF). A caller that needs the old
# behavior can set trust_server_pasv_ipv4_address on the source FTP
# object. See FTP.makepasv(), which applies the same rule.
untrusted_host, sourceport = parse227(source.sendcmd('PASV'))
if source.trust_server_pasv_ipv4_address:
sourcehost = untrusted_host
else:
sourcehost = source.sock.getpeername()[0]
sourcehost, sourceport = parse227(source.sendcmd('PASV'))
target.sendport(sourcehost, sourceport)
# RFC 959: the user must "listen" [...] BEFORE sending the
# transfer request.
Expand Down
51 changes: 14 additions & 37 deletions Lib/gzip.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,63 +484,40 @@ def _read_exact(fp, n):
return data


def _read_until_null(fp, append_to):
'''Read until the first encountered null byte in fp.
Append to given byte array object'''
while True:
s = fp.read(1)
append_to += s
if not s or s == b'\000':
break


def _read_gzip_header(fp):
'''Read a gzip header from `fp` and progress to the end of the header.

Returns last mtime if header was present or None otherwise.
'''
magic = fp.read(2)
if not magic:
if magic == b'':
return None

if magic != b'\037\213':
raise BadGzipFile('Not a gzipped file (%r)' % magic)
base_header = _read_exact(fp, 8)
(method, flag, last_mtime) = struct.unpack("<BBIxx", base_header)

(method, flag, last_mtime) = struct.unpack("<BBIxx", _read_exact(fp, 8))
if method != 8:
raise BadGzipFile('Unknown compression method')

# Most common cases are no flags (gzip.compress, zlib.compress) or only
# FNAME set (GzipFile, gzip command line application). Exit early
# in those cases.
if not flag:
return last_mtime
if flag == FNAME:
if flag & FEXTRA:
# Read & discard the extra field, if present
extra_len, = struct.unpack("<H", _read_exact(fp, 2))
_read_exact(fp, extra_len)
if flag & FNAME:
# Read and discard a null-terminated string containing the filename
while True:
s = fp.read(1)
if not s or s==b'\000':
break
return last_mtime

# Processing for more complex flags. Save header parts for FHCRC checking.
header = bytearray(magic + base_header)
if flag & FEXTRA:
extra_len_bytes = _read_exact(fp, 2)
extra_len, = struct.unpack("<H", extra_len_bytes)
header += extra_len_bytes
header += _read_exact(fp, extra_len)
if flag & FNAME:
_read_until_null(fp, append_to=header)
if flag & FCOMMENT:
_read_until_null(fp, append_to=header)
# Read and discard a null-terminated string containing a comment
while True:
s = fp.read(1)
if not s or s==b'\000':
break
if flag & FHCRC:
# Header CRC is the last 16 bits of a crc32.
header_crc, = struct.unpack("<H", _read_exact(fp, 2))
true_crc = zlib.crc32(header) & 0xFFFF
if header_crc != true_crc:
raise BadGzipFile(f"Corrupted gzip header. Checksums do not "
f"match: {true_crc:04x} != {header_crc:04x}")
_read_exact(fp, 2) # Read & discard the 16-bit header CRC
return last_mtime


Expand Down
Loading
Loading