Repository: spyder-ide/spyder

Issue:
Spyder always opens a new instance
## Description of your problem

Spyder opens new instance without requesting one. This is a reminder. Details have been previously reported.



**What steps will reproduce the problem?**

1. From the command line, typing 'spyder filename.py' always opens a new instance of spyder, even when the opposite behaviour (i.e., 'use a single instance) is selected in the preferences. 

2. 
3. 

**What is the expected output? What do you see instead?**


**Please provide any additional information below**


## Versions and main components

* Spyder Version: 3.1.3
* Python Version:  Python 3.5.2 :: Anaconda custom (x86_64)
* Qt Version:   5.6.2  
* PyQt Version: PyQT5 5.6 on Darwin
* Operating system: Mac OS 10.12.3


## Dependencies




Discussion:
Could you fill the missing info in the issue report, i.e. Python, Qt and PyQt versions? Thanks!
okay -- have added this info.

Thanks a lot!
@ccordoba12 just a reminder, this bug still happens in 3.1.4 on Mac
Also happens on OpenSuse Tumbleweed
Qt 5.7.1
Spyder 3.1.4 (both python 2.7 and python 3.6 versions).
Fixing this seems to keep getting pushed back. The bug is still present in 3.2.  Will it really be fixed soon, or will it get pushed back again? :) 
@ccordoba12 3.2.3 is released, this issue still remains
Yeah, sorry about that. We'll take a look at this (for sure) in 3.2.4
Same issue here at 1 machine, while another has no issues.
Both machines run Ubuntu 16.04 with latest updates. Installed Spyder3 by pip update.

Machine with issues (multiple instances) runs:
- Spyder 3.2.3
- Python 3.5.2 64bits
- Qt 5.9.1
- PyQt 5.5.9 on Linux

Machine that will use only 1 instance:
- Spyder 3.2.3
- Python 3.5.2 64bits
- Qt 4.8.7, 
- PyQt4 (API v2) 4.11.4 on Linux
Thanks for the details @XtremeNova. Maybe it's an issue with Qt 5.9 (I thought it was only present in macOS).
I'm not having the issue, but wondering if it might be a problem with the lock file? Running this code in a new Python instance, while Spyder is running, might shed some light.
```python
>>> from spyder.config.base import get_conf_path
>>> from spyder.utils.external import lockfile
>>> from spyder.config.main import CONF
>>> 
>>> # First make sure the config is being read correctly, this should be True
... CONF.get('main', 'single_instance')
True
>>> 
>>> # Next, try to get a lockfile, this should be False if Spyder is already running
... lock_file = get_conf_path('spyder.lock')
>>> lock = lockfile.FilesystemLock(lock_file)
>>> lock.lock()
False
```
@gkvallis, @XtremeNova, @fayeshine, were any of you able to try the above code?
I'm very sorry but I'm going to leave this for 3.2.5. In the meantime, please answer to @avylove's request.
Below is what I get when running the code in a separate Jupyter window, when Spyder is running. The answer to the lock.lock() question is True

from spyder.config.base import get_conf_pat
from spyder.utils.external import lock file
from spyder.config.main import CONF
CONF.get('main', 'single_instance')
Out[4]: True
lock_file = get_conf_path('spyder.lock')
lock = lockfile.FilesystemLock(lock_file)
lock.lock()
Out[7]: True


_________

Prof. Geoffrey Vallis
College of Engineering, Mathematics and Physical Sciences,
University of Exeter
http://empslocal.ex.ac.uk/people/staff/gv219/

On 30 Sep 2017, at 3:50 am, Avram Lubkin <notifications@github.com<mailto:notifications@github.com>> wrote:


I'm not having the issue, but wondering if it might be a problem with the lock file? Running this code in a new Python instance, while Spyder is running, might shed some light.

>>> from spyder.config.base import get_conf_path
>>> from spyder.utils.external import lockfile
>>> from spyder.config.main import CONF
>>>
>>> # First make sure the config is being read correctly, this should be True
... CONF.get('main', 'single_instance')
True
>>>
>>> # Next, try to get a lockfile, this should be False if Spyder is already running
... lock_file = get_conf_path('spyder.lock')
>>> lock = lockfile.FilesystemLock(lock_file)
>>> lock.lock()
False

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<https://github.com/spyder-ide/spyder/issues/4186#issuecomment-333277464>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AG0cn5gcLynxsK-OvcHj0DleicgchkMHks5snax1gaJpZM4MI2iD>.


