|
20 | 20 |
|
21 | 21 | ImportErrorPattern = re.compile(r"ModuleNotFoundError.*$", re.MULTILINE) |
22 | 22 |
|
23 | | -BLACKLIST_ADDOPTS = ("benchmark", "sugar", "codespeed", "cov", "profile", "junitxml") |
| 23 | +BLACKLIST_ADDOPTS = ("--benchmark", "--sugar", "--codespeed", "--cov", "--profile", "--junitxml", "-n") |
24 | 24 |
|
25 | 25 |
|
26 | 26 | def unified_diff_strings(code1: str, code2: str, fromfile: str = "original", tofile: str = "modified") -> str: |
@@ -84,45 +84,93 @@ def create_rank_dictionary_compact(int_array: list[int]) -> dict[int, int]: |
84 | 84 | return {original_index: rank for rank, original_index in enumerate(sorted_indices)} |
85 | 85 |
|
86 | 86 |
|
87 | | -def modify_addopts(config_file: Path) -> tuple[str, bool]: |
88 | | - content = "" |
| 87 | +def filter_args(addopts_args: list[str]) -> list[str]: |
| 88 | + filtered_args = [] |
| 89 | + i = 0 |
| 90 | + while i < len(addopts_args): |
| 91 | + current_arg = addopts_args[i] |
| 92 | + # Check if current argument starts with --cov |
| 93 | + if current_arg.startswith(BLACKLIST_ADDOPTS): |
| 94 | + # Skip this argument |
| 95 | + i += 1 |
| 96 | + # Check if the next argument is a value (doesn't start with -) |
| 97 | + if i < len(addopts_args) and not addopts_args[i].startswith("-"): |
| 98 | + # Skip the value as well |
| 99 | + i += 1 |
| 100 | + else: |
| 101 | + # Keep this argument |
| 102 | + filtered_args.append(current_arg) |
| 103 | + i += 1 |
| 104 | + return filtered_args |
| 105 | + |
| 106 | + |
| 107 | +def modify_addopts(config_file: Path) -> tuple[str, bool]: # noqa : PLR0911 |
| 108 | + file_type = config_file.suffix.lower() |
| 109 | + filename = config_file.name |
| 110 | + if file_type not in {".toml", ".ini", "cfg"} or not config_file.exists(): |
| 111 | + return "", False |
| 112 | + # Read original file |
| 113 | + with Path.open(config_file, encoding="utf-8") as f: |
| 114 | + content = f.read() |
89 | 115 | try: |
90 | | - if config_file.suffix.lower() == "toml": |
| 116 | + if filename == "pyproject.toml": |
91 | 117 | # use tomlkit |
92 | | - pass |
| 118 | + data = tomlkit.parse(content) |
| 119 | + original_addopts = data.get("tool", {}).get("pytest", {}).get("ini_options", {}).get("addopts", "") |
| 120 | + # nothing to do if no addopts present |
| 121 | + if original_addopts == "": |
| 122 | + return content, False |
| 123 | + if isinstance(original_addopts, list): |
| 124 | + original_addopts = " ".join(original_addopts) |
| 125 | + addopts_args = ( |
| 126 | + original_addopts.split() |
| 127 | + ) # any number of space characters as delimiter, doesn't look at = which is fine |
93 | 128 | else: |
94 | 129 | # use configparser |
95 | | - pass |
| 130 | + config = configparser.ConfigParser() |
| 131 | + config.read_string(content) |
| 132 | + data = {section: dict(config[section]) for section in config.sections()} |
| 133 | + if config_file.name in {"pytest.ini", ".pytest.ini", "tox.ini"}: |
| 134 | + original_addopts = data.get("pytest", {}).get("addopts", "") # should only be a string |
| 135 | + else: |
| 136 | + original_addopts = data.get("tool:pytest", {}).get("addopts", "") # should only be a string |
| 137 | + addopts_args = original_addopts.split() |
| 138 | + new_addopts_args = filter_args(addopts_args) |
| 139 | + if new_addopts_args == addopts_args: |
| 140 | + return content, False |
| 141 | + # change addopts now |
| 142 | + if file_type == "toml": |
| 143 | + data["tool"]["pytest"]["ini_options"]["addopts"] = " ".join(new_addopts_args) |
| 144 | + # Write modified file |
| 145 | + with Path.open(config_file, "w", encoding="utf-8") as f: |
| 146 | + f.write(tomlkit.dumps(data)) |
| 147 | + return content, True |
| 148 | + elif config_file.name in {"pytest.ini", ".pytest.ini", "tox.ini"}: |
| 149 | + config["pytest"]["addopts"] = " ".join(new_addopts_args) |
| 150 | + # Write modified file |
| 151 | + with Path.open(config_file, "w", encoding="utf-8") as f: |
| 152 | + config.write(f) |
| 153 | + return content, True |
| 154 | + else: |
| 155 | + config["tool:pytest"]["addopts"] = " ".join(new_addopts_args) |
| 156 | + # Write modified file |
| 157 | + with Path.open(config_file, "w", encoding="utf-8") as f: |
| 158 | + config.write(f) |
| 159 | + return content, True |
| 160 | + |
96 | 161 | except Exception: |
97 | 162 | logger.debug("Trouble parsing") |
98 | 163 | return content, False # not modified |
99 | | - config = configparser.ConfigParser() |
100 | | - config.read(config_file) |
101 | | - # read file |
102 | | - # parse |
103 | | - # modify |
104 | | - # save |
105 | | - # return original content |
106 | | - print(config_file) |
107 | | - return "", True |
108 | 164 |
|
109 | 165 |
|
110 | 166 | @contextmanager |
111 | 167 | def custom_addopts() -> None: |
112 | 168 | closest_config_files = get_all_closest_config_files() |
113 | 169 |
|
114 | | - # 1. find closest config files |
115 | | - # 2. iterate through each of them and mask the addopts |
116 | | - # 3. yield |
117 | | - # 4. restore the original addopts when the context manager exits |
118 | | - |
119 | 170 | original_content = {} |
120 | 171 |
|
121 | 172 | try: |
122 | 173 | for config_file in closest_config_files: |
123 | | - # Read original file |
124 | | - print(config_file) |
125 | | - # if pyproject_file.exists(): |
126 | 174 | original_content[config_file] = modify_addopts(config_file) |
127 | 175 | yield |
128 | 176 |
|
|
0 commit comments