def test_set_nested_key(key):
    config = copy.deepcopy(CONFIG_DICT)
    try:
        before_value = get_nested_key(config, key)
    except KeyError:
        pass
    else:
        assert before_value != 'arst'
    set_nested_key(config, key, 'arst')
    actual = get_nested_key(config, key)
    assert actual == 'arst'
Exemple #2
0
 def __getitem__(self, key):
     try:
         return self.resolve(get_nested_key(self._wrapped, key))
     except KeyError:
         raise KeyError(
             "Key '{0}' not found in {1}".format(
                 key, self._wrapped
             )
         )
Exemple #3
0
def resolve_config(config, master_config):
    if '$ref' in config:
        if len(config.keys()) != 1:
            raise KeyError(
                "Config references may not contain extra keys.  The keys "
                "'{0}' were found.".format("', '".join(config.keys())))
        if not has_nested_key(master_config, config['$ref']):
            raise KeyError(
                "Config reference {0} is not present in master configuration".
                format(config['$ref'], ))
        return get_nested_key(master_config, config['$ref'])
    else:
        return config
Exemple #4
0
def normalize_combined_json_contract_key(key_from_compiler, contract_data):
    if ':' not in key_from_compiler:
        try:
            compilation_target = get_nested_key(
                contract_data,
                'metadata.settings.compilationTarget',
            )
        except KeyError:
            pass
        else:
            if len(compilation_target) != 1:
                raise ValueError('Invalid compilationTarget {}'.format(compilation_target))
            return next(it for it in compilation_target.items())
    source_path, _, name = key_from_compiler.rpartition(':')
    return source_path, name
def normalize_combined_json_contract_key(key_from_compiler, contract_data):
    if ':' not in key_from_compiler:
        try:
            compilation_target = get_nested_key(
                contract_data,
                'metadata.settings.compilationTarget',
            )
        except KeyError:
            pass
        else:
            if len(compilation_target) != 1:
                raise ValueError('Invalid compilationTarget {}'.format(compilation_target))
            return next(it for it in compilation_target.items())
    source_path, _, name = key_from_compiler.rpartition(':')
    return source_path, name
Exemple #6
0
def resolve_config(config, master_config):
    if '$ref' in config:
        if len(config.keys()) != 1:
            raise KeyError(
                "Config references may not contain extra keys.  The keys "
                "'{0}' were found.".format("', '".join(config.keys()))
            )
        if not has_nested_key(master_config, config['$ref']):
            raise KeyError(
                "Config reference {0} is not present in master configuration".format(
                    config['$ref'],
                )
            )
        return get_nested_key(master_config, config['$ref'])
    else:
        return config
Exemple #7
0
def upgrade_v2_to_v3(v2_config):
    """
    Upgrade a v2 config file to a v3 config file.
    """
    errors = get_validation_errors(v2_config, version=V2)
    if errors:
        raise ValueError(
            "Cannot upgrade invalid config.  Please ensure that your current "
            "configuration file is valid:\n\n{0}".format(
                format_errors(errors), ))

    v2_default_config = load_default_config(version=V2)
    v3_default_config = load_default_config(version=V3)

    if v2_config == v2_default_config:
        return v3_default_config

    upgraded_v2_config = copy.deepcopy(v2_config)

    for key_path in NEW_V3_PATHS:
        if has_nested_key(upgraded_v2_config, key_path):
            continue
        set_nested_key(
            upgraded_v2_config,
            key_path,
            get_nested_key(v3_default_config, key_path),
        )

    # bump the version
    set_nested_key(upgraded_v2_config, 'version', V3)

    errors = get_validation_errors(upgraded_v2_config, version=V3)
    if errors:
        raise ValueError("Upgraded configuration did not pass validation:\n\n"
                         "\n=============Original-Configuration============\n"
                         "{0}"
                         "\n=============Upgraded-Configuration============\n"
                         "{1}"
                         "\n=============Validation-Errors============\n"
                         "{2}".format(
                             pprint.pformat(dict(v2_config)),
                             pprint.pformat(dict(upgraded_v2_config)),
                             format_errors(errors),
                         ))

    return upgraded_v2_config