(Sorry, mail went into the Junk folder)
On the QT4 machine:
In [1]: from spyder.config.base import get_conf_path
   ...: from spyder.utils.external import lockfile
   ...: from spyder.config.main import CONF
   ...: 
   ...: # First make sure the config is being read correctly, this should be True
   ...: CONF.get('main', 'single_instance')
   ...: 
Out[1]: True
In [2]: lock_file = get_conf_path('spyder.lock')
   ...: lock = lockfile.FilesystemLock(lock_file)
   ...: lock.lock()
   ...: 
Out[2]: **False**
(Same answer if ran in a python terminal outside Spyder)

On the Qt5 machine (with the issue): True, **True**
(Same answer if ran in both Spyder instances, or an python terminal outside Spyder)
My guess is either the symlink isn't behaving as expected or the process doesn't show up with an expected name. Here are a few more things to try. Same as before, run this in a new Python instance while Spyder is running.

```python
>>> from spyder.config.base import get_conf_path
>>> import os
>>> import psutil
>>> 
>>> lock_file = get_conf_path('spyder.lock')
>>> 
>>> # Try to get the pid from the lockfile path (Fails if it doesn't exist)
... pid = os.readlink(lock_file)
>>> 
>>> # Get the process (Fails if process isn't running
... process = psutil.Process(int(pid))
>>> 
>>> # Get process name (Should be spyder or spyder3)
... process.name()
'spyder3'
>>> 
>>> # Get command line
... process.cmdline()
['/usr/bin/python3', '/usr/bin/spyder3']
```


Here’s my output:

from spyder.config.base import get_conf_path
import os
import psutil
lock_file = get_conf_path('spyder.lock')
pid = os.readlink(lock_file)
process = psutil.Process(int(pid))
process.name()
Out[6]: 'python'
process.cmdline()
Out[7]:
['/Users/gkv/anaconda/python.app/Contents/MacOS/python',
 '/Users/gkv/anaconda/bin/spyder']


On Oct 13, 2017, at 4:52 PM, Avram Lubkin <notifications@github.com<mailto:notifications@github.com>> wrote:


My guess is either the symlink isn't behaving as expected or the process doesn't show up with an expected name. Here are a few more things to try. Same as before, run this in a new Python instance while Spyder is running.

>>> from spyder.config.base import get_conf_path
>>> import os
>>> import psutil
>>>
>>> lock_file = get_conf_path('spyder.lock')
>>>
>>> # Try to get the pid from the lockfile path (Fails if it doesn't exist)
... pid = os.readlink(lock_file)
>>>
>>> # Get the process (Fails if process isn't running
... process = psutil.Process(int(pid))
>>>
>>> # Get process name (Should be spyder or spyder3)
... process.name()
'spyder3'
>>>
>>> # Get command line
... process.cmdline()
['/usr/bin/python3', '/usr/bin/spyder3']

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub<https://github.com/spyder-ide/spyder/issues/4186#issuecomment-336492551>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AG0cn3_QLe76g29BTLc2Spp5wFpmyNfuks5sr4dXgaJpZM4MI2iD>.


@ccordoba12 , for @gkvallis the process name is returned as 'python' and not 'spyder'. This will cause spyder.utils.external.lockfile.FilesystemLock.lock() to remove the old lock and create a new one. It's only checking for the name to be 'spyder' or 'spyder3'; or 'bootstrap.py' in the command line arguments. it'd be good to see what the other guys have, but perhaps a fix could be to check if the basename for the first two cmdline arguments is spyder or spyder3.

> perhaps a fix could be to check if the basename for the first two cmdline arguments is spyder or spyder3

Sounds good to me. Could you open a pull request for this? If you decide to make it, please do it against our `3.x` branch.

Resolving patch:
diff --git a/spyder/utils/external/lockfile.py b/spyder/utils/external/lockfile.py
--- a/spyder/utils/external/lockfile.py
+++ b/spyder/utils/external/lockfile.py
@@ -182,10 +182,12 @@ def lock(self):
                             conditions = ['spyder' in c.lower()
                                           for c in p.cmdline()]
                         else:
-                            conditions = [p.name() == 'spyder',
-                                          p.name() == 'spyder3']
-                        # For DEV
-                        conditions += ['bootstrap.py' in p.cmdline()]
+                            # Valid names for main script
+                            names = set(['spyder', 'spyder3', 'bootstrap.py'])
+                            # Check the first three command line arguments
+                            arguments = set(os.path.basename(arg)
+                                            for arg in p.cmdline()[:3])
+                            conditions = [names & arguments]
                         if not any(conditions):
                             raise(OSError(errno.ESRCH, 'No such process'))
                     except OSError as e:


Test patch: