prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Launching a Python module using `-m` with `ptvsd.enable_attach` in __init__ fails
  ## Environment data
  
  - PTVSD version: Master
  - OS and version: Mac (may not be OS specific)
  - Python version (& distribution if applicable, e.g. Anaconda): 3.6
  - Using VS Code or Visual Studio:N/A
  
  ## Actual behavior
  
  ```
  Traceback (most recent call last):
    File "/Users/donjayamanne/Desktop/Development/vscode/ptvsd/tests/resources/system_tests/test_exceptions/mymod_attach1/__init__.py", line 4, in <module>
      ptvsd.enable_attach((sys.argv[1], sys.argv[2]))
    File "/Users/donjayamanne/Desktop/Development/vscode/ptvsd/ptvsd/attach_server.py", line 71, in enable_attach
      redirect_output=redirect_output,
    File "/Users/donjayamanne/Desktop/Development/vscode/ptvsd/ptvsd/_remote.py", line 27, in enable_attach
      **kwargs
    File "/Users/donjayamanne/Desktop/Development/vscode/ptvsd/ptvsd/pydevd_hooks.py", line 95, in install
      if __main__ is not pydevd and __main__.__file__ == pydevd.__file__:
  AttributeError: module '__main__' has no attribute '__file__'
  ```
  
  ## Expected  behavior
  
  Should not error out
  
  ## Steps to reproduce:
  
  * Create a python module
  * Add the following code in the `__init__.py`
  ```python
  import sys
  import ptvsd
  ptvsd.enable_attach(('localhost', 9876))
  ptvsd.wait_for_attach()
  
  try:
      raise ArithmeticError('Hello')
  except Exception:
      pass
  sys.stdout.write('end')
  ```
  * Start the module `python -m xyz`
  That's when it goes kaboom
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `ptvsd/pydevd_hooks.py`
  Content:
  ```
  1 import sys
  2 
  3 from _pydevd_bundle import pydevd_comm
  4 
  5 from ptvsd.socket import Address
  6 from ptvsd.daemon import Daemon, DaemonStoppedError, DaemonClosedError
  7 from ptvsd._util import debug, new_hidden_thread
  8 
  9 
  10 def start_server(daemon, host, port, **kwargs):
  11     """Return a socket to a (new) local pydevd-handling daemon.
  12 
  13     The daemon supports the pydevd client wire protocol, sending
  14     requests and handling responses (and events).
  15 
  16     This is a replacement for _pydevd_bundle.pydevd_comm.start_server.
  17     """
  18     sock, next_session = daemon.start_server((host, port))
  19 
  20     def handle_next():
  21         try:
  22             session = next_session(**kwargs)
  23             debug('done waiting')
  24             return session
  25         except (DaemonClosedError, DaemonStoppedError):
  26             # Typically won't happen.
  27             debug('stopped')
  28             raise
  29         except Exception as exc:
  30             # TODO: log this?
  31             debug('failed:', exc, tb=True)
  32             return None
  33 
  34     while True:
  35         debug('waiting on initial connection')
  36         handle_next()
  37         break
  38 
  39     def serve_forever():
  40         while True:
  41             debug('waiting on next connection')
  42             try:
  43                 handle_next()
  44             except (DaemonClosedError, DaemonStoppedError):
  45                 break
  46         debug('done')
  47 
  48     t = new_hidden_thread(
  49         target=serve_forever,
  50         name='sessions',
  51     )
  52     t.start()
  53     return sock
  54 
  55 
  56 def start_client(daemon, host, port, **kwargs):
  57     """Return a socket to an existing "remote" pydevd-handling daemon.
  58 
  59     The daemon supports the pydevd client wire protocol, sending
  60     requests and handling responses (and events).
  61 
  62     This is a replacement for _pydevd_bundle.pydevd_comm.start_client.
  63     """
  64     sock, start_session = daemon.start_client((host, port))
  65     start_session(**kwargs)
  66     return sock
  67 
  68 
  69 def install(pydevd, address,
  70             start_server=start_server, start_client=start_client,
  71             **kwargs):
  72     """Configure pydevd to use our wrapper.
  73 
  74     This is a bit of a hack to allow us to run our VSC debug adapter
  75     in the same process as pydevd.  Note that, as with most hacks,
  76     this is somewhat fragile (since the monkeypatching sites may
  77     change).
  78     """
  79     addr = Address.from_raw(address)
  80     daemon = Daemon(**kwargs)
  81 
  82     _start_server = (lambda p: start_server(daemon, addr.host, p))
  83     _start_server.orig = start_server
  84     _start_client = (lambda h, p: start_client(daemon, h, p))
  85     _start_client.orig = start_client
  86 
  87     # These are the functions pydevd invokes to get a socket to the client.
  88     pydevd_comm.start_server = _start_server
  89     pydevd_comm.start_client = _start_client
  90 
  91     # Ensure that pydevd is using our functions.
  92     pydevd.start_server = _start_server
  93     pydevd.start_client = _start_client
  94     __main__ = sys.modules['__main__']
  95     if __main__ is not pydevd and __main__.__file__ == pydevd.__file__:
  96         __main__.start_server = _start_server
  97         __main__.start_client = _start_client
  98     return daemon
  99
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/ptvsd/pydevd_hooks.py b/ptvsd/pydevd_hooks.py
  --- a/ptvsd/pydevd_hooks.py
  +++ b/ptvsd/pydevd_hooks.py
  @@ -92,7 +92,8 @@
       pydevd.start_server = _start_server
       pydevd.start_client = _start_client
       __main__ = sys.modules['__main__']
  -    if __main__ is not pydevd and __main__.__file__ == pydevd.__file__:
  -        __main__.start_server = _start_server
  -        __main__.start_client = _start_client
  +    if __main__ is not pydevd:
  +        if getattr(__main__, '__file__', None) == pydevd.__file__:
  +            __main__.start_server = _start_server
  +            __main__.start_client = _start_client
       return daemon
  
verification_info: {"golden_diff": "diff --git a/ptvsd/pydevd_hooks.py b/ptvsd/pydevd_hooks.py\n--- a/ptvsd/pydevd_hooks.py\n+++ b/ptvsd/pydevd_hooks.py\n@@ -92,7 +92,8 @@\n     pydevd.start_server = _start_server\n     pydevd.start_client = _start_client\n     __main__ = sys.modules['__main__']\n-    if __main__ is not pydevd and __main__.__file__ == pydevd.__file__:\n-        __main__.start_server = _start_server\n-        __main__.start_client = _start_client\n+    if __main__ is not pydevd:\n+        if getattr(__main__, '__file__', None) == pydevd.__file__:\n+            __main__.start_server = _start_server\n+            __main__.start_client = _start_client\n     return daemon\n", "issue": "Launching a Python module using `-m` with `ptvsd.enable_attach` in __init__ fails\n## Environment data\r\n\r\n- PTVSD version: Master\r\n- OS and version: Mac (may not be OS specific)\r\n- Python version (& distribution if applicable, e.g. Anaconda): 3.6\r\n- Using VS Code or Visual Studio:N/A\r\n\r\n## Actual behavior\r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"/Users/donjayamanne/Desktop/Development/vscode/ptvsd/tests/resources/system_tests/test_exceptions/mymod_attach1/__init__.py\", line 4, in <module>\r\n    ptvsd.enable_attach((sys.argv[1], sys.argv[2]))\r\n  File \"/Users/donjayamanne/Desktop/Development/vscode/ptvsd/ptvsd/attach_server.py\", line 71, in enable_attach\r\n    redirect_output=redirect_output,\r\n  File \"/Users/donjayamanne/Desktop/Development/vscode/ptvsd/ptvsd/_remote.py\", line 27, in enable_attach\r\n    **kwargs\r\n  File \"/Users/donjayamanne/Desktop/Development/vscode/ptvsd/ptvsd/pydevd_hooks.py\", line 95, in install\r\n    if __main__ is not pydevd and __main__.__file__ == pydevd.__file__:\r\nAttributeError: module '__main__' has no attribute '__file__'\r\n```\r\n\r\n## Expected  behavior\r\n\r\nShould not error out\r\n\r\n## Steps to reproduce:\r\n\r\n* Create a python module\r\n* Add the following code in the `__init__.py`\r\n```python\r\nimport sys\r\nimport ptvsd\r\nptvsd.enable_attach(('localhost', 9876))\r\nptvsd.wait_for_attach()\r\n\r\ntry:\r\n    raise ArithmeticError('Hello')\r\nexcept Exception:\r\n    pass\r\nsys.stdout.write('end')\r\n```\r\n* Start the module `python -m xyz`\r\nThat's when it goes kaboom\n", "before_files": [{"content": "import sys\n\nfrom _pydevd_bundle import pydevd_comm\n\nfrom ptvsd.socket import Address\nfrom ptvsd.daemon import Daemon, DaemonStoppedError, DaemonClosedError\nfrom ptvsd._util import debug, new_hidden_thread\n\n\ndef start_server(daemon, host, port, **kwargs):\n    \"\"\"Return a socket to a (new) local pydevd-handling daemon.\n\n    The daemon supports the pydevd client wire protocol, sending\n    requests and handling responses (and events).\n\n    This is a replacement for _pydevd_bundle.pydevd_comm.start_server.\n    \"\"\"\n    sock, next_session = daemon.start_server((host, port))\n\n    def handle_next():\n        try:\n            session = next_session(**kwargs)\n            debug('done waiting')\n            return session\n        except (DaemonClosedError, DaemonStoppedError):\n            # Typically won't happen.\n            debug('stopped')\n            raise\n        except Exception as exc:\n            # TODO: log this?\n            debug('failed:', exc, tb=True)\n            return None\n\n    while True:\n        debug('waiting on initial connection')\n        handle_next()\n        break\n\n    def serve_forever():\n        while True:\n            debug('waiting on next connection')\n            try:\n                handle_next()\n            except (DaemonClosedError, DaemonStoppedError):\n                break\n        debug('done')\n\n    t = new_hidden_thread(\n        target=serve_forever,\n        name='sessions',\n    )\n    t.start()\n    return sock\n\n\ndef start_client(daemon, host, port, **kwargs):\n    \"\"\"Return a socket to an existing \"remote\" pydevd-handling daemon.\n\n    The daemon supports the pydevd client wire protocol, sending\n    requests and handling responses (and events).\n\n    This is a replacement for _pydevd_bundle.pydevd_comm.start_client.\n    \"\"\"\n    sock, start_session = daemon.start_client((host, port))\n    start_session(**kwargs)\n    return sock\n\n\ndef install(pydevd, address,\n            start_server=start_server, start_client=start_client,\n            **kwargs):\n    \"\"\"Configure pydevd to use our wrapper.\n\n    This is a bit of a hack to allow us to run our VSC debug adapter\n    in the same process as pydevd.  Note that, as with most hacks,\n    this is somewhat fragile (since the monkeypatching sites may\n    change).\n    \"\"\"\n    addr = Address.from_raw(address)\n    daemon = Daemon(**kwargs)\n\n    _start_server = (lambda p: start_server(daemon, addr.host, p))\n    _start_server.orig = start_server\n    _start_client = (lambda h, p: start_client(daemon, h, p))\n    _start_client.orig = start_client\n\n    # These are the functions pydevd invokes to get a socket to the client.\n    pydevd_comm.start_server = _start_server\n    pydevd_comm.start_client = _start_client\n\n    # Ensure that pydevd is using our functions.\n    pydevd.start_server = _start_server\n    pydevd.start_client = _start_client\n    __main__ = sys.modules['__main__']\n    if __main__ is not pydevd and __main__.__file__ == pydevd.__file__:\n        __main__.start_server = _start_server\n        __main__.start_client = _start_client\n    return daemon\n", "path": "ptvsd/pydevd_hooks.py"}], "after_files": [{"content": "import sys\n\nfrom _pydevd_bundle import pydevd_comm\n\nfrom ptvsd.socket import Address\nfrom ptvsd.daemon import Daemon, DaemonStoppedError, DaemonClosedError\nfrom ptvsd._util import debug, new_hidden_thread\n\n\ndef start_server(daemon, host, port, **kwargs):\n    \"\"\"Return a socket to a (new) local pydevd-handling daemon.\n\n    The daemon supports the pydevd client wire protocol, sending\n    requests and handling responses (and events).\n\n    This is a replacement for _pydevd_bundle.pydevd_comm.start_server.\n    \"\"\"\n    sock, next_session = daemon.start_server((host, port))\n\n    def handle_next():\n        try:\n            session = next_session(**kwargs)\n            debug('done waiting')\n            return session\n        except (DaemonClosedError, DaemonStoppedError):\n            # Typically won't happen.\n            debug('stopped')\n            raise\n        except Exception as exc:\n            # TODO: log this?\n            debug('failed:', exc, tb=True)\n            return None\n\n    while True:\n        debug('waiting on initial connection')\n        handle_next()\n        break\n\n    def serve_forever():\n        while True:\n            debug('waiting on next connection')\n            try:\n                handle_next()\n            except (DaemonClosedError, DaemonStoppedError):\n                break\n        debug('done')\n\n    t = new_hidden_thread(\n        target=serve_forever,\n        name='sessions',\n    )\n    t.start()\n    return sock\n\n\ndef start_client(daemon, host, port, **kwargs):\n    \"\"\"Return a socket to an existing \"remote\" pydevd-handling daemon.\n\n    The daemon supports the pydevd client wire protocol, sending\n    requests and handling responses (and events).\n\n    This is a replacement for _pydevd_bundle.pydevd_comm.start_client.\n    \"\"\"\n    sock, start_session = daemon.start_client((host, port))\n    start_session(**kwargs)\n    return sock\n\n\ndef install(pydevd, address,\n            start_server=start_server, start_client=start_client,\n            **kwargs):\n    \"\"\"Configure pydevd to use our wrapper.\n\n    This is a bit of a hack to allow us to run our VSC debug adapter\n    in the same process as pydevd.  Note that, as with most hacks,\n    this is somewhat fragile (since the monkeypatching sites may\n    change).\n    \"\"\"\n    addr = Address.from_raw(address)\n    daemon = Daemon(**kwargs)\n\n    _start_server = (lambda p: start_server(daemon, addr.host, p))\n    _start_server.orig = start_server\n    _start_client = (lambda h, p: start_client(daemon, h, p))\n    _start_client.orig = start_client\n\n    # These are the functions pydevd invokes to get a socket to the client.\n    pydevd_comm.start_server = _start_server\n    pydevd_comm.start_client = _start_client\n\n    # Ensure that pydevd is using our functions.\n    pydevd.start_server = _start_server\n    pydevd.start_client = _start_client\n    __main__ = sys.modules['__main__']\n    if __main__ is not pydevd:\n        if getattr(__main__, '__file__', None) == pydevd.__file__:\n            __main__.start_server = _start_server\n            __main__.start_client = _start_client\n    return daemon\n", "path": "ptvsd/pydevd_hooks.py"}]}