{"id":18498501,"url":"https://github.com/xpodev/quickstruct","last_synced_at":"2025-05-14T05:24:07.462Z","repository":{"id":44536050,"uuid":"457315560","full_name":"xpodev/quickstruct","owner":"xpodev","description":"A library to ease the creation of C structs in Python","archived":false,"fork":false,"pushed_at":"2023-01-19T21:50:18.000Z","size":58,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-01-25T22:32:30.049Z","etag":null,"topics":["cpython","cstruct","data-structures","python","python-3","python3","struct","structs","structure","structures"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/quickstruct/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xpodev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-09T10:42:19.000Z","updated_at":"2022-02-10T00:44:25.000Z","dependencies_parsed_at":"2023-02-11T21:45:41.495Z","dependency_job_id":null,"html_url":"https://github.com/xpodev/quickstruct","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Fquickstruct","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Fquickstruct/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Fquickstruct/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpodev%2Fquickstruct/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xpodev","download_url":"https://codeload.github.com/xpodev/quickstruct/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239217107,"owners_count":19601593,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpython","cstruct","data-structures","python","python-3","python3","struct","structs","structure","structures"],"created_at":"2024-11-06T13:40:49.696Z","updated_at":"2025-02-17T00:44:49.564Z","avatar_url":"https://github.com/xpodev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# QuickStruct\n\nQuickStruct is a small library written in Python that allows you to\neasily create C structs (and a bit more dynamic stuff) in Python!\n\n## Installation\n```\npip install quickstruct\n```\n\n## Usage\n\nIt's fairly easy to use\n```py\nfrom quickstruct import *\n\nclass Person(DataStruct):\n    name: String\n    age: i8\n```\n\nStructs can also be composed\n\n```py\nclass TeachingClass(DataStruct):\n    teacher: Person\n    # We use Array[T] to make it dynamic sized\n    students: Array[Person]\n```\n\nAnd structs can also inherit other structs\n(we even support multiple inheritance!)\n```py\nclass Employee(Person):\n    salary: i32\n```\n\n\nNow let's use the structs we defined\n```py\n# We have 2 options when initializing.\n# Either by setting each attribute individually\nperson = Person()\nperson.name = \"John Doe\"\nperson.age = 42\n\n# Or by passing them as keyword arguments\nperson = Person(name=\"John Doe\", age=42)\n```\n\n\nThe main use for C structs is to convert them from bytes and back\n```py\ndata = person.to_bytes()\n# Do something with the data\n\n# And it's also easy to deserialize\nperson = Person.from_bytes(data)\n```\n\n\nWhen deserializing a struct with multiple bases or if one of the fields was overriden, \nthe deserialization must be done through the exact type of the struct.\n\n\n# Fixed Size Structs\nA fixed size struct is any struct that has a known fixed size at build time that doesn't depend on the \ndata it holds. QuickStruct can verify a struct has a fixed size.\n```py\n# The StructFlags.FixedSize flag is used to verify the struct has a fixed size.\n# If the size could not be verified, a SizeError is raised.\nclass FixedSizeStruct(DataStruct, flags=StructFlags.FixedSize):\n    a: i32\n    b: i8\n    c: f32\n    d: char\n    e: String[10] # 10 character string\n    f: Person[3] # 3 'person' objects\n    # g: Array[i32] \u003c- not a fixed size field. this will error\n```\n\n# Struct Properties\nIt is possible to query some information about a structure.\n```py\nfrom quickstruct import *\nclass Fixed(DataStruct):\n    s: String[10]\n    x: i32\n\nclass Dynamic(DataStruct):\n    s: String\n    x: i32\n\nprint(\"Fixed.size:\", Fixed.size) # 16 (padding automatically added)\nprint(\"Dynamic.size:\", Dynamic.size) # -1 (dynamic size)\n\nprint(\"Fixed.is_fixed_size:\", Fixed.is_fixed_size) # True\nprint(\"Dynamic.is_fixed_size:\", Dynamic.is_fixed_size) # False\n\nprint(\"Fixed.is_dynamic_size:\", Fixed.is_dynamic_size) # False\nprint(\"Dynamic.is_dynamic_size:\", Dynamic.is_dynamic_size) # True\n\nprint(\"Fixed.fields:\", Fixed.fields) # [s: String[10], __pad_0__: Padding(2), x: i32]\nprint(\"Dynamic.fields:\", Dynamic.fields) # [s: String, x: i32]\n\nprint(\"Fixed.alignment:\", Fixed.alignment) # 16.\nprint(\"Dynamic.alignment:\", Dynamic.alignment) # -1 (no alignment because dynamic struct can't be aligned).\n\nprint(\"Fixed.is_final:\", Fixed.is_final) # False\nprint(\"Dynamic.is_final:\", Dynamic.is_final) # False\n\nprint(\"Fixed.is_protected:\", Fixed.is_protected) # False\nprint(\"Dynamic.is_protected:\", Dynamic.is_protected) # False\n```\n\n# Alignment\nIt is also possible to add padding to the struct. There are 2 ways to do that:\n## Manual Alignment\nThis can be done with the `Padding` type.\n```py\nclass AlignedStruct(DataStruct):\n    c1: char\n    # This adds a single byte padding\n    _pad0: Padding\n    short: i16\n    # We can also add multi-byte padding\n    # Here we'll pad to get 8 byte alignment (missing 4 bytes)\n    _pad1: Padding[4]\n```\n\n## Automatic Alignment\nThis can done by passing some flags to the class definition. By default the struct is automatically aligned.\n```py\n# Aligned on 2 byte boundary\nclass AlignedStruct(DataStruct, flags = StructFlags.Align2Bytes):\n    c1: char\n    # Padding will be added here\n    short: i16\n```\n\n## Struct Flags\n| Flag              | Description                                                                                                                                                                                                      |\n|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Default           | The default to use if no flags are given. Same as `AllowOverride \\| AlignAuto`.                                                                                                                                  |\n| NoAlignment       | This is the most packed form of the struct. All fields are adjacent with no padding (unless manually added)                                                                                                      |\n| Packed            | Same as `NoAlignment` except that `NoAlignment` is a bit more optimized because no alignment is done.                                                                                                            |\n| Align1Byte        | Same as `Packed`                                                                                                                                                                                                 |\n| Align2Bytes       | Aligns the fields on 2 byte boundary.                                                                                                                                                                            |\n| Align4Bytes       | Aligns the fields on 4 byte boundary.                                                                                                                                                                            |\n| Align8Bytes       | Aligns the fields on 8 byte boundary.                                                                                                                                                                            |\n| AlignAuto         | Aligns the fields by their type.                                                                                                                                                                                 |\n| ReorderFields     | Specifies the fields should be reordered in order to make the struct a little more compressed.                                                                                                                   |\n| ForceDataOnly     | **Deprecated**. Specifies that the struct may only contain serializable fields. Data-only structs may only inherit data-only structs.                                                                            |\n| AllowOverride     | If set, fields defined in the struct may override fields that are defined in the base struct.                                                                                                                    |\n| TypeSafeOverride  | If set, when fields are overridden, they must have the same type (which would make it pretty useless to override). Implies `AllowOverride`. If fields have a different type, an `UnsafeOverrideError` is raised. |\n| ForceSafeOverride | **Deprectaed**. Same as `TypeSafeOverride`.                                                                                                                                                                      |\n| FixedSize         | If set, the struct must have a fixed size. If not, an exception `SizeError` is raised.                                                                                                                           |\n| ForceFixedSize    | **Deprecated**. Same as `FixedSize`.                                                                                                                                                                             |\n| AllowInline       | **Deprecated**. If set, the struct's fields will be inlined into another struct the contains this struct.                                                                                                        |\n| Protected         | If set, denies any overrides of that structure. If a struct is trying to override a field of it, an `UnoverridableFieldError` is raised.                                                                         |\n| LockedStructure   | **Deprecated**. Same as `Protected`.                                                                                                                                                                             |\n| Final             | Marks the structure so it won't be inheritable by any other class. If a struct is trying to inherit it, an `InheritanceError` is raised.                                                                         |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxpodev%2Fquickstruct","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxpodev%2Fquickstruct","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxpodev%2Fquickstruct/lists"}