バイトオブジェクト

下記の関数は、バイトオブジェクトを期待している引数にバイトオブジェクトでないパラメタを指定して呼び出されると、 TypeError を送出します。

PyBytesObject の内部バッファには、null 終端の C 文字列との互換性のため、末尾に常に追加の null バイトが含まれます。 この追加バイトは PyBytes_Size() や、以下の関数の各種 length 引数と size 引数には数えません。

type PyBytesObject

この PyObject のサブタイプは、Python バイトオブジェクトを表します。

PyTypeObject PyBytes_Type
次に属します: Stable ABI.

この PyTypeObject のインスタンスは、Python バイト型を表します; Pythonレイヤの bytes と同じオブジェクトです。

int PyBytes_Check(PyObject *o)

オブジェクト o が bytes オブジェクトか bytes 型のサブタイプのインスタンスである場合に真を返します。この関数は常に成功します。

int PyBytes_CheckExact(PyObject *o)

オブジェクト o が bytes オブジェクトだが bytes 型のサブタイプのインスタンスでない場合に真を返します。この関数は常に成功します。

PyObject *PyBytes_FromString(const char *v)
戻り値: 新しい参照。 次に属します: Stable ABI. Thread safety: Atomic.

成功時に、文字列 v のコピーを値とする新しいバイトオブジェクトを返し、失敗時に NULL を返します。 引数 v は NULL であってはなりません; そのチェックは行われません。

PyObject *PyBytes_FromStringAndSize(const char *v, Py_ssize_t len)
戻り値: 新しい参照。 次に属します: Stable ABI. Thread safety: Atomic.

成功時に、文字列 v のコピーを値とする長さ len の新しいバイトオブジェクトを返し、失敗時に NULL を返します。 引数 v が NULL の場合、バイトオブジェクトの中身は初期化されていません。

バージョン 3.15 で ソフト非推奨 <Soft deprecated>: PyBytes_FromStringAndSize(NULL, len) の代わりに PyBytesWriter API を使ってください。

PyObject *PyBytes_FromFormat(const char *format, ...)
戻り値: 新しい参照。 次に属します: Stable ABI. Thread safety: Atomic.

C 関数の printf() スタイルの format 文字列と可変長の引数を取り、結果のPython バイトオブジェクトのサイズを計算し、値を指定した書式にしたがって変換したバイトオブジェクトを返します。可変長の引数は C のデータ型でなければならず、 format 文字列中のフォーマット文字と厳密に関連付けられていなければなりません。下記のフォーマット文字が使用できます:

書式指定文字

型

備考

%%

n/a

リテラルの % 文字

%c

int

C の整数型で表現される単一のバイト。

%d

int

printf("%d") と同等。 [1]

%u

unsigned int

printf("%u") と同等。 [1]

%ld

long

printf("%ld") と同等。 [1]

%lu

unsigned long

printf("%lu") と同等。 [1]

%zd

Py_ssize_t

printf("%zd") と同等。 [1]

%zu

size_t

printf("%zu") と同等。 [1]

%i

int

printf("%i") と同等。 [1]

%x

int

printf("%x") と同等。 [1]

%s

const char*

null で終端された C の文字列。

%p

const void*

C ポインタの 16 進表記。printf("%p") とほとんど同じですが、プラットフォームにおける printf の定義に関わりなく先頭にリテラル 0x が付きます。

識別できない書式指定文字があった場合、残りの書式文字列はそのまま結果のオブジェクトにコピーされ、残りの引数は無視されます。

PyObject *PyBytes_FromFormatV(const char *format, va_list vargs)
戻り値: 新しい参照。 次に属します: Stable ABI. Thread safety: Atomic.

ちょうど2つの引数を取ることを除いて、 PyBytes_FromFormat() と同じです。

PyObject *PyBytes_FromObject(PyObject *o)
戻り値: 新しい参照。 次に属します: Stable ABI. Thread safety: Safe for concurrent use on the same object.

バッファプロトコルを実装するオブジェクト o のバイト表現を返します。

注釈

オブジェクトがバッファプロトコルを実装している場合、bytes オブジェクトの作成中にそのバッファを変更してはいけません。

Py_ssize_t PyBytes_Size(PyObject *o)
次に属します: Stable ABI. Thread safety: Atomic.

バイトオブジェクト o のバイト単位の長さを返します。

Py_ssize_t PyBytes_GET_SIZE(PyObject *o)
Thread safety: Atomic.

PyBytes_Size() に似ていますが、エラーチェックを行いません。

char *PyBytes_AsString(PyObject *o)
次に属します: Stable ABI. Thread safety: Safe to call from multiple threads with external synchronization only.

