diff --git a/doc/conf.py b/doc/conf.py index 10af14c..82a2984 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -55,7 +55,7 @@ # def get_package_version(verfile): - '''Scan the script for the version string''' + """Scan the script for the version string""" version = None with open(verfile) as fh: try: diff --git a/hdlparse/__init__.py b/hdlparse/__init__.py index 6df8ed0..70ccacf 100644 --- a/hdlparse/__init__.py +++ b/hdlparse/__init__.py @@ -1 +1,4 @@ -__version__ = '1.1.0' \ No newline at end of file +""" +Parse Verilog and VHDL files +""" +__version__ = '1.1.0' diff --git a/hdlparse/minilexer.py b/hdlparse/minilexer.py index dda7019..04c4a80 100644 --- a/hdlparse/minilexer.py +++ b/hdlparse/minilexer.py @@ -1,10 +1,12 @@ # -*- coding: utf-8 -*- # Copyright © 2017 Kevin Thibedeau # Distributed under the terms of the MIT license +""" +Minimalistic lexer engine inspired by the PyPigments RegexLexer +""" import re import logging -"""Minimalistic lexer engine inspired by the PyPigments RegexLexer""" log = logging.getLogger(__name__) @@ -15,7 +17,7 @@ log.addHandler(handler) -class MiniLexer(object): +class MiniLexer(): """Simple lexer state machine with regex matching rules""" def __init__(self, tokens, flags=re.MULTILINE): @@ -54,7 +56,7 @@ def run(self, text): text (str): Text to apply lexer to Yields: - A sequence of lexer matches. + A sequence of lexer matches """ stack = ['root'] @@ -67,7 +69,7 @@ def run(self, text): m = pat.match(text, pos) if m: if action: - log.debug(f"Match: {m.group().strip()} -> {action}") + log.debug("Match: %s -> %s", m.group().strip(), action) yield (pos, m.end() - 1), action, m.groups() diff --git a/hdlparse/verilog_parser.py b/hdlparse/verilog_parser.py index 73aec0e..590de24 100644 --- a/hdlparse/verilog_parser.py +++ b/hdlparse/verilog_parser.py @@ -1,12 +1,14 @@ # -*- coding: utf-8 -*- # Copyright © 2017 Kevin Thibedeau # Distributed under the terms of the MIT license +""" +Verilog documentation parser +""" import io import os from collections import OrderedDict from .minilexer import MiniLexer -"""Verilog documentation parser""" verilog_tokens = { # state @@ -109,11 +111,12 @@ def parse_verilog_file(fname): """Parse a named Verilog file Args: - fname (str): File to parse. + fname (str): File to parse + Returns: - List of parsed objects. + List of parsed objects """ - with open(fname, 'rt') as fh: + with open(fname, 'rt', encoding='UTF-8') as fh: text = fh.read() return parse_verilog(text) @@ -129,25 +132,21 @@ def parse_verilog(text): lex = VerilogLexer name = None - kind = None - saved_type = None mode = 'input' port_type = 'wire' param_type = '' metacomments = [] - parameters = [] generics = [] ports = OrderedDict() sections = [] port_param_index = 0 last_item = None - array_range_start_pos = 0 objects = [] - for pos, action, groups in lex.run(text): + for _, action, groups in lex.run(text): if action == 'metacomment': comment = groups[0].strip() if last_item is None: @@ -159,7 +158,6 @@ def parse_verilog(text): sections.append((port_param_index, groups[0])) elif action == 'module': - kind = 'module' name = groups[0] generics = [] ports = OrderedDict() diff --git a/hdlparse/vhdl_parser.py b/hdlparse/vhdl_parser.py index 1f9ca2f..9330be3 100644 --- a/hdlparse/vhdl_parser.py +++ b/hdlparse/vhdl_parser.py @@ -1,15 +1,17 @@ # -*- coding: utf-8 -*- # Copyright © 2017 Kevin Thibedeau # Distributed under the terms of the MIT license +""" +VHDL documentation parser +""" import ast import io import os import re from pprint import pprint -from typing import List, Optional +from typing import Any, Dict, List, Optional, Set from .minilexer import MiniLexer -"""VHDL documentation parser""" vhdl_tokens = { 'root': [ @@ -172,6 +174,7 @@ def __init__(self, name, desc=None): self.kind = 'unknown' self.desc = desc + def remove_outer_parenthesis(s: Optional[str]): if s: n = 1 @@ -179,6 +182,7 @@ def remove_outer_parenthesis(s: Optional[str]): s, n = re.subn(r'\([^()]*\)', '', s.strip()) # remove non-nested/flat balanced parts return s + class VhdlParameterType: """Parameter type definition @@ -213,7 +217,7 @@ class VhdlParameter: param_desc (optional str): Description of the parameter """ - def __init__(self, name, mode: Optional[str] = None, data_type: Optional[VhdlParameterType] = None, default_value: Optional[str] = None, desc: Optional[str] = None, param_desc: Optional[str] = None): + def __init__(self, name, mode: Optional[str] = None, data_type: Optional[VhdlParameterType] = None, default_value: Optional[str] = None, desc: Optional[str] = None): self.name = name self.mode = mode self.data_type = data_type @@ -356,6 +360,7 @@ def __repr__(self): class VhdlEntity(VhdlObject): """Entity declaration + Args: name (str): Name of the entity ports (list of VhdlParameter): Port parameters to the entity @@ -364,20 +369,20 @@ class VhdlEntity(VhdlObject): desc (str, optional): Description from object metacomments """ - def __init__(self, name: str, ports: List[VhdlParameter], generics: List[VhdlParameter] = [], sections: List[str] = [], desc: Optional[str] = None): + def __init__(self, name: str, ports: List[VhdlParameter], generics: Optional[List[VhdlParameter]] = None, sections: Optional[List[str]] = None, desc: Optional[str] = None): VhdlObject.__init__(self, name, desc) self.kind = 'entity' - self.generics = generics if generics is not None else [] + self.generics = generics if generics else [] self.ports = ports - self.sections = sections if sections is not None else {} + self.sections = sections if sections else {} def __repr__(self): return f"VhdlEntity('{self.name}')" def dump(self): print(f"VHDL entity: {self.name}") - for p in self.ports: - print(f"\t{p.name} ({type(p.name)}), {p.data_type} ({type(p.data_type)})") + for port in self.ports: + print(f"\t{port.name} ({type(port.name)}), {port.data_type} ({type(port.data_type)})") class VhdlComponent(VhdlObject): @@ -405,8 +410,8 @@ def __repr__(self): def dump(self): print(f"VHDL component: {self.name}") - for p in self.ports: - print(f"\t{p.name} ({type(p.name)}), {p.data_type} ({type(p.data_type)})") + for port in self.ports: + print(f"\t{port.name} ({type(port.name)}), {port.data_type} ({type(port.data_type)})") def parse_vhdl_file(fname): @@ -417,7 +422,7 @@ def parse_vhdl_file(fname): Returns: Parsed objects. """ - with open(fname, 'rt') as fh: + with open(fname, 'rt', encoding='UTF-8') as fh: text = fh.read() return parse_vhdl(text) @@ -540,9 +545,9 @@ def parse_vhdl(text): ptype = groups[0] last_items = [] for i in param_items: - p = VhdlParameter(i, 'in', VhdlParameterType(ptype)) - generics.append(p) - last_items.append(p) + param = VhdlParameter(i, 'in', VhdlParameterType(ptype)) + generics.append(param) + last_items.append(param) param_items = [] @@ -559,9 +564,9 @@ def parse_vhdl(text): last_items = [] for i in param_items: - p = VhdlParameter(i, mode, VhdlParameterType(ptype)) - ports.append(p) - last_items.append(p) + param = VhdlParameter(i, mode, VhdlParameterType(ptype)) + ports.append(param) + last_items.append(param) param_items = [] @@ -581,9 +586,9 @@ def parse_vhdl(text): last_items = [] for i in param_items: - p = VhdlParameter(i, mode, VhdlParameterType(ptype, direction, r_bound, l_bound, arange)) - ports.append(p) - last_items.append(p) + param = VhdlParameter(i, mode, VhdlParameterType(ptype, direction, r_bound, l_bound, arange)) + ports.append(param) + last_items.append(param) param_items = [] @@ -666,6 +671,7 @@ def subprogram_signature(vo, fullname=None): Args: vo (VhdlFunction, VhdlProcedure): Subprogram object + fullname (None, str): Override object name Returns: Signature string. """ @@ -701,12 +707,12 @@ class VhdlExtractor: array_types(set): Initial array types """ - def __init__(self, array_types=set()): + def __init__(self, array_types: Set[str] = None): self.array_types = set(('std_ulogic_vector', 'std_logic_vector', 'signed', 'unsigned', 'bit_vector')) - - self.array_types |= array_types - self.object_cache = {} + if array_types: + self.array_types |= array_types + self.object_cache: Dict[str, Any] = {} # Any -> VhdlObject def extract_objects(self, fname, type_filter=None): """Extract objects from a source file @@ -730,9 +736,10 @@ def extract_objects(self, fname, type_filter=None): if type_filter: if not isinstance(type_filter, list): type_filter = [type_filter] - objects = [ - o for o in objects if any(map(lambda clz: isinstance(o, clz), type_filter)) - ] + + def type_is_in_filter(obj): + return any(map(lambda clz: isinstance(obj, clz), type_filter)) + objects = [o for o in objects if type_is_in_filter(o)] return objects @@ -779,7 +786,7 @@ def load_array_types(self, fname): fname (str): Name of file to load array database from """ type_defs = '' - with open(fname, 'rt') as fh: + with open(fname, 'rt', encoding='UTF-8') as fh: type_defs = fh.read() try: @@ -796,7 +803,7 @@ def save_array_types(self, fname): fname (str): Name of file to save array database to """ type_defs = {'arrays': sorted(list(self.array_types))} - with open(fname, 'wt') as fh: + with open(fname, 'wt', encoding='UTF-8') as fh: pprint(type_defs, stream=fh) def _register_array_types(self, objects): diff --git a/setup.cfg b/setup.cfg index 2cb2386..23b5041 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,7 +25,15 @@ py_modules = install_requires = include_package_data = True - [pycodestyle] max_line_length = 120 -ignore = E501 \ No newline at end of file +ignore = E501 + +[pydocstyle] +ignore = D100,D102,D103,D105,D107,D202,D203,D213,D400,D405,D406,D407,D413,D415 + +[pylint] +disable = + C0103,C0301,C0103,C0116,R0201,R0801,R0903,R0912,R0913,R0914,R0915,W0702 +ignore-docstrings = yes +output-format = colorized \ No newline at end of file