Upgrading to yacman v1.0
Overview
Yacman v1.0 provides two major feature upgrades:
- New constructor pattern: Constructors now use
YAMLConfigManager.from_x(...)methods to make object creation clearer - Separate read/write locks: Locks are now separated into read locks and write locks, allowing multiple simultaneous readers
Upgrading from v0.9.3 to v1.0.0
Step 1: Update imports
If you were using FutureYAMLConfigManager in v0.9.3, update your imports:
Before (v0.9.3):
from yacman import FutureYAMLConfigManager as YAMLConfigManager
After (v1.0.0):
from yacman import YAMLConfigManager
Step 2: Update context managers
Context managers now use explicit write_lock or read_lock functions:
from yacman import write_lock, read_lock
Before (v0.9.3):
with ym as locked_ym:
locked_ym.write()
After (v1.0.0):
with write_lock(ym) as locked_ym:
locked_ym.rebase()
locked_ym.write()
Important: In v1.0, you must call rebase() before write() if you want to allow for multiple processes that may have written to the file since you read it in.
Step 3: Update constructors
You can no longer create a YAMLConfigManager object directly. Use the from_x() constructor methods instead:
Before (v0.9.3):
ym = YAMLConfigManager(filepath="config.yaml")
ym = YAMLConfigManager(entries={"key": "value"})
After (v1.0.0):
from yacman import YAMLConfigManager
# From a file
ym = YAMLConfigManager.from_yaml_file("config.yaml")
# From a dictionary
data = {"key": "value"}
ym = YAMLConfigManager.from_obj(data)
# From a YAML string
yaml_data = "key: value"
ym = YAMLConfigManager.from_yaml_data(yaml_data)
Step 4: Update file loading with overrides
In the past, you could load from a file and overwrite some attributes with a dict, all from the constructor. This is now more explicit:
Before (v0.9.3):
ym = YAMLConfigManager(filepath="config.yaml", entries={"override_key": "value"})
After (v1.0.0):
ym = YAMLConfigManager.from_yaml_file("config.yaml")
ym.update_from_obj({"override_key": "value"})
Complete examples
Example 1: Basic usage with locks
from yacman import YAMLConfigManager, write_lock, read_lock
data = {
"my_list": [1, 2, 3],
"my_int": 8,
"my_str": "hello world!",
"my_dict": {"nested_val": 15}
}
# Create from object
ym = YAMLConfigManager.from_obj(data)
# Access values
print(ym["my_list"])
print(ym["my_int"])
print(ym["my_dict"])
# Modify and write with a write lock
ym["new_var"] = 15
with write_lock(ym) as locked_ym:
locked_ym.rebase() # Capture any changes since file was loaded
locked_ym.write()
Example 2: Read locks
# Use a read lock to rebase
# This will replay any in-memory updates on top of whatever is re-read from the file
with read_lock(ym) as locked_ym:
locked_ym.rebase()
# Use a read lock to reset the in-memory object to whatever is on disk
with read_lock(ym) as locked_ym:
locked_ym.reset()
Example 3: Expanding environment variables
To expand environment variables in values, use the .exp attribute:
ym = YAMLConfigManager.from_yaml_file("config.yaml")
expanded_value = ym.exp["path_with_env_vars"]
Migration checklist
- [ ] Update imports from
FutureYAMLConfigManagertoYAMLConfigManager - [ ] Replace direct constructor calls with
from_yaml_file(),from_obj(), orfrom_yaml_data() - [ ] Update context managers to use
write_lock()orread_lock() - [ ] Add
rebase()calls beforewrite()in write-lock contexts - [ ] Replace combined file+override constructors with explicit
update_from_obj()calls - [ ] Test all file I/O operations
- [ ] Verify environment variable expansion works correctly
Deprecated features
The following are deprecated in v1.0 and will be removed in future versions:
- Direct instantiation of
YAMLConfigManager(usefrom_x()methods instead) - Using YAMLConfigManager object as a context manager directly (use
write_lock()orread_lock()) YacAttMapclass (replaced byYAMLConfigManager)