o の内容へのポインタを返します。 このポインタは len(o) + 1 バイトからなる o の内部バッファを参照します。 内部に他の null バイトがあるかどうかにかかわらず、バッファの最後のバイトは常に null です。 PyBytes_FromStringAndSize(NULL, size) で作成したばかりのオブジェクトでない限り、データを変更してはいけません。 このバッファを解放してはいけません。 o が bytes オブジェクトでなければ、PyBytes_AsString() は NULL を返し、TypeError を送出します。

char *PyBytes_AS_STRING(PyObject *string)
Thread safety: Safe to call from multiple threads with external synchronization only.

PyBytes_AsString() に似ていますが、エラーチェックを行いません。

int PyBytes_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length)
次に属します: Stable ABI. Thread safety: Safe to call from multiple threads with external synchronization only.

出力変数 buffer と length を通じて、オブジェクト obj の null 終端された内容を返します。 成功すると 0 を返します。

length が NULL の場合、bytes オブジェクトの内部に null バイトが含まれていてはいけません。 含まれている場合は -1 を返し、ValueError を送出します。

buffer は obj の内部バッファを参照します。 このバッファには末尾に追加の null バイトが含まれます (length には数えません)。 PyBytes_FromStringAndSize(NULL, size) で作成したばかりのオブジェクトでない限り、データを変更してはいけません。 このバッファを解放してはいけません。 obj が bytes オブジェクトでなければ、PyBytes_AsStringAndSize() は -1 を返し、TypeError を送出します。

バージョン 3.5 で変更: 以前は bytes オブジェクトにヌルバイトが埋め込まれていたときに TypeError を送出していました。

void PyBytes_Concat(PyObject **bytes, PyObject *newpart)
次に属します: Stable ABI. Thread safety: Safe for concurrent use on the same object.

bytes の内容に newpart の内容を追加した新しい bytes オブジェクトを *bytes に作成します。 呼び出し側はこの新しい参照を所有します。 bytes の元の値への参照は「盗まれます」。 新しいオブジェクトを作成できない場合も、bytes の元の参照は「盗まれ」、*bytes の値は NULL に設定され、適切な例外が設定されます。

注釈

newpart がバッファプロトコルを実装している場合、新しい bytes オブジェクトの作成中にそのバッファを変更してはいけません。

void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart)
次に属します: Stable ABI. Thread safety: Safe for concurrent use on the same object.

bytes の内容に newpart の内容を追加した新しい bytes オブジェクトを *bytes に作成します。 この関数は newpart への 強参照 を解放します (つまり参照カウントを減らします)。

注釈

newpart がバッファプロトコルを実装している場合、新しい bytes オブジェクトの作成中にそのバッファを変更してはいけません。

PyObject *PyBytes_Join(PyObject *sep, PyObject *iterable)
Thread safety: Safe for concurrent use on the same object.

Python の sep.join(iterable) と同様です。

sep は Python の bytes オブジェクトでなければなりません。 (PyUnicode_Join() は区切り文字として NULL を受け取り、空白として扱いますが、PyBytes_Join() は区切り文字に NULL を受け付けません。)

iterable は バッファプロトコル を実装するオブジェクトを生成するイテラブルオブジェクトでなければなりません。

成功すると新しい bytes オブジェクトを返します。 エラー時には例外を設定して NULL を返します。

Added in version 3.14.

注釈

iterable のオブジェクトがバッファプロトコルを実装している場合、新しい bytes オブジェクトの作成中にそれらのバッファを変更してはいけません。

int _PyBytes_Resize(PyObject **bytes, Py_ssize_t newsize)
Thread safety: Safe to call without external synchronization on distinct objects.

Resize a bytes object. newsize will be the new length of the bytes object. You can think of it as creating a new bytes object and destroying the old one, only more efficiently.

Pass the address of an existing bytes object as an lvalue (it may be written into), and the new size desired. On success, *bytes holds the resized bytes object and 0 is returned; the address in *bytes may differ from its input value. If the reallocation fails, the original bytes object at *bytes is deallocated, *bytes is set to NULL, MemoryError is set, and -1 is returned.

While bytes objects are usually immutable in Python, this special C API allows mutating a bytes object in-place. The returned bytes object can still be mutated using PyBytes_AsString(); except if newsize is zero in which case it returns the immutable empty bytes string.

バージョン 3.15 で ソフト非推奨 <Soft deprecated>: 代わりに PyBytesWriter API を使ってください。

PyObject *PyBytes_Repr(PyObject *bytes, int smartquotes)
次に属します: Stable ABI. Thread safety: Atomic.

bytes の文字列表現を取得します。 現在、この関数は Python の bytes.__repr__() の実装に使われています。

この関数は型チェックを行いません。 bytes に bytes オブジェクト以外のオブジェクトや NULL を渡すと、動作は未定義です。