Exemple #8
0
 def get(self, key, default=None):
     try:
         value = get_nested_key(self._wrapped, key)
     except KeyError:
         return default
     return self.resolve(value)
Exemple #9
0
 def __getitem__(self, key):
     try:
         return self.resolve(get_nested_key(self._wrapped, key))
     except KeyError:
         raise KeyError("Key '{0}' not found in {1}".format(
             key, self._wrapped))
    def get_compiled_contracts(self, source_file_paths, import_remappings):
        self.logger.debug("Import remappings: %s", import_remappings)
        self.logger.debug("Compiler Settings PRE: %s",
                          pprint.pformat(self.compiler_settings))

        # DEBUG
        self.compiler_settings['output_values'] = []
        self.logger.debug("Compiler Settings POST: %s",
                          pprint.pformat(self.compiler_settings))

        if 'remappings' in self.compiler_settings and import_remappings is not None:
            self.logger.warn(
                "Import remappings setting will by overridden by backend settings"
            )

        sources = build_standard_input_sources(source_file_paths)

        std_input = {
            'language': 'Solidity',
            'sources': sources,
            'settings': {
                'remappings': import_remappings,
                'outputSelection': {
                    '*': {
                        '*': REQUIRED_OUTPUT_SELECTION
                    }
                }
            }
        }

        # solc command line options as passed to solc_wrapper()
        # https://github.com/ethereum/py-solc/blob/3a6de359dc31375df46418e6ffd7f45ab9567287/solc/wrapper.py#L20
        command_line_options = self.compiler_settings.get(
            "command_line_options", {})

        # Get Solidity Input Description settings section
        # http://solidity.readthedocs.io/en/develop/using-the-compiler.html#input-description
        std_input_settings = self.compiler_settings.get("stdin", {})
        std_input['settings'].update(std_input_settings)

        # Make sure the output selection has all of the required output values.
        if has_nested_key(std_input, OUTPUT_SELECTION_KEY):
            current_selection = get_nested_key(std_input, OUTPUT_SELECTION_KEY)
            output_selection = list(
                set(concatv(current_selection, REQUIRED_OUTPUT_SELECTION)))
        else:
            output_selection = REQUIRED_OUTPUT_SELECTION

        set_nested_key(std_input, OUTPUT_SELECTION_KEY, output_selection)

        self.logger.debug("std_input sections: %s", std_input.keys())
        self.logger.debug("Input Description JSON settings are: %s",
                          std_input["settings"])
        self.logger.debug("Command line options are: %s", command_line_options)
        try:
            compilation_result = compile_standard(std_input,
                                                  **command_line_options)
        except ContractsNotFound:
            return {}

        compiled_contracts = normalize_compilation_result(compilation_result)

        return compiled_contracts
Exemple #11
0
 def get(self, key, default=None):
     try:
         value = get_nested_key(self._wrapped, key)
     except KeyError:
         return default
     return self.resolve(value)
