We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
startproject only allows creating the project on an existing folder if the path is specified with an invalid module name
```
(venv) [adrian@afonsox temporal]$ mkdir existing_folder
(venv) [adrian@afonsox temporal]$ scrapy startproject existing_folder
Error: Module 'existing_folder' already exists
(venv) [adrian@afonsox temporal]$ cd existing_folder && scrapy startproject existing_folder .
New Scrapy project 'existing_folder', using template directory '/home/adrian/temporal/venv/lib/python3.8/site-packages/scrapy/templates/project', created in:
    /home/adrian/temporal/existing_folder

You can start your first spider with:
    cd .
    scrapy genspider example example.com
```

--- 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/commands/startproject.py`
Content:
```
1 import re
2 import os
3 import string
4 from importlib import import_module
5 from os.path import join, exists, abspath
6 from shutil import ignore_patterns, move, copy2, copystat
7 from stat import S_IWUSR as OWNER_WRITE_PERMISSION
8 
9 import scrapy
10 from scrapy.commands import ScrapyCommand
11 from scrapy.utils.template import render_templatefile, string_camelcase
12 from scrapy.exceptions import UsageError
13 
14 
15 TEMPLATES_TO_RENDER = (
16     ('scrapy.cfg',),
17     ('${project_name}', 'settings.py.tmpl'),
18     ('${project_name}', 'items.py.tmpl'),
19     ('${project_name}', 'pipelines.py.tmpl'),
20     ('${project_name}', 'middlewares.py.tmpl'),
21 )
22 
23 IGNORE = ignore_patterns('*.pyc', '__pycache__', '.svn')
24 
25 
26 def _make_writable(path):
27     current_permissions = os.stat(path).st_mode
28     os.chmod(path, current_permissions | OWNER_WRITE_PERMISSION)
29 
30 
31 class Command(ScrapyCommand):
32 
33     requires_project = False
34     default_settings = {'LOG_ENABLED': False,
35                         'SPIDER_LOADER_WARN_ONLY': True}
36 
37     def syntax(self):
38         return "<project_name> [project_dir]"
39 
40     def short_desc(self):
41         return "Create new project"
42 
43     def _is_valid_name(self, project_name):
44         def _module_exists(module_name):
45             try:
46                 import_module(module_name)
47                 return True
48             except ImportError:
49                 return False
50 
51         if not re.search(r'^[_a-zA-Z]\w*$', project_name):
52             print('Error: Project names must begin with a letter and contain'
53                   ' only\nletters, numbers and underscores')
54         elif _module_exists(project_name):
55             print(f'Error: Module {project_name!r} already exists')
56         else:
57             return True
58         return False
59 
60     def _copytree(self, src, dst):
61         """
62         Since the original function always creates the directory, to resolve
63         the issue a new function had to be created. It's a simple copy and
64         was reduced for this case.
65 
66         More info at:
67         https://github.com/scrapy/scrapy/pull/2005
68         """
69         ignore = IGNORE
70         names = os.listdir(src)
71         ignored_names = ignore(src, names)
72 
73         if not os.path.exists(dst):
74             os.makedirs(dst)
75 
76         for name in names:
77             if name in ignored_names:
78                 continue
79 
80             srcname = os.path.join(src, name)
81             dstname = os.path.join(dst, name)
82             if os.path.isdir(srcname):
83                 self._copytree(srcname, dstname)
84             else:
85                 copy2(srcname, dstname)
86                 _make_writable(dstname)
87 
88         copystat(src, dst)
89         _make_writable(dst)
90 
91     def run(self, args, opts):
92         if len(args) not in (1, 2):
93             raise UsageError()
94 
95         project_name = args[0]
96         project_dir = args[0]
97 
98         if len(args) == 2:
99             project_dir = args[1]
100 
101         if exists(join(project_dir, 'scrapy.cfg')):
102             self.exitcode = 1
103             print(f'Error: scrapy.cfg already exists in {abspath(project_dir)}')
104             return
105 
106         if not self._is_valid_name(project_name):
107             self.exitcode = 1
108             return
109 
110         self._copytree(self.templates_dir, abspath(project_dir))
111         move(join(project_dir, 'module'), join(project_dir, project_name))
112         for paths in TEMPLATES_TO_RENDER:
113             path = join(*paths)
114             tplfile = join(project_dir, string.Template(path).substitute(project_name=project_name))
115             render_templatefile(tplfile, project_name=project_name, ProjectName=string_camelcase(project_name))
116         print(f"New Scrapy project '{project_name}', using template directory "
117               f"'{self.templates_dir}', created in:")
118         print(f"    {abspath(project_dir)}\n")
119         print("You can start your first spider with:")
120         print(f"    cd {project_dir}")
121         print("    scrapy genspider example example.com")
122 
123     @property
124     def templates_dir(self):
125         return join(
126             self.settings['TEMPLATES_DIR'] or join(scrapy.__path__[0], 'templates'),
127             'project'
128         )
129
```
--- 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/commands/startproject.py b/scrapy/commands/startproject.py
--- a/scrapy/commands/startproject.py
+++ b/scrapy/commands/startproject.py
@@ -1,7 +1,7 @@
 import re
 import os
 import string
-from importlib import import_module
+from importlib.util import find_spec
 from os.path import join, exists, abspath
 from shutil import ignore_patterns, move, copy2, copystat
 from stat import S_IWUSR as OWNER_WRITE_PERMISSION
@@ -42,11 +42,8 @@
 
     def _is_valid_name(self, project_name):
         def _module_exists(module_name):
-            try:
-                import_module(module_name)
-                return True
-            except ImportError:
-                return False
+            spec = find_spec(module_name)
+            return spec is not None and spec.loader is not None
 
         if not re.search(r'^[_a-zA-Z]\w*$', project_name):
             print('Error: Project names must begin with a letter and contain'

{"golden_diff": "diff --git a/scrapy/commands/startproject.py b/scrapy/commands/startproject.py\n--- a/scrapy/commands/startproject.py\n+++ b/scrapy/commands/startproject.py\n@@ -1,7 +1,7 @@\n import re\n import os\n import string\n-from importlib import import_module\n+from importlib.util import find_spec\n from os.path import join, exists, abspath\n from shutil import ignore_patterns, move, copy2, copystat\n from stat import S_IWUSR as OWNER_WRITE_PERMISSION\n@@ -42,11 +42,8 @@\n \n     def _is_valid_name(self, project_name):\n         def _module_exists(module_name):\n-            try:\n-                import_module(module_name)\n-                return True\n-            except ImportError:\n-                return False\n+            spec = find_spec(module_name)\n+            return spec is not None and spec.loader is not None\n \n         if not re.search(r'^[_a-zA-Z]\\w*$', project_name):\n             print('Error: Project names must begin with a letter and contain'\n", "issue": "startproject only allows creating the project on an existing folder if the path is specified with an invalid module name\n```\r\n(venv) [adrian@afonsox temporal]$ mkdir existing_folder\r\n(venv) [adrian@afonsox temporal]$ scrapy startproject existing_folder\r\nError: Module 'existing_folder' already exists\r\n(venv) [adrian@afonsox temporal]$ cd existing_folder && scrapy startproject existing_folder .\r\nNew Scrapy project 'existing_folder', using template directory '/home/adrian/temporal/venv/lib/python3.8/site-packages/scrapy/templates/project', created in:\r\n    /home/adrian/temporal/existing_folder\r\n\r\nYou can start your first spider with:\r\n    cd .\r\n    scrapy genspider example example.com\r\n```\n", "before_files": [{"content": "import re\nimport os\nimport string\nfrom importlib import import_module\nfrom os.path import join, exists, abspath\nfrom shutil import ignore_patterns, move, copy2, copystat\nfrom stat import S_IWUSR as OWNER_WRITE_PERMISSION\n\nimport scrapy\nfrom scrapy.commands import ScrapyCommand\nfrom scrapy.utils.template import render_templatefile, string_camelcase\nfrom scrapy.exceptions import UsageError\n\n\nTEMPLATES_TO_RENDER = (\n    ('scrapy.cfg',),\n    ('${project_name}', 'settings.py.tmpl'),\n    ('${project_name}', 'items.py.tmpl'),\n    ('${project_name}', 'pipelines.py.tmpl'),\n    ('${project_name}', 'middlewares.py.tmpl'),\n)\n\nIGNORE = ignore_patterns('*.pyc', '__pycache__', '.svn')\n\n\ndef _make_writable(path):\n    current_permissions = os.stat(path).st_mode\n    os.chmod(path, current_permissions | OWNER_WRITE_PERMISSION)\n\n\nclass Command(ScrapyCommand):\n\n    requires_project = False\n    default_settings = {'LOG_ENABLED': False,\n                        'SPIDER_LOADER_WARN_ONLY': True}\n\n    def syntax(self):\n        return \"<project_name> [project_dir]\"\n\n    def short_desc(self):\n        return \"Create new project\"\n\n    def _is_valid_name(self, project_name):\n        def _module_exists(module_name):\n            try:\n                import_module(module_name)\n                return True\n            except ImportError:\n                return False\n\n        if not re.search(r'^[_a-zA-Z]\\w*$', project_name):\n            print('Error: Project names must begin with a letter and contain'\n                  ' only\\nletters, numbers and underscores')\n        elif _module_exists(project_name):\n            print(f'Error: Module {project_name!r} already exists')\n        else:\n            return True\n        return False\n\n    def _copytree(self, src, dst):\n        \"\"\"\n        Since the original function always creates the directory, to resolve\n        the issue a new function had to be created. It's a simple copy and\n        was reduced for this case.\n\n        More info at:\n        https://github.com/scrapy/scrapy/pull/2005\n        \"\"\"\n        ignore = IGNORE\n        names = os.listdir(src)\n        ignored_names = ignore(src, names)\n\n        if not os.path.exists(dst):\n            os.makedirs(dst)\n\n        for name in names:\n            if name in ignored_names:\n                continue\n\n            srcname = os.path.join(src, name)\n            dstname = os.path.join(dst, name)\n            if os.path.isdir(srcname):\n                self._copytree(srcname, dstname)\n            else:\n                copy2(srcname, dstname)\n                _make_writable(dstname)\n\n        copystat(src, dst)\n        _make_writable(dst)\n\n    def run(self, args, opts):\n        if len(args) not in (1, 2):\n            raise UsageError()\n\n        project_name = args[0]\n        project_dir = args[0]\n\n        if len(args) == 2:\n            project_dir = args[1]\n\n        if exists(join(project_dir, 'scrapy.cfg')):\n            self.exitcode = 1\n            print(f'Error: scrapy.cfg already exists in {abspath(project_dir)}')\n            return\n\n        if not self._is_valid_name(project_name):\n            self.exitcode = 1\n            return\n\n        self._copytree(self.templates_dir, abspath(project_dir))\n        move(join(project_dir, 'module'), join(project_dir, project_name))\n        for paths in TEMPLATES_TO_RENDER:\n            path = join(*paths)\n            tplfile = join(project_dir, string.Template(path).substitute(project_name=project_name))\n            render_templatefile(tplfile, project_name=project_name, ProjectName=string_camelcase(project_name))\n        print(f\"New Scrapy project '{project_name}', using template directory \"\n              f\"'{self.templates_dir}', created in:\")\n        print(f\"    {abspath(project_dir)}\\n\")\n        print(\"You can start your first spider with:\")\n        print(f\"    cd {project_dir}\")\n        print(\"    scrapy genspider example example.com\")\n\n    @property\n    def templates_dir(self):\n        return join(\n            self.settings['TEMPLATES_DIR'] or join(scrapy.__path__[0], 'templates'),\n            'project'\n        )\n", "path": "scrapy/commands/startproject.py"}], "after_files": [{"content": "import re\nimport os\nimport string\nfrom importlib.util import find_spec\nfrom os.path import join, exists, abspath\nfrom shutil import ignore_patterns, move, copy2, copystat\nfrom stat import S_IWUSR as OWNER_WRITE_PERMISSION\n\nimport scrapy\nfrom scrapy.commands import ScrapyCommand\nfrom scrapy.utils.template import render_templatefile, string_camelcase\nfrom scrapy.exceptions import UsageError\n\n\nTEMPLATES_TO_RENDER = (\n    ('scrapy.cfg',),\n    ('${project_name}', 'settings.py.tmpl'),\n    ('${project_name}', 'items.py.tmpl'),\n    ('${project_name}', 'pipelines.py.tmpl'),\n    ('${project_name}', 'middlewares.py.tmpl'),\n)\n\nIGNORE = ignore_patterns('*.pyc', '__pycache__', '.svn')\n\n\ndef _make_writable(path):\n    current_permissions = os.stat(path).st_mode\n    os.chmod(path, current_permissions | OWNER_WRITE_PERMISSION)\n\n\nclass Command(ScrapyCommand):\n\n    requires_project = False\n    default_settings = {'LOG_ENABLED': False,\n                        'SPIDER_LOADER_WARN_ONLY': True}\n\n    def syntax(self):\n        return \"<project_name> [project_dir]\"\n\n    def short_desc(self):\n        return \"Create new project\"\n\n    def _is_valid_name(self, project_name):\n        def _module_exists(module_name):\n            spec = find_spec(module_name)\n            return spec is not None and spec.loader is not None\n\n        if not re.search(r'^[_a-zA-Z]\\w*$', project_name):\n            print('Error: Project names must begin with a letter and contain'\n                  ' only\\nletters, numbers and underscores')\n        elif _module_exists(project_name):\n            print('Error: Module %r already exists' % project_name)\n        else:\n            return True\n        return False\n\n    def _copytree(self, src, dst):\n        \"\"\"\n        Since the original function always creates the directory, to resolve\n        the issue a new function had to be created. It's a simple copy and\n        was reduced for this case.\n\n        More info at:\n        https://github.com/scrapy/scrapy/pull/2005\n        \"\"\"\n        ignore = IGNORE\n        names = os.listdir(src)\n        ignored_names = ignore(src, names)\n\n        if not os.path.exists(dst):\n            os.makedirs(dst)\n\n        for name in names:\n            if name in ignored_names:\n                continue\n\n            srcname = os.path.join(src, name)\n            dstname = os.path.join(dst, name)\n            if os.path.isdir(srcname):\n                self._copytree(srcname, dstname)\n            else:\n                copy2(srcname, dstname)\n                _make_writable(dstname)\n\n        copystat(src, dst)\n        _make_writable(dst)\n\n    def run(self, args, opts):\n        if len(args) not in (1, 2):\n            raise UsageError()\n\n        project_name = args[0]\n        project_dir = args[0]\n\n        if len(args) == 2:\n            project_dir = args[1]\n\n        if exists(join(project_dir, 'scrapy.cfg')):\n            self.exitcode = 1\n            print('Error: scrapy.cfg already exists in %s' % abspath(project_dir))\n            return\n\n        if not self._is_valid_name(project_name):\n            self.exitcode = 1\n            return\n\n        self._copytree(self.templates_dir, abspath(project_dir))\n        move(join(project_dir, 'module'), join(project_dir, project_name))\n        for paths in TEMPLATES_TO_RENDER:\n            path = join(*paths)\n            tplfile = join(project_dir, string.Template(path).substitute(project_name=project_name))\n            render_templatefile(tplfile, project_name=project_name, ProjectName=string_camelcase(project_name))\n        print(\"New Scrapy project '%s', using template directory '%s', \"\n              \"created in:\" % (project_name, self.templates_dir))\n        print(\"    %s\\n\" % abspath(project_dir))\n        print(\"You can start your first spider with:\")\n        print(\"    cd %s\" % project_dir)\n        print(\"    scrapy genspider example example.com\")\n\n    @property\n    def templates_dir(self):\n        return join(\n            self.settings['TEMPLATES_DIR'] or join(scrapy.__path__[0], 'templates'),\n            'project'\n        )\n", "path": "scrapy/commands/startproject.py"}]}