{"id":8024,"library":"colander","title":"Colander","description":"Colander is a Python library providing a simple schema-based serialization and deserialization framework, currently at version 2.0. It allows developers to define data schemas to validate and transform data structures (like those from XML, JSON, or HTML forms) into Python objects, and vice-versa. The project is actively maintained, with a focus on stability and compatibility with modern Python versions, and typically releases updates as needed.","status":"active","version":"2.0","language":"en","source_language":"en","source_url":"https://github.com/Pylons/colander","tags":["schema","validation","serialization","deserialization","pylons"],"install":[{"cmd":"pip install colander","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"SchemaNode","correct":"from colander import SchemaNode"},{"symbol":"MappingSchema","correct":"from colander import MappingSchema"},{"symbol":"SequenceSchema","correct":"from colander import SequenceSchema"},{"symbol":"String","correct":"from colander import String"},{"symbol":"Int","correct":"from colander import Int"},{"symbol":"Float","correct":"from colander import Float"},{"symbol":"Boolean","correct":"from colander import Boolean"},{"note":"While Range is a validator, it's typically imported directly from the top-level 'colander' package for convenience and consistency.","wrong":"from colander.validators import Range","symbol":"Range","correct":"from colander import Range"},{"note":"The primary exception for validation failures is exposed directly under the top-level 'colander' package.","wrong":"from colander.exceptions import Invalid","symbol":"Invalid","correct":"from colander import Invalid"},{"note":"'null' is a special singleton value used in Colander to represent missing or explicit null data, distinct from Python's None.","symbol":"null","correct":"from colander import null"}],"quickstart":{"code":"import colander\n\nclass UserSchema(colander.MappingSchema):\n    name = colander.SchemaNode(colander.String())\n    age = colander.SchemaNode(colander.Int(), validator=colander.Range(min=0, max=150))\n    email = colander.SchemaNode(colander.String(), validator=colander.Email(), missing=colander.drop)\n\n# --- Deserialization (Input Validation) ---\n\n# Valid data\nappstruct = {'name': 'Alice', 'age': 30, 'email': 'alice@example.com'}\nschema = UserSchema()\ntry:\n    deserialized_data = schema.deserialize(appstruct)\n    print(f\"Successfully deserialized: {deserialized_data}\")\nexcept colander.Invalid as e:\n    print(f\"Deserialization failed: {e.asdict()}\")\n\n# Invalid data (age out of range, missing required name, invalid email)\nappstruct_invalid = {'name': 'Bob', 'age': 200, 'email': 'invalid-email'}\ntry:\n    schema.deserialize(appstruct_invalid)\nexcept colander.Invalid as e:\n    print(f\"Deserialization failed with errors: {e.asdict()}\")\n\n# Data with 'missing=colander.drop' field omitted\nappstruct_partial = {'name': 'Charlie', 'age': 25}\ntry:\n    deserialized_partial = schema.deserialize(appstruct_partial)\n    print(f\"Deserialized partial data: {deserialized_partial}\")\nexcept colander.Invalid as e:\n    print(f\"Deserialization of partial data failed: {e.asdict()}\")\n\n# --- Serialization (Output Generation) ---\n\n# Python application structure\npython_data = {'name': 'Dave', 'age': 40}\nserialized_data = schema.serialize(python_data)\nprint(f\"Successfully serialized: {serialized_data}\")\n\npython_data_full = {'name': 'Eve', 'age': 22, 'email': 'eve@example.com'}\nserialized_data_full = schema.serialize(python_data_full)\nprint(f\"Successfully serialized full data: {serialized_data_full}\")\n","lang":"python","description":"This quickstart demonstrates how to define a schema using `colander.MappingSchema` and `colander.SchemaNode`. It shows how to use various types (String, Int) and validators (Range, Email). The example covers both deserializing incoming data, including handling validation errors via `colander.Invalid`, and serializing Python application structures back into schema-compliant data. It also illustrates the use of `colander.drop` for optional fields."},"warnings":[{"fix":"Upgrade Python to 3.7+ or pin Colander to a 1.x version (e.g., `colander<2`).","message":"Colander 2.0 dropped support for older Python versions (2.7, 3.4, 3.5, 3.6). Users on these versions must upgrade their Python environment or remain on Colander 1.x.","severity":"breaking","affected_versions":"2.0.0+"},{"fix":"Explicitly decode `bytes` objects to `str` before passing them to the schema node for serialization (e.g., `value.decode('utf-8')`).","message":"When serializing a `bytes` object via a `colander.String` schema node with the `encoding` parameter specified in Colander 2.0, the `bytes` object is now passed directly through `str()` before encoding. This results in an output string with a `b''` prefix (e.g., `b'my_string'`).","severity":"breaking","affected_versions":"2.0.0+"},{"fix":"Ensure you are using Colander 0.9.1 or later. If using an older version and relying on `is colander.null` checks after unpickling, this might lead to unexpected behavior.","message":"In Colander versions prior to 0.9.1, unpickling `colander.null` would create a new instance of `_null` instead of returning the singleton, causing `is colander.null` checks to fail across pickling boundaries.","severity":"gotcha","affected_versions":"<0.9.1"},{"fix":"Upgrade to Colander 2.0 or later. If using custom validators with `colander.All` in older versions, ensure they consistently return string messages for `Invalid.msg`.","message":"Older versions of Colander's `colander.All` validator could cause `colander.Invalid.asdict()` to crash with a `TypeError` if `Invalid.msg` was `None` or a list. This was fixed in version 2.0.","severity":"gotcha","affected_versions":"<2.0.0"},{"fix":"Upgrade to Colander 2.0 or later for correct behavior of `default=colander.drop`.","message":"An issue existed in older `Mapping` and `Sequence` schemas where a `default` value of `colander.drop` incorrectly caused missing values to be dropped during deserialization. `colander.drop` should only affect serialization of default values, and only `missing` should affect deserialization. This was fixed in 2.0.","severity":"gotcha","affected_versions":"<2.0.0"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Upgrade to Colander 2.0 or later. If using custom validators with `colander.All` in older versions, ensure they consistently return string messages for `Invalid.msg`.","cause":"This error typically occurs when `colander.Invalid.asdict()` is called and one of the validation messages (`Invalid.msg`) in the error tree is `None` or a list of strings, which older versions of Colander's `colander.All` validator did not handle gracefully.","error":"TypeError: sequence item 1: expected str instance, NoneType found"},{"fix":"Catch the `colander.Invalid` exception and use its `asdict()` method to get a dictionary of specific error messages. Adjust the input data to conform to the schema's rules based on these messages.","cause":"This is the standard exception raised by Colander when input data fails to meet the requirements defined by the schema (e.g., wrong data type, missing a required field, value outside a specified range, or failing a custom validator).","error":"colander.Invalid: {'field_name': 'Error message for field'}"},{"fix":"Before passing `bytes` data to a `colander.String` schema node for serialization, explicitly decode it to a Python `str` (e.g., `my_bytes_value.decode('utf-8')`).","cause":"In Colander 2.0, when a `bytes` object is provided to a `colander.String` schema node with `encoding` specified, it's passed through Python's `str()` function before processing, which adds the `b''` prefix if the object is still `bytes`.","error":"Output contains 'b'' prefix (e.g., b'my_value') when serializing strings."}]}