smartquotes が真の場合、bytes にシングルクォートが含まれていれば、その表現にはシングルクォートの代わりにダブルクォートで囲んだ文字列を使います。 例えば、バイト文字列 'Python' の表現は、smartquotes が真なら b"'Python'"、偽なら b'\'Python\'' となります。

成功すると、この関数は表現を格納した str オブジェクトへの 強参照 を返します。 失敗すると例外を設定して NULL を返します。

PyObject *PyBytes_DecodeEscape(const char *s, Py_ssize_t len, const char *errors, Py_ssize_t unicode, const char *recode_encoding)
次に属します: Stable ABI. Thread safety: Atomic.

バックスラッシュでエスケープされた文字列 s のエスケープを解除します。 s は NULL であってはなりません。 len は s のサイズでなければなりません。

errors は "strict"、"replace"、"ignore" のいずれかでなければなりません。 errors が NULL の場合、デフォルトで "strict" を使います。

成功すると、この関数はエスケープを解除した文字列を格納する Python の bytes オブジェクトへの 強参照 を返します。 失敗すると例外を設定して NULL を返します。

バージョン 3.9 で変更: unicode と recode_encoding は使われなくなりました。

PyBytesWriter

PyBytesWriter API を使って Python の bytes オブジェクトを作成できます。

Added in version 3.15.

type PyBytesWriter

A bytes writer object.

この API は スレッドセーフではありません。 複数のスレッドでライターを共有するには、クリティカルセクションまたはロックが必要です。

成功時には PyBytesWriter_Finish()、エラー時には PyBytesWriter_Discard() でインスタンスを破棄しなければなりません。

作成、完了、破棄

PyBytesWriter *PyBytesWriter_Create(Py_ssize_t size)

size バイトを書き込むための PyBytesWriter を作成します。

size がゼロより大きければ size バイトを割り当て、ライターのサイズを size に設定します。 呼び出し側は PyBytesWriter_GetData() を使って size バイトを書き込む責任があります。 この関数は余分な領域を割り当てません。

エラー時には例外を設定して NULL を返します。

size は正の値またはゼロでなければなりません。

PyObject *PyBytesWriter_Finish(PyBytesWriter *writer)

PyBytesWriter_Create() で作成した PyBytesWriter の処理を完了します。

成功すると Python の bytes オブジェクトを返します。 エラー時には例外を設定して NULL を返します。

呼び出し後は、成功したかどうかにかかわらずライターのインスタンスは無効になります。 PyBytesWriter_Finish() の後に、そのライターに対して API を呼び出すことはできません。

PyObject *PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)

PyBytesWriter_Finish() と同様ですが、bytes オブジェクトを作成する前にライターのサイズを size バイトに変更します。

PyObject *PyBytesWriter_FinishWithPointer(PyBytesWriter *writer, void *buf)

PyBytesWriter_Finish() と同様ですが、bytes オブジェクトを作成する前に buf ポインタを使ってライターのサイズを変更します。

buf ポインタが内部バッファの範囲外であれば、例外を設定して NULL を返します。

関数の疑似コードを示します。

Py_ssize_t size = (char*)buf - (char*)PyBytesWriter_GetData(writer);
return PyBytesWriter_FinishWithSize(writer, size);
void PyBytesWriter_Discard(PyBytesWriter *writer)

PyBytesWriter_Create() で作成した PyBytesWriter を破棄します。

writer が NULL の場合は何もしません。

呼び出し後はライターのインスタンスは無効になります。 PyBytesWriter_Discard() の後に、そのライターに対して API を呼び出すことはできません。

高レベルAPI

int PyBytesWriter_WriteBytes(PyBytesWriter *writer, const void *bytes, Py_ssize_t size)

writer の内部バッファを size バイト拡張し、bytes の size バイトを writer の末尾に書き込み、writer のサイズに size を加えます。

size が -1 の場合は strlen(bytes) を呼び出して文字列の長さを取得します。

成功すると 0 を返します。 エラー時には例外を設定して -1 を返します。

int PyBytesWriter_Format(PyBytesWriter *writer, const char *format, ...)

PyBytes_FromFormat() と同様ですが、出力をライターの末尾に直接書き込みます。 必要に応じてライターの内部バッファを拡張します。 その後、書き込んだサイズをライターのサイズに加えます。

成功すると 0 を返します。 エラー時には例外を設定して -1 を返します。

値の取得

Py_ssize_t PyBytesWriter_GetSize(PyBytesWriter *writer)

ライターのサイズを取得します。

この関数は PyBytesWriter_GetData() が返したポインタを無効にしません。

この関数は失敗しません。

void *PyBytesWriter_GetData(PyBytesWriter *writer)

ライターのデータ、つまり内部バッファの先頭を取得します。

