Source code for knittingpattern.InstructionLibrary

"""Instructions have  many attributes that do not need to be specified
in each :class:`knitting pattern set

This module provides the functionality to load default values for instructions
from various locations.
from .Instruction import TYPE
from .Loader import JSONLoader
from .Instruction import Instruction

[docs]class InstructionLibrary(object): """This library can be used to look up default specification of instructions. The specification is searched for by the type of the instruction. """ @property def _loader_class(self): """:return: the class for loading the specifications with :attr:`load` """ return JSONLoader @property def _instruction_class(self): """:return: the class for the specifications """ return Instruction
[docs] def __init__(self): """Create a new :class:`InstructionLibrary <knittingpattern.InstructionLibrary.InstructionLibrary>` without arguments. Use :attr:`load` to load specifications. """ self._type_to_instruction = {}
@property def load(self): """:return: a loader that can be used to load specifications :rtype: knittingpattern.Loader.JSONLoader A file to load is a list of instructions in JSON format. .. code:: json [ { "type" : "knit", "another" : "attribute" }, { "type" : "purl" } ] """ return self._loader_class(self._process_loaded_object) def _process_loaded_object(self, obj): """add the loaded instructions from :attr:`load` """ for instruction in obj: self.add_instruction(instruction) return self
[docs] def add_instruction(self, specification): """Add an instruction specification :param specification: a specification with a key :data:`knittingpattern.Instruction.TYPE` .. seealso:: :meth:`as_instruction` """ instruction = self.as_instruction(specification) self._type_to_instruction[instruction.type] = instruction
[docs] def as_instruction(self, specification): """Convert the specification into an instruction :param specification: a specification with a key :data:`knittingpattern.Instruction.TYPE` The instruction is not added. .. seealso:: :meth:`add_instruction` """ instruction = self._instruction_class(specification) type_ = instruction.type if type_ in self._type_to_instruction: instruction.inherit_from(self._type_to_instruction[type_]) return instruction
[docs] def __getitem__(self, instruction_type): """:return: the specification for :paramref:`instruction_type` .. seealso:: :meth:`as_instruction` """ return self.as_instruction({TYPE: instruction_type})
@property def loaded_types(self): """The types loaded in this library. :return: a list of types, preferably as :class:`string <str>` :rtype: list """ return list(self._type_to_instruction)
[docs]class DefaultInstructions(InstructionLibrary): """The default specifications for instructions ported with this package """ #: the folder relative to this module where the instructions are located INSTRUCTIONS_FOLDER = "instructions"
[docs] def __init__(self): """Create the default instruction library without arguments. The default specifications are loaded automatically form this package. """ super().__init__() self.load.relative_folder(__file__, self.INSTRUCTIONS_FOLDER)
[docs]def default_instructions(): """:return: a default instruction library :rtype: DefaultInstructions .. warning:: The return value is mutable and you should not add new instructions to it. If you would like to add instructions to it, create a new :class:`~knittingpattern.InstructionLibrary.DefaultInstructions` instance. """ global _default_instructions if _default_instructions is None: _default_instructions = DefaultInstructions() return _default_instructions
_default_instructions = None __all__ = ["InstructionLibrary", "DefaultInstructions", "default_instructions"]