From 725d68eb797654c351176664d7bc84a1ef62127b Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson Date: Thu, 11 Jul 2024 14:50:28 +0200 Subject: [PATCH] Use Paths rather than strings where possible --- tests/common.py | 2 +- tests/unit/test_activehdl_interface.py | 6 ++-- tests/unit/test_incisive_interface.py | 34 +++++++++---------- tests/unit/test_modelsim_interface.py | 4 +-- tests/unit/test_rivierapro_interface.py | 12 +++---- tests/unit/test_test_runner.py | 12 +++---- tests/unit/test_verilog_parser.py | 2 +- vunit/database.py | 19 ++++++----- vunit/ostools.py | 7 ++-- vunit/sim_if/__init__.py | 15 +++++++-- vunit/sim_if/activehdl.py | 43 +++++++++++++------------ vunit/sim_if/ghdl.py | 36 ++++++++++----------- vunit/sim_if/incisive.py | 43 ++++++++++++------------- vunit/sim_if/modelsim.py | 28 ++++++++-------- vunit/sim_if/nvc.py | 11 +++---- vunit/sim_if/rivierapro.py | 36 +++++++++++---------- vunit/sim_if/vsim_simulator_mixin.py | 21 ++++++------ vunit/test/runner.py | 32 +++++++++--------- vunit/test/suites.py | 10 +++--- vunit/ui/__init__.py | 26 +++++++-------- vunit/ui/results.py | 4 +-- vunit/vivado/vivado.py | 7 ++-- 22 files changed, 212 insertions(+), 198 deletions(-) diff --git a/tests/common.py b/tests/common.py index a6b35df36..a77e835c3 100644 --- a/tests/common.py +++ b/tests/common.py @@ -97,7 +97,7 @@ def create_tempdir(path: Path = None): if path.exists(): shutil.rmtree(path) - os.makedirs(str(path)) + path.mkdir(parents=True) try: yield path diff --git a/tests/unit/test_activehdl_interface.py b/tests/unit/test_activehdl_interface.py index 85ceabf2e..ca6938d1f 100644 --- a/tests/unit/test_activehdl_interface.py +++ b/tests/unit/test_activehdl_interface.py @@ -70,7 +70,7 @@ def _test_compile_project_vhdl(self, standard, process, check_output): str(Path("prefix") / "vcom"), "-quiet", "-j", - self.output_path, + str(self.output_path), f"-{standard}", "-work", "lib", @@ -116,7 +116,7 @@ def test_compile_project_vhdl_extra_flags(self, process, check_output): str(Path("prefix") / "vcom"), "-quiet", "-j", - self.output_path, + str(self.output_path), "custom", "flags", "-2008", @@ -322,7 +322,7 @@ def test_supports_vhdl_package_generics_false(self, find_prefix): self.assertFalse(simif.supports_vhdl_package_generics()) def setUp(self): - self.output_path = str(Path(__file__).parent / "test_activehdl_out") + self.output_path = Path(__file__).parent / "test_activehdl_out" renew_path(self.output_path) self.project = Project() self.cwd = os.getcwd() diff --git a/tests/unit/test_incisive_interface.py b/tests/unit/test_incisive_interface.py index 1dcb73033..ebed1aabf 100644 --- a/tests/unit/test_incisive_interface.py +++ b/tests/unit/test_incisive_interface.py @@ -514,12 +514,12 @@ def test_simulate_vhdl(self, run_command, find_cds_root_irun, find_cds_root_virt "-f", Path(elaborate_args_file).name, ], - cwd=str(Path(elaborate_args_file).parent), + cwd=Path(elaborate_args_file).parent, env=simif.get_env(), ), mock.call( [str(Path("prefix") / "irun"), "-f", Path(simulate_args_file).name], - cwd=str(Path(simulate_args_file).parent), + cwd=Path(simulate_args_file).parent, env=simif.get_env(), ), ] @@ -602,12 +602,12 @@ def test_simulate_verilog(self, run_command, find_cds_root_irun, find_cds_root_v "-f", Path(elaborate_args_file).name, ], - cwd=str(Path(elaborate_args_file).parent), + cwd=Path(elaborate_args_file).parent, env=simif.get_env(), ), mock.call( [str(Path("prefix") / "irun"), "-f", Path(simulate_args_file).name], - cwd=str(Path(simulate_args_file).parent), + cwd=Path(simulate_args_file).parent, env=simif.get_env(), ), ] @@ -681,12 +681,12 @@ def test_simulate_extra_flags(self, run_command, find_cds_root_irun, find_cds_ro "-f", Path(elaborate_args_file).name, ], - cwd=str(Path(elaborate_args_file).parent), + cwd=Path(elaborate_args_file).parent, env=simif.get_env(), ), mock.call( [str(Path("prefix") / "irun"), "-f", Path(simulate_args_file).name], - cwd=str(Path(simulate_args_file).parent), + cwd=Path(simulate_args_file).parent, env=simif.get_env(), ), ] @@ -719,12 +719,12 @@ def test_simulate_generics_and_parameters(self, run_command, find_cds_root_irun, "-f", Path(elaborate_args_file).name, ], - cwd=str(Path(elaborate_args_file).parent), + cwd=Path(elaborate_args_file).parent, env=simif.get_env(), ), mock.call( [str(Path("prefix") / "irun"), "-f", Path(simulate_args_file).name], - cwd=str(Path(simulate_args_file).parent), + cwd=Path(simulate_args_file).parent, env=simif.get_env(), ), ] @@ -755,12 +755,12 @@ def test_simulate_hdlvar(self, run_command, find_cds_root_irun, find_cds_root_vi "-f", Path(elaborate_args_file).name, ], - cwd=str(Path(elaborate_args_file).parent), + cwd=Path(elaborate_args_file).parent, env=simif.get_env(), ), mock.call( [str(Path("prefix") / "irun"), "-f", Path(simulate_args_file).name], - cwd=str(Path(simulate_args_file).parent), + cwd=Path(simulate_args_file).parent, env=simif.get_env(), ), ] @@ -788,7 +788,7 @@ def test_elaborate(self, run_command, find_cds_root_irun, find_cds_root_virtuoso "-f", Path(elaborate_args_file).name, ], - cwd=str(Path(elaborate_args_file).parent), + cwd=Path(elaborate_args_file).parent, env=simif.get_env(), ) ] @@ -836,7 +836,7 @@ def test_elaborate_fail(self, run_command, find_cds_root_irun, find_cds_root_vir "-f", Path(elaborate_args_file).name, ], - cwd=str(Path(elaborate_args_file).parent), + cwd=Path(elaborate_args_file).parent, env=simif.get_env(), ) ] @@ -861,12 +861,12 @@ def test_simulate_fail(self, run_command, find_cds_root_irun, find_cds_root_virt "-f", Path(elaborate_args_file).name, ], - cwd=str(Path(elaborate_args_file).parent), + cwd=Path(elaborate_args_file).parent, env=simif.get_env(), ), mock.call( [str(Path("prefix") / "irun"), "-f", Path(simulate_args_file).name], - cwd=str(Path(simulate_args_file).parent), + cwd=Path(simulate_args_file).parent, env=simif.get_env(), ), ] @@ -899,12 +899,12 @@ def test_simulate_gui(self, run_command, find_cds_root_irun, find_cds_root_virtu "-f", Path(elaborate_args_file).name, ], - cwd=str(Path(elaborate_args_file).parent), + cwd=Path(elaborate_args_file).parent, env=simif.get_env(), ), mock.call( [str(Path("prefix") / "irun"), "-f", Path(simulate_args_file).name], - cwd=str(Path(simulate_args_file).parent), + cwd=Path(simulate_args_file).parent, env=simif.get_env(), ), ] @@ -974,7 +974,7 @@ def test_configuration_and_entity_selection(self, find_cds_root_irun, find_cds_r self.assertEqual(simif._select_vhdl_top(config), "lib.tb_entity:arch") # pylint: disable=protected-access def setUp(self): - self.output_path = str(Path(__file__).parent / "test_incisive_out") + self.output_path = Path(__file__).parent / "test_incisive_out" renew_path(self.output_path) self.project = Project() self.cwd = os.getcwd() diff --git a/tests/unit/test_modelsim_interface.py b/tests/unit/test_modelsim_interface.py index 76b0d016c..9ba1f3fc3 100644 --- a/tests/unit/test_modelsim_interface.py +++ b/tests/unit/test_modelsim_interface.py @@ -319,7 +319,7 @@ def test_overwrites_modelsim_ini_file_from_user(self): def setUp(self): self.test_path = str(Path(__file__).parent / "test_modelsim_out") - self.output_path = str(Path(self.test_path) / "modelsim") + self.output_path = Path(self.test_path) / "modelsim" self.prefix_path = str(Path(self.test_path) / "prefix" / "bin") renew_path(self.test_path) renew_path(self.output_path) @@ -327,7 +327,7 @@ def setUp(self): installed_modelsim_ini = str(Path(self.prefix_path) / ".." / "modelsim.ini") write_file(installed_modelsim_ini, "[Library]") self.project = Project() - self.cwd = os.getcwd() + self.cwd = Path(os.getcwd()) os.chdir(self.test_path) def tearDown(self): diff --git a/tests/unit/test_rivierapro_interface.py b/tests/unit/test_rivierapro_interface.py index 1b6373792..6433d0447 100644 --- a/tests/unit/test_rivierapro_interface.py +++ b/tests/unit/test_rivierapro_interface.py @@ -50,7 +50,7 @@ def test_compile_project_vhdl_2019(self, _find_prefix, process, check_output): str(Path("prefix") / "vcom"), "-quiet", "-j", - self.output_path, + str(self.output_path), "-2019", "-work", "lib", @@ -84,7 +84,7 @@ def test_compile_project_vhdl_2008(self, _find_prefix, process, check_output): str(Path("prefix") / "vcom"), "-quiet", "-j", - self.output_path, + str(self.output_path), "-2008", "-work", "lib", @@ -118,7 +118,7 @@ def test_compile_project_vhdl_2002(self, _find_prefix, process, check_output): str(Path("prefix") / "vcom"), "-quiet", "-j", - self.output_path, + str(self.output_path), "-2002", "-work", "lib", @@ -152,7 +152,7 @@ def test_compile_project_vhdl_93(self, _find_prefix, process, check_output): str(Path("prefix") / "vcom"), "-quiet", "-j", - self.output_path, + str(self.output_path), "-93", "-work", "lib", @@ -187,7 +187,7 @@ def test_compile_project_vhdl_extra_flags(self, _find_prefix, process, check_out str(Path("prefix") / "vcom"), "-quiet", "-j", - self.output_path, + str(self.output_path), "custom", "flags", "-2008", @@ -385,7 +385,7 @@ def test_compile_project_verilog_define(self, _find_prefix, process, check_outpu ) def setUp(self): - self.output_path = str(Path(__file__).parent / "test_rivierapro_out") + self.output_path = Path(__file__).parent / "test_rivierapro_out" renew_path(self.output_path) self.project = Project() self.cwd = os.getcwd() diff --git a/tests/unit/test_test_runner.py b/tests/unit/test_test_runner.py index d29988fa2..168805dee 100644 --- a/tests/unit/test_test_runner.py +++ b/tests/unit/test_test_runner.py @@ -146,7 +146,7 @@ def test_get_output_path_on_linux(self): test_output = runner._get_output_path(test_name) self.assertEqual( test_output, - str(Path(output_path).resolve() / (test_name + "_" + hash_string(test_name))), + Path(output_path).resolve() / (test_name + "_" + hash_string(test_name)), ) output_path = "output_path" @@ -154,7 +154,7 @@ def test_get_output_path_on_linux(self): test_output = runner._get_output_path(test_name) self.assertEqual( test_output, - str(Path(output_path).resolve() / (test_name + "_" + hash_string(test_name))), + Path(output_path).resolve() / (test_name + "_" + hash_string(test_name)), ) output_path = "output_path" @@ -163,7 +163,7 @@ def test_get_output_path_on_linux(self): test_output = runner._get_output_path(test_name) self.assertEqual( test_output, - str(Path(output_path).resolve() / (safe_name + "_" + hash_string(test_name))), + Path(output_path).resolve() / (safe_name + "_" + hash_string(test_name)), ) def test_get_output_path_on_windows(self): @@ -175,7 +175,7 @@ def test_get_output_path_on_windows(self): with mock.patch("os.environ", new={}): test_name = "_" * 400 test_output = runner._get_output_path(test_name) - self.assertEqual(len(test_output), 260 - 100 + 1) + self.assertEqual(len(str(test_output)), 260 - 100 + 1) with mock.patch("os.environ", new={"VUNIT_TEST_OUTPUT_PATH_MARGIN": "-1000"}): output_path = "output_path" @@ -183,7 +183,7 @@ def test_get_output_path_on_windows(self): test_output = runner._get_output_path(test_name) self.assertEqual( test_output, - str(Path(output_path).resolve() / (test_name + "_" + hash_string(test_name))), + Path(output_path).resolve() / (test_name + "_" + hash_string(test_name)), ) with mock.patch("os.environ", new={"VUNIT_SHORT_TEST_OUTPUT_PATHS": ""}): @@ -192,7 +192,7 @@ def test_get_output_path_on_windows(self): test_output = runner._get_output_path(test_name) self.assertEqual( test_output, - str(Path(output_path).resolve() / hash_string(test_name)), + Path(output_path).resolve() / hash_string(test_name), ) @staticmethod diff --git a/tests/unit/test_verilog_parser.py b/tests/unit/test_verilog_parser.py index f97e4eb44..bcd195114 100644 --- a/tests/unit/test_verilog_parser.py +++ b/tests/unit/test_verilog_parser.py @@ -384,7 +384,7 @@ def write_file(self, file_name, contents): full_name = Path(self.output_path) / file_name full_path = full_name.parent if not full_path.exists(): - os.makedirs(str(full_path)) + full_path.mkdir(parents=True) with full_name.open("w") as fptr: fptr.write(contents) diff --git a/vunit/database.py b/vunit/database.py index 98ac46cd0..399676b5f 100644 --- a/vunit/database.py +++ b/vunit/database.py @@ -11,7 +11,6 @@ from pathlib import Path import os import pickle -import io import struct from vunit.ostools import renew_path @@ -55,7 +54,7 @@ def _discover_nodes(self): """ keys_to_nodes = {} for file_base_name in os.listdir(self._path): - key = self._read_key(str(Path(self._path) / file_base_name)) + key = self._read_key(Path(self._path) / file_base_name) assert key not in keys_to_nodes # Two nodes contains the same key keys_to_nodes[key] = int(file_base_name) return keys_to_nodes @@ -70,37 +69,37 @@ def _read_key_from_fptr(fptr): key = fptr.read(key_size) return key - def _read_key(self, file_name): + def _read_key(self, file_name: Path): """ Read key found in file_name """ - with io.open(file_name, "rb") as fptr: + with file_name.open("rb") as fptr: return self._read_key_from_fptr(fptr) - def _read_data(self, file_name): + def _read_data(self, file_name: Path): """ Read key found in file_name """ - with io.open(file_name, "rb") as fptr: + with file_name.open("rb") as fptr: self._read_key_from_fptr(fptr) data = fptr.read() return data @staticmethod - def _write_node(file_name, key, value): + def _write_node(file_name: Path, key, value): """ Write node to file """ - with io.open(file_name, "wb") as fptr: + with file_name.open("wb") as fptr: fptr.write(struct.pack("I", len(key))) fptr.write(key) fptr.write(value) - def _to_file_name(self, key): + def _to_file_name(self, key) -> Path: """ Convert key to file name """ - return str(Path(self._path) / str(self._keys_to_nodes[key])) + return Path(self._path) / str(self._keys_to_nodes[key]) def _allocate_node_for_key(self, key): """ diff --git a/vunit/ostools.py b/vunit/ostools.py index 3cb0eca01..79d1ea7e1 100644 --- a/vunit/ostools.py +++ b/vunit/ostools.py @@ -328,16 +328,17 @@ def renew_path(path): http://stackoverflow.com/questions/27625683/can-anyone-explain-this-weird-behaviour-of-shutil-rmtree-and-shutil-copytree """ + path = Path(path) if IS_WINDOWS_SYSTEM: retries = 10 - while retries > 0 and Path(path).exists(): + while retries > 0 and path.exists(): shutil.rmtree(path, ignore_errors=retries > 1) time.sleep(0.01) retries -= 1 else: - if Path(path).exists(): + if path.exists(): shutil.rmtree(path) - makedirs(path) + path.mkdir(parents=True) def simplify_path(path): diff --git a/vunit/sim_if/__init__.py b/vunit/sim_if/__init__.py index 5596dbd3c..12d6b20a7 100644 --- a/vunit/sim_if/__init__.py +++ b/vunit/sim_if/__init__.py @@ -50,11 +50,11 @@ class SimulatorInterface(object): # pylint: disable=too-many-public-methods supports_colors_in_gui = False def __init__(self, output_path, gui): - self._output_path = output_path + self._output_path = Path(output_path) self._gui = gui @property - def output_path(self): + def output_path(self) -> Path: return self._output_path @property @@ -319,6 +319,17 @@ def get_env(): Allows inheriting classes to overload this to modify environment variables. Return None for default environment """ + def get_script_path(self, output_path) -> Path: + """ + Get path for scripts. + + Also creates the required directories if they do not exist. + """ + script_path = Path(output_path) / self.name + if not script_path.exists(): + script_path.mkdir(parents=True) + return script_path + def isfile(file_name): """ diff --git a/vunit/sim_if/activehdl.py b/vunit/sim_if/activehdl.py index 521b8cfae..6b1a668f1 100644 --- a/vunit/sim_if/activehdl.py +++ b/vunit/sim_if/activehdl.py @@ -10,6 +10,7 @@ from functools import total_ordering from pathlib import Path +from typing import Union import os import re import logging @@ -159,15 +160,17 @@ def create_library(self, library_name, path, mapped_libraries=None): """ mapped_libraries = mapped_libraries if mapped_libraries is not None else {} - apath = str(Path(path).parent.resolve()) + path = Path(path) - if not file_exists(apath): - os.makedirs(apath) + apath = path.parent.resolve() - if not file_exists(path): + if not apath.exists(): + apath.mkdir(parents=True) + + if not path.exists(): proc = Process( - [str(Path(self._prefix) / "vlib"), library_name, path], - cwd=str(Path(self._library_cfg).parent), + [str(Path(self._prefix) / "vlib"), library_name, str(path)], + cwd=Path(self._library_cfg).parent, env=self.get_env(), ) proc.consume_output(callback=None) @@ -176,8 +179,8 @@ def create_library(self, library_name, path, mapped_libraries=None): return proc = Process( - [str(Path(self._prefix) / "vmap"), library_name, path], - cwd=str(Path(self._library_cfg).parent), + [str(Path(self._prefix) / "vmap"), library_name, str(path)], + cwd=Path(self._library_cfg).parent, env=self.get_env(), ) proc.consume_output(callback=None) @@ -250,9 +253,9 @@ def _create_load_function(self, config, output_path): vsim_flags.append(config.vhdl_configuration_name) if config.sim_options.get("enable_coverage", False): - coverage_file_path = str(Path(output_path) / "coverage.acdb") + coverage_file_path = Path(output_path) / "coverage.acdb" self._coverage_files.add(coverage_file_path) - vsim_flags += [f"-acdb_file {{{fix_path(coverage_file_path)!s}}}"] + vsim_flags += [f"-acdb_file {{{fix_path(coverage_file_path)}}}"] vsim_flags += [self._vsim_extra_args(config)] @@ -326,8 +329,8 @@ def merge_coverage(self, file_name, args=None): merge_command += f" -o {{{fix_path(file_name)!s}}}\n" - merge_script_name = str(Path(self._output_path) / "acdb_merge.tcl") - with Path(merge_script_name).open("w", encoding="utf-8") as fptr: + merge_script_name = self.output_path / "acdb_merge.tcl" + with merge_script_name.open("w", encoding="utf-8") as fptr: fptr.write(merge_command + "\n") vcover_cmd = [ @@ -468,8 +471,8 @@ def _create_user_init_function(self, config): tcl = "proc vunit_user_init {} {\n" if init_file is not None: tcl += f"set vunit_tb_name {config.design_unit_name}\n" - tcl += f"set vunit_tb_path {fix_path(str(Path(config.tb_path).resolve()))}\n" - tcl += f'source "{fix_path(str(Path(init_file).resolve()))!s}"\n' + tcl += f"set vunit_tb_path {fix_path(Path(config.tb_path).resolve())}\n" + tcl += f'source "{fix_path(Path(init_file).resolve())}"\n' tcl += " return 0\n" tcl += "}\n" return tcl @@ -486,7 +489,7 @@ def _create_gui_script(self, common_file_name, config): tcl += "design create -a design .\n" for library in self._libraries: - tcl += f"vmap {library.name!s} {fix_path(library.directory)!s}\n" + tcl += f"vmap {library.name!s} {fix_path(library.directory)}\n" tcl += self._create_user_init_function(config) tcl += "if {![vunit_load]} {\n" @@ -496,12 +499,12 @@ def _create_gui_script(self, common_file_name, config): return tcl - def _run_batch_file(self, batch_file_name, gui, cwd): + def _run_batch_file(self, batch_file_name: Union[Path, str], gui, cwd): """ Run a test bench in batch by invoking a new vsim process from the command line """ - todo = f'@do -tcl ""{fix_path(batch_file_name)!s}""' + todo = f'@do -tcl ""{fix_path(batch_file_name)}""' if not gui: todo = "@onerror {quit -code 1};" + todo @@ -525,7 +528,7 @@ def simulate(self, output_path, test_suite_name, config, elaborate_only): """ Run a test bench """ - script_path = Path(output_path) / self.name + script_path = self.get_script_path(output_path) common_file_name = script_path / "common.tcl" batch_file_name = script_path / "batch.tcl" gui_file_name = script_path / "gui.tcl" @@ -538,11 +541,11 @@ def simulate(self, output_path, test_suite_name, config, elaborate_only): ) if self._gui: - gui_path = str(script_path / "gui") + gui_path = script_path / "gui" renew_path(gui_path) return self._run_batch_file(str(gui_file_name), gui=True, cwd=gui_path) - return self._run_batch_file(str(batch_file_name), gui=False, cwd=str(Path(self._library_cfg).parent)) + return self._run_batch_file(str(batch_file_name), gui=False, cwd=Path(self._library_cfg).parent) @total_ordering diff --git a/vunit/sim_if/ghdl.py b/vunit/sim_if/ghdl.py index 6fd33dee0..12255bb24 100644 --- a/vunit/sim_if/ghdl.py +++ b/vunit/sim_if/ghdl.py @@ -9,7 +9,7 @@ """ from pathlib import Path -from os import environ, makedirs, remove +from os import environ import logging import subprocess import shlex @@ -207,7 +207,7 @@ def setup_library_mapping(self, project): self._project = project for library in project.get_libraries(): if not Path(library.directory).exists(): - makedirs(library.directory) + Path(library.directory).mkdir(parents=True) vhdl_standards = set( source_file.get_vhdl_standard() @@ -260,7 +260,7 @@ def compile_vhdl_file_command(self, source_file): "-a", f"--workdir={source_file.library.directory!s}", f"--work={source_file.library.name!s}", - f"--std={self._std_str(source_file.get_vhdl_standard())!s}", + f"--std={self._std_str(source_file.get_vhdl_standard())}", ] for library in self._project.get_libraries(): cmd += [f"-P{library.directory!s}"] @@ -281,11 +281,12 @@ def _get_command( """ Return GHDL simulation command """ + output_path = Path(output_path) cmd = [str(Path(self._prefix) / self.executable)] cmd += ["-e"] if ghdl_e else ["--elab-run"] - cmd += [f"--std={self._std_str(self._vhdl_standard)!s}"] + cmd += [f"--std={self._std_str(self._vhdl_standard)}"] cmd += [f"--work={config.library_name!s}"] cmd += [f"--workdir={self._project.get_library(config.library_name).directory!s}"] cmd += [f"-P{lib.directory!s}" for lib in self._project.get_libraries()] @@ -299,8 +300,8 @@ def _get_command( # Enable coverage in linker cmd += ["-Wl,-lgcov"] else: - coverage_file = str(Path(output_path) / f"{test_suite_name!s}.json") - cmd += ["--coverage", f"--coverage-output={coverage_file!s}"] + coverage_file = output_path / f"{test_suite_name!s}.json" + cmd += ["--coverage", f"--coverage-output={coverage_file}"] if config.vhdl_configuration_name is not None: cmd += [config.vhdl_configuration_name] @@ -328,13 +329,13 @@ def _get_command( cmd += ["--no-run"] else: try: - makedirs(output_path, mode=0o777) + output_path.mkdir(parents=True, mode=0o777) except OSError: pass - with (Path(output_path) / "args.json").open("w", encoding="utf-8") as fname: + with (output_path / "args.json").open("w", encoding="utf-8") as fname: dump( { - "bin": str(Path(output_path) / f"{config.entity_name!s}-{config.architecture_name!s}"), + "bin": str(output_path / f"{config.entity_name}-{config.architecture_name}"), "build": cmd[1:], "sim": sim, }, @@ -348,17 +349,14 @@ def simulate(self, output_path, test_suite_name, config, elaborate_only): # pyl Simulate with entity as top level using generics """ - script_path = str(Path(output_path) / self.name) - - if not Path(script_path).exists(): - makedirs(script_path) + script_path = self.get_script_path(output_path) ghdl_e = elaborate_only and config.sim_options.get("ghdl.elab_e", False) if self._gtkwave_fmt is not None: - data_file_name = str(Path(script_path) / f"wave.{self._gtkwave_fmt!s}") - if Path(data_file_name).exists(): - remove(data_file_name) + data_file_name = script_path / f"wave.{self._gtkwave_fmt!s}" + if data_file_name.exists(): + data_file_name.unlink() else: data_file_name = None @@ -374,7 +372,7 @@ def simulate(self, output_path, test_suite_name, config, elaborate_only): # pyl gcov_env["GCOV_PREFIX"] = coverage_dir self._coverage_test_dirs.add(coverage_dir) else: - self._coverage_files.add(str(Path(script_path) / f"{test_suite_name!s}.json")) + self._coverage_files.add(str(script_path / f"{test_suite_name}.json")) try: proc = Process(cmd, env=gcov_env) @@ -387,9 +385,9 @@ def simulate(self, output_path, test_suite_name, config, elaborate_only): # pyl init_file = config.sim_options.get(self.name + ".gtkwave_script.gui", None) if init_file is not None: - cmd += ["--script", str(Path(init_file).resolve())] + cmd += ["--script", Path(init_file).resolve()] - stdout.write(" ".join(cmd) + "\n") + stdout.write(" ".join(str(c) for c in cmd) + "\n") subprocess.call(cmd) return status diff --git a/vunit/sim_if/incisive.py b/vunit/sim_if/incisive.py index f4b829300..609e560c7 100644 --- a/vunit/sim_if/incisive.py +++ b/vunit/sim_if/incisive.py @@ -10,11 +10,10 @@ from pathlib import Path from os.path import relpath -import os import subprocess import logging from ..exceptions import CompileError -from ..ostools import write_file, file_exists +from ..ostools import write_file from ..vhdl_standard import VHDL from . import SimulatorInterface, run_command, ListOfStringOption from .cds_file import CDSFile @@ -126,7 +125,7 @@ def _create_cdslib(self): # needed for referencing the library 'basic' for cells 'cds_alias', 'cds_thru' etc. in analog models: # NOTE: 'virtuoso' executable not found! # define basic ".../tools/dfII/etc/cdslib/basic" -define work "{self._output_path}/libraries/work" +define work "{self.output_path}/libraries/work" """ if cds_root_virtuoso is None else f"""\ @@ -134,7 +133,7 @@ def _create_cdslib(self): softinclude {self._cds_root_irun}/tools/inca/files/cds.lib # needed for referencing the library 'basic' for cells 'cds_alias', 'cds_thru' etc. in analog models: define basic "{cds_root_virtuoso}/tools/dfII/etc/cdslib/basic" -define work "{self._output_path}/libraries/work" +define work "{self.output_path}/libraries/work" """ ) @@ -193,7 +192,7 @@ def compile_vhdl_file_command(self, source_file): args += ["-work work"] args += [f'-cdslib "{self._cdslib!s}"'] args += self._hdlvar_args() - args += [f'-log "{(Path(self._output_path) / f"irun_compile_vhdl_file_{source_file.library.name!s}.log")!s}"'] + args += [f'-log "{(Path(self.output_path) / f"irun_compile_vhdl_file_{source_file.library.name!s}.log")!s}"'] if not self._log_level == "debug": args += ["-quiet"] else: @@ -204,7 +203,7 @@ def compile_vhdl_file_command(self, source_file): args += [f"-makelib {source_file.library.directory!s}"] args += [f'"{source_file.name!s}"'] args += ["-endlib"] - argsfile = str(Path(self._output_path) / f"irun_compile_vhdl_file_{source_file.library.name!s}.args") + argsfile = str(Path(self.output_path) / f"irun_compile_vhdl_file_{source_file.library.name!s}.args") write_file(argsfile, "\n".join(args)) return [cmd, "-f", argsfile] @@ -228,7 +227,7 @@ def compile_verilog_file_command(self, source_file): args += [f'-cdslib "{self._cdslib!s}"'] args += self._hdlvar_args() args += [ - f'-log "{(Path(self._output_path) / f"irun_compile_verilog_file_{source_file.library.name!s}.log")!s}"' + f'-log "{(Path(self.output_path) / f"irun_compile_verilog_file_{source_file.library.name}.log")}"' ] if not self._log_level == "debug": args += ["-quiet"] @@ -236,19 +235,19 @@ def compile_verilog_file_command(self, source_file): args += ["-messages"] args += ["-libverbose"] for include_dir in source_file.include_dirs: - args += [f'-incdir "{include_dir!s}"'] + args += [f'-incdir "{include_dir}"'] # for "disciplines.vams" etc. - args += [f'-incdir "{self._cds_root_irun!s}/tools/spectre/etc/ahdl/"'] + args += [f'-incdir "{self._cds_root_irun}/tools/spectre/etc/ahdl/"'] for key, value in source_file.defines.items(): val = value.replace('"', '\\"') - args += [f"-define {key!s}={val!s}"] - args += [f'-nclibdirname "{Path(source_file.library.directory).parent!s}"'] - args += [f"-makelib {source_file.library.name!s}"] - args += [f'"{source_file.name!s}"'] + args += [f"-define {key}={val}"] + args += [f'-nclibdirname "{Path(source_file.library.directory).parent}"'] + args += [f"-makelib {source_file.library.name}"] + args += [f'"{source_file.name}"'] args += ["-endlib"] - argsfile = str(Path(self._output_path) / f"irun_compile_verilog_file_{source_file.library.name!s}.args") + argsfile = str(self.output_path / f"irun_compile_verilog_file_{source_file.library.name!s}.args") write_file(argsfile, "\n".join(args)) return [cmd, "-f", argsfile] @@ -258,10 +257,10 @@ def create_library(self, library_name, library_path, mapped_libraries=None): """ mapped_libraries = mapped_libraries if mapped_libraries is not None else {} - lpath = str(Path(library_path).resolve().parent) + lpath = Path(library_path).resolve().parent - if not file_exists(lpath): - os.makedirs(lpath) + if not lpath.exists(): + lpath.mkdir(parents=True) if library_name in mapped_libraries and mapped_libraries[library_name] == library_path: return @@ -281,7 +280,7 @@ def _get_mapped_libraries(self): def _select_vhdl_top(config): "Select VHDL configuration or entity as top." if config.vhdl_configuration_name is None: - return f"{config.library_name!s}.{config.entity_name!s}:{config.architecture_name!s}" + return f"{config.library_name}.{config.entity_name}:{config.architecture_name}" return f"{config.vhdl_configuration_name!s}" @@ -292,7 +291,7 @@ def simulate( Elaborates and Simulates with entity as top level using generics """ - script_path = str(Path(output_path) / self.name) + script_path = self.get_script_path(output_path) launch_gui = self._gui is not False and not elaborate_only if elaborate_only: @@ -320,11 +319,11 @@ def simulate( args += ["-ncerror EVBSTR"] # promote to error: "bad string literal in generic association" args += ["-ncerror EVBNAT"] # promote to error: "bad natural literal in generic association" args += ["-work work"] - args += [f'-nclibdirname "{Path(self._output_path) / "libraries"!s}"'] # @TODO: ugly + args += [f'-nclibdirname "{self.output_path / "libraries"}"'] # @TODO: ugly args += config.sim_options.get("incisive.irun_sim_flags", []) args += [f'-cdslib "{self._cdslib!s}"'] args += self._hdlvar_args() - args += [f'-log "{(Path(script_path) / f"irun_{step!s}.log")!s}"'] + args += [f'-log "{(script_path / f"irun_{step}.log")}"'] if not self._log_level == "debug": args += ["-quiet"] else: @@ -332,7 +331,7 @@ def simulate( # args += ['-libverbose'] args += self._generic_args(config.entity_name, config.generics) for library in self._libraries: - args += [f'-reflib "{library.directory!s}"'] + args += [f'-reflib "{library.directory}"'] if launch_gui: args += ["-access +rwc"] # args += ['-linedebug'] diff --git a/vunit/sim_if/modelsim.py b/vunit/sim_if/modelsim.py index dc353211d..b6a5a7656 100644 --- a/vunit/sim_if/modelsim.py +++ b/vunit/sim_if/modelsim.py @@ -102,9 +102,9 @@ def _create_modelsim_ini(self): """ Create the modelsim.ini file """ - parent = str(Path(self._sim_cfg_file_name).parent) - if not file_exists(parent): - os.makedirs(parent) + parent = Path(self._sim_cfg_file_name).parent + if not parent.exists(): + parent.mkdir(parents=True) original_modelsim_ini = os.environ.get("VUNIT_MODELSIM_INI", str(Path(self._prefix).parent / "modelsim.ini")) with Path(original_modelsim_ini).open("rb") as fread: @@ -202,13 +202,15 @@ def create_library(self, library_name, path, mapped_libraries=None): """ mapped_libraries = mapped_libraries if mapped_libraries is not None else {} - apath = str(Path(path).parent.resolve()) + path = Path(path) - if not file_exists(apath): - os.makedirs(apath) + apath = path.parent.resolve() - if not file_exists(path): - proc = Process([str(Path(self._prefix) / "vlib"), "-unix", path], env=self.get_env()) + if not apath.exists(): + apath.mkdir(parents=True) + + if not path.exists(): + proc = Process([str(Path(self._prefix) / "vlib"), "-unix", str(path)], env=self.get_env()) proc.consume_output(callback=None) if library_name in mapped_libraries and mapped_libraries[library_name] == path: @@ -265,7 +267,7 @@ def _create_load_function(self, test_suite_name, config, output_path): ) vsim_flags = [ - f"-wlf {{{fix_path(str(Path(output_path) / 'vsim.wlf'))!s}}}", + f"-wlf {{{fix_path(Path(output_path) / 'vsim.wlf')}}}", "-quiet", "-t ps", # for correct handling of verilog fatal/finish @@ -280,7 +282,7 @@ def _create_load_function(self, test_suite_name, config, output_path): # There is a known bug in modelsim that prevents the -modelsimini flag from accepting # a space in the path even with escaping, see issue #36 if " " not in self._sim_cfg_file_name: - vsim_flags.insert(0, f"-modelsimini {fix_path(self._sim_cfg_file_name)!s}") + vsim_flags.insert(0, f"-modelsimini {fix_path(self._sim_cfg_file_name)}") for library in self._libraries: vsim_flags += ["-L", library.name] @@ -383,9 +385,9 @@ def merge_coverage(self, file_name, args=None): if args is None: args = [] - coverage_files = str(Path(self._output_path) / "coverage_files.txt") - vcover_cmd = [str(Path(self._prefix) / "vcover"), "merge", "-inputs"] + [coverage_files] + args + [file_name] - with Path(coverage_files).open("w", encoding="utf-8") as fptr: + coverage_files = self.output_path / "coverage_files.txt" + vcover_cmd = [Path(self._prefix) / "vcover", "merge", "-inputs"] + [coverage_files] + args + [file_name] + with coverage_files.open("w", encoding="utf-8") as fptr: for coverage_file in self._coverage_files: if file_exists(coverage_file): fptr.write(str(coverage_file) + "\n") diff --git a/vunit/sim_if/nvc.py b/vunit/sim_if/nvc.py index 8f64ecae3..37e4214b0 100644 --- a/vunit/sim_if/nvc.py +++ b/vunit/sim_if/nvc.py @@ -9,7 +9,7 @@ """ from pathlib import Path -from os import environ, makedirs, remove +from os import environ import logging import subprocess import shlex @@ -160,7 +160,7 @@ def setup_library_mapping(self, project): path = Path(library.directory) if not path.exists(): if not path.parent.exists(): - makedirs(path.parent) + path.parent.mkdir(parents=True) if not run_command( [str(Path(self._prefix) / self.executable), "--work=" + library.directory, "--init"], @@ -246,15 +246,12 @@ def simulate(self, output_path, test_suite_name, config, elaborate_only): # pyl Simulate with entity as top level using generics """ - script_path = Path(output_path) / self.name - - if not script_path.exists(): - makedirs(script_path) + script_path = self.get_script_path(output_path) if self._gui: wave_file = script_path / (f"{config.entity_name}.fst") if wave_file.exists(): - remove(wave_file) + wave_file.unlink() else: wave_file = None diff --git a/vunit/sim_if/rivierapro.py b/vunit/sim_if/rivierapro.py index c794e9c0b..fe4f3bde8 100644 --- a/vunit/sim_if/rivierapro.py +++ b/vunit/sim_if/rivierapro.py @@ -9,7 +9,6 @@ """ from pathlib import Path -import os import re import logging from ..exceptions import CompileError @@ -66,7 +65,7 @@ def find_prefix_from_path(cls): """ def no_avhdl(path): - return not file_exists(str(Path(path) / "avhdl.exe")) + return not (Path(path) / "avhdl.exe").exists() return cls.find_toolchain(["vsim", "vsimsa"], constraints=[no_avhdl]) @@ -224,15 +223,17 @@ def create_library(self, library_name, path, mapped_libraries=None): """ mapped_libraries = mapped_libraries if mapped_libraries is not None else {} - apath = str(Path(path).parent.resolve()) + path = Path(path) - if not file_exists(apath): - os.makedirs(apath) + apath = path.parent.resolve() - if not file_exists(path): + if not apath.exists(): + apath.mkdir(parents=True) + + if not path.exists(): proc = Process( - [str(Path(self._prefix) / "vlib"), library_name, path], - cwd=str(Path(self._sim_cfg_file_name).parent), + [str(Path(self._prefix) / "vlib"), library_name, str(path)], + cwd=Path(self._sim_cfg_file_name).parent, env=self.get_env(), ) proc.consume_output(callback=None) @@ -241,8 +242,8 @@ def create_library(self, library_name, path, mapped_libraries=None): return proc = Process( - [str(Path(self._prefix) / "vmap"), library_name, path], - cwd=str(Path(self._sim_cfg_file_name).parent), + [str(Path(self._prefix) / "vmap"), library_name, str(path)], + cwd=Path(self._sim_cfg_file_name).parent, env=self.get_env(), ) proc.consume_output(callback=None) @@ -251,10 +252,11 @@ def _create_library_cfg(self): """ Create the library.cfg file if it does not exist """ - if file_exists(self._sim_cfg_file_name): + cfg_file = Path(self._sim_cfg_file_name) + if cfg_file.exists(): return - with Path(self._sim_cfg_file_name).open("w", encoding="utf-8") as ofile: + with cfg_file.open("w", encoding="utf-8") as ofile: ofile.write(f'$INCLUDE = "{self._builtin_library_cfg!s}"\n') @property @@ -268,7 +270,7 @@ def _get_mapped_libraries(self, library_cfg_file): Get mapped libraries by running vlist on the working directory """ lines = [] - proc = Process([str(Path(self._prefix) / "vlist")], cwd=str(Path(library_cfg_file).parent)) + proc = Process([str(Path(self._prefix) / "vlist")], cwd=Path(library_cfg_file).parent) proc.consume_output(callback=lines.append) libraries = {} @@ -291,15 +293,15 @@ def _create_load_function(self, test_suite_name, config, output_path): # pylint pli_str = " ".join(f'-pli "{fix_path(name)}"' for name in config.sim_options.get("pli", [])) vsim_flags = [ - f"-dataset {{{fix_path(str(Path(output_path) / 'dataset.asdb'))!s}}}", + f"-dataset {{{fix_path(Path(output_path) / 'dataset.asdb')}}}", pli_str, set_generic_str, ] if config.sim_options.get("enable_coverage", False): - coverage_file_path = str(Path(output_path) / "coverage.acdb") + coverage_file_path = Path(output_path) / "coverage.acdb" self._coverage_files.add(coverage_file_path) - vsim_flags += [f"-acdb_file {{{coverage_file_path!s}}}"] + vsim_flags += [f"-acdb_file {{{coverage_file_path}}}"] vsim_flags += [self._vsim_extra_args(config)] @@ -418,7 +420,7 @@ def merge_coverage(self, file_name, args=None): fname = file_name.replace("\\", "/") merge_command += f" -o {{{fname}}}" - merge_script_name = Path(self._output_path) / "acdb_merge.tcl" + merge_script_name = self.output_path / "acdb_merge.tcl" with merge_script_name.open("w", encoding="utf-8") as fptr: fptr.write(merge_command + "\n") diff --git a/vunit/sim_if/vsim_simulator_mixin.py b/vunit/sim_if/vsim_simulator_mixin.py index 1ff8bb59c..95cd2f2e7 100644 --- a/vunit/sim_if/vsim_simulator_mixin.py +++ b/vunit/sim_if/vsim_simulator_mixin.py @@ -12,6 +12,7 @@ import sys import os from pathlib import Path +from typing import Union from ..ostools import write_file, Process from ..test.suites import get_result_file_name from ..persistent_tcl_shell import PersistentTclShell @@ -41,7 +42,7 @@ def create_process(ident): "-do", str((Path(__file__).parent / "tcl_read_eval_loop.tcl").resolve()), ], - cwd=str(Path(sim_cfg_file_name).parent), + cwd=Path(sim_cfg_file_name).parent, env=env, ) @@ -177,7 +178,7 @@ def _create_batch_script(common_file_name, load_only=False): """ batch_do = "" batch_do += "onerror {quit -code 1}\n" - batch_do += f'source "{fix_path(common_file_name)!s}"\n' + batch_do += f'source "{fix_path(common_file_name)}"\n' batch_do += "set failed [vunit_load]\n" batch_do += "if {$failed} {quit -code 1}\n" if not load_only: @@ -259,7 +260,7 @@ def _create_gui_script(self, common_file_name, config): """ Create the user facing script which loads common functions and prints a help message """ - tcl = f'source "{fix_path(common_file_name)!s}"\n' + tcl = f'source "{fix_path(common_file_name)}"\n' tcl += self._create_user_init_function(config) tcl += "if {![vunit_load]} {\n" tcl += " vunit_user_init\n" @@ -279,10 +280,10 @@ def _run_batch_file(self, batch_file_name, gui=False): "-l", str(Path(batch_file_name).parent / "transcript"), "-do", - f'source "{fix_path(batch_file_name)!s}"', + f'source "{fix_path(batch_file_name)}"', ] - proc = Process(args, cwd=str(Path(self._sim_cfg_file_name).parent)) + proc = Process(args, cwd=Path(self._sim_cfg_file_name).parent) proc.consume_output() except Process.NonZeroExitCode: return False @@ -293,7 +294,7 @@ def _run_persistent(self, common_file_name, load_only=False): Run a test bench using the persistent vsim process """ try: - self._persistent_shell.execute(f'source "{fix_path(common_file_name)!s}"') + self._persistent_shell.execute(f'source "{fix_path(common_file_name)}"') self._persistent_shell.execute("set failed [vunit_load]") if self._persistent_shell.read_bool("failed"): return False @@ -311,7 +312,7 @@ def simulate(self, output_path, test_suite_name, config, elaborate_only): """ Run a test bench """ - script_path = Path(output_path) / self.name + script_path = self.get_script_path(output_path) common_file_name = script_path / "common.do" gui_file_name = script_path / "gui.do" @@ -336,11 +337,11 @@ def simulate(self, output_path, test_suite_name, config, elaborate_only): return self._run_batch_file(str(batch_file_name)) -def fix_path(path): +def fix_path(path: Union[Path, str]) -> str: """ Adjust path for TCL usage """ - return path.replace("\\", "/").replace(" ", "\\ ") + return str(path).replace("\\", "/").replace(" ", "\\ ") def get_is_test_suite_done_tcl(vunit_result_file): @@ -350,7 +351,7 @@ def get_is_test_suite_done_tcl(vunit_result_file): """ return f""" proc is_test_suite_done {{}} {{ - set fd [open "{fix_path(vunit_result_file)!s}" "r"] + set fd [open "{fix_path(vunit_result_file)}" "r"] set contents [read $fd] close $fd set lines [split $contents "\n"] diff --git a/vunit/test/runner.py b/vunit/test/runner.py index 5fa35af31..b9abd7ac5 100644 --- a/vunit/test/runner.py +++ b/vunit/test/runner.py @@ -49,7 +49,7 @@ def __init__( # pylint: disable=too-many-arguments self._abort = False self._local = threading.local() self._report = report - self._output_path = output_path + self._output_path = Path(output_path) assert verbosity in ( self.VERBOSITY_QUIET, self.VERBOSITY_NORMAL, @@ -78,8 +78,8 @@ def run(self, test_suites): Run a list of test suites """ - if not Path(self._output_path).exists(): - os.makedirs(self._output_path) + if not self._output_path.exists(): + self._output_path.mkdir(parents=True) self._create_test_mapping_file(test_suites) @@ -146,13 +146,13 @@ def _run_thread(self, write_stdout, scheduler, num_tests, is_main): test_suite = scheduler.next() output_path = self._get_output_path(test_suite.name) - output_file_name = str(Path(output_path) / "output.txt") + output_file_name = output_path / "output.txt" with self._stdout_lock(): for test_name in test_suite.test_names: now = datetime.now().strftime("%H:%M:%S") - print(f"({now}) Starting {test_name!s}") - print(f"Output file: {output_file_name!s}") + print(f"({now}) Starting {test_name}") + print(f"Output file: {output_file_name}") self._run_test_suite(test_suite, write_stdout, num_tests, output_path, output_file_name) @@ -171,12 +171,12 @@ def _run_thread(self, write_stdout, scheduler, num_tests, is_main): if test_suite is not None: scheduler.test_done() - def _get_output_path(self, test_suite_name): + def _get_output_path(self, test_suite_name) -> Path: """ Construct the full output path of a test case. Ensure no bad characters and no long path names. """ - output_path = str(Path(self._output_path).resolve()) + output_path = self._output_path.resolve() safe_name = "".join(char if _is_legal(char) else "_" for char in test_suite_name) + "_" hash_name = hash_string(test_suite_name) @@ -185,12 +185,12 @@ def _get_output_path(self, test_suite_name): elif sys.platform == "win32": max_path = 260 margin = int(os.environ.get("VUNIT_TEST_OUTPUT_PATH_MARGIN", "100")) - prefix_len = len(output_path) + prefix_len = len(str(output_path)) full_name = safe_name[: min(max_path - margin - prefix_len - len(hash_name), len(safe_name))] + hash_name else: full_name = safe_name + hash_name - return str(Path(output_path) / full_name) + return output_path / full_name def _add_skipped_tests(self, test_suite, results, start_time, num_tests, output_file_name): """ @@ -206,7 +206,7 @@ def _run_test_suite( # pylint: disable=too-many-locals """ Run the actual test suite """ - color_output_file_name = str(Path(output_path) / "output_with_color.txt") + color_output_file_name = Path(output_path) / "output_with_color.txt" output_file = None color_output_file = None @@ -226,7 +226,7 @@ def _run_test_suite( # pylint: disable=too-many-locals if write_stdout: output_from = self._stdout_ansi else: - color_output_file = Path(color_output_file_name).open( # pylint: disable=consider-using-with + color_output_file = color_output_file_name.open( # pylint: disable=consider-using-with "w", encoding="utf-8" ) output_from = color_output_file @@ -283,7 +283,7 @@ def _create_test_mapping_file(self, test_suites): Create a file mapping test name to test output folder. This is to allow the user to find the test output folder when it is hashed """ - mapping_file_name = Path(self._output_path) / "test_name_to_path_mapping.txt" + mapping_file_name = self._output_path / "test_name_to_path_mapping.txt" # Load old mapping to remember non-deleted test folders as well # even when re-running only a single test case @@ -295,7 +295,7 @@ def _create_test_mapping_file(self, test_suites): for test_suite in test_suites: test_output = self._get_output_path(test_suite.name) - mapping.add(f"{Path(test_output).name!s} {test_suite.name!s}") + mapping.add(f"{test_output.name} {test_suite.name}") # Sort by everything except hash mapping = sorted(mapping, key=lambda value: value[value.index(" ") :]) @@ -304,11 +304,11 @@ def _create_test_mapping_file(self, test_suites): for value in mapping: fptr.write(value + "\n") - def _print_output(self, output_file_name): + def _print_output(self, output_file_path: Path): """ Print contents of output file if it exists """ - with Path(output_file_name).open("r", encoding="utf-8") as fread: + with output_file_path.open("r", encoding="utf-8") as fread: for line in fread.readlines(): self._stdout_ansi.write(line) diff --git a/vunit/test/suites.py b/vunit/test/suites.py index 9f63ac4c2..381ec2167 100644 --- a/vunit/test/suites.py +++ b/vunit/test/suites.py @@ -9,6 +9,7 @@ """ from pathlib import Path +from typing import Union from .. import ostools from .report import PASSED, SKIPPED, FAILED @@ -218,15 +219,16 @@ def _simulate(self, output_path): config = self._config.copy() + output_path = str(output_path).replace("\\", "/") + "/" if "output_path" in config.generic_names and "output_path" not in config.generics: - config.generics["output_path"] = str(output_path.replace("\\", "/")) + "/" + config.generics["output_path"] = output_path runner_cfg = { "enabled_test_cases": ",".join( encode_test_case(test_case) for test_case in self._test_cases if test_case is not None ), "use_color": self._simulator_if.use_color, - "output path": output_path.replace("\\", "/") + "/", + "output path": output_path, "active python runner": True, "tb path": config.tb_path.replace("\\", "/") + "/", } @@ -326,5 +328,5 @@ def _full_name(test_suite_name, test_case_name): return test_suite_name + "." + test_case_name -def get_result_file_name(output_path): - return str(Path(output_path) / "vunit_results") +def get_result_file_name(output_path: Union[Path, str]) -> Path: + return Path(output_path) / "vunit_results" diff --git a/vunit/ui/__init__.py b/vunit/ui/__init__.py index 3ddc531e3..3f8ec5888 100644 --- a/vunit/ui/__init__.py +++ b/vunit/ui/__init__.py @@ -118,7 +118,7 @@ def __init__( ): self._args = args self._configure_logging(args.log_level) - self._output_path = str(Path(args.output_path).resolve()) + self._output_path = Path(args.output_path).resolve() if args.no_color: self._printer = NO_COLOR_PRINTER @@ -145,10 +145,10 @@ def test_filter(name, attribute_names): # Use default simulator options if no simulator was present if self._simulator_class is None: simulator_class = SimulatorInterface - self._simulator_output_path = str(Path(self._output_path) / "none") + self._simulator_output_path = self._output_path / "none" else: simulator_class = self._simulator_class - self._simulator_output_path = str(Path(self._output_path) / simulator_class.name) + self._simulator_output_path = self._output_path / simulator_class.name self._create_output_path(args.clean) @@ -169,7 +169,7 @@ def _create_database(self): Check for Python version used to create the database is the same as the running python instance or re-create """ - project_database_file_name = str(Path(self._output_path) / "project_database") + project_database_file_name = str(self._output_path / "project_database") create_new = False key = b"version" version = str((9, sys.version)).encode() @@ -290,9 +290,9 @@ def add_library( """ standard = self._which_vhdl_standard(vhdl_standard) - path = Path(self._simulator_output_path) / "libraries" / library_name + path = self._simulator_output_path / "libraries" / library_name if not self._project.has_library(library_name): - self._project.add_library(library_name, str(path.resolve()), standard) + self._project.add_library(library_name, path.resolve(), standard) elif not allow_duplicate: raise ValueError(f"Library {library_name!s} already added. Use allow_duplicate to ignore this error.") return self.library(library_name) @@ -765,8 +765,8 @@ def _create_simulator_if(self): ) sys.exit(1) - if not Path(self._simulator_output_path).exists(): - os.makedirs(self._simulator_output_path) + if not self._simulator_output_path.exists(): + self._simulator_output_path.mkdir(parents=True) return self._simulator_class.from_args(args=self._args, output_path=self._simulator_output_path) @@ -893,8 +893,8 @@ def _create_output_path(self, clean: bool): """ if clean: ostools.renew_path(self._output_path) - elif not Path(self._output_path).exists(): - os.makedirs(self._output_path) + elif not self._output_path.exists(): + self._output_path.mkdir(parents=True) ostools.renew_path(self._preprocessed_path) @@ -904,11 +904,11 @@ def vhdl_standard(self) -> str: @property def _preprocessed_path(self): - return str(Path(self._output_path) / "preprocessed") + return str(self._output_path / "preprocessed") @property def codecs_path(self): - return str(Path(self._output_path) / "codecs") + return str(self._output_path / "codecs") def _compile(self, simulator_if: SimulatorInterface): """ @@ -952,7 +952,7 @@ def _run_test(self, test_cases, report): runner = TestRunner( report, - str(Path(self._output_path) / TEST_OUTPUT_PATH), + str(self._output_path / TEST_OUTPUT_PATH), verbosity=verbosity, num_threads=self._args.num_threads, fail_fast=self._args.fail_fast, diff --git a/vunit/ui/results.py b/vunit/ui/results.py index ea2ddfd6b..86e454e86 100644 --- a/vunit/ui/results.py +++ b/vunit/ui/results.py @@ -19,7 +19,7 @@ class Results(object): """ def __init__(self, output_path, simulator_if, report): - self._output_path = output_path + self._output_path = Path(output_path) self._simulator_if = simulator_if self._report = report @@ -44,7 +44,7 @@ def get_report(self): report.tests.update( { test.name: TestResult( - Path(self._output_path) / TEST_OUTPUT_PATH, + self._output_path / TEST_OUTPUT_PATH, obj["status"], obj["time"], obj["path"], diff --git a/vunit/vivado/vivado.py b/vunit/vivado/vivado.py index 25f8a9d93..de82aa996 100644 --- a/vunit/vivado/vivado.py +++ b/vunit/vivado/vivado.py @@ -9,7 +9,6 @@ """ from subprocess import check_call -from os import makedirs from pathlib import Path @@ -69,7 +68,7 @@ def create_compile_order_file(project_file, compile_order_file, vivado_path=None fpath = Path(compile_order_file) if not fpath.parent.exists(): - makedirs(str(fpath.parent)) + fpath.parent.mkdir(parents=True) print("Extracting compile order ...") run_vivado( @@ -122,9 +121,9 @@ def run_vivado(tcl_file_name, tcl_args=None, cwd=None, vivado_path=None): Note: the shell=True is important in windows where Vivado is just a bat file. """ vivado = "vivado" if vivado_path is None else str(Path(vivado_path).resolve() / "bin" / "vivado") - cmd = f"{vivado} -nojournal -nolog -notrace -mode batch -source {str(Path(tcl_file_name).resolve())}" + cmd = f"{vivado} -nojournal -nolog -notrace -mode batch -source {Path(tcl_file_name).resolve()}" if tcl_args is not None: - cmd += " -tclargs " + " ".join([str(val) for val in tcl_args]) + cmd += " -tclargs " + " ".join(str(val) for val in tcl_args) print(cmd) check_call(cmd, cwd=cwd, shell=True)