このポインタは、writer に対して PyBytesWriter_GetData() と PyBytesWriter_GetSize() 以外の PyBytesWriter 関数を呼び出すまで有効です。

この関数は失敗しません。

低レベルAPI

int PyBytesWriter_Resize(PyBytesWriter *writer, Py_ssize_t size)

ライターのサイズを size バイトに変更します。 ライターの拡張にも縮小にも使えます。 この関数は通常、サイズ変更を繰り返したときの償却性能をよくするため、余分な領域を割り当てます。

新しく割り当てられたバイトは初期化されません。

成功すると 0 を返します。 エラー時には例外を設定して -1 を返します。

size は正の値またはゼロでなければなりません。

int PyBytesWriter_Grow(PyBytesWriter *writer, Py_ssize_t grow)

現在のライターのサイズに grow バイトを加えてサイズを変更します。 この関数は通常、サイズ変更を繰り返したときの償却性能をよくするため、余分な領域を割り当てます。

新しく割り当てられたバイトは初期化されません。

成功すると 0 を返します。 エラー時には例外を設定して -1 を返します。

grow に負の値を指定するとライターを縮小できます。

void *PyBytesWriter_GrowAndUpdatePointer(PyBytesWriter *writer, Py_ssize_t size, void *buf)

PyBytesWriter_Grow() と同様ですが、buf ポインタも更新します。

内部バッファがメモリ上で移動した場合は、buf ポインタも移動します。 内部バッファ内での buf の相対位置は変わりません。

エラー時には例外を設定して NULL を返します。

buf は NULL であってはなりません。

関数の疑似コードを示します。

Py_ssize_t pos = (char*)buf - (char*)PyBytesWriter_GetData(writer);
if (PyBytesWriter_Grow(writer, size) < 0) {
    return NULL;
}
return (char*)PyBytesWriter_GetData(writer) + pos;

文字列 b'abc' を作成する例

3 バイトの固定サイズでバイト文字列 b"abc" を作成する例です。

PyObject* create_abc(void)
{
    PyBytesWriter *writer = PyBytesWriter_Create(3);
    if (writer == NULL) {
        return NULL;
    }

    char *str = PyBytesWriter_GetData(writer);
    memcpy(str, "abc", 3);
    return PyBytesWriter_Finish(writer);
}

ポインタを使って最終的なサイズを計算する別の例です。

PyObject* create_abc_ptr(void)
{
    PyBytesWriter *writer = PyBytesWriter_Create(3);
    if (writer == NULL) {
        return NULL;
    }

    char *str = PyBytesWriter_GetData(writer);
    memcpy(str, "abc", 3);
    str += 3;
    return PyBytesWriter_FinishWithPointer(writer, str);
}

PyBytes_FromStringAndSize() を使うコードの更新

ソフト非推奨の API PyBytes_FromStringAndSize(NULL, size) を使うコードの例です。

int copy_bytes(char *dest, const char *src, Py_ssize_t num_bytes)
{
    ...
}

PyObject* create_string(const char *start, Py_ssize_t num_bytes)
{
    PyObject *result = PyBytes_FromStringAndSize(NULL, num_bytes);
    if (result == NULL) {
        return NULL;
    }
    if (copy_bytes(PyBytes_AS_STRING(result), start, num_bytes) < 0) {
        Py_CLEAR(result);
    }
    return result;
}

これを次のように更新できます。

PyObject* create_string(const char *start, Py_ssize_t num_bytes)
{
    PyBytesWriter *writer = PyBytesWriter_Create(num_bytes);
    if (writer == NULL) {
        return NULL;
    }
    if (copy_bytes(PyBytesWriter_GetData(writer), start, num_bytes) < 0) {
        PyBytesWriter_Discard(writer);
        return NULL;
    }
    return PyBytesWriter_Finish(writer);
}

_PyBytes_Resize() を使うコードの更新

ソフト非推奨の API _PyBytes_Resize() を使うコードの例です。

PyObject* create_string(Py_ssize_t size)
{
    PyObject *bytes = PyBytes_FromStringAndSize(NULL, size);
    if (bytes == NULL) {
        return NULL;
    }
    char *str = PyBytes_AS_STRING(bytes);

    // ... str にデータを書き込む ...

    if (_PyBytes_Resize(&bytes, (str - PyBytes_AS_STRING(bytes)))) {
        return NULL;
    }
    return bytes;
}

これを次のように更新できます。

PyObject* create_string(Py_ssize_t size)
{
    PyBytesWriter *writer = PyBytesWriter_Create(size);
    if (writer == NULL) {
        return NULL;
    }
    char *str = PyBytesWriter_GetData(writer);

    // ... str にデータを書き込む ...

    return PyBytesWriter_FinishWithPointer(writer, str);
}