### Install bencode2 using pip Source: https://github.com/trim21/bencode-py/blob/master/readme.md Use this command to install the bencode2 package from PyPI. ```shell pip install bencode2 ``` -------------------------------- ### Compute Torrent Info-Hash Source: https://context7.com/trim21/bencode-py/llms.txt A practical example demonstrating how to read a .torrent file, decode its content, extract the 'info' dictionary, re-encode it, and compute its SHA-1 info-hash using `hashlib`. ```python import hashlib from pathlib import Path import bencode2 def get_info_hash(torrent_path: str) -> str: """Return the hex SHA-1 info-hash of a .torrent file.""" raw = Path(torrent_path).read_bytes() torrent = bencode2.bdecode(raw) # Keys are bytes — b"info", not "info" info_dict = torrent[b"info"] # Re-encode the info dict to canonical bencode bytes info_bytes = bencode2.bencode(info_dict) return hashlib.sha1(info_bytes).hexdigest() ``` -------------------------------- ### Get Torrent Info Hash Source: https://context7.com/trim21/bencode-py/llms.txt Calculates the info hash for a given torrent file. Ensure the `get_info_hash` function is available in your scope. ```python info_hash = get_info_hash("ubuntu-22.04.2-desktop-amd64.iso.torrent") print(info_hash) # a7838b75c42b612da3b6cc99beed4ecb2d04cff2 ``` -------------------------------- ### Build Native Extension with Meson Source: https://github.com/trim21/bencode-py/blob/master/readme.md Commands to build the native extension using Meson. This process involves setting up the build environment, compiling the code, and copying the compiled artifacts to the source directory for testing. ```shell meson setup build meson compile -C build ninja -C build copy ``` -------------------------------- ### Check Runtime Implementation (COMPILED) Source: https://context7.com/trim21/bencode-py/llms.txt Shows how to check if the native C++ extension (`COMPILED`) is active or if the pure-Python fallback is being used. This is useful for testing and conditional logic. ```python import bencode2 if bencode2.COMPILED: print("Running with C++ extension (CPython + nanobind)") else: print("Running with pure-Python fallback") # Example: skip a benchmark that only makes sense with the native module import pytest @pytest.mark.skipif(not bencode2.COMPILED, reason="only meaningful with binary module") def test_large_payload_performance(): # Encode 100 MB of bytes — no GIL held in the native path result = bencode2.bencode(b" " * (100 * 1024 * 1024)) assert result.startswith(b"104857600:") ``` -------------------------------- ### Basic bencode/bdecode Usage Source: https://github.com/trim21/bencode-py/blob/master/readme.md Demonstrates the fundamental usage of bencode2 for decoding bencoded bytes to a Python dictionary and encoding a Python dictionary to bencoded bytes. Note that bencode2 decodes bencode string values to Python bytes. ```python import bencode2 assert bencode2.bdecode(b"d4:spaml1:a1:bee") == {b"spam": [b"a", b"b"]} assert bencode2.bencode({'hello': 'world'}) == b'd5:hello5:worlde' ``` -------------------------------- ### Decode Bencoded Data Source: https://context7.com/trim21/bencode-py/llms.txt Demonstrates decoding various bencoded data structures including integers, lists, dictionaries, and nested structures. Also shows handling of bytearray and memoryview inputs. ```python assert bencode2.bdecode(b"i18446744073709551616e") == 18446744073709551616 assert bencode2.bdecode(b"le") == [] assert bencode2.bdecode(b"l4:spam4:eggse") == [b"spam", b"eggs"] assert bencode2.bdecode(b"de") == {} assert bencode2.bdecode(b"d3:cow3:moo4:spam4:eggse") == {b"cow": b"moo", b"spam": b"eggs"} assert bencode2.bdecode(b"d4:spaml1:a1:bee") == {b"spam": [b"a", b"b"]} assert bencode2.bdecode(b"d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe") == { b"a": {b"id": b"abcdefghij0123456789"}, b"q": b"ping", b"t": b"aa", b"y": b"q", } assert bencode2.bdecode(bytearray(b"i99e")) == 99 assert bencode2.bdecode(memoryview(b"4:test")) == b"test" ``` -------------------------------- ### Safe Bencode Encoding with Error Handling Source: https://context7.com/trim21/bencode-py/llms.txt Provides a robust function `safe_encode` that wraps `bencode2.bencode` to catch and report `TypeError` for unsupported types and `BencodeEncodeError` for encoding issues like duplicate keys, returning None on failure. ```python import bencode2 def safe_encode(value) -> bytes | None: try: return bencode2.bencode(value) except TypeError as e: print(f"Unsupported type: {e}") return None except bencode2.BencodeEncodeError as e: print(f"Encode error: {e}") return None safe_encode({"key": 1}) # b"d3:keyi1ee" safe_encode({"key": 1, b"key": 2}) # Encode error: find duplicated keys ... safe_encode(None) # Unsupported type: ... ``` -------------------------------- ### Handle Bencode Decode Errors Source: https://context7.com/trim21/bencode-py/llms.txt Illustrates common invalid bencode inputs that raise BencodeDecodeError, such as empty input, invalid integers, incorrect lengths, unsorted keys, and duplicate keys. Also shows TypeError for non-byte inputs and depth limit enforcement. ```python invalid_inputs = [ b"", # empty input b"i-0e", # negative zero not allowed b"i01e", # leading zero in integer b"ie", # empty integer b"i-e", # minus with no digits b"10:short", # declared length exceeds buffer b"d3:foo4:spam3:bari42ee", # keys not sorted (foo > bar) b"d3:keyi1e3:keyi2ee", # duplicate keys ] for bad in invalid_inputs: try: bencode2.bdecode(bad) except bencode2.BencodeDecodeError as e: print(f"Rejected {bad!r}: {e}") try: bencode2.bdecode("not bytes") # type: ignore except TypeError: print("Only buffer types accepted") # Depth limit protects against stack overflow attacks deep = b"l" * 5000 + b"e" * 5000 try: bencode2.bdecode(deep) except (bencode2.BencodeDecodeError, RecursionError): print("Depth limit enforced") ``` -------------------------------- ### Read and Decode Torrent Metadata Source: https://context7.com/trim21/bencode-py/llms.txt Reads a .torrent file and decodes its metadata into Python data structures. Access fields using bytes keys (e.g., `b"info"`). ```python raw = Path("example.torrent").read_bytes() meta = bencode2.bdecode(raw) info = meta[b"info"] name = info[b"name"] # bytes — may not be valid UTF-8 length = info.get(b"length") # single-file torrent size files = info.get(b"files") # multi-file: list of dicts announce = meta[b"announce"] # tracker URL as bytes print(name.decode("utf-8", errors="replace")) ``` -------------------------------- ### Safe Bencode Decoding with Error Handling Source: https://context7.com/trim21/bencode-py/llms.txt Provides a robust function `safe_decode` that wraps `bencode2.bdecode` to catch and report `TypeError` for incorrect input types and `BencodeDecodeError` for malformed bencode data, returning None on failure. ```python import bencode2 def safe_decode(data: bytes): try: return bencode2.bdecode(data) except TypeError as e: print(f"Wrong input type: {e}") return None except bencode2.BencodeDecodeError as e: print(f"Invalid bencode: {e}") return None safe_decode(b"d4:spaml1:a1:bee") # {b'spam': [b'a', b'b']} safe_decode(b"corrupted") # Invalid bencode: ... safe_decode("string input") # Wrong input type: ... ``` -------------------------------- ### bencode(v) Source: https://context7.com/trim21/bencode-py/llms.txt Encodes a Python value into its bencode byte representation. It supports various primitive types and collections, automatically sorting dictionary keys and detecting circular references. Raises `TypeError` for unsupported types. ```APIDOC ## bencode(v) — Encode a Python object to bencode bytes ### Description Encodes a Python value into its bencode byte representation. Supported types include `int`, `bool`, `str`, `bytes`, `bytearray`, `memoryview`, `list`, `tuple`, `NamedTuple`, `dict`, `OrderedDict`, `MappingProxyType`, and `dataclasses`. Dictionary keys (str or bytes) are automatically sorted and checked for duplicates. Circular references are detected and raise `BencodeEncodeError`. Raises `TypeError` for unsupported types (e.g., `float`, `None`). ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **v** (any supported type) - The Python object to encode. ### Request Example ```python import bencode2 encoded_data = bencode2.bencode(42) print(encoded_data) ``` ### Response #### Success Response (bytes) - Returns the bencode-encoded bytes representation of the input object. #### Response Example ```python b'i42e' ``` ### Error Handling - `TypeError`: Raised if the input type is not supported. - `BencodeEncodeError`: Raised for issues like duplicate dictionary keys or circular references. ``` -------------------------------- ### bdecode(b) Source: https://context7.com/trim21/bencode-py/llms.txt Decodes bencode-encoded bytes into Python objects. It handles integers, lists, dictionaries, and strings (decoded as bytes). The decoder is strict and raises `BencodeDecodeError` for malformed input. ```APIDOC ## bdecode(b) — Decode bencode bytes to a Python object ### Description Decodes a bencode-encoded `bytes`, `bytearray`, or `memoryview` buffer into Python objects. Bencode integers become Python `int` (arbitrary precision), bencode lists become `list`, bencode dictionaries become `dict`, and bencode strings become Python `bytes` (never `str`). The decoder is strict: empty input, malformed integers (`i-0e`, `i01e`, `ie`), unsorted or duplicate dictionary keys, invalid length prefixes, and excessively deep nesting all raise `BencodeDecodeError`. Raises `TypeError` if the input is not a buffer type. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **b** (bytes | bytearray | memoryview) - The bencode-encoded buffer to decode. ### Request Example ```python import bencode2 decoded_data = bencode2.bdecode(b'i42e') print(decoded_data) ``` ### Response #### Success Response (any) - Returns the decoded Python object. Integers are `int`, strings are `bytes`, lists are `list`, and dictionaries are `dict`. #### Response Example ```python 42 ``` ### Error Handling - `TypeError`: Raised if the input is not a buffer type. - `BencodeDecodeError`: Raised for malformed bencode data, including invalid integers, duplicate/unsorted dictionary keys, and invalid length prefixes. ``` -------------------------------- ### Encode Python Objects to Bencode Bytes Source: https://context7.com/trim21/bencode-py/llms.txt Use `bencode` to encode Python objects like integers, strings, lists, and dictionaries into bencode bytes. It automatically sorts dictionary keys and handles various primitive and collection types. Ensure input types are supported to avoid `TypeError` or `BencodeEncodeError` for issues like circular references or duplicate keys. ```python import bencode2 import dataclasses import enum import types from collections import OrderedDict from typing import NamedTuple # --- Primitives --- assert bencode2.bencode(42) == b"i42e" assert bencode2.bencode(-3) == b"i-3e" assert bencode2.bencode(0) == b"i0e" assert bencode2.bencode(True) == b"i1e" assert bencode2.bencode(False) == b"i0e" assert bencode2.bencode(b"spam") == b"4:spam" assert bencode2.bencode("hello") == b"5:hello" assert bencode2.bencode("你好") == b"6:\xe4\xbd\xa0\xe5\xa5\xbd" assert bencode2.bencode(bytearray([1, 2, 3])) == b"3:\x01\x02\x03" assert bencode2.bencode(memoryview(b"abc")) == b"3:abc" # Arbitrarily large integers are supported assert bencode2.bencode(18446744073709551616) == b"i18446744073709551616e" # --- Collections --- assert bencode2.bencode([b"spam", b"eggs"]) == b"l4:spam4:eggse" assert bencode2.bencode((b"spam", b"eggs")) == b"l4:spam4:eggse" # tuple → list assert bencode2.bencode({b"cow": b"moo", b"spam": b"eggs"}) == b"d3:cow3:moo4:spam4:eggse" assert bencode2.bencode({}) == b"de" # Keys are sorted automatically (mixed str/bytes keys both work) assert bencode2.bencode({"spam": [b"a", b"b"]}) == b"d4:spaml1:a1:bee" assert bencode2.bencode(OrderedDict()) == b"de" assert bencode2.bencode(types.MappingProxyType({b"spam": [b"a", b"b"]})) == b"d4:spaml1:a1:bee" # --- Enums --- class Color(str, enum.Enum): RED = "red" class Priority(enum.IntEnum): HIGH = 1 assert bencode2.bencode(Color.RED) == b"3:red" assert bencode2.bencode(Priority.HIGH) == b"i1e" # --- Dataclasses (fields are sorted by name) --- @dataclasses.dataclass class Peer: port: int host: str p = Peer(port=6881, host="127.0.0.1") assert bencode2.bencode(p) == b"d4:host9:127.0.0.14:porti6881ee" # equivalent to bencode2.bencode(dataclasses.asdict(p)) # --- NamedTuple (encoded as a list) --- class Point(NamedTuple): x: int y: int assert bencode2.bencode(Point(1, 2)) == b"l i1e i2ee".replace(b" ", b"") # --- Error cases --- try: bencode2.bencode(3.14) # float not supported except TypeError as e: print(e) # type '' not supported by bencode try: bencode2.bencode({"key": 1, b"key": 2}) # duplicate keys after normalization except bencode2.BencodeEncodeError as e: print(e) d = {} d["self"] = d try: bencode2.bencode(d) # circular reference except bencode2.BencodeEncodeError as e: print(e) # circular reference found ... ``` -------------------------------- ### Decode Bencode Bytes to Python Objects Source: https://context7.com/trim21/bencode-py/llms.txt Use `bdecode` to convert bencode-encoded bytes into Python objects. It strictly validates the input and decodes integers to `int`, lists to `list`, dictionaries to `dict`, and strings to `bytes`. Ensure the input is a buffer type and adheres to bencode format to avoid `TypeError` or `BencodeDecodeError`. ```python import bencode2 # --- Primitives --- assert bencode2.bdecode(b"i42e") == 42 assert bencode2.bdecode(b"i-3e") == -3 assert bencode2.bdecode(b"i0e") == 0 assert bencode2.bdecode(b"4:spam") == b"spam" # string → bytes, never str assert bencode2.bdecode(b"0:") == b"" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.