def freezedicts(obj): """Recursively iterate over ``obj``, supporting dicts, tuples and lists, and freeze ``dicts`` such that ``obj`` can be used with hash(). """ if isinstance(obj, (list, tuple)): return type(obj)([freezedicts(sub) for sub in obj]) if isinstance(obj, dict): return frozenset(six.iteritems(obj)) return obj
def _get_bundles(self, obj, known_bundles=None): """Return a dict that keys bundle names to bundles.""" bundles = {} for key, data in six.iteritems(obj): if data is None: data = {} bundles[key] = self._get_bundle(data) # now we need to recurse through the bundles and get any that # are included in each other. for bundle_name, bundle in bundles.items(): # copy contents contents = list(bundle.contents) for i, item in enumerate(bundle.contents): if item in bundles: contents[i] = bundles[item] elif known_bundles and item in known_bundles: contents[i] = known_bundles[item] # cast back to a tuple contents = tuple(contents) if contents != bundle.contents: bundle.contents = contents return bundles
def load_environment(self): """Load an :class:`Environment` instance defined in the YAML file. Expects the following format: .. code-block:: yaml directory: ../static url: /media debug: True updater: timestamp config: compass_bin: /opt/compass another_custom_config_value: foo bundles: # ... All values, including ``directory`` and ``url`` are optional. The syntax for defining bundles is the same as for :meth:`~.YAMLLoader.load_bundles`. Sample usage:: from webassets.loaders import YAMLLoader loader = YAMLLoader('asset.yml') env = loader.load_environment() env['some-bundle'].urls() """ f, filename = self._open() try: obj = self.yaml.load(f) or {} env = Environment() # Load environment settings for setting in ('debug', 'cache', 'versions', 'url_expire', 'auto_build', 'url', 'directory', 'manifest', # TODO: The deprecated values; remove at some point 'expire', 'updater'): if setting in obj: setattr(env, setting, obj[setting]) # Treat the 'directory' option special, make it relative to the # path of the YAML file, if we know it. if filename and 'directory' in env.config: env.directory = path.normpath( path.join(path.dirname(filename), env.config['directory'])) # Load custom config options if 'config' in obj: env.config.update(obj['config']) # Load bundles bundles = self._get_bundles(obj.get('bundles', {})) for name, bundle in six.iteritems(bundles): env.register(name, bundle) return env finally: f.close()
def load_environment(self): """Load an :class:`Environment` instance defined in the YAML file. Expects the following format: .. code-block:: yaml directory: ../static url: /media debug: True updater: timestamp config: compass_bin: /opt/compass another_custom_config_value: foo bundles: # ... All values, including ``directory`` and ``url`` are optional. The syntax for defining bundles is the same as for :meth:`~.YAMLLoader.load_bundles`. Sample usage:: from webassets.loaders import YAMLLoader loader = YAMLLoader('asset.yml') env = loader.load_environment() env['some-bundle'].urls() """ f, filename = self._open() try: obj = self.yaml.load(f) or {} env = Environment() # Load environment settings for setting in ( 'debug', 'cache', 'versions', 'url_expire', 'auto_build', 'url', 'directory', 'manifest', # TODO: The deprecated values; remove at some point 'expire', 'updater'): if setting in obj: setattr(env, setting, obj[setting]) # Treat the 'directory' option special, make it relative to the # path of the YAML file, if we know it. if filename and 'directory' in env.config: env.directory = path.normpath( path.join(path.dirname(filename), env.config['directory'])) # Load custom config options if 'config' in obj: env.config.update(obj['config']) # Load bundles bundles = self._get_bundles(obj.get('bundles', {})) for name, bundle in six.iteritems(bundles): env.register(name, bundle) return env finally: f.close()
def load_environment(self): """Load an :class:`Environment` instance defined in the YAML file. Expects the following format: .. code-block:: yaml directory: ../static url: /media debug: True updater: timestamp filters: - my_custom_package.my_filter config: compass_bin: /opt/compass another_custom_config_value: foo bundles: # ... All values, including ``directory`` and ``url`` are optional. The syntax for defining bundles is the same as for :meth:`~.YAMLLoader.load_bundles`. Sample usage:: from webassets.loaders import YAMLLoader loader = YAMLLoader('asset.yml') env = loader.load_environment() env['some-bundle'].urls() """ f, filename = self._open() try: obj = self.yaml.load(f) or {} env = Environment() # Load environment settings for setting in ('debug', 'cache', 'versions', 'url_expire', 'auto_build', 'url', 'directory', 'manifest', 'load_path', 'cache_file_mode', # TODO: The deprecated values; remove at some point 'expire', 'updater'): if setting in obj: setattr(env, setting, obj[setting]) # Treat the 'directory' option special, make it relative to the # path of the YAML file, if we know it. if filename and 'directory' in env.config: env.directory = path.normpath( path.join(path.dirname(filename), env.config['directory'])) # Treat the 'filters' option special, it should resolve the # entries as classes and register them to the environment if 'filters' in obj: try: resolve_dotted = self._get_import_resolver() except ImportError: raise EnvironmentError( "In order to use custom filters in the YAMLLoader " "you must install the zope.dottedname package") for filter_class in obj['filters']: try: cls = resolve_dotted(filter_class) except ImportError: raise LoaderError("Unable to resolve class %s" % filter_class) if inspect.isclass(cls): register_filter(cls) else: raise LoaderError("Custom filters must be classes " "not modules or functions") # Load custom config options if 'config' in obj: env.config.update(obj['config']) # Load bundles bundles = self._get_bundles(obj.get('bundles', {})) for name, bundle in six.iteritems(bundles): env.register(name, bundle) return env finally: f.close()
def load_environment(self): """Load an :class:`Environment` instance defined in the YAML file. Expects the following format: .. code-block:: yaml directory: ../static url: /media debug: True updater: timestamp filters: - my_custom_package.my_filter config: compass_bin: /opt/compass another_custom_config_value: foo bundles: # ... All values, including ``directory`` and ``url`` are optional. The syntax for defining bundles is the same as for :meth:`~.YAMLLoader.load_bundles`. Sample usage:: from webassets.loaders import YAMLLoader loader = YAMLLoader('asset.yml') env = loader.load_environment() env['some-bundle'].urls() """ f, filename = self._open() try: obj = self.yaml.load(f) or {} env = Environment() # Load environment settings for setting in ( 'debug', 'cache', 'versions', 'url_expire', 'auto_build', 'url', 'directory', 'manifest', 'load_path', 'cache_file_mode', # TODO: The deprecated values; remove at some point 'expire', 'updater'): if setting in obj: setattr(env, setting, obj[setting]) # Treat the 'directory' option special, make it relative to the # path of the YAML file, if we know it. if filename and 'directory' in env.config: env.directory = path.normpath( path.join(path.dirname(filename), env.config['directory'])) # Treat the 'filters' option special, it should resolve the # entries as classes and register them to the environment if 'filters' in obj: try: resolve_dotted = self._get_import_resolver() except ImportError: raise EnvironmentError( "In order to use custom filters in the YAMLLoader " "you must install the zope.dottedname package") for filter_class in obj['filters']: try: cls = resolve_dotted(filter_class) except ImportError: raise LoaderError("Unable to resolve class %s" % filter_class) if inspect.isclass(cls): register_filter(cls) else: raise LoaderError("Custom filters must be classes " "not modules or functions") # Load custom config options if 'config' in obj: env.config.update(obj['config']) # Load bundles bundles = self._get_bundles(obj.get('bundles', {})) for name, bundle in six.iteritems(bundles): env.register(name, bundle) return env finally: f.close()