init: only imoprt jsonschema if needed

- It turns out that jsonschema is one of the more expensive imports.

- move imports of jsonschema into functions to avoid the performance hits
  for calls that don't need config.
This commit is contained in:
Todd Gamblin 2018-05-12 21:51:05 -07:00 committed by scheibelp
parent 6f2cac9565
commit 1fe5dbf338

View File

@ -59,9 +59,7 @@
from six import iteritems from six import iteritems
import yaml import yaml
import jsonschema
from yaml.error import MarkedYAMLError from yaml.error import MarkedYAMLError
from jsonschema import Draft4Validator, validators
import llnl.util.tty as tty import llnl.util.tty as tty
from llnl.util.filesystem import mkdirp from llnl.util.filesystem import mkdirp
@ -72,7 +70,6 @@
from spack.error import SpackError from spack.error import SpackError
from spack.util.ordereddict import OrderedDict from spack.util.ordereddict import OrderedDict
# Hacked yaml for configuration files preserves line numbers. # Hacked yaml for configuration files preserves line numbers.
import spack.util.spack_yaml as syaml import spack.util.spack_yaml as syaml
@ -132,6 +129,7 @@ def _extend_with_default(validator_class):
commented out. commented out.
""" """
import jsonschema
validate_properties = validator_class.VALIDATORS["properties"] validate_properties = validator_class.VALIDATORS["properties"]
validate_pattern_properties = validator_class.VALIDATORS[ validate_pattern_properties = validator_class.VALIDATORS[
"patternProperties"] "patternProperties"]
@ -157,16 +155,12 @@ def set_pp_defaults(validator, properties, instance, schema):
validator, properties, instance, schema): validator, properties, instance, schema):
yield err yield err
return validators.extend(validator_class, { return jsonschema.validators.extend(validator_class, {
"properties": set_defaults, "properties": set_defaults,
"patternProperties": set_pp_defaults "patternProperties": set_pp_defaults
}) })
#: the validator we use for Spack config files
DefaultSettingValidator = _extend_with_default(Draft4Validator)
class ConfigScope(object): class ConfigScope(object):
"""This class represents a configuration scope. """This class represents a configuration scope.
@ -192,6 +186,7 @@ def get_section(self, section):
return self.sections[section] return self.sections[section]
def write_section(self, section): def write_section(self, section):
import jsonschema
filename = self.get_section_filename(section) filename = self.get_section_filename(section)
data = self.get_section(section) data = self.get_section(section)
try: try:
@ -545,8 +540,14 @@ def _validate_section(data, schema):
on Spack YAML structures. on Spack YAML structures.
""" """
import jsonschema
if not hasattr(_validate_section, 'validator'):
DefaultSettingValidator = _extend_with_default(
jsonschema.Draft4Validator)
_validate_section.validator = DefaultSettingValidator
try: try:
DefaultSettingValidator(schema).validate(data) _validate_section.validator(schema).validate(data)
except jsonschema.ValidationError as e: except jsonschema.ValidationError as e:
raise ConfigFormatError(e, data) raise ConfigFormatError(e, data)