Spaces:
Runtime error
Runtime error
| # coding=utf-8 | |
| # Copyright 2022 The HuggingFace Inc. team. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| """ Style utils to preprocess files for doc tests. | |
| The doc precossing function can be run on a list of files and/org | |
| directories of files. It will recursively check if the files have | |
| a python code snippet by looking for a ```python or ```py syntax. | |
| In the default mode - `remove_new_line==False` the script will | |
| add a new line before every python code ending ``` line to make | |
| the docstrings ready for pytest doctests. | |
| However, we don't want to have empty lines displayed in the | |
| official documentation which is why the new line command can be | |
| reversed by adding the flag `--remove_new_line` which sets | |
| `remove_new_line==True`. | |
| When debugging the doc tests locally, please make sure to | |
| always run: | |
| ```python utils/prepare_for_doc_test.py src docs``` | |
| before running the doc tests: | |
| ```pytest --doctest-modules $(cat utils/documentation_tests.txt) -sv --doctest-continue-on-failure --doctest-glob="*.mdx"``` | |
| Afterwards you should revert the changes by running | |
| ```python utils/prepare_for_doc_test.py src docs --remove_new_line``` | |
| """ | |
| import argparse | |
| import os | |
| def process_code_block(code, add_new_line=True): | |
| if add_new_line: | |
| return maybe_append_new_line(code) | |
| else: | |
| return maybe_remove_new_line(code) | |
| def maybe_append_new_line(code): | |
| """ | |
| Append new line if code snippet is a | |
| Python code snippet | |
| """ | |
| lines = code.split("\n") | |
| if lines[0] in ["py", "python"]: | |
| # add new line before last line being ``` | |
| last_line = lines[-1] | |
| lines.pop() | |
| lines.append("\n" + last_line) | |
| return "\n".join(lines) | |
| def maybe_remove_new_line(code): | |
| """ | |
| Remove new line if code snippet is a | |
| Python code snippet | |
| """ | |
| lines = code.split("\n") | |
| if lines[0] in ["py", "python"]: | |
| # add new line before last line being ``` | |
| lines = lines[:-2] + lines[-1:] | |
| return "\n".join(lines) | |
| def process_doc_file(code_file, add_new_line=True): | |
| """ | |
| Process given file. | |
| Args: | |
| code_file (`str` or `os.PathLike`): The file in which we want to style the docstring. | |
| """ | |
| with open(code_file, "r", encoding="utf-8", newline="\n") as f: | |
| code = f.read() | |
| # fmt: off | |
| splits = code.split("```") | |
| if len(splits) % 2 != 1: | |
| raise ValueError("The number of occurrences of ``` should be an even number.") | |
| splits = [s if i % 2 == 0 else process_code_block(s, add_new_line=add_new_line) for i, s in enumerate(splits)] | |
| clean_code = "```".join(splits) | |
| # fmt: on | |
| diff = clean_code != code | |
| if diff: | |
| print(f"Overwriting content of {code_file}.") | |
| with open(code_file, "w", encoding="utf-8", newline="\n") as f: | |
| f.write(clean_code) | |
| def process_doc_files(*files, add_new_line=True): | |
| """ | |
| Applies doc styling or checks everything is correct in a list of files. | |
| Args: | |
| files (several `str` or `os.PathLike`): The files to treat. | |
| Whether to restyle file or just check if they should be restyled. | |
| Returns: | |
| List[`str`]: The list of files changed or that should be restyled. | |
| """ | |
| for file in files: | |
| # Treat folders | |
| if os.path.isdir(file): | |
| files = [os.path.join(file, f) for f in os.listdir(file)] | |
| files = [f for f in files if os.path.isdir(f) or f.endswith(".mdx") or f.endswith(".py")] | |
| process_doc_files(*files, add_new_line=add_new_line) | |
| else: | |
| try: | |
| process_doc_file(file, add_new_line=add_new_line) | |
| except Exception: | |
| print(f"There is a problem in {file}.") | |
| raise | |
| def main(*files, add_new_line=True): | |
| process_doc_files(*files, add_new_line=add_new_line) | |
| if __name__ == "__main__": | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("files", nargs="+", help="The file(s) or folder(s) to restyle.") | |
| parser.add_argument( | |
| "--remove_new_line", | |
| action="store_true", | |
| help="Whether to remove new line after each python code block instead of adding one.", | |
| ) | |
| args = parser.parse_args() | |
| main(*args.files, add_new_line=not args.remove_new_line) | |