Skip to content
This repository was archived by the owner on Nov 22, 2022. It is now read-only.

Commit 0217d4f

Browse files
Titousenseifacebook-github-bot
authored andcommitted
config adapter helper functions (#896)
Summary: Pull Request resolved: #896 config adapter has a very powerfull function `rename_parameter`. This diff splits this function to expose its inner functions that can be useful for more than just renaming parameters. These new functions will be used in the next diff in the stack Reviewed By: bethebunny Differential Revision: D16749189 fbshipit-source-id: 3e9c9e0eb0e977d8392e3239101e4a17e1b2039b
1 parent f9e662f commit 0217d4f

1 file changed

Lines changed: 50 additions & 39 deletions

File tree

pytext/config/config_adapter.py

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77

88
ADAPTERS = {}
9+
NOT_THERE = (None, None, None)
910

1011

1112
def register_adapter(from_version):
@@ -49,7 +50,51 @@ def is_type_specifier(json_dict):
4950
return key[0] == key[0].upper()
5051

5152

52-
def rename_parameter(config, old_path, new_path):
53+
def find_parameter(config, path_str):
54+
# Recursively find path elements, skipping into type specifiers.
55+
# Return the value and its container so the value can be deleted.
56+
57+
path = path_str.split(".")
58+
value = config
59+
container = None
60+
for segment in path:
61+
while is_type_specifier(value):
62+
container, value = value, next(iter(value.values()))
63+
if segment not in value:
64+
return NOT_THERE
65+
container, value = value, value[segment]
66+
return path[-1], container, value
67+
68+
69+
def _create_path(config, path):
70+
# Recursively find path elements, skipping into type specifiers.
71+
# If any container isn't there, create a new empty object for it.
72+
# This will only be created if the
73+
value = config
74+
for segment in path:
75+
while is_type_specifier(value):
76+
value = next(iter(value.values()))
77+
if segment not in value:
78+
value[segment] = {}
79+
value = value[segment]
80+
while is_type_specifier(value):
81+
value = next(iter(value.values()))
82+
return value
83+
84+
85+
def create_parameter(config, path_str, value):
86+
*path, param = path_str.split(".")
87+
new_container = _create_path(config, path)
88+
new_container[param] = value
89+
90+
91+
def delete_parameter(config, path_str):
92+
param_name, container, _ = find_parameter(config, path_str)
93+
if container:
94+
container.pop(param_name, None)
95+
96+
97+
def rename_parameter(config, old_path, new_path, transform=lambda x: x):
5398
"""A powerful tool for writing config adapters, this allows you to specify
5499
a JSON-style path for an old and new config parameter. For instance
55100
@@ -60,47 +105,13 @@ def rename_parameter(config, old_path, new_path):
60105
set it in task.trainer.num_batches_per_epoch instead, creating trainer as an empty
61106
dictionary if necessary."""
62107

63-
old_path = old_path.split(".")
64-
new_path = new_path.split(".")
65-
66-
NOT_THERE = object()
67-
68-
def find_path(config, path):
69-
# Recursively find path elements, skipping into type specifiers.
70-
# Return the value and its container so the value can be deleted.
71-
value = config
72-
container = None
73-
for segment in path:
74-
while is_type_specifier(value):
75-
container, value = value, next(iter(value.values()))
76-
if segment not in value:
77-
return NOT_THERE
78-
container, value = value, value[segment]
79-
return container, value
80-
81-
def create_path(config, path):
82-
# Recursively find path elements, skipping into type specifiers.
83-
# If any container isn't there, create a new empty object for it.
84-
# This will only be created if the
85-
value = config
86-
for segment in path:
87-
while is_type_specifier(value):
88-
value = next(iter(value.values()))
89-
if segment not in value:
90-
value[segment] = {}
91-
value = value[segment]
92-
while is_type_specifier(value):
93-
value = next(iter(value.values()))
94-
return value
95-
96-
found = find_path(config, old_path)
108+
found = find_parameter(config, old_path)
97109
if found is not NOT_THERE:
98-
container, old_value = found
110+
param_name, container, old_value = found
99111
# Delete old value
100-
container.pop(old_path[-1])
112+
container.pop(param_name)
101113
# Update new value
102-
new_container = create_path(config, new_path[:-1])
103-
new_container[new_path[-1]] = old_value
114+
create_parameter(config, new_path, transform(old_value))
104115

105116
return config
106117

0 commit comments

Comments
 (0)