{"id":7245,"library":"formencode","title":"FormEncode","description":"FormEncode is a Python library for HTML form validation, generation, and data conversion. It handles complex, nested data structures and provides a declarative way to define validation schemas. Currently at version 2.1.1, released on January 31, 2025, the library maintains an active release cadence with several updates per year, focusing on Python 3 compatibility and modern development practices.","status":"active","version":"2.1.1","language":"en","source_language":"en","source_url":"https://github.com/formencode/formencode","tags":["form validation","HTML forms","data conversion","schema validation"],"install":[{"cmd":"pip install formencode","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"symbol":"Schema","correct":"from formencode import Schema"},{"symbol":"Invalid","correct":"from formencode import Invalid"},{"note":"Common validators like String, Int, Email are accessed via `formencode.validators`.","symbol":"validators","correct":"from formencode import validators"},{"note":"Used for filling HTML forms with defaults and error messages.","symbol":"htmlfill","correct":"from formencode import htmlfill"}],"quickstart":{"code":"from formencode import Schema, Invalid\nfrom formencode import validators\nfrom formencode import htmlfill\n\n# 1. Define a Schema\nclass RegistrationSchema(Schema):\n    username = validators.String(not_empty=True, min=3, max=20)\n    email = validators.Email(resolve_domain=False)\n    age = validators.Int(min=18, max=99)\n    password = validators.String(not_empty=True, min=6)\n    password_confirm = validators.String(not_empty=True)\n    chained_validators = [validators.FieldsMatch('password', 'password_confirm')]\n\n# 2. Example usage: validate form data\nform_data_valid = {\n    'username': 'testuser',\n    'email': 'test@example.com',\n    'age': '25',\n    'password': 'securepassword',\n    'password_confirm': 'securepassword'\n}\n\nform_data_invalid = {\n    'username': 'tu',\n    'email': 'invalid-email',\n    'age': '16',\n    'password': 'short',\n    'password_confirm': 'mismatch'\n}\n\nvalidator = RegistrationSchema()\n\nprint('--- Valid Data ---')\ntry:\n    validated_data = validator.to_python(form_data_valid)\n    print('Validation successful:', validated_data)\nexcept Invalid as e:\n    print('Validation failed:', e.unpack_errors())\n\nprint('\\n--- Invalid Data ---')\nerrors_for_html = {}\ntry:\n    validated_data = validator.to_python(form_data_invalid)\n    print('Validation successful (should not happen):', validated_data)\nexcept Invalid as e:\n    print('Validation failed:')\n    errors_for_html = e.unpack_errors()\n    for field, msg in errors_for_html.items():\n        print(f'  {field}: {msg}')\n\n# 3. Example htmlfill usage (if you have an HTML template)\nhtml_template = '''\n<form>\n  Username: <input type=\"text\" name=\"username\"><br>\n  Email: <input type=\"text\" name=\"email\"><br>\n  Age: <input type=\"text\" name=\"age\"><br>\n  Password: <input type=\"password\" name=\"password\"><br>\n  Confirm Password: <input type=\"password\" name=\"password_confirm\"><br>\n  <form:error name=\"username\"/>\n  <form:error name=\"email\"/>\n  <form:error name=\"age\"/>\n  <form:error name=\"password\"/>\n  <form:error name=\"password_confirm\"/>\n  <form:error name=\"form\"/>\n</form>\n'''\n\nprint('\\n--- HTML Fill with Errors ---')\nfilled_html = htmlfill.render(html_template, form_data_invalid, errors_for_html)\nprint(filled_html)\n","lang":"python","description":"This quickstart demonstrates defining a `Schema` with various `validators`, handling `Invalid` exceptions by calling `to_python`, and using `htmlfill.render` to pre-populate an HTML form with submitted data and error messages."},"warnings":[{"fix":"Upgrade to Python 3.6+ and use FormEncode >= 2.0.0. For Python 2.x compatibility, use FormEncode versions < 1.3.","message":"FormEncode 2.0.0 and later are not compatible with Python 2.x. Version 2.0.0 itself dropped support for Python 2.6 and Python 3.2-3.5.","severity":"breaking","affected_versions":"<2.0.0 for Python 2.x, 2.0.0 for Python 3.6+ only"},{"fix":"Plan to upgrade your Python environment to 3.9 or newer to ensure compatibility with future FormEncode releases.","message":"FormEncode 2.1.1 is the last version to officially support Python 3.7 and 3.8. Future versions will drop compatibility with these Python versions.","severity":"deprecated","affected_versions":">=2.1.1"},{"fix":"Always refer to the official GitHub repository for source code, bug tracking, and current development. The official website is www.formencode.org.","message":"Older repository locations (SourceForge CVS, svn.colorstudy.com Subversion, Bitbucket Mercurial) are outdated and no longer maintained.","severity":"gotcha","affected_versions":"All versions"},{"fix":"In your HTML or Python code for `htmlfill`, use `class_` (e.g., `<input type=\"text\" class_=\"my-class\">`) to specify CSS classes.","message":"When using `htmlfill`, if an input field needs a CSS class, you must use `class_` as the attribute name instead of `class` because `class` is a Python reserved keyword.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Catch the `Invalid` exception and use `e.unpack_errors()` to get a dictionary of field-specific errors. This dictionary is ideal for displaying errors next to their respective form fields.","cause":"When a Schema or Validator fails, it raises an `Invalid` exception. Directly printing `e` might not give a user-friendly or complete error message, especially for schemas with multiple field errors.","error":"formencode.Invalid: ..."},{"fix":"To make a field optional, pass `if_missing=None` (or another default value) to the validator definition within your `Schema` class. Alternatively, set `allow_extra_fields=True` on the `Schema` itself if you want to permit fields not explicitly defined.","cause":"A `Schema` by default expects all fields defined within it to be present in the input dictionary. If a field is missing, it will raise an error.","error":"KeyError: 'field_name'"}]}