Exemple #12
0
def upgrade_v3_to_v4(v3_config):
    """
    Upgrade a v3 config file to a v4 config file.
    """
    errors = get_validation_errors(v3_config, version=V3)
    if errors:
        raise ValueError(
            "Cannot upgrade invalid config.  Please ensure that your current "
            "configuration file is valid:\n\n{0}".format(
                format_errors(errors),
            )
        )

    v3_default_config = load_default_config(version=V3)
    v4_default_config = load_default_config(version=V4)

    if v3_config == v3_default_config:
        return v4_default_config

    upgraded_v3_config = copy.deepcopy(v3_config)

    for key_path in NEW_V4_PATHS:
        if has_nested_key(upgraded_v3_config, key_path):
            continue
        set_nested_key(
            upgraded_v3_config,
            key_path,
            get_nested_key(v4_default_config, key_path),
        )

    for old_path, new_path in MOVED_V3_PATHS.items():
        default_value = get_nested_key(v4_default_config, new_path)

        if has_nested_key(upgraded_v3_config, old_path):
            existing_value = pop_nested_key(upgraded_v3_config, old_path)

            if is_dict(default_value) and is_dict(existing_value):
                merged_value = deep_merge_dicts(default_value, existing_value)
            elif is_list_like(default_value) and is_list_like(existing_value):
                merged_value = list(set(itertools.chain(default_value, existing_value)))
            else:
                raise ValueError(
                    "Unable to merge {0} with {1}".format(
                        type(default_value),
                        type(existing_value),
                    )
                )

            set_nested_key(
                upgraded_v3_config,
                new_path,
                merged_value,
            )
        else:
            set_nested_key(
                upgraded_v3_config,
                new_path,
                default_value,
            )

    # bump the version
    set_nested_key(upgraded_v3_config, 'version', V4)

    errors = get_validation_errors(upgraded_v3_config, version=V4)
    if errors:
        raise ValueError(
            "Upgraded configuration did not pass validation:\n\n"
            "\n=============Original-Configuration============\n"
            "{0}"
            "\n=============Upgraded-Configuration============\n"
            "{1}"
            "\n=============Validation-Errors============\n"
            "{2}".format(
                pprint.pformat(dict(v3_config)),
                pprint.pformat(dict(upgraded_v3_config)),
                format_errors(errors),
            )
        )

    return upgraded_v3_config
Exemple #13
0
def upgrade_v5_to_v6(v5_config):
    """
    Upgrade a v5 config file to a v6 config file.
    """
    errors = get_validation_errors(v5_config, version=V5)
    if errors:
        raise ValueError(
            "Cannot upgrade invalid config.  Please ensure that your current "
            "configuration file is valid:\n\n{0}".format(
                format_errors(errors),
            )
        )

    v5_default_config = load_default_config(version=V5)
    v6_default_config = load_default_config(version=V6)

    if v5_config == v5_default_config:
        return v6_default_config

    upgraded_v5_config = copy.deepcopy(v5_config)

    # new configuration values whos keys were not present in the previous
    # configuration.
    for key_path in NEW_V6_PATHS:
        if has_nested_key(upgraded_v5_config, key_path):
            continue
        set_nested_key(
            upgraded_v5_config,
            key_path,
            get_nested_key(v6_default_config, key_path),
        )

    if has_nested_key(upgraded_v5_config, 'compilation.contracts_source_dir'):
        current_contracts_source_dir = pop_nested_key(
            upgraded_v5_config,
            'compilation.contracts_source_dir',
        )
        if is_string(current_contracts_source_dir):
            contract_source_dirs = [current_contracts_source_dir]
        else:
            contract_source_dirs = current_contracts_source_dir
        set_nested_key(
            upgraded_v5_config,
            'compilation.contract_source_dirs',
            contract_source_dirs,
        )

    # bump the version
    set_nested_key(upgraded_v5_config, 'version', V6)

    errors = get_validation_errors(upgraded_v5_config, version=V6)
    if errors:
        raise ValueError(
            "Upgraded configuration did not pass validation:\n\n"
            "\n=============Original-Configuration============\n"
            "{0}"
            "\n=============Upgraded-Configuration============\n"
            "{1}"
            "\n=============Validation-Errors============\n"
            "{2}".format(
                pprint.pformat(dict(v5_config)),
                pprint.pformat(dict(upgraded_v5_config)),
                format_errors(errors),
            )
        )

    return upgraded_v5_config
