{"id":8587,"library":"recordclass","title":"recordclass","description":"recordclass is a Python library that provides mutable variants of `collections.namedtuple`, supporting assignments and offering memory-saving alternatives like `dataobject` and `structclass`. These types aim for high performance and reduced memory footprint by optionally disabling cyclic garbage collection and removing instance dictionaries. Currently at version 0.24, the library is actively maintained with releases supporting the latest Python versions, including 3.14, and aims to be a fast, memory-efficient, and flexible choice for data representation.","status":"active","version":"0.24","language":"en","source_language":"en","source_url":"https://github.com/intellimath/recordclass","tags":["data structures","namedtuple","dataclasses","performance","memory management","mutable"],"install":[{"cmd":"pip install recordclass","lang":"bash","label":"Install latest stable version"}],"dependencies":[],"imports":[{"note":"For creating mutable namedtuple-like classes.","symbol":"recordclass","correct":"from recordclass import recordclass"},{"note":"For creating compact dataclass-like objects with memory optimizations.","symbol":"dataobject","correct":"from recordclass import dataobject"},{"note":"Factory function to create dataobject-based classes, similar to standard dataclasses.make_dataclass.","symbol":"make_dataclass","correct":"from recordclass import make_dataclass"},{"note":"Decorator for def-style declarations of dataobject-based classes that behave like structs.","symbol":"as_record","correct":"from recordclass import as_record"},{"note":"The base type for recordclass instances; less commonly directly instantiated by users.","symbol":"mutabletuple","correct":"from recordclass import mutabletuple"}],"quickstart":{"code":"from recordclass import recordclass, dataobject, make_dataclass, as_record\nimport os\n\n# Using recordclass (mutable namedtuple-like)\nPoint = recordclass('Point', 'x y')\np = Point(1, 2)\nprint(f\"Initial Point: {p}\")\np.x = 10\nprint(f\"Modified Point: {p}\")\n\n# Using dataobject (compact dataclass-like)\nclass ColorPoint(dataobject):\n    x: int\n    y: int\n    color: str = 'red'\n\ncp = ColorPoint(1, 2)\nprint(f\"ColorPoint: {cp}\")\ncp.color = 'blue'\nprint(f\"Modified ColorPoint: {cp}\")\n\n# Using make_dataclass\nUser = make_dataclass(\"User\", [(\"name\", str), (\"age\", int)])\nu = User(\"Alice\", 30)\nprint(f\"User: {u}\")\n\n# Using as_record decorator\n@as_record()\ndef Product(name: str, price: float, sku=None):\n    pass\n\nprod = Product(\"Laptop\", 1200.0, \"LAP001\")\nprint(f\"Product: {prod}\")","lang":"python","description":"This quickstart demonstrates how to create mutable record-like objects using `recordclass`, `dataobject` (similar to dataclasses), `make_dataclass`, and the `as_record` decorator. It highlights the mutability aspect and attribute access."},"warnings":[{"fix":"Use `class MyData(dataobject, copy_default=True): my_list: list = []` or `from recordclass import Factory; class MyData(dataobject): my_list: list = Factory(list)`.","message":"Mutable Default Values: When defining `dataobject` classes with mutable default values (e.g., lists, dicts), the default object is shared across all instances. This is a common Python pitfall. Use `copy_default=True` or `recordclass.Factory` for independent defaults.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Instead of `del p.x`, assign `p.x = None` or use a method to clear/reset the field if available and semantically appropriate.","message":"Attribute Deletion Not Allowed: Attempting to delete an attribute using `del instance.attribute` will raise an `AttributeError`. This was explicitly disallowed for `dataobject`-based classes in recent versions to maintain internal structure.","severity":"breaking","affected_versions":"0.24 and newer"},{"fix":"Define all required fields in the class definition. If dynamic attributes are strictly needed, consider `collections.namedtuple` (immutable), `dataclasses` (mutable with `__dict__`), or re-evaluating the use case. You can enable GC and `__dict__` if necessary via decorators or factory functions for specific classes, but this negates the memory benefits.","message":"No `__dict__` by Default in `dataobject`: `dataobject`-based classes do not have an instance `__dict__` or `__weakref__` by default for memory optimization. This means you cannot add new attributes to instances after creation, which can lead to `AttributeError`.","severity":"gotcha","affected_versions":"All versions (since introduction of dataobject)"},{"fix":"Upgrade to the latest `recordclass` version (0.24 or newer), which explicitly adds support for Python 3.14 and earlier versions.","message":"Python Version Compatibility (older versions): Older versions of `recordclass` (e.g., <0.24) had known build and runtime issues with newer Python interpreters (e.g., Python 3.9, 3.12, 3.14) due to internal C API changes. This often manifested as build errors during `pip install`.","severity":"breaking","affected_versions":"Prior to 0.24 (e.g., 0.14.0, 0.22.0.2 with Python 3.12/3.14)"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure distinct variable names for classes and instances (e.g., `PointClass` and `point_instance`) or be careful about scope. A common Python convention is to capitalize class names: `Point = recordclass(...)`, then `point = Point(...)`.","cause":"This usually occurs when you shadow a class name with an instance of that class, then try to call the instance as if it were the class itself to create a new object. For example, `Point = recordclass(...)`, then `point = Point(...)`, and later `point = point(...)`.","error":"TypeError: 'X' object is not callable"},{"fix":"Define all necessary attributes as fields in the `dataobject` class definition. If truly dynamic attributes are needed, `recordclass` may not be the ideal choice for that specific data structure.","cause":"You are attempting to assign a new attribute (`Y`) to an instance of a `dataobject`-based class (`X`) that was not defined in the class's fields. These classes omit `__dict__` for memory efficiency, preventing dynamic attribute assignment.","error":"AttributeError: 'X' object has no attribute 'Y' and no __dict__ for setting new attributes"},{"fix":"Review the class definition and the arguments passed during instantiation. Ensure that the number and names of arguments match the defined fields, accounting for default values. If using `__init__` in a subclass, ensure it correctly calls the superclass's initializer and handles its arguments.","cause":"This error occurs during instance creation when too many arguments (either positional or keyword) are provided compared to the fields defined in the `recordclass` or `dataobject` type. It can also happen in subclasses with custom `__init__` methods if argument handling is incorrect.","error":"TypeError: the number of the arguments greater than the number of fields"},{"fix":"Ensure you have C/C++ build tools installed (e.g., `build-essential` on Debian/Ubuntu, Xcode Command Line Tools on macOS, Visual C++ Build Tools on Windows). Upgrade `recordclass` to the latest version (0.24) as it includes fixes for newer Python versions.","cause":"This build error typically indicates problems compiling the C extensions of `recordclass`. Common causes include missing C build tools, incompatible Python development headers, or, historically, `recordclass` versions not yet supporting newer Python releases due to C API changes.","error":"Building wheel for recordclass (setup.py) ... error"}]}