Repository: microsoft/ptvsd

Issue:
ptvsd -m ... doesn't work for modules in current directory
Suppose we're in a folder that contains a file named `foo.py`. This works:
```
python -m foo
```
but this doesn't:
```
python -m ptvsd -m foo
```
It can be made to work if the folder is manually added to `PYTHONPATH`, but this shouldn't be necessary - the behavior of `ptvsd -m` should correspond exactly to the behavior of `python -m`.



Discussion:
This appears to be a pydevd limitation - ptvsd simply rewrites the arguments for pydevd, but this can be observed with pydevd alone. For example, this also doesn't work:
```
pydevd --port 5678 --client localhost --module --file foo:
```
@fabioz, can you clarify if this is by design? 
Of note, this does work:
```
python3 -c "import runpy; runpy.run_module('foo')"
```
as does this:
```
python3 -c "import runpy; runpy._run_module_as_main('foo', alter_argv=False)"
```

I found also this behavior but I think this was working in previous releases.  Did the new version introduce a bug ?  Now I need to add directory to PYTHONPATH to launch modules for debugging. Thanks. 
The package developer of VSCode's Python extension says the workaround proposed here (adding project folder to pythonpath) was the cause of another issue I encountered trying to use the VSCode/Python debugger: https://github.com/DonJayamanne/pythonVSCode/issues/1441
@MaxPowerWasTaken Is there a copy of that issue in https://github.com/Microsoft/vscode-python?  Getting a 404, looks like everything has been moved to that new repo.  Just got the debugger working for python modules by adding my project to the `PYTHONPATH`, but if it's just going to cause more issues down the road would like to weigh my options.  Thanks!
I wasn't able to reproduce it with the latest master (the only thing is that `ptvsd` required me to pass the `--host` and `--port` to run)... 

See shell output below:

```
(ptvsd) ~/Desktop/ptvsd_workspace$ echo "print('on module')" > foo.py
(ptvsd) ~/Desktop/ptvsd_workspace$ python --version
Python 3.6.5 :: Anaconda, Inc.
(ptvsd) ~/Desktop/ptvsd_workspace$ python -m foo
on module
(ptvsd) ~/Desktop/ptvsd_workspace$ python -m ptvsd -m foo
usage: python -m ptvsd [-h] [--nodebug] [--client] --host HOST --port PORT
                       [--multiprocess] [-m MODULE] [-c CODE] [--pid PID]
                       [--single-session] [--wait] [-V]
                       [filename]
python -m ptvsd: error: the following arguments are required: --host, --port
(ptvsd) ~/Desktop/ptvsd_workspace$ python -m ptvsd --host 127.0.0.1 --port 3456 -m foo
on module
(ptvsd) ~/Desktop/ptvsd_workspace$ source deactivate
~/Desktop/ptvsd_workspace$ source activate py27
(py27) ~/Desktop/ptvsd_workspace$ python --version
Python 2.7.15 :: Anaconda, Inc.
(py27) ~/Desktop/ptvsd_workspace$ python -m foo
on module
(py27) ~/Desktop/ptvsd_workspace$ python -m ptvsd --host 127.0.0.1 --port 3456 -m foo
on module
(py27) ~/Desktop/ptvsd_workspace$ 
```

So, it seems to work testing with Python 2.7 and 3.6 (on Linux) for me... are you doing something different or is this actually fixed on master? 

-- as a note, my `PYTHONPATH` is not including the current directory, I only included `ptvsd/src` for it to find `ptvsd`.
@mattyfresh yeah my other issue seems to have been deleted after it was closed with the suggestion not to include my project repo in the pythonpath, don't think the issue was moved to the Microsoft fork. But hey man if it's working for you I wouldn't sweat it.
I am having the same issue, and this did definitely work in a prior version.

I am able to work around for now by adding `"env": { "PYTHONPATH": "${workspaceRoot}"}` to launch.json configuration.

I am on version 2018.11.0 of the `ms-python.python` extension, and 1.29.1 of vscode.

Is this the wrong place to post this issue and should it be posted elsewhere?
Note: although `python -m ptvsd --host 127.0.0.1 --port 3456 -m foo` does work for me, a launch such as the one below didn't work (will investigate).

```
{
    "name": "Python: foo module",
    "type": "python",
    "request": "launch",
    "module": "foo",
    "console": "integratedTerminal",
}
```

Resolving patch:
diff --git a/src/ptvsd/_vendored/pydevd/pydevd.py b/src/ptvsd/_vendored/pydevd/pydevd.py
--- a/src/ptvsd/_vendored/pydevd/pydevd.py
+++ b/src/ptvsd/_vendored/pydevd/pydevd.py
@@ -1203,6 +1203,13 @@ def run(self, file, globals=None, locals=None, is_module=False, set_trace=True):
         module_name = None
         entry_point_fn = ''
         if is_module:
+            # When launching with `python -m <module>`, python automatically adds
+            # an empty path to the PYTHONPATH which resolves files in the current
+            # directory, so, depending how pydevd itself is launched, we may need
+            # to manually add such an entry to properly resolve modules in the
+            # current directory (see: https://github.com/Microsoft/ptvsd/issues/1010).
+            if '' not in sys.path:
+                sys.path.insert(0, '')
             file, _,  entry_point_fn = file.partition(':')
             module_name = file
             filename = get_fullname(file)


Test patch:
diff --git a/src/ptvsd/_vendored/pydevd/tests_python/test_run.py b/src/ptvsd/_vendored/pydevd/tests_python/test_run.py
--- a/src/ptvsd/_vendored/pydevd/tests_python/test_run.py
+++ b/src/ptvsd/_vendored/pydevd/tests_python/test_run.py
@@ -2,10 +2,11 @@
     str('_pytest.pytester'),
 ]
 
-def _run_and_check(testdir, path):
+
+def _run_and_check(testdir, path, check_for='Worked'):
     result = testdir.runpython(path)
     result.stdout.fnmatch_lines([
-        'Worked'
+        check_for
     ])
 
 def test_run(testdir):
@@ -63,3 +64,41 @@ def test_run(testdir):
 py_db.run(%(foo_module)r, is_module=True, set_trace=False)
 ''' % locals()))
 
+
+def test_run_on_local_module_without_adding_to_pythonpath(testdir):
+    import sys
+    import os
+
+    pydevd_dir = os.path.dirname(os.path.dirname(__file__))
+    assert os.path.exists(os.path.join(pydevd_dir, 'pydevd.py'))
+
+    foo_module = 'local_foo'
+    with open(os.path.join(os.getcwd(), 'local_foo.py'), 'w') as stream:
+        stream.write('print("WorkedLocalFoo")')
+
+    _run_and_check(testdir, testdir.makepyfile('''
+import sys
+import os
+sys.path.append(%(pydevd_dir)r)
+sys.argv.append('--as-module')
+cwd = os.path.abspath(os.getcwd())
+while cwd in sys.path:
+    sys.path.remove(cwd)
+import pydevd
+py_db = pydevd.PyDB()
+py_db.ready_to_run = True
+py_db.run(%(foo_module)r, is_module=True)
+''' % locals()), check_for='WorkedLocalFoo')
+
+    _run_and_check(testdir, testdir.makepyfile('''
+import sys
+import os
+sys.argv.append('--as-module')
+sys.path.append(%(pydevd_dir)r)
+cwd = os.path.abspath(os.getcwd())
+while cwd in sys.path:
+    sys.path.remove(cwd)
+import pydevd
+py_db = pydevd.PyDB()
+py_db.run(%(foo_module)r, is_module=True, set_trace=False)
+''' % locals()), check_for='WorkedLocalFoo')