Exemple #14
0
def upgrade_v4_to_v5(v4_config):
    """
    Upgrade a v4 config file to a v5 config file.
    """
    errors = get_validation_errors(v4_config, version=V4)
    if errors:
        raise ValueError(
            "Cannot upgrade invalid config.  Please ensure that your current "
            "configuration file is valid:\n\n{0}".format(
                format_errors(errors),
            )
        )

    v4_default_config = load_default_config(version=V4)
    v5_default_config = load_default_config(version=V5)

    if v4_config == v4_default_config:
        return v5_default_config

    upgraded_v4_config = copy.deepcopy(v4_config)

    # new configuration values whos keys were not present in the previous
    # configuration.
    for key_path in NEW_V5_PATHS:
        if has_nested_key(upgraded_v4_config, key_path):
            continue
        set_nested_key(
            upgraded_v4_config,
            key_path,
            get_nested_key(v5_default_config, key_path),
        )

    # keys in the new configuration that were relocated.
    for old_path, new_path in MOVED_V4_PATHS.items():
        default_value = get_nested_key(v5_default_config, new_path)

        if has_nested_key(upgraded_v4_config, old_path):
            existing_value = pop_nested_key(upgraded_v4_config, old_path)

            if is_dict(default_value) and is_dict(existing_value):
                merged_value = deep_merge_dicts(default_value, existing_value)
            elif is_list_like(default_value) and is_list_like(existing_value):
                merged_value = list(set(itertools.chain(default_value, existing_value)))
            else:
                raise ValueError(
                    "Unable to merge {0} with {1}".format(
                        type(default_value),
                        type(existing_value),
                    )
                )

            set_nested_key(
                upgraded_v4_config,
                new_path,
                merged_value,
            )
        else:
            set_nested_key(
                upgraded_v4_config,
                new_path,
                default_value,
            )

    # keys from the previous configuration that were changed.
    for key_path in MODIFIED_V4_PATHS:
        new_default = get_nested_key(v5_default_config, key_path)
        if key_path not in upgraded_v4_config:
            set_nested_key(
                upgraded_v4_config,
                key_path,
                new_default,
            )
        else:
            current_value = get_nested_key(upgraded_v4_config, key_path)
            old_default = get_nested_key(v4_default_config, key_path)
            if current_value == old_default:
                set_nested_key(
                    upgraded_v4_config,
                    key_path,
                    new_default,
                )

    # bump the version
    set_nested_key(upgraded_v4_config, 'version', V5)

    errors = get_validation_errors(upgraded_v4_config, version=V5)
    if errors:
        raise ValueError(
            "Upgraded configuration did not pass validation:\n\n"
            "\n=============Original-Configuration============\n"
            "{0}"
            "\n=============Upgraded-Configuration============\n"
            "{1}"
            "\n=============Validation-Errors============\n"
            "{2}".format(
                pprint.pformat(dict(v4_config)),
                pprint.pformat(dict(upgraded_v4_config)),
                format_errors(errors),
            )
        )

    return upgraded_v4_config
Exemple #15
0
def upgrade_v3_to_v4(v3_config):
    """
    Upgrade a v3 config file to a v4 config file.
    """
    errors = get_validation_errors(v3_config, version=V3)
    if errors:
        raise ValueError(
            "Cannot upgrade invalid config.  Please ensure that your current "
            "configuration file is valid:\n\n{0}".format(
                format_errors(errors), ))

    v3_default_config = load_default_config(version=V3)
    v4_default_config = load_default_config(version=V4)

    if v3_config == v3_default_config:
        return v4_default_config

    upgraded_v3_config = copy.deepcopy(v3_config)

    for key_path in NEW_V4_PATHS:
        if has_nested_key(upgraded_v3_config, key_path):
            continue
        set_nested_key(
            upgraded_v3_config,
            key_path,
            get_nested_key(v4_default_config, key_path),
        )

    for old_path, new_path in MOVED_V3_PATHS.items():
        default_value = get_nested_key(v4_default_config, new_path)

        if has_nested_key(upgraded_v3_config, old_path):
            existing_value = pop_nested_key(upgraded_v3_config, old_path)

            if is_dict(default_value) and is_dict(existing_value):
                merged_value = deep_merge_dicts(default_value, existing_value)
            elif is_list_like(default_value) and is_list_like(existing_value):
                merged_value = list(
                    set(itertools.chain(default_value, existing_value)))
            else:
                raise ValueError("Unable to merge {0} with {1}".format(
                    type(default_value),
                    type(existing_value),
                ))

            set_nested_key(
                upgraded_v3_config,
                new_path,
                merged_value,
            )
        else:
            set_nested_key(
                upgraded_v3_config,
                new_path,
                default_value,
            )

    # bump the version
    set_nested_key(upgraded_v3_config, 'version', V4)

    errors = get_validation_errors(upgraded_v3_config, version=V4)
    if errors:
        raise ValueError("Upgraded configuration did not pass validation:\n\n"
                         "\n=============Original-Configuration============\n"
                         "{0}"
                         "\n=============Upgraded-Configuration============\n"
                         "{1}"
                         "\n=============Validation-Errors============\n"
                         "{2}".format(
                             pprint.pformat(dict(v3_config)),
                             pprint.pformat(dict(upgraded_v3_config)),
                             format_errors(errors),
                         ))

    return upgraded_v3_config
def test_get_nested_key_with_missing_key(key):
    config = copy.deepcopy(CONFIG_DICT)
    with pytest.raises(KeyError):
        get_nested_key(config, key)
def test_get_nested_key(key, expected):
    config = copy.deepcopy(CONFIG_DICT)
    actual = get_nested_key(config, key)
    assert actual == expected
Exemple #18
0
def upgrade_v4_to_v5(v4_config):
    """
    Upgrade a v4 config file to a v5 config file.
    """
    errors = get_validation_errors(v4_config, version=V4)
    if errors:
        raise ValueError(
            "Cannot upgrade invalid config.  Please ensure that your current "
            "configuration file is valid:\n\n{0}".format(
                format_errors(errors), ))

    v4_default_config = load_default_config(version=V4)
    v5_default_config = load_default_config(version=V5)

    if v4_config == v4_default_config:
        return v5_default_config

    upgraded_v4_config = copy.deepcopy(v4_config)

    # new configuration values whos keys were not present in the previous
    # configuration.
    for key_path in NEW_V5_PATHS:
        if has_nested_key(upgraded_v4_config, key_path):
            continue
        set_nested_key(
            upgraded_v4_config,
            key_path,
            get_nested_key(v5_default_config, key_path),
        )

    # keys in the new configuration that were relocated.
    for old_path, new_path in MOVED_V4_PATHS.items():
        default_value = get_nested_key(v5_default_config, new_path)

        if has_nested_key(upgraded_v4_config, old_path):
            existing_value = pop_nested_key(upgraded_v4_config, old_path)

            if is_dict(default_value) and is_dict(existing_value):
                merged_value = deep_merge_dicts(default_value, existing_value)
            elif is_list_like(default_value) and is_list_like(existing_value):
                merged_value = list(
                    set(itertools.chain(default_value, existing_value)))
            else:
                raise ValueError("Unable to merge {0} with {1}".format(
                    type(default_value),
                    type(existing_value),
                ))

            set_nested_key(
                upgraded_v4_config,
                new_path,
                merged_value,
            )
        else:
            set_nested_key(
                upgraded_v4_config,
                new_path,
                default_value,
            )

    # keys from the previous configuration that were changed.
    for key_path in MODIFIED_V4_PATHS:
        new_default = get_nested_key(v5_default_config, key_path)
        if key_path not in upgraded_v4_config:
            set_nested_key(
                upgraded_v4_config,
                key_path,
                new_default,
            )
        else:
            current_value = get_nested_key(upgraded_v4_config, key_path)
            old_default = get_nested_key(v4_default_config, key_path)
            if current_value == old_default:
                set_nested_key(
                    upgraded_v4_config,
                    key_path,
                    new_default,
                )

    # bump the version
    set_nested_key(upgraded_v4_config, 'version', V5)

    errors = get_validation_errors(upgraded_v4_config, version=V5)
    if errors:
        raise ValueError("Upgraded configuration did not pass validation:\n\n"
                         "\n=============Original-Configuration============\n"
                         "{0}"
                         "\n=============Upgraded-Configuration============\n"
                         "{1}"
                         "\n=============Validation-Errors============\n"
                         "{2}".format(
                             pprint.pformat(dict(v4_config)),
                             pprint.pformat(dict(upgraded_v4_config)),
                             format_errors(errors),
                         ))

    return upgraded_v4_config
