Repository: spyder-ide/spyder

Issue:
FileNotFoundError generated for template.py
## Description

**What steps will reproduce the problem?**

1. 
2. 
3. 

**What is the expected output? What do you see instead?**


**Please provide any additional information below**

  File "C:\ProgramData\Anaconda3\envs\MyProjects\lib\site-packages\spyder\plugins\editor.py", line 1712, in new
    text, enc = encoding.read(self.TEMPLATE_PATH)
  File "C:\ProgramData\Anaconda3\envs\MyProjects\lib\site-packages\spyder\utils\encoding.py", line 243, in read
    text, encoding = decode( open(filename, 'rb').read() )
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\Edilbert\\.spyder-py3\\template.py'


## Version and main components

* Spyder Version: 3.2.4 
* Python Version: 3.6.3
* Qt Versions: 5.6.2, PyQt5 5.6 on Windows

## Dependencies
```
pyflakes >=0.6.0 :  1.6.0 (OK)
pycodestyle >=2.3:  2.3.1 (OK)
pygments >=2.0   :  2.2.0 (OK)
pandas >=0.13.1  :  0.20.3 (OK)
numpy >=1.7      :  1.13.3 (OK)
sphinx >=0.6.6   :  1.6.3 (OK)
rope >=0.9.4     :  0.10.5 (OK)
jedi >=0.9.0     :  0.10.2 (OK)
nbconvert >=4.0  :  5.3.1 (OK)
sympy >=0.7.3    :  None (NOK)
cython >=0.21    :  None (NOK)
qtconsole >=4.2.0:  4.3.1 (OK)
IPython >=4.0    :  6.1.0 (OK)
pylint >=0.25    :  1.7.4 (OK)

```



Discussion:
I'm still new to Spyder myself, but this (perhaps naively) appears at least partially recognizable. Was this just launching Spyder, or did you try to create a new file? A quick look at your error is sufficient to guess at the proximate cause: it would seem that spyder couldn't read the template file it uses to create a new file (normally located at `"C:\Users\[Username]\.spyder-py3\template.py"`; in this case Spyder is looking for it at `'C:\Users\Edilbert\.spyder-py3\template.py'`) and thus experienced an error. 

More detail (or really, any detail) about the circumstances during which this error occurred would likely be of help in diagnosing this further, and determining the root cause (as it could conceivably be that simply  something happened to just this file, or this is a symptom of some deeper issue with your Spyder install), and to start with you could report whether the file and directory in question exists, and (if at least the latter is true) creating a fresh file with that name with some dummy text and seeing if the problem (or what problem) reoccurs in the same circumstances.

Again, I'm new to Spyder so the actual problem may be something much deeper entirely, but hopefully this is of some help to get started.
@CAMGerlach-Baron, thanks for chiming in. I think you're right about the source of this error. My gut feeling tells me that this could be generated by an antivirus issue, which is removing the template file from the filesystem while Spyder is running.

I really don't have any other explanation for this...
@CAMGerlach-Baron, I think this is a Windows only issue and it happens when people installs Anaconda as Administrator on Windows and then runs it for a particular user.

Could you try to reproduce it with a clean config, please?
@ccordoba12 My current home machine is set up that way, Anaconda installed as admin/"For all users", and then running on the local account. I haven't seen this issue prior, so I logged in via a clean, non-admin user account I use for troubleshooting, different from the one I installed it on, and it didn't have any issue running spyder or creating/saving a new file either from the command line or Anaconda navigator. 

I can certainly go beyond this in testing, Would you like me to try installing Spyder in a fresh environment under that user account, and then trying again? Or should I do a complete uninstall of Anaconda and it when logged in as the clean non-Admin user, using my Admin rights to install, and then trying to run Spyder from that account? Given its a fairly big step, I want to be clear on the procedure you think most likely to reproduce it. Thanks!
I think this is a permissions error, so the problem should appear if you install Anaconda for your user as Admin, then try to use it with an unprivileged user.
Although I don't know if that's possible.
@ccordoba12 Okay thanks. It is indeed possible, as that is essentially what I did on my machine. I originally installed Anaconda with my admin account a few months back, use Spyder regularly with my normal account, and then just tried running Spyder with another clean, unprivileged user account and it worked just fine, and I've never seen this issue.

One thing I didn't try, which I can do when I get home tonight, is uninstall Anaconda with my admin account, then log in to the clean temp account, launch the installer, and then tell it to install for all users, elevating with UAC (like Windows ``sudo``) as need be (versus originally, when I was actually logged in to my admin account when I installed it, and first used it there). It could be something with the UAC substitute process giving the files the wrong permissions or ownership, or something. Other than that, I don't know.

