Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b1bc308
Replace deprecated pyparse calls with current API calls
erikwa Jan 8, 2026
3c04d3f
Remove old directory check from main.py
erikwa Jan 9, 2026
7000bde
Fix print of undefined variable in get_backend ImportError exception …
erikwa Jan 9, 2026
cf186ca
Fix flake8 E713 warning: Test for membership should be 'not in'
erikwa Jan 8, 2026
facf93a
Fix flake8 E721 warning: Do not compare types, use 'isinstance()'
erikwa Jan 8, 2026
5773fc1
Fix flake8 E722 warning: Do not use bare except, specify exception in…
erikwa Jan 8, 2026
c91a459
Fix flake8 E712 warning: Comparison to true should be 'if cond is tru…
erikwa Jan 8, 2026
5d53206
Fix flake8 F401 warning: Module imported but unused
erikwa Jan 8, 2026
2c6d8cf
Fix flake8 F841 warning: Local variable name is assigned to but never…
erikwa Jan 9, 2026
ebf6d1c
Fix flake8 E711 warning: Comparison to None should be 'cond is None:'
erikwa Jan 9, 2026
97db6d6
Fix flake8 F601 warning: Dictionary key repeated with different values
erikwa Jan 9, 2026
1261975
Fix flake8 F541 warning: f-string without any placeholders
erikwa Jan 9, 2026
91e56b6
Fix flake8 F523 warning: Unused positional arguments
erikwa Jan 9, 2026
63ebc31
Fix flake8 E731 warning: Do not assign a lambda expression, use a def
erikwa Jan 9, 2026
41cad41
Fix flake8 E402 warning: Module level import not at top of file
erikwa Jan 9, 2026
88cd829
Fix flake8 E741 warning: Do not use variables named 'I', 'O', or 'l'
erikwa Jan 9, 2026
caafd5a
Fix flake8 E743 warning: Do not define functions named 'I', 'O', or 'l'
erikwa Jan 9, 2026
24c326d
Fix ruff E714 warning: Test for object identity should be 'is not'
erikwa Jan 9, 2026
7780502
Fix ruff E721 warning: type-comparison
erikwa Jan 9, 2026
104b127
Fix ruff E741 warning: ambiguous-variable-name
erikwa Jan 9, 2026
404a891
Added ruff linting
HU90m Feb 25, 2025
8fe3bbb
Change ruff-pre-commit version from 0.9.7 to 0.14.11
erikwa Jan 9, 2026
9a2dbf0
Remove ruff linter ignore list
erikwa Jan 9, 2026
4c1f245
Run ruff-check for linting instead of (legacy) ruff
erikwa Jan 9, 2026
af2bbf2
Fix linting errors in doc folder
erikwa Jan 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,10 @@ repos:
rev: 22.3.0
hooks:
- id: black
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.11
hooks:
# Run the linter.
- id: ruff-check
# The formatter could be run in the future
#- id: ruff-format
11 changes: 4 additions & 7 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config

import importlib.util
import os
import sys
from datetime import datetime
from importlib.metadata import version as get_version

import jsonschema2md

import fusesoc
from fusesoc.capi2.json_schema import capi2_schema
from fusesoc.utils import yaml_read

Expand All @@ -34,8 +35,6 @@
copyright = f"2018-{datetime.now().year}, Olof Kindgren"
author = "Olof Kindgren"

from importlib.metadata import version as get_version

# The full version, including alpha/beta/rc tags.
release: str = get_version("fusesoc")

Expand Down Expand Up @@ -109,11 +108,9 @@
# or
# - apt-get install python-sphinx-rtd-theme

try:
import sphinx_rtd_theme

