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

Commit

Permalink
config adapter helper functions (#896)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Titousensei authored and facebook-github-bot committed Aug 15, 2019
1 parent f9e662f commit 0217d4f
Showing 1 changed file with 50 additions and 39 deletions.
89 changes: 50 additions & 39 deletions pytext/config/config_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


ADAPTERS = {}
NOT_THERE = (None, None, None)


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


def rename_parameter(config, old_path, new_path):
def find_parameter(config, path_str):
# Recursively find path elements, skipping into type specifiers.
# Return the value and its container so the value can be deleted.

path = path_str.split(".")
value = config
container = None
for segment in path:
while is_type_specifier(value):
container, value = value, next(iter(value.values()))
if segment not in value:
return NOT_THERE
container, value = value, value[segment]
return path[-1], container, value


def _create_path(config, path):
# Recursively find path elements, skipping into type specifiers.
# If any container isn't there, create a new empty object for it.
# This will only be created if the
value = config
for segment in path:
while is_type_specifier(value):
value = next(iter(value.values()))
if segment not in value:
value[segment] = {}
value = value[segment]
while is_type_specifier(value):
value = next(iter(value.values()))
return value


def create_parameter(config, path_str, value):
*path, param = path_str.split(".")
new_container = _create_path(config, path)
new_container[param] = value


def delete_parameter(config, path_str):
param_name, container, _ = find_parameter(config, path_str)
if container:
container.pop(param_name, None)


def rename_parameter(config, old_path, new_path, transform=lambda x: x):
"""A powerful tool for writing config adapters, this allows you to specify
a JSON-style path for an old and new config parameter. For instance
Expand All @@ -60,47 +105,13 @@ def rename_parameter(config, old_path, new_path):
set it in task.trainer.num_batches_per_epoch instead, creating trainer as an empty
dictionary if necessary."""

old_path = old_path.split(".")
new_path = new_path.split(".")

NOT_THERE = object()

def find_path(config, path):
# Recursively find path elements, skipping into type specifiers.
# Return the value and its container so the value can be deleted.
value = config
container = None
for segment in path:
while is_type_specifier(value):
container, value = value, next(iter(value.values()))
if segment not in value:
return NOT_THERE
container, value = value, value[segment]
return container, value

def create_path(config, path):
# Recursively find path elements, skipping into type specifiers.
# If any container isn't there, create a new empty object for it.
# This will only be created if the
value = config
for segment in path:
while is_type_specifier(value):
value = next(iter(value.values()))
if segment not in value:
value[segment] = {}
value = value[segment]
while is_type_specifier(value):
value = next(iter(value.values()))
return value

found = find_path(config, old_path)
found = find_parameter(config, old_path)
if found is not NOT_THERE:
container, old_value = found
param_name, container, old_value = found
# Delete old value
container.pop(old_path[-1])
container.pop(param_name)
# Update new value
new_container = create_path(config, new_path[:-1])
new_container[new_path[-1]] = old_value
create_parameter(config, new_path, transform(old_value))

return config

Expand Down

0 comments on commit 0217d4f

Please sign in to comment.