We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
ManimConfig Write Bug
## Description of bug / unexpected behavior
<!-- Add a clear and concise description of the problem you encountered. -->
```
(manim) C:\Users\a\Documents\repos\ManimCommunity\manim>manim cfg export
You are reading the config from the same directory you are exporting to.
This means that the exported config will overwrite the config for this directory.
Are you sure you want to continue? (y/n)y
Traceback (most recent call last):
  File "C:\Users\a\anaconda3\envs\manim\Scripts\manim", line 5, in <module>
    main()
  File "C:\Users\a\Documents\repos\ManimCommunity\manim\manim\__main__.py", line 65, in main
    cfg_subcmds.export(args.dir)
  File "C:\Users\a\Documents\repos\ManimCommunity\manim\manim\_config\cfg_subcmds.py", line 245, in export
    config.write(outpath)
AttributeError: 'ManimConfig' object has no attribute 'write'
```
```
(manim) C:\Users\a\Documents\repos\ManimCommunity\manim>manim cfg export --dir test
Creating folder: test.
Traceback (most recent call last):
  File "C:\Users\a\anaconda3\envs\manim\Scripts\manim", line 5, in <module>
    main()
  File "C:\Users\a\Documents\repos\ManimCommunity\manim\manim\__main__.py", line 65, in main
    cfg_subcmds.export(args.dir)
  File "C:\Users\a\Documents\repos\ManimCommunity\manim\manim\_config\cfg_subcmds.py", line 245, in export
    config.write(outpath)
AttributeError: 'ManimConfig' object has no attribute 'write'

```
## Expected behavior
A manim.cfg file populated at the specified directory (defaults to cwd).

## How to reproduce the issue
<!-- Provide a piece of code illustrating the undesired behavior. -->
Clone the master branch and run as I did in the CLI above:
`manim cfg export`
`manim cfg export --dir test`

## System specifications
- OS (with version, e.g Windows 10 v2004 or macOS 10.15 (Catalina)):

