We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Backward compatibility in utils.conf.build_component_list
There is some code from 2015 in `scrapy.utils.conf.build_component_list` marked as "Backward compatibility for old (base, custom) call signature", which was added in #1586. I couldn't understand after a quick glance why is it "backward compatibility" but if it's something deprecated we should deprecare it properly with a message, and if it's a properly supported code path we should remove the comments.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `scrapy/utils/conf.py`
Content:
```
1 import numbers
2 import os
3 import sys
4 import warnings
5 from configparser import ConfigParser
6 from operator import itemgetter
7 from pathlib import Path
8 from typing import Any, Dict, List, Optional, Union
9 
10 from scrapy.exceptions import ScrapyDeprecationWarning, UsageError
11 from scrapy.settings import BaseSettings
12 from scrapy.utils.deprecate import update_classpath
13 from scrapy.utils.python import without_none_values
14 
15 
16 def build_component_list(compdict, custom=None, convert=update_classpath):
17     """Compose a component list from a { class: order } dictionary."""
18 
19     def _check_components(complist):
20         if len({convert(c) for c in complist}) != len(complist):
21             raise ValueError(
22                 f"Some paths in {complist!r} convert to the same object, "
23                 "please update your settings"
24             )
25 
26     def _map_keys(compdict):
27         if isinstance(compdict, BaseSettings):
28             compbs = BaseSettings()
29             for k, v in compdict.items():
30                 prio = compdict.getpriority(k)
31                 assert prio is not None
32                 if compbs.getpriority(convert(k)) == prio:
33                     raise ValueError(
34                         f"Some paths in {list(compdict.keys())!r} "
35                         "convert to the same "
36                         "object, please update your settings"
37                     )
38                 else:
39                     compbs.set(convert(k), v, priority=prio)
40             return compbs
41         _check_components(compdict)
42         return {convert(k): v for k, v in compdict.items()}
43 
44     def _validate_values(compdict):
45         """Fail if a value in the components dict is not a real number or None."""
46         for name, value in compdict.items():
47             if value is not None and not isinstance(value, numbers.Real):
48                 raise ValueError(
49                     f"Invalid value {value} for component {name}, "
50                     "please provide a real number or None instead"
51                 )
52 
53     if isinstance(custom, (list, tuple)):
54         _check_components(custom)
55         return type(custom)(convert(c) for c in custom)
56 
57     if custom is not None:
58         compdict.update(custom)
59 
60     _validate_values(compdict)
61     compdict = without_none_values(_map_keys(compdict))
62     return [k for k, v in sorted(compdict.items(), key=itemgetter(1))]
63 
64 
65 def arglist_to_dict(arglist):
66     """Convert a list of arguments like ['arg1=val1', 'arg2=val2', ...] to a
67     dict
68     """
69     return dict(x.split("=", 1) for x in arglist)
70 
71 
72 def closest_scrapy_cfg(
73     path: Union[str, os.PathLike] = ".",
74     prevpath: Optional[Union[str, os.PathLike]] = None,
75 ) -> str:
76     """Return the path to the closest scrapy.cfg file by traversing the current
77     directory and its parents
78     """
79     if prevpath is not None and str(path) == str(prevpath):
80         return ""
81     path = Path(path).resolve()
82     cfgfile = path / "scrapy.cfg"
83     if cfgfile.exists():
84         return str(cfgfile)
85     return closest_scrapy_cfg(path.parent, path)
86 
87 
88 def init_env(project="default", set_syspath=True):
89     """Initialize environment to use command-line tool from inside a project
90     dir. This sets the Scrapy settings module and modifies the Python path to
91     be able to locate the project module.
92     """
93     cfg = get_config()
94     if cfg.has_option("settings", project):
95         os.environ["SCRAPY_SETTINGS_MODULE"] = cfg.get("settings", project)
96     closest = closest_scrapy_cfg()
97     if closest:
98         projdir = str(Path(closest).parent)
99         if set_syspath and projdir not in sys.path:
100             sys.path.append(projdir)
101 
102 
103 def get_config(use_closest=True):
104     """Get Scrapy config file as a ConfigParser"""
105     sources = get_sources(use_closest)
106     cfg = ConfigParser()
107     cfg.read(sources)
108     return cfg
109 
110 
111 def get_sources(use_closest=True) -> List[str]:
112     xdg_config_home = (
113         os.environ.get("XDG_CONFIG_HOME") or Path("~/.config").expanduser()
114     )
115     sources = [
116         "/etc/scrapy.cfg",
117         r"c:\scrapy\scrapy.cfg",
118         str(Path(xdg_config_home) / "scrapy.cfg"),
119         str(Path("~/.scrapy.cfg").expanduser()),
120     ]
121     if use_closest:
122         sources.append(closest_scrapy_cfg())
123     return sources
124 
125 
126 def feed_complete_default_values_from_settings(feed, settings):
127     out = feed.copy()
128     out.setdefault("batch_item_count", settings.getint("FEED_EXPORT_BATCH_ITEM_COUNT"))
129     out.setdefault("encoding", settings["FEED_EXPORT_ENCODING"])
130     out.setdefault("fields", settings.getdictorlist("FEED_EXPORT_FIELDS") or None)
131     out.setdefault("store_empty", settings.getbool("FEED_STORE_EMPTY"))
132     out.setdefault("uri_params", settings["FEED_URI_PARAMS"])
133     out.setdefault("item_export_kwargs", {})
134     if settings["FEED_EXPORT_INDENT"] is None:
135         out.setdefault("indent", None)
136     else:
137         out.setdefault("indent", settings.getint("FEED_EXPORT_INDENT"))
138     return out
139 
140 
141 def feed_process_params_from_cli(
142     settings,
143     output: List[str],
144     output_format=None,
145     overwrite_output: Optional[List[str]] = None,
146 ):
147     """
148     Receives feed export params (from the 'crawl' or 'runspider' commands),
149     checks for inconsistencies in their quantities and returns a dictionary
150     suitable to be used as the FEEDS setting.
151     """
152     valid_output_formats = without_none_values(
153         settings.getwithbase("FEED_EXPORTERS")
154     ).keys()
155 
156     def check_valid_format(output_format):
157         if output_format not in valid_output_formats:
158             raise UsageError(
159                 f"Unrecognized output format '{output_format}'. "
160                 f"Set a supported one ({tuple(valid_output_formats)}) "
161                 "after a colon at the end of the output URI (i.e. -o/-O "
162                 "<URI>:<FORMAT>) or as a file extension."
163             )
164 
165     overwrite = False
166     if overwrite_output:
167         if output:
168             raise UsageError(
169                 "Please use only one of -o/--output and -O/--overwrite-output"
170             )
171         if output_format:
172             raise UsageError(
173                 "-t/--output-format is a deprecated command line option"
174                 " and does not work in combination with -O/--overwrite-output."
175                 " To specify a format please specify it after a colon at the end of the"
176                 " output URI (i.e. -O <URI>:<FORMAT>)."
177                 " Example working in the tutorial: "
178                 "scrapy crawl quotes -O quotes.json:json"
179             )
180         output = overwrite_output
181         overwrite = True
182 
183     if output_format:
184         if len(output) == 1:
185             check_valid_format(output_format)
186             message = (
187                 "The -t/--output-format command line option is deprecated in favor of "
188                 "specifying the output format within the output URI using the -o/--output or the"
189                 " -O/--overwrite-output option (i.e. -o/-O <URI>:<FORMAT>). See the documentation"
190                 " of the -o or -O option or the following examples for more information. "
191                 "Examples working in the tutorial: "
192                 "scrapy crawl quotes -o quotes.csv:csv   or   "
193                 "scrapy crawl quotes -O quotes.json:json"
194             )
195             warnings.warn(message, ScrapyDeprecationWarning, stacklevel=2)
196             return {output[0]: {"format": output_format}}
197         raise UsageError(
198             "The -t command-line option cannot be used if multiple output "
199             "URIs are specified"
200         )
201 
202     result: Dict[str, Dict[str, Any]] = {}
203     for element in output:
204         try:
205             feed_uri, feed_format = element.rsplit(":", 1)
206             check_valid_format(feed_format)
207         except (ValueError, UsageError):
208             feed_uri = element
209             feed_format = Path(element).suffix.replace(".", "")
210         else:
211             if feed_uri == "-":
212                 feed_uri = "stdout:"
213         check_valid_format(feed_format)
214         result[feed_uri] = {"format": feed_format}
215         if overwrite:
216             result[feed_uri]["overwrite"] = True
217 
218     # FEEDS setting should take precedence over the matching CLI options
219     result.update(settings.getdict("FEEDS"))
220 
221     return result
222
```
--- 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/scrapy/utils/conf.py b/scrapy/utils/conf.py
--- a/scrapy/utils/conf.py
+++ b/scrapy/utils/conf.py
@@ -50,11 +50,17 @@
                     "please provide a real number or None instead"
                 )
 