Exemple #19
0
def upgrade_v1_to_v2(v1_config):
    """
    Upgrade a v1 config file to a v2 config file.
    """
    errors = get_validation_errors(v1_config, version=V1)
    if errors:
        raise ValueError(
            "Cannot upgrade invalid config.  Please ensure that your current "
            "configuration file is valid:\n\n{0}".format(
                format_errors(errors),
            )
        )

    v1_default_config = load_default_config(version=V1)
    v2_default_config = load_default_config(version=V2)

    if v1_config == v1_default_config:
        return v2_default_config

    upgraded_v1_config = copy.deepcopy(v1_config)

    for key_path in NEW_V2_PATHS:
        if has_nested_key(upgraded_v1_config, key_path):
            continue
        set_nested_key(
            upgraded_v1_config,
            key_path,
            get_nested_key(v2_default_config, key_path),
        )

    for old_path, new_path in V2_TRANSLATIONS.items():
        if not has_nested_key(upgraded_v1_config, old_path):
            continue
        set_nested_key(
            upgraded_v1_config,
            new_path,
            pop_nested_key(upgraded_v1_config, old_path),
        )

    for key_path in V2_UPDATES:
        if not has_nested_key(upgraded_v1_config, key_path):
            continue
        current_value = get_nested_key(upgraded_v1_config, key_path)
        old_default_value = get_nested_key(v1_default_config, key_path)

        if current_value == old_default_value:
            set_nested_key(
                upgraded_v1_config,
                key_path,
                get_nested_key(v2_default_config, key_path),
            )

    # bump the version
    set_nested_key(upgraded_v1_config, 'version', V2)

    errors = get_validation_errors(upgraded_v1_config, version=V2)
    if errors:
        raise ValueError(
            "Upgraded configuration did not pass validation:\n\n"
            "\n=============Original-Configuration============\n"
            "{0}"
            "\n=============Upgraded-Configuration============\n"
            "{1}"
            "\n=============Validation-Errors============\n"
            "{2}".format(
                pprint.pformat(dict(v1_config)),
                pprint.pformat(dict(upgraded_v1_config)),
                format_errors(errors),
            )
        )

    return upgraded_v1_config
Exemple #20
0
def upgrade_v5_to_v6(v5_config):
    """
    Upgrade a v5 config file to a v6 config file.
    """
    errors = get_validation_errors(v5_config, version=V5)
    if errors:
        raise ValueError(
            "Cannot upgrade invalid config.  Please ensure that your current "
            "configuration file is valid:\n\n{0}".format(
                format_errors(errors),
            )
        )

    v5_default_config = load_default_config(version=V5)
    v6_default_config = load_default_config(version=V6)

    if v5_config == v5_default_config:
        return v6_default_config

    upgraded_v5_config = copy.deepcopy(v5_config)

    # new configuration values whos keys were not present in the previous
    # configuration.
    for key_path in NEW_V6_PATHS:
        if has_nested_key(upgraded_v5_config, key_path):
            continue
        set_nested_key(
            upgraded_v5_config,
            key_path,
            get_nested_key(v6_default_config, key_path),
        )

    if has_nested_key(upgraded_v5_config, 'compilation.contracts_source_dir'):
        current_contracts_source_dir = pop_nested_key(
            upgraded_v5_config,
            'compilation.contracts_source_dir',
        )
        if is_string(current_contracts_source_dir):
            contract_source_dirs = [current_contracts_source_dir]
        else:
            contract_source_dirs = current_contracts_source_dir
        set_nested_key(
            upgraded_v5_config,
            'compilation.contract_source_dirs',
            contract_source_dirs,
        )

    # bump the version
    set_nested_key(upgraded_v5_config, 'version', V6)

    errors = get_validation_errors(upgraded_v5_config, version=V6)
    if errors:
        raise ValueError(
            "Upgraded configuration did not pass validation:\n\n"
            "\n=============Original-Configuration============\n"
            "{0}"
            "\n=============Upgraded-Configuration============\n"
            "{1}"
            "\n=============Validation-Errors============\n"
            "{2}".format(
                pprint.pformat(dict(v5_config)),
                pprint.pformat(dict(upgraded_v5_config)),
                format_errors(errors),
            )
        )

    return upgraded_v5_config