def format_line(line: str) -> str: """Try format a source code line""" formatted_line = line try: # If we handling multilines this will not be parsed formatted_line, _ = FormatCode(line) except IndentationError as error: # Case of trying to parse a piece of a statement, like a for loop header # Try again with a pass stament formatted_line, _ = FormatCode(line + "pass") formatted_line = formatted_line.replace("pass", "") except SyntaxError as error: if error.args[0] == "unexpected EOF while parsing": try: formatted_line, _ = FormatCode(line + "pass") formatted_line = formatted_line.replace("pass", "") except SyntaxError as syntax_error: raise ParseError("Could not parse line: {}".format(line)) from syntax_error else: raise ParseError("Could not parse line: {}".format(line)) from error return formatted_line.strip()
def _format(document, lines=None): # Yapf doesn't work with CRLF/CR line endings, so we replace them by '\n' # and restore them below. replace_eols = False source = document.source eol_chars = get_eol_chars(source) if eol_chars in ['\r', '\r\n']: replace_eols = True source = source.replace(eol_chars, '\n') new_source, changed = FormatCode( source, lines=lines, filename=document.filename, style_config=file_resources.GetDefaultStyleForDir( os.path.dirname(document.path) ) ) if not changed: return [] if replace_eols: new_source = new_source.replace('\n', eol_chars) # I'm too lazy at the moment to parse diffs into TextEdit items # So let's just return the entire file... return [{ 'range': { 'start': {'line': 0, 'character': 0}, # End char 0 of the line after our document 'end': {'line': len(document.lines), 'character': 0} }, 'newText': new_source }]
def get_setup(self): # render template with self.setup_path.open(encoding='utf-8') as f: document = f.read() template = Environment().from_string(document) document = template.render( package=self.package, format_vcs=self._format_vcs, ) # format by yapf style = CreateGoogleStyle() document, _changed = FormatCode(document, style_config=style) # remove empty strings while '\n\n' in document: document = document.replace('\n\n', '\n') # format by autopep8 document = fix_code(document) return document
def get_function_signature( function, owner_class=None, strip_self_param=False, show_module=False, pretty=True, ): # Get base name. name_parts = [] if show_module: name_parts.append(function.__module__) if owner_class: name_parts.append(owner_class.__name__) if hasattr(function, '__name__'): name_parts.append(function.__name__) else: name_parts.append(type(function).__name__) name_parts.append('__call__') function = function.__call__ name = '.'.join(name_parts) try: argspec = get_full_arg_spec(function) except TypeError: parameters = [] else: parameters = get_paramaters_from_arg_spec(argspec, strip_self=strip_self_param) # Prettify annotations. class repr_str(str): def __repr__(self): return self def prettify(val): # type: (Parameter.Value) -> Parameter.Value if isinstance(val.value, type): val = Parameter.Value(repr_str(val.value.__name__)) return val for i, param in enumerate(parameters): if param.annotation: param = param.replace(annotation=prettify(param.annotation)) if param.default: param = param.replace(default=prettify(param.default)) parameters[i] = param if pretty: # Replace annotations and defaults with placeholders that are valid syntax. supplements = {} counter = [0] def _add_supplement(value): annotation_id = '_{}'.format(counter[0]) annotation_id += '_' * (len(repr(value)) - len(annotation_id)) supplements[annotation_id] = value counter[0] += 1 return repr_str(annotation_id) for i, param in enumerate(parameters): if param.annotation: param = param.replace(annotation=Parameter.Value( _add_supplement(param.annotation.value))) if param.default: param = param.replace(default=Parameter.Value( _add_supplement(param.default.value))) parameters[i] = param # Use a placeholder in pretty mode as the generated *name* may also # sometimes not be valid syntax (eg. if it includes the class name). name_placeholder = '_PH_' + '_' * (len(name) - 2) sig = (name_placeholder if pretty else name) + '(' + format_parameters_list(parameters) + ')' if pretty: sig, _ = FormatCode('def ' + sig + ': pass', style_config='pep8') sig = sig[4:].rpartition(':')[0] # Replace the annotation and default placeholders with the actual values. for placeholder, annotation in supplements.items(): sig = sig.replace(placeholder, repr(annotation)) # Replace the placeholder and fix indents. sig = sig.replace(name_placeholder, name) delta = len(name_placeholder) - len(name) lines = sig.split('\n') for i, line in enumerate(lines[1:], 1): indent = len(line) - len(line.lstrip()) - delta - 4 # 4 for "def " if indent <= 0 and line.strip() != ')': indent = 4 lines[i] = ' ' * indent + line.lstrip() sig = '\n'.join(lines) return sig