# Buggy code
def set_path_value(config, path, value, prefix=()):
    # Postgresql GUCs can't be nested, but can contain dots so we re-flatten the structure for this case
    if prefix == ("postgresql", "parameters"):
        path = [".".join(path)]

    if len(path) == 1:
        if value is None:
            config.pop(path[0], None)
        else:
            config[path[0]] = value
    else:
        key = path[0]
        if key not in config:
            config[key] = {}
        set_path_value(config[key], path[1:], value, prefix + (key,))
        if config[key] == {}:
            del config[key]


# Traceback (kazoo.exceptions.ConnectionClosedError)
[root@postgres-5-2 ~]# patronictl -c /etc/patroni.yaml edit-config postgres-5
---
+++
@@ -11,4 +11,4 @@
use_pg_rewind: true
use_slots: true
retry_timeout: 10
-ttl: 30
+ttl: 31

Apply these changes? [y/N]: y
2017-07-28 23:27:53,965 - ERROR - Unhandled exception in connection loop
Traceback (most recent call last):
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 541, in _connect_attempt
self._send_request(read_timeout, connect_timeout)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 445, in _send_request
self._submit(request, connect_timeout, xid)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 279, in _submit
b += request.serialize()
File "/usr/lib/python3.4/site-packages/kazoo/protocol/serialization.py", line 195, in serialize
b.extend(int_struct.pack(self.version))
struct.error: 'i' format requires -2147483648 <= number <= 2147483647
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib64/python3.4/threading.py", line 911, in _bootstrap_inner
self.run()
File "/usr/lib64/python3.4/threading.py", line 859, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 471, in zk_loop
if retry(self._connect_loop, retry) is STOP_CONNECTING:
File "/usr/lib/python3.4/site-packages/kazoo/retry.py", line 123, in __call__
return func(*args, **kwargs)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 488, in _connect_loop
status = self._connect_attempt(host, port, retry)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 541, in _connect_attempt
self._send_request(read_timeout, connect_timeout)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 445, in _send_request
self._submit(request, connect_timeout, xid)
File "/usr/lib/python3.4/site-packages/kazoo/protocol/connection.py", line 279, in _submit
b += request.serialize()
File "/usr/lib/python3.4/site-packages/kazoo/protocol/serialization.py", line 195, in serialize
b.extend(int_struct.pack(self.version))
struct.error: 'i' format requires -2147483648 <= number <= 2147483647

2017-07-28 23:27:54,328 - ERROR - set_config_value
Traceback (most recent call last):
File "/usr/lib/python3.4/site-packages/patroni/dcs/zookeeper.py", line 230, in set_config_value
self._client.retry(self._client.set, self.config_path, value.encode('utf-8'), version=index or -1)
File "/usr/lib/python3.4/site-packages/kazoo/client.py", line 273, in _retry
return self._retry.copy()(*args, **kwargs)
File "/usr/lib/python3.4/site-packages/kazoo/retry.py", line 123, in __call__
return func(*args, **kwargs)
File "/usr/lib/python3.4/site-packages/kazoo/client.py", line 1219, in set
return self.set_async(path, value, version).get()
File "/usr/lib/python3.4/site-packages/kazoo/handlers/utils.py", line 72, in get
raise self._exception
kazoo.exceptions.ConnectionClosedError: Connection has been closed
Error: Config modification aborted due to concurrent changes

# Fixed code
def set_path_value(config, path, value, prefix=()):
    # Postgresql GUCs can't be nested, but can contain dots so we re-flatten the structure for this case
    if prefix == ("postgresql", "parameters"):
        path = [".".join(path)]

    key = path[0]
    if len(path) == 1:
        if value is None:
            config.pop(key, None)
        else:
            config[key] = value
    else:
        if not isinstance(config.get(key), dict):
            config[key] = {}
        set_path_value(config[key], path[1:], value, prefix + (key,))
        if config[key] == {}:
            del config[key]