gh-125063: marshal: Add version 5, improve documentation (GH-126829)

* Document that slices can be marshalled
* Deduplicate and organize the list of supported types
  in docs
* Organize the type code list in marshal.c, to make
  it more obvious that this is a versioned format
* Back-fill some historical info

Co-authored-by: Michael Droettboom <mdboom@gmail.com>
This commit is contained in:
Petr Viktorin 2024-11-15 13:48:57 +01:00 committed by GitHub
parent e17486982c
commit d00f7b1b9d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 110 additions and 41 deletions

View file

@ -50,41 +50,52 @@ module marshal
# define MAX_MARSHAL_STACK_DEPTH 2000
#endif
/* Supported types */
#define TYPE_NULL '0'
#define TYPE_NONE 'N'
#define TYPE_FALSE 'F'
#define TYPE_TRUE 'T'
#define TYPE_STOPITER 'S'
#define TYPE_ELLIPSIS '.'
#define TYPE_INT 'i'
/* TYPE_INT64 is not generated anymore.
Supported for backward compatibility only. */
#define TYPE_INT64 'I'
#define TYPE_FLOAT 'f'
#define TYPE_BINARY_FLOAT 'g'
#define TYPE_COMPLEX 'x'
#define TYPE_BINARY_COMPLEX 'y'
#define TYPE_LONG 'l'
#define TYPE_STRING 's'
#define TYPE_INTERNED 't'
#define TYPE_REF 'r'
#define TYPE_TUPLE '('
#define TYPE_BINARY_FLOAT 'g' // Version 0 uses TYPE_FLOAT instead.
#define TYPE_BINARY_COMPLEX 'y' // Version 0 uses TYPE_COMPLEX instead.
#define TYPE_LONG 'l' // See also TYPE_INT.
#define TYPE_STRING 's' // Bytes. (Name comes from Python 2.)
#define TYPE_TUPLE '(' // See also TYPE_SMALL_TUPLE.
#define TYPE_LIST '['
#define TYPE_DICT '{'
#define TYPE_CODE 'c'
#define TYPE_UNICODE 'u'
#define TYPE_UNKNOWN '?'
// added in version 2:
#define TYPE_SET '<'
#define TYPE_FROZENSET '>'
// added in version 5:
#define TYPE_SLICE ':'
#define FLAG_REF '\x80' /* with a type, add obj to index */
// Remember to update the version and documentation when adding new types.
/* Special cases for unicode strings (added in version 4) */
#define TYPE_INTERNED 't' // Version 1+
#define TYPE_ASCII 'a'
#define TYPE_ASCII_INTERNED 'A'
#define TYPE_SMALL_TUPLE ')'
#define TYPE_SHORT_ASCII 'z'
#define TYPE_SHORT_ASCII_INTERNED 'Z'
/* Special cases for small objects */
#define TYPE_INT 'i' // All versions. 32-bit encoding.
#define TYPE_SMALL_TUPLE ')' // Version 4+
/* Supported for backwards compatibility */
#define TYPE_COMPLEX 'x' // Generated for version 0 only.
#define TYPE_FLOAT 'f' // Generated for version 0 only.
#define TYPE_INT64 'I' // Not generated any more.
/* References (added in version 3) */
#define TYPE_REF 'r'
#define FLAG_REF '\x80' /* with a type, add obj to index */
// Error codes:
#define WFERR_OK 0
#define WFERR_UNMARSHALLABLE 1
#define WFERR_NESTEDTOODEEP 2
@ -615,6 +626,11 @@ w_complex_object(PyObject *v, char flag, WFILE *p)
PyBuffer_Release(&view);
}
else if (PySlice_Check(v)) {
if (p->version < 5) {
w_byte(TYPE_UNKNOWN, p);
p->error = WFERR_UNMARSHALLABLE;
return;
}
PySliceObject *slice = (PySliceObject *)v;
W_TYPE(TYPE_SLICE, p);
w_object(slice->start, p);