{"id":7873,"library":"yacman","title":"YAML Configuration Manager","description":"Yacman is a Python library designed for managing YAML configuration files. It provides a robust YAML configuration manager with features for merging multiple configuration layers, validation, and atomic updates. The library recently released version 1.0.0, which introduced significant changes to constructor patterns and enhanced multi-process locking mechanisms, and maintains a consistent release cadence with active development.","status":"active","version":"1.0.0","language":"en","source_language":"en","source_url":"https://github.com/databio/yacman","tags":["configuration management","YAML","data science","bioinformatics"],"install":[{"cmd":"pip install yacman","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Requires Python 3.10 or newer due to modern type hint syntax and other features introduced in v1.0.0.","package":"python","optional":false}],"imports":[{"note":"The `FutureYAMLConfigManager` alias was removed in v1.0.0. Direct instantiation of `YAMLConfigManager` with data is also deprecated; use `from_x` constructors instead.","wrong":"from yacman import FutureYAMLConfigManager as YAMLConfigManager","symbol":"YAMLConfigManager","correct":"from yacman import YAMLConfigManager"},{"note":"These are essential for managing concurrent access and writes to configuration files in yacman v1.0.0.","symbol":"read_lock, write_lock","correct":"from yacman import read_lock, write_lock"}],"quickstart":{"code":"import os\nfrom yacman import YAMLConfigManager, write_lock, read_lock\n\n# Example data\ndata = {\"my_list\": [1,2,3], \"my_int\": 8, \"my_str\": \"hello world!\", \"my_dict\": {\"nested_val\": 15}}\n\n# Create a YAMLConfigManager from a dictionary\nym = YAMLConfigManager(data)\n\n# Access data like a dictionary\nprint(f\"my_list: {ym['my_list']}\")\nprint(f\"my_int: {ym['my_int']}\")\nprint(f\"nested_val: {ym['my_dict']['nested_val']}\")\n\n# Modify data\nym[\"new_var\"] = 15\n\n# To write changes to a file, use a write_lock context manager\n# and explicitly rebase_and_write for multi-process safety.\n# For a real scenario, you would create ym from a file path: ym = YAMLConfigManager(filepath='config.yaml')\n# For this quickstart, we'll simulate writing to a dummy file.\nconfig_file_path = \"./temp_config.yaml\"\nwith open(config_file_path, 'w') as f:\n    f.write(str(ym))\n\n# Now, let's load it from the file and demonstrate writing safely\nym_from_file = YAMLConfigManager(filepath=config_file_path)\n\n# Use a write-lock, and rebase before writing to ensure you capture any changes\n# since you loaded the file (important in multi-process environments)\nwith write_lock(ym_from_file) as locked_ym:\n    locked_ym['another_key'] = 'another_value'\n    locked_ym.rebase_and_write()\n\nprint(f\"Updated config from file: {ym_from_file.to_dict()}\")\n\n# Cleanup (optional)\nos.remove(config_file_path)\n","lang":"python","description":"This quickstart demonstrates how to initialize `YAMLConfigManager` from a dictionary, access and modify configuration values, and safely write changes to a file using the `write_lock` context manager and `rebase_and_write` method. Note the direct initialization `YAMLConfigManager(data)` is primarily for dictionary data; for file-based configuration, you would typically use `YAMLConfigManager(filepath='your_config.yaml')`."},"warnings":[{"fix":"Update your code to use the new constructor methods, e.g., `ym = YAMLConfigManager.from_dict(data)` or `ym = YAMLConfigManager.from_file('path/to/config.yaml')`.","message":"In yacman v1.0.0, the constructors for `YAMLConfigManager` have changed. Instead of direct instantiation like `YAMLConfigManager(data)`, you should now use class methods like `YAMLConfigManager.from_dict(data)` or `YAMLConfigManager.from_file(filepath)` to make the source of the configuration clearer.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Replace `with ym as locked_ym:` with `with write_lock(ym) as locked_ym:` or `with read_lock(ym) as locked_ym:`. Additionally, for write operations, ensure you call `locked_ym.rebase()` before `locked_ym.write()` or use the convenience method `locked_ym.rebase_and_write()` for multi-process safety.","message":"The locking mechanism in yacman v1.0.0 has been significantly refactored. The `with ym as locked_ym: locked_ym.write()` pattern from v0.x is no longer valid. Instead, explicit `read_lock` and `write_lock` context managers are required.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Simply update your imports to `from yacman import YAMLConfigManager` and adjust usage according to the new constructor and locking patterns.","message":"The `FutureYAMLConfigManager` class and its use as `from yacman import FutureYAMLConfigManager as YAMLConfigManager` have been removed in v1.0.0. The standard `YAMLConfigManager` now incorporates those features.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Always use `locked_ym.rebase_and_write()` or explicitly call `locked_ym.rebase()` followed by `locked_ym.write()` within a `write_lock` context.","message":"When writing to a configuration file in a multi-process environment with `yacman v1.0.0`, it is crucial to rebase your configuration before writing to ensure you incorporate any changes made by other processes since you last read the file. Not doing so can lead to data loss or inconsistencies.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Remove the `FutureYAMLConfigManager` import. In yacman v1.0.0, simply use `from yacman import YAMLConfigManager`.","cause":"Attempting to import `FutureYAMLConfigManager` from `yacman` in version 1.0.0 or later, where this class has been removed.","error":"AttributeError: module 'yacman' has no attribute 'FutureYAMLConfigManager'"},{"fix":"Use the appropriate class method for initialization, e.g., `ym = YAMLConfigManager.from_dict(data)` for dictionary input or `ym = YAMLConfigManager.from_file('path/to/config.yaml')` for file input.","cause":"Attempting to initialize `YAMLConfigManager` by directly passing data or a filepath to its constructor in v1.0.0+, which expects specific `from_x` class methods.","error":"TypeError: YAMLConfigManager.__init__() got an unexpected keyword argument 'data' (or similar error when passing a dict to constructor)"},{"fix":"Ensure all write operations are performed within a `with write_lock(ym) as locked_ym:` block. For example, `with write_lock(ym) as locked_ym: locked_ym.rebase_and_write()`.","cause":"Trying to call `write()` on a `YAMLConfigManager` object in v1.0.0+ without first acquiring a `write_lock` through its context manager.","error":"RuntimeError: Attempted to write to a Yacman object that is not locked for writing."}]}