{"id":1965,"library":"cobble","title":"Cobble: Create Python Data Objects","description":"Cobble is a Python library designed for the easy creation of data objects. It automatically implements common methods such as `__eq__` and `__repr__`, simplifying the boilerplate typically associated with simple data-holding classes. The current version is 0.1.4, released on June 1, 2024, and it is actively maintained with a stable release cadence.","status":"active","version":"0.1.4","language":"en","source_language":"en","source_url":"http://github.com/mwilliamson/python-cobble","tags":["data objects","dataclasses","boilerplate reduction","visitor pattern"],"install":[{"cmd":"pip install cobble","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"note":"Used as a decorator to define data objects.","symbol":"data","correct":"import cobble\n@cobble.data"},{"note":"Used within a cobble.data class to define fields, similar to dataclasses.field.","symbol":"field","correct":"import cobble\ncobble.field()"},{"note":"Used to create visitor patterns for hierarchies of cobble data objects.","symbol":"visitor","correct":"import cobble\ncobble.visitor(BaseClass)"}],"quickstart":{"code":"import cobble\n\n@cobble.data\nclass Song(object):\n    name = cobble.field()\n    artist = cobble.field()\n    album = cobble.field(default=None)\n\nsong = Song(\"MFEO\", artist=\"Jack's Mannequin\", album=\"Everything in Transit\")\nprint(song)\n\n@cobble.data\nclass Literal:\n    value = cobble.field()\n\n@cobble.data\nclass Add:\n    left = cobble.field()\n    right = cobble.field()\n\nclass Evaluator(cobble.visitor(object)):\n    def visit_literal(self, literal):\n        return literal.value\n    def visit_add(self, add):\n        return self.visit(add.left) + self.visit(add.right)\n\nexpression = Add(Literal(2), Literal(4))\nresult = Evaluator().visit(expression)\nprint(f\"Evaluation of {expression} is: {result}\")","lang":"python","description":"This example demonstrates how to define a simple data object `Song` using the `@cobble.data` decorator and `cobble.field()`. It also shows how to create a more complex structure like an expression tree with `Literal` and `Add` and then process it using a visitor pattern with `cobble.visitor`."},"warnings":[{"fix":"Use `default_factory` for mutable defaults, e.g., `my_list = cobble.field(default_factory=list)`.","message":"Mutable default arguments in `cobble.field(default=...)` can lead to unexpected shared state across instances. This is a common Python footgun, also applicable to `dataclasses` and `cobble`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Prefer using `__post_init__` for custom initialization logic or ensure your custom `__init__` explicitly initializes all fields defined by `cobble.field()`.","message":"Overriding `__init__` in a `cobble.data` class will prevent Cobble from automatically generating its own `__init__` method, potentially leading to uninitialized fields or `AttributeError` if not handled carefully.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always instantiate the class (e.g., `instance = MyClass(...)`) before attempting to access instance-specific fields. Use `typing.ClassVar` if an attribute truly needs to be a class-level variable and should not be part of the `__init__` generated by `cobble`.","message":"Accessing fields directly on a `cobble.data` class before instantiation (e.g., `MyClass.field_name`) will result in an `AttributeError` if the field is intended for instances.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}