## Additional comments
This also seems to be in the case in Ubuntu 20.04 as tested by @huguesdevimeux 


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `manim/_config/cfg_subcmds.py`
Content:
```
1 """
2 cfg_subcmd.py
3 ------------
4 
5 General Config File Managing Utilities.
6 The functions below can be called via the `manim cfg` subcommand.
7 
8 """
9 
10 import os
11 from ast import literal_eval
12 from typing import Union
13 
14 from manim import config, console
15 from manim._config.utils import config_file_paths, make_config_parser
16 from manim.utils.file_ops import guarantee_existence, open_file
17 from rich.errors import StyleSyntaxError
18 from rich.style import Style
19 
20 __all__ = ["write", "show", "export"]
21 
22 RICH_COLOUR_INSTRUCTIONS: str = """
23 [red]The default colour is used by the input statement.
24 If left empty, the default colour will be used.[/red]
25 [magenta] For a full list of styles, visit[/magenta] [green]https://rich.readthedocs.io/en/latest/style.html[/green]
26 """
27 RICH_NON_STYLE_ENTRIES: str = ["log.width", "log.height", "log.timestamps"]
28 
29 
30 def value_from_string(value: str) -> Union[str, int, bool]:
31     """Extracts the literal of proper datatype from a string.
32     Parameters
33     ----------
34     value : :class:`str`
35         The value to check get the literal from.
36 
37     Returns
38     -------
39     Union[:class:`str`, :class:`int`, :class:`bool`]
40         Returns the literal of appropriate datatype.
41     """
42     try:
43         value = literal_eval(value)
44     except (SyntaxError, ValueError):
45         pass
46     return value
47 
48 
49 def _is_expected_datatype(value: str, expected: str, style: bool = False) -> bool:
50     """Checks whether `value` is the same datatype as `expected`,
51     and checks if it is a valid `style` if `style` is true.
52 
53     Parameters
54     ----------
55     value : :class:`str`
56         The string of the value to check (obtained from reading the user input).
57     expected : :class:`str`
58         The string of the literal datatype must be matched by `value`. Obtained from
59         reading the cfg file.
60     style : :class:`bool`, optional
61         Whether or not to confirm if `value` is a style, by default False
62 
63     Returns
64     -------
65     :class:`bool`
66         Whether or not `value` matches the datatype of `expected`.
67     """
68     value = value_from_string(value)
69     expected = type(value_from_string(expected))
70 
71     return isinstance(value, expected) and (is_valid_style(value) if style else True)
72 
73 
74 def is_valid_style(style: str) -> bool:
75     """Checks whether the entered color is a valid color according to rich
76     Parameters
77     ----------
78     style : :class:`str`
79         The style to check whether it is valid.
80     Returns
81     -------
82     Boolean
83         Returns whether it is valid style or not according to rich.
84     """
85     try:
86         Style.parse(style)
87         return True
88     except StyleSyntaxError:
89         return False
90 
91 
92 def replace_keys(default: dict) -> dict:
93     """Replaces _ to . and vice versa in a dictionary for rich
94     Parameters
95     ----------
96     default : :class:`dict`
97         The dictionary to check and replace
98     Returns
99     -------
100     :class:`dict`
101         The dictionary which is modified by replacing _ with . and vice versa
102     """
103     for key in default:
104         if "_" in key:
105             temp = default[key]
106             del default[key]
107             key = key.replace("_", ".")
108             default[key] = temp
109         else:
110             temp = default[key]
111             del default[key]
112             key = key.replace(".", "_")
113             default[key] = temp
114     return default
115 
116 
117 def write(level: str = None, openfile: bool = False) -> None:
118     config_paths = config_file_paths()
119     console.print(
120         "[yellow bold]Manim Configuration File Writer[/yellow bold]", justify="center"
121     )
122 
123     USER_CONFIG_MSG = f"""A configuration file at [yellow]{config_paths[1]}[/yellow] has been created with your required changes.
124 This will be used when running the manim command. If you want to override this config,
125 you will have to create a manim.cfg in the local directory, where you want those changes to be overridden."""
126 
127     CWD_CONFIG_MSG = f"""A configuration file at [yellow]{config_paths[2]}[/yellow] has been created.
128 To save your config please save that file and place it in your current working directory, from where you run the manim command."""
129 
130     parser = make_config_parser()
131     if not openfile:
132         action = "save this as"
133         for category in parser:
134             console.print(f"{category}", style="bold green underline")
135             default = parser[category]
136             if category == "logger":
137                 console.print(RICH_COLOUR_INSTRUCTIONS)
138                 default = replace_keys(default)
139 
140             for key in default:
141                 # All the cfg entries for logger need to be validated as styles,
142                 # as long as they arent setting the log width or height etc
143                 if category == "logger" and key not in RICH_NON_STYLE_ENTRIES:
144                     desc = "style"
145                     style = default[key]
146                 else:
147                     desc = "value"
148                     style = None
149 
150                 console.print(f"Enter the {desc} for {key} ", style=style, end="")
151                 if category != "logger" or key in RICH_NON_STYLE_ENTRIES:
152                     defaultval = (
153                         repr(default[key])
154                         if isinstance(value_from_string(default[key]), str)
155                         else default[key]
156                     )
157                     console.print(f"(defaults to {defaultval}) :", end="")
158                 try:
159                     temp = input()
160                 except EOFError:
161                     raise Exception(
162                         """Not enough values in input.
163 You may have added a new entry to default.cfg, in which case you will have to
164 modify write_cfg_subcmd_input to account for it."""
165                     )
166                 if temp:
167                     while temp and not _is_expected_datatype(
168                         temp, default[key], bool(style)
169                     ):
170                         console.print(
171                             f"[red bold]Invalid {desc}. Try again.[/red bold]"
172                         )
173                         console.print(
174                             f"Enter the {desc} for {key}:", style=style, end=""
175                         )
176                         temp = input()
177                     else:
178                         default[key] = temp
179 
180             default = replace_keys(default) if category == "logger" else default
181 
182             parser[category] = dict(default)
183 
184     else:
185         action = "open"
186 
187     if level is None:
188         console.print(
189             f"Do you want to {action} the default config for this User?(y/n)[[n]]",
190             style="dim purple",
191             end="",
192         )
193         action_to_userpath = input()
194     else:
195         action_to_userpath = ""
196 
197     if action_to_userpath.lower() == "y" or level == "user":
198         cfg_file_path = config_paths[1]
199         guarantee_existence(config_paths[1].parents[0])
200         console.print(USER_CONFIG_MSG)
201     else:
202         cfg_file_path = config_paths[2]
203         guarantee_existence(config_paths[2].parents[0])
204         console.print(CWD_CONFIG_MSG)
205     with open(cfg_file_path, "w") as fp:
206         parser.write(fp)
207     if openfile:
208         open_file(cfg_file_path)
209 
210 
211 def show() -> None:
212     parser = make_config_parser()
213     rich_non_style_entries = [a.replace(".", "_") for a in RICH_NON_STYLE_ENTRIES]
214     for category in parser:
215         console.print(f"{category}", style="bold green underline")
216         for entry in parser[category]:
217             if category == "logger" and entry not in rich_non_style_entries:
218                 console.print(f"{entry} :", end="")
219                 console.print(
220                     f" {parser[category][entry]}",
221                     style=parser[category][entry],
222                 )
223             else:
224                 console.print(f"{entry} : {parser[category][entry]}")
225         console.print("\n")
226 
227 
228 def export(path):
229     if os.path.abspath(path) == os.path.abspath(os.getcwd()):
230         console.print(
231             """You are reading the config from the same directory you are exporting to.
232 This means that the exported config will overwrite the config for this directory.
233 Are you sure you want to continue? (y/n)""",
234             style="red bold",
235             end="",
236         )
237         proceed = True if input().lower() == "y" else False
238     else:
239         proceed = True
240     if proceed:
241         if not os.path.isdir(path):
242             console.print(f"Creating folder: {path}.", style="red bold")
243             os.mkdir(path)
244         with open(os.path.join(path, "manim.cfg"), "w") as outpath:
245             config.write(outpath)
246             from_path = os.path.join(os.getcwd(), "manim.cfg")
247             to_path = os.path.join(path, "manim.cfg")
248         console.print(f"Exported final Config at {from_path} to {to_path}.")
249     else:
250         console.print("Aborted...", style="red bold")
251
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/manim/_config/cfg_subcmds.py b/manim/_config/cfg_subcmds.py
--- a/manim/_config/cfg_subcmds.py
+++ b/manim/_config/cfg_subcmds.py
@@ -238,11 +238,12 @@
     else:
         proceed = True
     if proceed:
+        parser = make_config_parser()
         if not os.path.isdir(path):
             console.print(f"Creating folder: {path}.", style="red bold")
             os.mkdir(path)
         with open(os.path.join(path, "manim.cfg"), "w") as outpath:
-            config.write(outpath)
+            parser.write(outpath)
             from_path = os.path.join(os.getcwd(), "manim.cfg")
             to_path = os.path.join(path, "manim.cfg")
         console.print(f"Exported final Config at {from_path} to {to_path}.")

{"golden_diff": "diff --git a/manim/_config/cfg_subcmds.py b/manim/_config/cfg_subcmds.py\n--- a/manim/_config/cfg_subcmds.py\n+++ b/manim/_config/cfg_subcmds.py\n@@ -238,11 +238,12 @@\n     else:\n         proceed = True\n     if proceed:\n+        parser = make_config_parser()\n         if not os.path.isdir(path):\n             console.print(f\"Creating folder: {path}.\", style=\"red bold\")\n             os.mkdir(path)\n         with open(os.path.join(path, \"manim.cfg\"), \"w\") as outpath:\n-            config.write(outpath)\n+            parser.write(outpath)\n             from_path = os.path.join(os.getcwd(), \"manim.cfg\")\n             to_path = os.path.join(path, \"manim.cfg\")\n         console.print(f\"Exported final Config at {from_path} to {to_path}.\")\n", "issue": "ManimConfig Write Bug\n## Description of bug / unexpected behavior\r\n<!-- Add a clear and concise description of the problem you encountered. -->\r\n```\r\n(manim) C:\\Users\\a\\Documents\\repos\\ManimCommunity\\manim>manim cfg export\r\nYou are reading the config from the same directory you are exporting to.\r\nThis means that the exported config will overwrite the config for this directory.\r\nAre you sure you want to continue? (y/n)y\r\nTraceback (most recent call last):\r\n  File \"C:\\Users\\a\\anaconda3\\envs\\manim\\Scripts\\manim\", line 5, in <module>\r\n    main()\r\n  File \"C:\\Users\\a\\Documents\\repos\\ManimCommunity\\manim\\manim\\__main__.py\", line 65, in main\r\n    cfg_subcmds.export(args.dir)\r\n  File \"C:\\Users\\a\\Documents\\repos\\ManimCommunity\\manim\\manim\\_config\\cfg_subcmds.py\", line 245, in export\r\n    config.write(outpath)\r\nAttributeError: 'ManimConfig' object has no attribute 'write'\r\n```\r\n```\r\n(manim) C:\\Users\\a\\Documents\\repos\\ManimCommunity\\manim>manim cfg export --dir test\r\nCreating folder: test.\r\nTraceback (most recent call last):\r\n  File \"C:\\Users\\a\\anaconda3\\envs\\manim\\Scripts\\manim\", line 5, in <module>\r\n    main()\r\n  File \"C:\\Users\\a\\Documents\\repos\\ManimCommunity\\manim\\manim\\__main__.py\", line 65, in main\r\n    cfg_subcmds.export(args.dir)\r\n  File \"C:\\Users\\a\\Documents\\repos\\ManimCommunity\\manim\\manim\\_config\\cfg_subcmds.py\", line 245, in export\r\n    config.write(outpath)\r\nAttributeError: 'ManimConfig' object has no attribute 'write'\r\n\r\n```\r\n## Expected behavior\r\nA manim.cfg file populated at the specified directory (defaults to cwd).\r\n\r\n## How to reproduce the issue\r\n<!-- Provide a piece of code illustrating the undesired behavior. -->\r\nClone the master branch and run as I did in the CLI above:\r\n`manim cfg export`\r\n`manim cfg export --dir test`\r\n\r\n## System specifications\r\n- OS (with version, e.g Windows 10 v2004 or macOS 10.15 (Catalina)):\r\n\r\n## Additional comments\r\nThis also seems to be in the case in Ubuntu 20.04 as tested by @huguesdevimeux \r\n\n", "before_files": [{"content": "\"\"\"\ncfg_subcmd.py\n------------\n\nGeneral Config File Managing Utilities.\nThe functions below can be called via the `manim cfg` subcommand.\n\n\"\"\"\n\nimport os\nfrom ast import literal_eval\nfrom typing import Union\n\nfrom manim import config, console\nfrom manim._config.utils import config_file_paths, make_config_parser\nfrom manim.utils.file_ops import guarantee_existence, open_file\nfrom rich.errors import StyleSyntaxError\nfrom rich.style import Style\n\n__all__ = [\"write\", \"show\", \"export\"]\n\nRICH_COLOUR_INSTRUCTIONS: str = \"\"\"\n[red]The default colour is used by the input statement.\nIf left empty, the default colour will be used.[/red]\n[magenta] For a full list of styles, visit[/magenta] [green]https://rich.readthedocs.io/en/latest/style.html[/green]\n\"\"\"\nRICH_NON_STYLE_ENTRIES: str = [\"log.width\", \"log.height\", \"log.timestamps\"]\n\n\ndef value_from_string(value: str) -> Union[str, int, bool]:\n    \"\"\"Extracts the literal of proper datatype from a string.\n    Parameters\n    ----------\n    value : :class:`str`\n        The value to check get the literal from.\n\n    Returns\n    -------\n    Union[:class:`str`, :class:`int`, :class:`bool`]\n        Returns the literal of appropriate datatype.\n    \"\"\"\n    try:\n        value = literal_eval(value)\n    except (SyntaxError, ValueError):\n        pass\n    return value\n\n\ndef _is_expected_datatype(value: str, expected: str, style: bool = False) -> bool:\n    \"\"\"Checks whether `value` is the same datatype as `expected`,\n    and checks if it is a valid `style` if `style` is true.\n\n    Parameters\n    ----------\n    value : :class:`str`\n        The string of the value to check (obtained from reading the user input).\n    expected : :class:`str`\n        The string of the literal datatype must be matched by `value`. Obtained from\n        reading the cfg file.\n    style : :class:`bool`, optional\n        Whether or not to confirm if `value` is a style, by default False\n\n    Returns\n    -------\n    :class:`bool`\n        Whether or not `value` matches the datatype of `expected`.\n    \"\"\"\n    value = value_from_string(value)\n    expected = type(value_from_string(expected))\n\n    return isinstance(value, expected) and (is_valid_style(value) if style else True)\n\n\ndef is_valid_style(style: str) -> bool:\n    \"\"\"Checks whether the entered color is a valid color according to rich\n    Parameters\n    ----------\n    style : :class:`str`\n        The style to check whether it is valid.\n    Returns\n    -------\n    Boolean\n        Returns whether it is valid style or not according to rich.\n    \"\"\"\n    try:\n        Style.parse(style)\n        return True\n    except StyleSyntaxError:\n        return False\n\n\ndef replace_keys(default: dict) -> dict:\n    \"\"\"Replaces _ to . and vice versa in a dictionary for rich\n    Parameters\n    ----------\n    default : :class:`dict`\n        The dictionary to check and replace\n    Returns\n    -------\n    :class:`dict`\n        The dictionary which is modified by replacing _ with . and vice versa\n    \"\"\"\n    for key in default:\n        if \"_\" in key:\n            temp = default[key]\n            del default[key]\n            key = key.replace(\"_\", \".\")\n            default[key] = temp\n        else:\n            temp = default[key]\n            del default[key]\n            key = key.replace(\".\", \"_\")\n            default[key] = temp\n    return default\n\n\ndef write(level: str = None, openfile: bool = False) -> None:\n    config_paths = config_file_paths()\n    console.print(\n        \"[yellow bold]Manim Configuration File Writer[/yellow bold]\", justify=\"center\"\n    )\n\n    USER_CONFIG_MSG = f\"\"\"A configuration file at [yellow]{config_paths[1]}[/yellow] has been created with your required changes.\nThis will be used when running the manim command. If you want to override this config,\nyou will have to create a manim.cfg in the local directory, where you want those changes to be overridden.\"\"\"\n\n    CWD_CONFIG_MSG = f\"\"\"A configuration file at [yellow]{config_paths[2]}[/yellow] has been created.\nTo save your config please save that file and place it in your current working directory, from where you run the manim command.\"\"\"\n\n    parser = make_config_parser()\n    if not openfile:\n        action = \"save this as\"\n        for category in parser:\n            console.print(f\"{category}\", style=\"bold green underline\")\n            default = parser[category]\n            if category == \"logger\":\n                console.print(RICH_COLOUR_INSTRUCTIONS)\n                default = replace_keys(default)\n\n            for key in default:\n                # All the cfg entries for logger need to be validated as styles,\n                # as long as they arent setting the log width or height etc\n                if category == \"logger\" and key not in RICH_NON_STYLE_ENTRIES:\n                    desc = \"style\"\n                    style = default[key]\n                else:\n                    desc = \"value\"\n                    style = None\n\n                console.print(f\"Enter the {desc} for {key} \", style=style, end=\"\")\n                if category != \"logger\" or key in RICH_NON_STYLE_ENTRIES:\n                    defaultval = (\n                        repr(default[key])\n                        if isinstance(value_from_string(default[key]), str)\n                        else default[key]\n                    )\n                    console.print(f\"(defaults to {defaultval}) :\", end=\"\")\n                try:\n                    temp = input()\n                except EOFError:\n                    raise Exception(\n                        \"\"\"Not enough values in input.\nYou may have added a new entry to default.cfg, in which case you will have to\nmodify write_cfg_subcmd_input to account for it.\"\"\"\n                    )\n                if temp:\n                    while temp and not _is_expected_datatype(\n                        temp, default[key], bool(style)\n                    ):\n                        console.print(\n                            f\"[red bold]Invalid {desc}. Try again.[/red bold]\"\n                        )\n                        console.print(\n                            f\"Enter the {desc} for {key}:\", style=style, end=\"\"\n                        )\n                        temp = input()\n                    else:\n                        default[key] = temp\n\n            default = replace_keys(default) if category == \"logger\" else default\n\n            parser[category] = dict(default)\n\n    else:\n        action = \"open\"\n\n    if level is None:\n        console.print(\n            f\"Do you want to {action} the default config for this User?(y/n)[[n]]\",\n            style=\"dim purple\",\n            end=\"\",\n        )\n        action_to_userpath = input()\n    else:\n        action_to_userpath = \"\"\n\n    if action_to_userpath.lower() == \"y\" or level == \"user\":\n        cfg_file_path = config_paths[1]\n        guarantee_existence(config_paths[1].parents[0])\n        console.print(USER_CONFIG_MSG)\n    else:\n        cfg_file_path = config_paths[2]\n        guarantee_existence(config_paths[2].parents[0])\n        console.print(CWD_CONFIG_MSG)\n    with open(cfg_file_path, \"w\") as fp:\n        parser.write(fp)\n    if openfile:\n        open_file(cfg_file_path)\n\n\ndef show() -> None:\n    parser = make_config_parser()\n    rich_non_style_entries = [a.replace(\".\", \"_\") for a in RICH_NON_STYLE_ENTRIES]\n    for category in parser:\n        console.print(f\"{category}\", style=\"bold green underline\")\n        for entry in parser[category]:\n            if category == \"logger\" and entry not in rich_non_style_entries:\n                console.print(f\"{entry} :\", end=\"\")\n                console.print(\n                    f\" {parser[category][entry]}\",\n                    style=parser[category][entry],\n                )\n            else:\n                console.print(f\"{entry} : {parser[category][entry]}\")\n        console.print(\"\\n\")\n\n\ndef export(path):\n    if os.path.abspath(path) == os.path.abspath(os.getcwd()):\n        console.print(\n            \"\"\"You are reading the config from the same directory you are exporting to.\nThis means that the exported config will overwrite the config for this directory.\nAre you sure you want to continue? (y/n)\"\"\",\n            style=\"red bold\",\n            end=\"\",\n        )\n        proceed = True if input().lower() == \"y\" else False\n    else:\n        proceed = True\n    if proceed:\n        if not os.path.isdir(path):\n            console.print(f\"Creating folder: {path}.\", style=\"red bold\")\n            os.mkdir(path)\n        with open(os.path.join(path, \"manim.cfg\"), \"w\") as outpath:\n            config.write(outpath)\n            from_path = os.path.join(os.getcwd(), \"manim.cfg\")\n            to_path = os.path.join(path, \"manim.cfg\")\n        console.print(f\"Exported final Config at {from_path} to {to_path}.\")\n    else:\n        console.print(\"Aborted...\", style=\"red bold\")\n", "path": "manim/_config/cfg_subcmds.py"}], "after_files": [{"content": "\"\"\"\ncfg_subcmd.py\n------------\n\nGeneral Config File Managing Utilities.\nThe functions below can be called via the `manim cfg` subcommand.\n\n\"\"\"\n\nimport os\nfrom ast import literal_eval\nfrom typing import Union\n\nfrom manim import config, console\nfrom manim._config.utils import config_file_paths, make_config_parser\nfrom manim.utils.file_ops import guarantee_existence, open_file\nfrom rich.errors import StyleSyntaxError\nfrom rich.style import Style\n\n__all__ = [\"write\", \"show\", \"export\"]\n\nRICH_COLOUR_INSTRUCTIONS: str = \"\"\"\n[red]The default colour is used by the input statement.\nIf left empty, the default colour will be used.[/red]\n[magenta] For a full list of styles, visit[/magenta] [green]https://rich.readthedocs.io/en/latest/style.html[/green]\n\"\"\"\nRICH_NON_STYLE_ENTRIES: str = [\"log.width\", \"log.height\", \"log.timestamps\"]\n\n\ndef value_from_string(value: str) -> Union[str, int, bool]:\n    \"\"\"Extracts the literal of proper datatype from a string.\n    Parameters\n    ----------\n    value : :class:`str`\n        The value to check get the literal from.\n\n    Returns\n    -------\n    Union[:class:`str`, :class:`int`, :class:`bool`]\n        Returns the literal of appropriate datatype.\n    \"\"\"\n    try:\n        value = literal_eval(value)\n    except (SyntaxError, ValueError):\n        pass\n    return value\n\n\ndef _is_expected_datatype(value: str, expected: str, style: bool = False) -> bool:\n    \"\"\"Checks whether `value` is the same datatype as `expected`,\n    and checks if it is a valid `style` if `style` is true.\n\n    Parameters\n    ----------\n    value : :class:`str`\n        The string of the value to check (obtained from reading the user input).\n    expected : :class:`str`\n        The string of the literal datatype must be matched by `value`. Obtained from\n        reading the cfg file.\n    style : :class:`bool`, optional\n        Whether or not to confirm if `value` is a style, by default False\n\n    Returns\n    -------\n    :class:`bool`\n        Whether or not `value` matches the datatype of `expected`.\n    \"\"\"\n    value = value_from_string(value)\n    expected = type(value_from_string(expected))\n\n    return isinstance(value, expected) and (is_valid_style(value) if style else True)\n\n\ndef is_valid_style(style: str) -> bool:\n    \"\"\"Checks whether the entered color is a valid color according to rich\n    Parameters\n    ----------\n    style : :class:`str`\n        The style to check whether it is valid.\n    Returns\n    -------\n    Boolean\n        Returns whether it is valid style or not according to rich.\n    \"\"\"\n    try:\n        Style.parse(style)\n        return True\n    except StyleSyntaxError:\n        return False\n\n\ndef replace_keys(default: dict) -> dict:\n    \"\"\"Replaces _ to . and vice versa in a dictionary for rich\n    Parameters\n    ----------\n    default : :class:`dict`\n        The dictionary to check and replace\n    Returns\n    -------\n    :class:`dict`\n        The dictionary which is modified by replacing _ with . and vice versa\n    \"\"\"\n    for key in default:\n        if \"_\" in key:\n            temp = default[key]\n            del default[key]\n            key = key.replace(\"_\", \".\")\n            default[key] = temp\n        else:\n            temp = default[key]\n            del default[key]\n            key = key.replace(\".\", \"_\")\n            default[key] = temp\n    return default\n\n\ndef write(level: str = None, openfile: bool = False) -> None:\n    config_paths = config_file_paths()\n    console.print(\n        \"[yellow bold]Manim Configuration File Writer[/yellow bold]\", justify=\"center\"\n    )\n\n    USER_CONFIG_MSG = f\"\"\"A configuration file at [yellow]{config_paths[1]}[/yellow] has been created with your required changes.\nThis will be used when running the manim command. If you want to override this config,\nyou will have to create a manim.cfg in the local directory, where you want those changes to be overridden.\"\"\"\n\n    CWD_CONFIG_MSG = f\"\"\"A configuration file at [yellow]{config_paths[2]}[/yellow] has been created.\nTo save your config please save that file and place it in your current working directory, from where you run the manim command.\"\"\"\n\n    parser = make_config_parser()\n    if not openfile:\n        action = \"save this as\"\n        for category in parser:\n            console.print(f\"{category}\", style=\"bold green underline\")\n            default = parser[category]\n            if category == \"logger\":\n                console.print(RICH_COLOUR_INSTRUCTIONS)\n                default = replace_keys(default)\n\n            for key in default:\n                # All the cfg entries for logger need to be validated as styles,\n                # as long as they arent setting the log width or height etc\n                if category == \"logger\" and key not in RICH_NON_STYLE_ENTRIES:\n                    desc = \"style\"\n                    style = default[key]\n                else:\n                    desc = \"value\"\n                    style = None\n\n                console.print(f\"Enter the {desc} for {key} \", style=style, end=\"\")\n                if category != \"logger\" or key in RICH_NON_STYLE_ENTRIES:\n                    defaultval = (\n                        repr(default[key])\n                        if isinstance(value_from_string(default[key]), str)\n                        else default[key]\n                    )\n                    console.print(f\"(defaults to {defaultval}) :\", end=\"\")\n                try:\n                    temp = input()\n                except EOFError:\n                    raise Exception(\n                        \"\"\"Not enough values in input.\nYou may have added a new entry to default.cfg, in which case you will have to\nmodify write_cfg_subcmd_input to account for it.\"\"\"\n                    )\n                if temp:\n                    while temp and not _is_expected_datatype(\n                        temp, default[key], bool(style)\n                    ):\n                        console.print(\n                            f\"[red bold]Invalid {desc}. Try again.[/red bold]\"\n                        )\n                        console.print(\n                            f\"Enter the {desc} for {key}:\", style=style, end=\"\"\n                        )\n                        temp = input()\n                    else:\n                        default[key] = temp\n\n            default = replace_keys(default) if category == \"logger\" else default\n\n            parser[category] = dict(default)\n\n    else:\n        action = \"open\"\n\n    if level is None:\n        console.print(\n            f\"Do you want to {action} the default config for this User?(y/n)[[n]]\",\n            style=\"dim purple\",\n            end=\"\",\n        )\n        action_to_userpath = input()\n    else:\n        action_to_userpath = \"\"\n\n    if action_to_userpath.lower() == \"y\" or level == \"user\":\n        cfg_file_path = config_paths[1]\n        guarantee_existence(config_paths[1].parents[0])\n        console.print(USER_CONFIG_MSG)\n    else:\n        cfg_file_path = config_paths[2]\n        guarantee_existence(config_paths[2].parents[0])\n        console.print(CWD_CONFIG_MSG)\n    with open(cfg_file_path, \"w\") as fp:\n        parser.write(fp)\n    if openfile:\n        open_file(cfg_file_path)\n\n\ndef show() -> None:\n    parser = make_config_parser()\n    rich_non_style_entries = [a.replace(\".\", \"_\") for a in RICH_NON_STYLE_ENTRIES]\n    for category in parser:\n        console.print(f\"{category}\", style=\"bold green underline\")\n        for entry in parser[category]:\n            if category == \"logger\" and entry not in rich_non_style_entries:\n                console.print(f\"{entry} :\", end=\"\")\n                console.print(\n                    f\" {parser[category][entry]}\",\n                    style=parser[category][entry],\n                )\n            else:\n                console.print(f\"{entry} : {parser[category][entry]}\")\n        console.print(\"\\n\")\n\n\ndef export(path):\n    if os.path.abspath(path) == os.path.abspath(os.getcwd()):\n        console.print(\n            \"\"\"You are reading the config from the same directory you are exporting to.\nThis means that the exported config will overwrite the config for this directory.\nAre you sure you want to continue? (y/n)\"\"\",\n            style=\"red bold\",\n            end=\"\",\n        )\n        proceed = True if input().lower() == \"y\" else False\n    else:\n        proceed = True\n    if proceed:\n        parser = make_config_parser()\n        if not os.path.isdir(path):\n            console.print(f\"Creating folder: {path}.\", style=\"red bold\")\n            os.mkdir(path)\n        with open(os.path.join(path, \"manim.cfg\"), \"w\") as outpath:\n            parser.write(outpath)\n            from_path = os.path.join(os.getcwd(), \"manim.cfg\")\n            to_path = os.path.join(path, \"manim.cfg\")\n        console.print(f\"Exported final Config at {from_path} to {to_path}.\")\n    else:\n        console.print(\"Aborted...\", style=\"red bold\")\n", "path": "manim/_config/cfg_subcmds.py"}]}