if importlib.util.find_spec("sphinx_rtd_theme") is not None:
html_theme = "sphinx_rtd_theme"
except ImportError:
else:
sys.stderr.write(
"Warning: The Sphinx 'sphinx_rtd_theme' HTML theme was "
+ "not found. Make sure you have the theme installed to produce pretty "
Expand Down
43 changes: 21 additions & 22 deletions fusesoc/capi2/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def export(self, dst_dir, flags={}):
_abs_f = os.path.join(root, f)
_rel_f = os.path.normpath(os.path.relpath(_abs_f, dst_dir))

if not _rel_f in [os.path.normpath(x) for x in src_files]:
if _rel_f not in [os.path.normpath(x) for x in src_files]:
os.remove(_abs_f)

def _get_script_names(self, flags):
Expand All @@ -148,7 +148,7 @@ def _get_script_names(self, flags):
if scripts:
hooks[hook] = []
for script in scripts:
if not script in cd_scripts:
if script not in cd_scripts:
raise SyntaxError(
"Script '{}', requested by target '{}', was not found".format(
script, target_name
Expand Down Expand Up @@ -276,10 +276,10 @@ def get_files(self, flags):
attributes = {
k: v
for k, v in attributes.items()
if (type(v) == bool and v == True)
or (type(v) == str and len(v)) > 0
or (type(v) == list and len(v)) > 0
or (type(v) == dict and len(v)) > 0
if (isinstance(v, bool) and v is True)
or (isinstance(v, str) and len(v) > 0)
or (isinstance(v, list) and len(v) > 0)
or (isinstance(v, dict) and len(v) > 0)
}

_src_files.append(attributes)
Expand All @@ -302,7 +302,7 @@ def get_virtuals(self, flags={}):
def get_parameters(self, flags={}, ext_parameters={}):
def _parse_param_value(name, datatype, default):
if datatype == "bool":
if type(default) == str:
if isinstance(default, str):
if default.lower() == "true":
return True
elif default.lower() == "false":
Expand All @@ -312,12 +312,12 @@ def _parse_param_value(name, datatype, default):
raise SyntaxError(_s.format(self.name, default, p))
return default
elif datatype == "int":
if type(default) == int:
if isinstance(default, int):
return default
else:
return int(default, 0)
elif datatype == "real":
if type(default) == float:
if isinstance(default, float):
return default
else:
return float(default)
Expand All @@ -332,11 +332,11 @@ def _parse_param(flags, name, core_param):
core_param["description"] if "description" in core_param else ""
)

if not datatype in ["bool", "file", "int", "real", "str"]:
if datatype not in ["bool", "file", "int", "real", "str"]:
_s = "{} : Invalid datatype '{}' for parameter {}"
raise SyntaxError(_s.format(self.name, datatype, p))

if not paramtype in [
if paramtype not in [
"cmdlinearg",
"generic",
"plusarg",
Expand Down Expand Up @@ -384,7 +384,6 @@ def _parse_param(flags, name, core_param):
# ...or in any of its dependencies
elif p in ext_parameters:
parameters[p] = ext_parameters[p]
datatype = parameters[p]["datatype"]

else:
raise SyntaxError(
Expand All @@ -402,7 +401,7 @@ def _parse_param(flags, name, core_param):
# If default is a string and it is empty it should be deleted
if (
"default" in parameters[p]
and type(parameters[p]["default"]) == str
and isinstance(parameters[p]["default"], str)
and len(parameters[p]["default"]) == 0
):
del parameters[p]["default"]
Expand All @@ -420,7 +419,7 @@ def get_toplevel(self, flags):
if "toplevel" in target:
toplevel = target["toplevel"]
self._debug(f"Matched toplevel {toplevel}")
return " ".join(toplevel) if type(toplevel) == list else toplevel
return " ".join(toplevel) if isinstance(toplevel, list) else toplevel
else:
s = "{} : Target '{}' has no toplevel"
raise SyntaxError(s.format(self.name, target_name))
Expand All @@ -436,9 +435,9 @@ def get_ttptttg(self, flags):
_ttptttg = []
if "generate" in target:
for f in target["generate"]:
if type(f) == str:
if isinstance(f, str):
_ttptttg.append({"name": f, "params": {}})
elif type(f) == dict:
elif isinstance(f, dict):
for k, v in f.items():
_ttptttg.append({"name": k, "params": v})

Expand All @@ -447,7 +446,7 @@ def get_ttptttg(self, flags):
for gen in _ttptttg:
gen_name = gen["name"]
cd_generate = self._coredata.get_generate(flags)
if not gen_name in cd_generate:
if gen_name not in cd_generate:
raise SyntaxError(
"Generator instance '{}', requested by target '{}', was not found".format(
gen_name, target_name
Expand Down Expand Up @@ -500,7 +499,7 @@ def _get_vpi(self, flags):
vpi[vpi_name] = {
"src_files": files,
"inc_files": incfiles,
"libs": [l for l in libs],
"libs": [lib for lib in libs],
}
return vpi

Expand Down Expand Up @@ -535,12 +534,12 @@ def info(self, trustfile):
cd_target = self._coredata.get_targets({})

if cd_target:
l = max(len(x) for x in cd_target)
maxlen = max(len(x) for x in cd_target)
targets = ""

for t in sorted(cd_target):
targets += "{} : {}\n".format(
t.ljust(l),
t.ljust(maxlen),
cd_target[t]["description"]
if "description" in cd_target[t]
else "<No description>",
Expand Down Expand Up @@ -620,7 +619,7 @@ def _get_filesets(self, flags):
cd_filesets = self._coredata.get_filesets(flags)

for fs in target.get("filesets", []):
if not fs in cd_filesets:
if fs not in cd_filesets:
raise SyntaxError(
"{} : Fileset '{}', requested by target '{}', was not found".format(
self.name, fs, target_name
Expand Down Expand Up @@ -686,7 +685,7 @@ def sig_status(self, trustfile):
ok = True
except RuntimeError:
return "*" # Signature is not for this core (should not happen)
except:
except Exception:
return "!" # Other signature checking error
if ok:
return "good"
Expand Down
29 changes: 15 additions & 14 deletions fusesoc/capi2/coredata.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,57 +17,58 @@ def __init__(self, capi_data):
self._append_lists(self._capi_data)

def _expand_use(self, data, flags):
if type(data) == dict:
if isinstance(data, dict):
remove = []
append = {}
for k, v in data.items():
# Only run expand() if a string contains a "?" to avoid
# issues with strings containing for instance parentheses
if type(v) == str and len(v) > 0 and "?" in v:
if isinstance(v, str) and len(v) > 0 and "?" in v:
data[k] = Exprs(v).expand(flags)
if type(k) == str and "?" in k:
if isinstance(k, str) and "?" in k:
expanded_k = Exprs(k).expand(flags)
if len(expanded_k) == 0:
remove.append(k)
elif expanded_k != k:
append[expanded_k] = v
remove.append(k)

if type(v) == dict or type(v) == list:
if isinstance(v, (dict, list)):
self._expand_use(data[k], flags)

for i in remove:
del data[i]

data.update(append)

if type(data) == list:
if isinstance(data, list):
remove = []
for idx, i in enumerate(data):
if type(i) == str and len(i) > 0 and "?" in i:
if isinstance(i, str) and len(i) > 0 and "?" in i:
expanded = Exprs(i).expand(flags)
if i != expanded:
if len(expanded) > 0:
data[idx] = expanded
else:
remove.append(idx)
elif type(i) == dict or type(i) == list:
elif isinstance(i, (dict, list)):
self._expand_use(i, flags)
for i in reversed(remove):
data.pop(i)

def _append_lists(self, data):
if type(data) == list:
if isinstance(data, list):
for i in data:
self._append_lists(i)

if type(data) == dict:
if isinstance(data, dict):
data_append = {}
for k, v in data.items():
if k.endswith("_append"):
_k = k[:-7]

if type(v) == list and (not _k in data or type(data[_k]) == list):
if isinstance(v, list) and (
_k not in data or isinstance(data[_k], list)
):
if _k in data:
# If for instance default target is included for several other
# targets we need to create a copy to avoid modifying the source
Expand Down Expand Up @@ -106,11 +107,11 @@ def _setup_file(self, file, fs):
d["logical_name"] = fs["logical_name"]

# If we already have values for the file attributes we overwrite the defaults
if type(file) == dict:
if isinstance(file, dict):
for k in file.keys():
d.update(file[k])
file_name = k
elif type(file) == str:
elif isinstance(file, str):
file_name = file

return {file_name: d}
Expand All @@ -121,7 +122,7 @@ def _setup_fileset(self, data, flags):
for file in fs.get("files", []):
files.append(self._setup_file(file, fs))

if not "depend" in fs:
if "depend" not in fs:
fs["depend"] = []

fs["files"] = files
Expand Down
4 changes: 2 additions & 2 deletions fusesoc/capi2/exprs.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def _get_parser():
+ Suppress(")")
)
exprs <<= OneOrMore(conditional ^ word)
conditional.setParseAction(_cond_parse_action)
conditional.set_parse_action(_cond_parse_action)
_PARSER = exprs
return _PARSER

Expand Down Expand Up @@ -138,7 +138,7 @@ def _parse(string):

"""
try:
raw_ast = _get_parser().parseString(string, parseAll=True)
raw_ast = _get_parser().parse_string(string, parse_all=True)
except ParseException as err:
raise ValueError(
f"Invalid syntax for string: {err}. Parsed text was {string!r}."
Expand Down
12 changes: 6 additions & 6 deletions fusesoc/capi2/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,27 @@ def __init__(self, data=None, resolve_env_vars=False):
def add_files(
self, files, fileset="rtl", targets=["default"], file_type="", logical_name=""
):
if not fileset in self.filesets:
if fileset not in self.filesets:
self.filesets[fileset] = {"files": []}
self.filesets[fileset]["files"] = files
self.filesets[fileset]["file_type"] = file_type
self.filesets[fileset]["logical_name"] = logical_name

for target in targets:
if not target in self.targets:
if target not in self.targets:
self.targets[target] = {"filesets": []}
if not fileset in self.targets[target]["filesets"]:
if fileset not in self.targets[target]["filesets"]:
self.targets[target]["filesets"].append(fileset)

def add_parameter(self, parameter, data={}, targets=["default"]):
self.parameters[parameter] = data

for target in targets:
if not target in self.targets:
if target not in self.targets:
self.targets[target] = {}
if not "parameters" in self.targets[target]:
if "parameters" not in self.targets[target]:
self.targets[target]["parameters"] = []
if not parameter in self.targets[target]["parameters"]:
if parameter not in self.targets[target]["parameters"]:
self.targets[target]["parameters"].append(parameter)

def write(self):
Expand Down
2 changes: 1 addition & 1 deletion fusesoc/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ def ignored_dirs(self):
@ignored_dirs.setter
def ignored_dirs(self, val):
self._set_default_section(
"ignored_dirs", " ".join(val) if type(val) == list else val
"ignored_dirs", " ".join(val) if isinstance(val, list) else val
)

@property
Expand Down
Loading
Loading