-    if isinstance(custom, (list, tuple)):
-        _check_components(custom)
-        return type(custom)(convert(c) for c in custom)
-
     if custom is not None:
+        warnings.warn(
+            "The 'custom' attribute of build_component_list() is deprecated. "
+            "Please merge its value into 'compdict' manually or change your "
+            "code to use Settings.getwithbase().",
+            category=ScrapyDeprecationWarning,
+            stacklevel=2,
+        )
+        if isinstance(custom, (list, tuple)):
+            _check_components(custom)
+            return type(custom)(convert(c) for c in custom)
         compdict.update(custom)
 
     _validate_values(compdict)

{"golden_diff": "diff --git a/scrapy/utils/conf.py b/scrapy/utils/conf.py\n--- a/scrapy/utils/conf.py\n+++ b/scrapy/utils/conf.py\n@@ -50,11 +50,17 @@\n                     \"please provide a real number or None instead\"\n                 )\n \n-    if isinstance(custom, (list, tuple)):\n-        _check_components(custom)\n-        return type(custom)(convert(c) for c in custom)\n-\n     if custom is not None:\n+        warnings.warn(\n+            \"The 'custom' attribute of build_component_list() is deprecated. \"\n+            \"Please merge its value into 'compdict' manually or change your \"\n+            \"code to use Settings.getwithbase().\",\n+            category=ScrapyDeprecationWarning,\n+            stacklevel=2,\n+        )\n+        if isinstance(custom, (list, tuple)):\n+            _check_components(custom)\n+            return type(custom)(convert(c) for c in custom)\n         compdict.update(custom)\n \n     _validate_values(compdict)\n", "issue": "Backward compatibility in utils.conf.build_component_list\nThere is some code from 2015 in `scrapy.utils.conf.build_component_list` marked as \"Backward compatibility for old (base, custom) call signature\", which was added in #1586. I couldn't understand after a quick glance why is it \"backward compatibility\" but if it's something deprecated we should deprecare it properly with a message, and if it's a properly supported code path we should remove the comments.\n", "before_files": [{"content": "import numbers\nimport os\nimport sys\nimport warnings\nfrom configparser import ConfigParser\nfrom operator import itemgetter\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Optional, Union\n\nfrom scrapy.exceptions import ScrapyDeprecationWarning, UsageError\nfrom scrapy.settings import BaseSettings\nfrom scrapy.utils.deprecate import update_classpath\nfrom scrapy.utils.python import without_none_values\n\n\ndef build_component_list(compdict, custom=None, convert=update_classpath):\n    \"\"\"Compose a component list from a { class: order } dictionary.\"\"\"\n\n    def _check_components(complist):\n        if len({convert(c) for c in complist}) != len(complist):\n            raise ValueError(\n                f\"Some paths in {complist!r} convert to the same object, \"\n                \"please update your settings\"\n            )\n\n    def _map_keys(compdict):\n        if isinstance(compdict, BaseSettings):\n            compbs = BaseSettings()\n            for k, v in compdict.items():\n                prio = compdict.getpriority(k)\n                assert prio is not None\n                if compbs.getpriority(convert(k)) == prio:\n                    raise ValueError(\n                        f\"Some paths in {list(compdict.keys())!r} \"\n                        \"convert to the same \"\n                        \"object, please update your settings\"\n                    )\n                else:\n                    compbs.set(convert(k), v, priority=prio)\n            return compbs\n        _check_components(compdict)\n        return {convert(k): v for k, v in compdict.items()}\n\n    def _validate_values(compdict):\n        \"\"\"Fail if a value in the components dict is not a real number or None.\"\"\"\n        for name, value in compdict.items():\n            if value is not None and not isinstance(value, numbers.Real):\n                raise ValueError(\n                    f\"Invalid value {value} for component {name}, \"\n                    \"please provide a real number or None instead\"\n                )\n\n    if isinstance(custom, (list, tuple)):\n        _check_components(custom)\n        return type(custom)(convert(c) for c in custom)\n\n    if custom is not None:\n        compdict.update(custom)\n\n    _validate_values(compdict)\n    compdict = without_none_values(_map_keys(compdict))\n    return [k for k, v in sorted(compdict.items(), key=itemgetter(1))]\n\n\ndef arglist_to_dict(arglist):\n    \"\"\"Convert a list of arguments like ['arg1=val1', 'arg2=val2', ...] to a\n    dict\n    \"\"\"\n    return dict(x.split(\"=\", 1) for x in arglist)\n\n\ndef closest_scrapy_cfg(\n    path: Union[str, os.PathLike] = \".\",\n    prevpath: Optional[Union[str, os.PathLike]] = None,\n) -> str:\n    \"\"\"Return the path to the closest scrapy.cfg file by traversing the current\n    directory and its parents\n    \"\"\"\n    if prevpath is not None and str(path) == str(prevpath):\n        return \"\"\n    path = Path(path).resolve()\n    cfgfile = path / \"scrapy.cfg\"\n    if cfgfile.exists():\n        return str(cfgfile)\n    return closest_scrapy_cfg(path.parent, path)\n\n\ndef init_env(project=\"default\", set_syspath=True):\n    \"\"\"Initialize environment to use command-line tool from inside a project\n    dir. This sets the Scrapy settings module and modifies the Python path to\n    be able to locate the project module.\n    \"\"\"\n    cfg = get_config()\n    if cfg.has_option(\"settings\", project):\n        os.environ[\"SCRAPY_SETTINGS_MODULE\"] = cfg.get(\"settings\", project)\n    closest = closest_scrapy_cfg()\n    if closest:\n        projdir = str(Path(closest).parent)\n        if set_syspath and projdir not in sys.path:\n            sys.path.append(projdir)\n\n\ndef get_config(use_closest=True):\n    \"\"\"Get Scrapy config file as a ConfigParser\"\"\"\n    sources = get_sources(use_closest)\n    cfg = ConfigParser()\n    cfg.read(sources)\n    return cfg\n\n\ndef get_sources(use_closest=True) -> List[str]:\n    xdg_config_home = (\n        os.environ.get(\"XDG_CONFIG_HOME\") or Path(\"~/.config\").expanduser()\n    )\n    sources = [\n        \"/etc/scrapy.cfg\",\n        r\"c:\\scrapy\\scrapy.cfg\",\n        str(Path(xdg_config_home) / \"scrapy.cfg\"),\n        str(Path(\"~/.scrapy.cfg\").expanduser()),\n    ]\n    if use_closest:\n        sources.append(closest_scrapy_cfg())\n    return sources\n\n\ndef feed_complete_default_values_from_settings(feed, settings):\n    out = feed.copy()\n    out.setdefault(\"batch_item_count\", settings.getint(\"FEED_EXPORT_BATCH_ITEM_COUNT\"))\n    out.setdefault(\"encoding\", settings[\"FEED_EXPORT_ENCODING\"])\n    out.setdefault(\"fields\", settings.getdictorlist(\"FEED_EXPORT_FIELDS\") or None)\n    out.setdefault(\"store_empty\", settings.getbool(\"FEED_STORE_EMPTY\"))\n    out.setdefault(\"uri_params\", settings[\"FEED_URI_PARAMS\"])\n    out.setdefault(\"item_export_kwargs\", {})\n    if settings[\"FEED_EXPORT_INDENT\"] is None:\n        out.setdefault(\"indent\", None)\n    else:\n        out.setdefault(\"indent\", settings.getint(\"FEED_EXPORT_INDENT\"))\n    return out\n\n\ndef feed_process_params_from_cli(\n    settings,\n    output: List[str],\n    output_format=None,\n    overwrite_output: Optional[List[str]] = None,\n):\n    \"\"\"\n    Receives feed export params (from the 'crawl' or 'runspider' commands),\n    checks for inconsistencies in their quantities and returns a dictionary\n    suitable to be used as the FEEDS setting.\n    \"\"\"\n    valid_output_formats = without_none_values(\n        settings.getwithbase(\"FEED_EXPORTERS\")\n    ).keys()\n\n    def check_valid_format(output_format):\n        if output_format not in valid_output_formats:\n            raise UsageError(\n                f\"Unrecognized output format '{output_format}'. \"\n                f\"Set a supported one ({tuple(valid_output_formats)}) \"\n                \"after a colon at the end of the output URI (i.e. -o/-O \"\n                \"<URI>:<FORMAT>) or as a file extension.\"\n            )\n\n    overwrite = False\n    if overwrite_output:\n        if output:\n            raise UsageError(\n                \"Please use only one of -o/--output and -O/--overwrite-output\"\n            )\n        if output_format:\n            raise UsageError(\n                \"-t/--output-format is a deprecated command line option\"\n                \" and does not work in combination with -O/--overwrite-output.\"\n                \" To specify a format please specify it after a colon at the end of the\"\n                \" output URI (i.e. -O <URI>:<FORMAT>).\"\n                \" Example working in the tutorial: \"\n                \"scrapy crawl quotes -O quotes.json:json\"\n            )\n        output = overwrite_output\n        overwrite = True\n\n    if output_format:\n        if len(output) == 1:\n            check_valid_format(output_format)\n            message = (\n                \"The -t/--output-format command line option is deprecated in favor of \"\n                \"specifying the output format within the output URI using the -o/--output or the\"\n                \" -O/--overwrite-output option (i.e. -o/-O <URI>:<FORMAT>). See the documentation\"\n                \" of the -o or -O option or the following examples for more information. \"\n                \"Examples working in the tutorial: \"\n                \"scrapy crawl quotes -o quotes.csv:csv   or   \"\n                \"scrapy crawl quotes -O quotes.json:json\"\n            )\n            warnings.warn(message, ScrapyDeprecationWarning, stacklevel=2)\n            return {output[0]: {\"format\": output_format}}\n        raise UsageError(\n            \"The -t command-line option cannot be used if multiple output \"\n            \"URIs are specified\"\n        )\n\n    result: Dict[str, Dict[str, Any]] = {}\n    for element in output:\n        try:\n            feed_uri, feed_format = element.rsplit(\":\", 1)\n            check_valid_format(feed_format)\n        except (ValueError, UsageError):\n            feed_uri = element\n            feed_format = Path(element).suffix.replace(\".\", \"\")\n        else:\n            if feed_uri == \"-\":\n                feed_uri = \"stdout:\"\n        check_valid_format(feed_format)\n        result[feed_uri] = {\"format\": feed_format}\n        if overwrite:\n            result[feed_uri][\"overwrite\"] = True\n\n    # FEEDS setting should take precedence over the matching CLI options\n    result.update(settings.getdict(\"FEEDS\"))\n\n    return result\n", "path": "scrapy/utils/conf.py"}], "after_files": [{"content": "import numbers\nimport os\nimport sys\nimport warnings\nfrom configparser import ConfigParser\nfrom operator import itemgetter\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Optional, Union\n\nfrom scrapy.exceptions import ScrapyDeprecationWarning, UsageError\nfrom scrapy.settings import BaseSettings\nfrom scrapy.utils.deprecate import update_classpath\nfrom scrapy.utils.python import without_none_values\n\n\ndef build_component_list(compdict, custom=None, convert=update_classpath):\n    \"\"\"Compose a component list from a { class: order } dictionary.\"\"\"\n\n    def _check_components(complist):\n        if len({convert(c) for c in complist}) != len(complist):\n            raise ValueError(\n                f\"Some paths in {complist!r} convert to the same object, \"\n                \"please update your settings\"\n            )\n\n    def _map_keys(compdict):\n        if isinstance(compdict, BaseSettings):\n            compbs = BaseSettings()\n            for k, v in compdict.items():\n                prio = compdict.getpriority(k)\n                assert prio is not None\n                if compbs.getpriority(convert(k)) == prio:\n                    raise ValueError(\n                        f\"Some paths in {list(compdict.keys())!r} \"\n                        \"convert to the same \"\n                        \"object, please update your settings\"\n                    )\n                else:\n                    compbs.set(convert(k), v, priority=prio)\n            return compbs\n        _check_components(compdict)\n        return {convert(k): v for k, v in compdict.items()}\n\n    def _validate_values(compdict):\n        \"\"\"Fail if a value in the components dict is not a real number or None.\"\"\"\n        for name, value in compdict.items():\n            if value is not None and not isinstance(value, numbers.Real):\n                raise ValueError(\n                    f\"Invalid value {value} for component {name}, \"\n                    \"please provide a real number or None instead\"\n                )\n\n    if custom is not None:\n        warnings.warn(\n            \"The 'custom' attribute of build_component_list() is deprecated. \"\n            \"Please merge its value into 'compdict' manually or change your \"\n            \"code to use Settings.getwithbase().\",\n            category=ScrapyDeprecationWarning,\n            stacklevel=2,\n        )\n        if isinstance(custom, (list, tuple)):\n            _check_components(custom)\n            return type(custom)(convert(c) for c in custom)\n        compdict.update(custom)\n\n    _validate_values(compdict)\n    compdict = without_none_values(_map_keys(compdict))\n    return [k for k, v in sorted(compdict.items(), key=itemgetter(1))]\n\n\ndef arglist_to_dict(arglist):\n    \"\"\"Convert a list of arguments like ['arg1=val1', 'arg2=val2', ...] to a\n    dict\n    \"\"\"\n    return dict(x.split(\"=\", 1) for x in arglist)\n\n\ndef closest_scrapy_cfg(\n    path: Union[str, os.PathLike] = \".\",\n    prevpath: Optional[Union[str, os.PathLike]] = None,\n) -> str:\n    \"\"\"Return the path to the closest scrapy.cfg file by traversing the current\n    directory and its parents\n    \"\"\"\n    if prevpath is not None and str(path) == str(prevpath):\n        return \"\"\n    path = Path(path).resolve()\n    cfgfile = path / \"scrapy.cfg\"\n    if cfgfile.exists():\n        return str(cfgfile)\n    return closest_scrapy_cfg(path.parent, path)\n\n\ndef init_env(project=\"default\", set_syspath=True):\n    \"\"\"Initialize environment to use command-line tool from inside a project\n    dir. This sets the Scrapy settings module and modifies the Python path to\n    be able to locate the project module.\n    \"\"\"\n    cfg = get_config()\n    if cfg.has_option(\"settings\", project):\n        os.environ[\"SCRAPY_SETTINGS_MODULE\"] = cfg.get(\"settings\", project)\n    closest = closest_scrapy_cfg()\n    if closest:\n        projdir = str(Path(closest).parent)\n        if set_syspath and projdir not in sys.path:\n            sys.path.append(projdir)\n\n\ndef get_config(use_closest=True):\n    \"\"\"Get Scrapy config file as a ConfigParser\"\"\"\n    sources = get_sources(use_closest)\n    cfg = ConfigParser()\n    cfg.read(sources)\n    return cfg\n\n\ndef get_sources(use_closest=True) -> List[str]:\n    xdg_config_home = (\n        os.environ.get(\"XDG_CONFIG_HOME\") or Path(\"~/.config\").expanduser()\n    )\n    sources = [\n        \"/etc/scrapy.cfg\",\n        r\"c:\\scrapy\\scrapy.cfg\",\n        str(Path(xdg_config_home) / \"scrapy.cfg\"),\n        str(Path(\"~/.scrapy.cfg\").expanduser()),\n    ]\n    if use_closest:\n        sources.append(closest_scrapy_cfg())\n    return sources\n\n\ndef feed_complete_default_values_from_settings(feed, settings):\n    out = feed.copy()\n    out.setdefault(\"batch_item_count\", settings.getint(\"FEED_EXPORT_BATCH_ITEM_COUNT\"))\n    out.setdefault(\"encoding\", settings[\"FEED_EXPORT_ENCODING\"])\n    out.setdefault(\"fields\", settings.getdictorlist(\"FEED_EXPORT_FIELDS\") or None)\n    out.setdefault(\"store_empty\", settings.getbool(\"FEED_STORE_EMPTY\"))\n    out.setdefault(\"uri_params\", settings[\"FEED_URI_PARAMS\"])\n    out.setdefault(\"item_export_kwargs\", {})\n    if settings[\"FEED_EXPORT_INDENT\"] is None:\n        out.setdefault(\"indent\", None)\n    else:\n        out.setdefault(\"indent\", settings.getint(\"FEED_EXPORT_INDENT\"))\n    return out\n\n\ndef feed_process_params_from_cli(\n    settings,\n    output: List[str],\n    output_format=None,\n    overwrite_output: Optional[List[str]] = None,\n):\n    \"\"\"\n    Receives feed export params (from the 'crawl' or 'runspider' commands),\n    checks for inconsistencies in their quantities and returns a dictionary\n    suitable to be used as the FEEDS setting.\n    \"\"\"\n    valid_output_formats = without_none_values(\n        settings.getwithbase(\"FEED_EXPORTERS\")\n    ).keys()\n\n    def check_valid_format(output_format):\n        if output_format not in valid_output_formats:\n            raise UsageError(\n                f\"Unrecognized output format '{output_format}'. \"\n                f\"Set a supported one ({tuple(valid_output_formats)}) \"\n                \"after a colon at the end of the output URI (i.e. -o/-O \"\n                \"<URI>:<FORMAT>) or as a file extension.\"\n            )\n\n    overwrite = False\n    if overwrite_output:\n        if output:\n            raise UsageError(\n                \"Please use only one of -o/--output and -O/--overwrite-output\"\n            )\n        if output_format:\n            raise UsageError(\n                \"-t/--output-format is a deprecated command line option\"\n                \" and does not work in combination with -O/--overwrite-output.\"\n                \" To specify a format please specify it after a colon at the end of the\"\n                \" output URI (i.e. -O <URI>:<FORMAT>).\"\n                \" Example working in the tutorial: \"\n                \"scrapy crawl quotes -O quotes.json:json\"\n            )\n        output = overwrite_output\n        overwrite = True\n\n    if output_format:\n        if len(output) == 1:\n            check_valid_format(output_format)\n            message = (\n                \"The -t/--output-format command line option is deprecated in favor of \"\n                \"specifying the output format within the output URI using the -o/--output or the\"\n                \" -O/--overwrite-output option (i.e. -o/-O <URI>:<FORMAT>). See the documentation\"\n                \" of the -o or -O option or the following examples for more information. \"\n                \"Examples working in the tutorial: \"\n                \"scrapy crawl quotes -o quotes.csv:csv   or   \"\n                \"scrapy crawl quotes -O quotes.json:json\"\n            )\n            warnings.warn(message, ScrapyDeprecationWarning, stacklevel=2)\n            return {output[0]: {\"format\": output_format}}\n        raise UsageError(\n            \"The -t command-line option cannot be used if multiple output \"\n            \"URIs are specified\"\n        )\n\n    result: Dict[str, Dict[str, Any]] = {}\n    for element in output:\n        try:\n            feed_uri, feed_format = element.rsplit(\":\", 1)\n            check_valid_format(feed_format)\n        except (ValueError, UsageError):\n            feed_uri = element\n            feed_format = Path(element).suffix.replace(\".\", \"\")\n        else:\n            if feed_uri == \"-\":\n                feed_uri = \"stdout:\"\n        check_valid_format(feed_format)\n        result[feed_uri] = {\"format\": feed_format}\n        if overwrite:\n            result[feed_uri][\"overwrite\"] = True\n\n    # FEEDS setting should take precedence over the matching CLI options\n    result.update(settings.getdict(\"FEEDS\"))\n\n    return result\n", "path": "scrapy/utils/conf.py"}]}