def _extract_name(self, source: ParseSource) -> str: try: name = self._instruction_name_extractor_function(source.remaining_part_of_current_line) if not isinstance(name, str): raise InvalidInstructionSyntaxException(line_sequence_from_line(source.current_line)) except Exception: raise InvalidInstructionSyntaxException(line_sequence_from_line(source.current_line)) return name
def _extract_name(self, source: ParseSource) -> str: try: name = self._instruction_name_extractor_function( source.remaining_part_of_current_line) if not isinstance(name, str): raise InvalidInstructionSyntaxException( line_sequence_from_line(source.current_line)) except Exception: raise InvalidInstructionSyntaxException( line_sequence_from_line(source.current_line)) return name
def parse_file_names_resolver( source: ParseSource, path_resolver: SinglePathResolver = single_regular_file_resolver ) -> FileNamesResolver: def parse_and_raise_instruction_exception() -> FileNamesResolver: token = parse_token_on_current_line(source, 'file name or glob pattern') source.consume_initial_space_on_current_line() if not source.is_at_eol: msg = 'Superfluous argument: `{}\''.format( source.remaining_part_of_current_line) raise SingleInstructionInvalidArgumentException(msg) source.consume_current_line() if token.is_quoted: return FileNamesResolverForPlainFileName(path_resolver, token.string) else: if is_wildcard_pattern(token.string): return FileNamesResolverForGlobPattern(path_resolver, token.string) else: return FileNamesResolverForPlainFileName( path_resolver, token.string) first_line = source.current_line try: return parse_and_raise_instruction_exception() except SingleInstructionInvalidArgumentException as ex: raise InvalidInstructionSyntaxException( line_sequence_from_line(first_line), ex.error_message)
def parse(self, fs_location_info: FileSystemLocationInfo, source: ParseSource) -> ParsedInstruction: current_line = source.current_line source.consume_current_line() instruction = ActPhaseInstructionThatRecords( fs_location_info.current_source_file, current_line.text) return ParsedInstruction(line_sequence_from_line(current_line), InstructionInfo(instruction, None))
def _lookup_parser(self, original_source_line: line_source.Line, name: str) -> InstructionParser: """ :raises: UnknownInstructionException """ if name not in self.__instruction_name__2__single_instruction_parser: raise UnknownInstructionException( line_sequence_from_line(original_source_line), name) return self.__instruction_name__2__single_instruction_parser[name]
def extract_section_name_from_current_line(self) -> str: try: section_name = syntax.extract_section_name_from_section_line(self._current_line.text) except ValueError as ex: raise FileSourceError(line_sequence_from_line(self._current_line), str(ex), None, self._source_location_info_of_current_line()) return section_name
def ending_at(self, after_parse: ParseSource) -> LineSequence: num_chars = len(self._remaining__before) - len( after_parse.remaining_source) if num_chars < len(self._first_line.text): return line_sequence_from_line(self._first_line) source__consumed = self._remaining__before[:num_chars].rstrip() return LineSequence(self._first_line.line_number, source__consumed.split('\n'))
def parse_element_at_current_line_using_current_section_element_parser(self): parsed_element = self.parser_for_current_section.parse( FileSystemLocationInfo(self._current_file_location), self._document_source) if parsed_element is None: raise FileSourceError(line_sequence_from_line(self._document_source.current_line), 'Syntax error', self._name_of_current_section, self._source_location_info_of_current_line()) return self._element_constructor.visit(parsed_element)
def _lookup_parser(self, original_source_line: line_source.Line, name: str) -> InstructionParser: """ :raises: UnknownInstructionException """ if name not in self.__instruction_name__2__single_instruction_parser: raise UnknownInstructionException(line_sequence_from_line(original_source_line), name) return self.__instruction_name__2__single_instruction_parser[name]
def _parse(fs_location_info: FileSystemLocationInfo, source: ParseSource, parser: InstructionParser, name: str) -> model.Instruction: """ :raises: InvalidInstructionException """ first_line = source.current_line try: return parser.parse(fs_location_info, source) except SingleInstructionInvalidArgumentException as ex: raise InvalidInstructionArgumentException(line_sequence_from_line(first_line), name, ex.error_message) except Exception as ex: raise ArgumentParsingImplementationException(line_sequence_from_line(first_line), name, parser, str(ex))
def parse(self, fs_location_info: FileSystemLocationInfo, source: ParseSource) -> ParsedInstruction: current_line = source.current_line source.consume_current_line() instruction = ActPhaseInstructionThatRecords(fs_location_info.current_source_file, current_line.text) return ParsedInstruction(line_sequence_from_line(current_line), InstructionInfo(instruction, None))
def file_source_error_equals_line( line: Line, maybe_section_name: Assertion[str] = asrt.anything_goes() ) -> Assertion[FileSourceError]: return asrt.and_([ asrt.sub_component('maybe_section_name', FileSourceError.maybe_section_name.fget, maybe_section_name), asrt.sub_component('source', FileSourceError.source.fget, equals_line_sequence( line_sequence_from_line(line))), ])
def file_source_error_equals_line(line: Line, maybe_section_name: ValueAssertion[str] = asrt.anything_goes() ) -> ValueAssertion[FileSourceError]: return asrt.and_([ asrt.sub_component('maybe_section_name', FileSourceError.maybe_section_name.fget, maybe_section_name), asrt.sub_component('source', FileSourceError.source.fget, equals_line_sequence(line_sequence_from_line(line))), ])
def source_location_path_of( file_path: Optional[Path], line: Optional[Line]) -> Optional[SourceLocationPath]: """ :return: None iff file_path and line is None """ if file_path is None and line is None: return None line_sequence = None if line: line_sequence = line_sequence_from_line(line) return source_location_path_without_inclusions( SourceLocation(line_sequence, file_path))
def assert_equals_single_line(test_case: unittest.TestCase, expected: Line, actual: LineSequence, message_header: str = None): """ :param expected: May be None :param actual: May be None :param message_header: Optional header for assert messages. """ if expected is None: assertion = asrt.is_none else: assertion = equals_line_sequence(line_sequence_from_line(expected)) message_builder = asrt.MessageBuilder('' if message_header is None else message_header) assertion.apply(test_case, actual, message_builder)
def assert_equals_single_line(test_case: unittest.TestCase, expected: Line, actual: LineSequence, message_header: str = None): """ :param expected: May be None :param actual: May be None :param message_header: Optional header for assert messages. """ if expected is None: assertion = asrt.is_none else: assertion = equals_line_sequence(line_sequence_from_line(expected)) message_builder = asrt.MessageBuilder( '' if message_header is None else message_header) assertion.apply(test_case, actual, message_builder)
def parse(self, fs_location_info: FileSystemLocationInfo, source: ParseSource) -> Optional[ParsedFileInclusionDirective]: parts = source.current_line_text.strip().split() if len(parts) == 0 or parts[0] != self._directive_token: return None directive_source = line_sequence_from_line(source.current_line) source.consume_current_line() if len(parts) == 1: raise RecognizedSectionElementSourceError(directive_source, 'Missing {} argument'.format(FILE_ARGUMENT_NAME)) if len(parts) != 2: raise RecognizedSectionElementSourceError(directive_source, 'Superfluous arguments: ' + ' '.join(parts[2:])) path = pathlib.Path(pathlib.PurePosixPath(parts[1])) return ParsedFileInclusionDirective(directive_source, [path])
def switch_section_according_to_last_section_line_and_consume_section_lines(self): """ Precondition: Current line is a section-line Post condition: Current line is not a section-line. If there are many consecutive section lines, then all of these are consumed. """ while not self.is_at_eof() and self.current_line_is_section_line(): section_line = self._current_line section_name = self.extract_section_name_from_current_line() if not self.has_section(section_name): msg = 'There is no {section} named "{name}"'.format( section=self.configuration.section_element_name_for_error_messages, name=section_name) raise FileSourceError(line_sequence_from_line(section_line), msg, None, self._source_location_info_of_current_line()) self.move_one_line_forward() self.set_current_section(section_name)
def parse_file_names_resolver(source: ParseSource, path_resolver: SinglePathResolver = single_regular_file_resolver) -> FileNamesResolver: def parse_and_raise_instruction_exception() -> FileNamesResolver: token = parse_token_on_current_line(source, 'file name or glob pattern') source.consume_initial_space_on_current_line() if not source.is_at_eol: msg = 'Superfluous argument: `{}\''.format(source.remaining_part_of_current_line) raise SingleInstructionInvalidArgumentException(msg) source.consume_current_line() if token.is_quoted: return FileNamesResolverForPlainFileName(path_resolver, token.string) else: if is_wildcard_pattern(token.string): return FileNamesResolverForGlobPattern(path_resolver, token.string) else: return FileNamesResolverForPlainFileName(path_resolver, token.string) first_line = source.current_line try: return parse_and_raise_instruction_exception() except SingleInstructionInvalidArgumentException as ex: raise InvalidInstructionSyntaxException( line_sequence_from_line(first_line), ex.error_message)
def apply(self) -> RawDoc: if self.is_at_eof(): return {} if self.current_line_is_section_line(): self.switch_section_according_to_last_section_line_and_consume_section_lines() self.read_rest_of_document_from_inside_section_or_at_eof() else: if self.configuration.default_section_name is not None: self.set_current_section(self.configuration.default_section_name) self.read_rest_of_document_from_inside_section_or_at_eof() else: self.skip_standard_comment_and_empty_lines() if not self.is_at_eof(): if self.current_line_is_section_line(): self.switch_section_according_to_last_section_line_and_consume_section_lines() self.read_rest_of_document_from_inside_section_or_at_eof() else: msg = 'Instruction outside of {section}'.format( section=self.configuration.section_element_name_for_error_messages) raise FileSourceError(line_sequence_from_line(self._current_line), msg, None, self._source_location_info_of_current_line()) return self._section_name_2_element_list
def new_recognized_section_element_error_of_single_line( line: line_source.Line, message: str) -> SectionElementError: return RecognizedSectionElementSourceError(line_sequence_from_line(line), message)
def new_recognized_section_element_error_of_single_line(line: line_source.Line, message: str) -> SectionElementError: return RecognizedSectionElementSourceError(line_sequence_from_line(line), message)