(data: dict[str, Any], to_remove: Iterable[str])
| 148 | |
| 149 | |
| 150 | def recursive_remove_key(data: dict[str, Any], to_remove: Iterable[str]) -> dict[str, Any]: |
| 151 | def _sort_list(entry): |
| 152 | if isinstance(entry, list): |
| 153 | if len(entry) == 0: |
| 154 | return entry |
| 155 | if isinstance(entry[0], str): |
| 156 | return sorted(entry) |
| 157 | if isinstance(entry[0], list): |
| 158 | return [_sort_list(item) for item in entry] |
| 159 | return sorted( |
| 160 | entry, |
| 161 | key=lambda obj: (getattr(obj, "id", None) |
| 162 | or getattr(obj, "name", None) or 0) |
| 163 | if isinstance(obj, dict) |
| 164 | else obj, |
| 165 | ) |
| 166 | |
| 167 | if not isinstance(data, (dict, set, list)): |
| 168 | return data |
| 169 | |
| 170 | if isinstance(data, list): |
| 171 | return [recursive_remove_key(item, to_remove) for item in _sort_list(data)] |
| 172 | |
| 173 | returndata = {} |
| 174 | for key in sorted(data.keys()): |
| 175 | value = data[key] |
| 176 | if key in to_remove: |
| 177 | continue |
| 178 | elif isinstance(value, (str, bool, int, float, NoneType)): |
| 179 | returndata[key] = value |
| 180 | elif isinstance(value, dict): |
| 181 | returndata[key] = recursive_remove_key( |
| 182 | {k: value[k] for k in sorted(value.keys())}, |
| 183 | to_remove, |
| 184 | ) |
| 185 | elif isinstance(value, (list, set)): |
| 186 | returndata[key] = [recursive_remove_key( |
| 187 | item, to_remove) for item in _sort_list(value)] |
| 188 | else: |
| 189 | returndata[key] = type(value) |
| 190 | return returndata |
| 191 | |
| 192 | |
| 193 | def fixture(filename, asjson=True): |
searching dependent graphs…