Resolving patch:
diff --git a/spyder/plugins/editor.py b/spyder/plugins/editor.py
--- a/spyder/plugins/editor.py
+++ b/spyder/plugins/editor.py
@@ -1717,31 +1717,39 @@ def new(self, fname=None, editorstack=None, text=None):
         fname=<basestring> --> create file
         """
         # If no text is provided, create default content
-        if text is None:
+        empty = False
+        try:
+            if text is None:
+                default_content = True
+                text, enc = encoding.read(self.TEMPLATE_PATH)
+                enc_match = re.search(r'-*- coding: ?([a-z0-9A-Z\-]*) -*-',
+                                      text)
+                if enc_match:
+                    enc = enc_match.group(1)
+                # Initialize template variables
+                # Windows
+                username = encoding.to_unicode_from_fs(
+                                os.environ.get('USERNAME', ''))
+                # Linux, Mac OS X
+                if not username:
+                    username = encoding.to_unicode_from_fs(
+                                   os.environ.get('USER', '-'))
+                VARS = {
+                    'date': time.ctime(),
+                    'username': username,
+                }
+                try:
+                    text = text % VARS
+                except Exception:
+                    pass
+            else:
+                default_content = False
+                enc = encoding.read(self.TEMPLATE_PATH)[1]
+        except (IOError, OSError):
+            text = ''
+            enc = 'utf-8'
             default_content = True
-            text, enc = encoding.read(self.TEMPLATE_PATH)
-            enc_match = re.search(r'-*- coding: ?([a-z0-9A-Z\-]*) -*-', text)
-            if enc_match:
-                enc = enc_match.group(1)
-            # Initialize template variables
-            # Windows
-            username = encoding.to_unicode_from_fs(os.environ.get('USERNAME',
-                                                                  ''))
-            # Linux, Mac OS X
-            if not username:
-                username = encoding.to_unicode_from_fs(os.environ.get('USER',
-                                                                      '-'))
-            VARS = {
-                'date': time.ctime(),
-                'username': username,
-            }
-            try:
-                text = text % VARS
-            except:
-                pass
-        else:
-            default_content = False
-            enc = encoding.read(self.TEMPLATE_PATH)[1]
+            empty = True
 
         create_fname = lambda n: to_text_string(_("untitled")) + ("%d.py" % n)
         # Creating editor widget
@@ -1775,7 +1783,8 @@ def new(self, fname=None, editorstack=None, text=None):
         # Creating the editor widget in the first editorstack (the one that
         # can't be destroyed), then cloning this editor widget in all other
         # editorstacks:
-        finfo = self.editorstacks[0].new(fname, enc, text, default_content)
+        finfo = self.editorstacks[0].new(fname, enc, text, default_content,
+                                         empty)
         finfo.path = self.main.get_spyder_pythonpath()
         self._clone_file_everywhere(finfo)
         current_editor = current_es.set_current_filename(finfo.filename)
diff --git a/spyder/widgets/editor.py b/spyder/widgets/editor.py
--- a/spyder/widgets/editor.py
+++ b/spyder/widgets/editor.py
@@ -2221,14 +2221,16 @@ def send_to_help(self, qstr1, qstr2=None, qstr3=None, qstr4=None,
             editor = self.get_current_editor()
             editor.setFocus()
 
-    def new(self, filename, encoding, text, default_content=False):
+    def new(self, filename, encoding, text, default_content=False,
+            empty=False):
         """
         Create new filename with *encoding* and *text*
         """
         finfo = self.create_new_editor(filename, encoding, text,
                                        set_current=False, new=True)
         finfo.editor.set_cursor_position('eof')
-        finfo.editor.insert_text(os.linesep)
+        if not empty:
+            finfo.editor.insert_text(os.linesep)
         if default_content:
             finfo.default = True
             finfo.editor.document().setModified(False)


Test patch:
diff --git a/spyder/plugins/tests/test_editor.py b/spyder/plugins/tests/test_editor.py
--- a/spyder/plugins/tests/test_editor.py
+++ b/spyder/plugins/tests/test_editor.py
@@ -6,6 +6,8 @@
 """Tests for the Editor plugin."""
 
 # Standard library imports
+import os.path as osp
+import shutil
 
 # Third party imports
 import pytest
@@ -31,6 +33,10 @@ class MainMock(QWidget):
         def __getattr__(self, attr):
             if attr.endswith('actions'):
                 return []
+            elif attr == 'projects':
+                projects = Mock()
+                projects.get_active_project.return_value = None
+                return projects
             else:
                 return Mock()
 
@@ -69,3 +75,27 @@ def test_renamed_tree(setup_editor, mocker):
                                       dest='test/dir/file2.txt')
     assert editor.renamed.called_with(source='/test/directory/file4.rst',
                                       dest='test/dir/file4.rst')
+
+
+def test_no_template(setup_editor):
+    """
+    Test that new files can be opened when no template is found.
+    """
+    editor, qtbot = setup_editor
+
+    # Move template to another file to simulate the lack of it
+    template = editor.TEMPLATE_PATH
+    shutil.move(template, osp.join(osp.dirname(template), 'template.py.old'))
+
+    # Open a new file
+    editor.new()
+
+    # Get contents
+    code_editor = editor.get_focus_widget()
+    contents = code_editor.get_text('sof', 'eof')
+
+    # Assert contents are empty
+    assert not contents
+
+    # Revert template back
+    shutil.move(osp.join(osp.dirname(template), 'template.py.old'), template)