Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ptvsd debugger component. #23336

Merged
merged 12 commits into from Apr 30, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .coveragerc
Expand Up @@ -450,6 +450,7 @@ omit =
homeassistant/components/proxy/camera.py
homeassistant/components/ps4/__init__.py
homeassistant/components/ps4/media_player.py
homeassistant/components/ptvsd/*
homeassistant/components/pulseaudio_loopback/switch.py
homeassistant/components/pushbullet/notify.py
homeassistant/components/pushbullet/sensor.py
Expand Down
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Expand Up @@ -172,6 +172,7 @@ homeassistant/components/plant/* @ChristianKuehnel
homeassistant/components/point/* @fredrike
homeassistant/components/pollen/* @bachya
homeassistant/components/ps4/* @ktnrg45
homeassistant/components/ptvsd/* @swamp-ig
homeassistant/components/push/* @dgomes
homeassistant/components/pvoutput/* @fabaff
homeassistant/components/qnap/* @colinodell
Expand Down
10 changes: 10 additions & 0 deletions homeassistant/bootstrap.py
Expand Up @@ -26,6 +26,7 @@
# hass.data key for logging information.
DATA_LOGGING = 'logging'

DEBUGGER_INTEGRATIONS = {'ptvsd', }
CORE_INTEGRATIONS = ('homeassistant', 'persistent_notification')
LOGGING_INTEGRATIONS = {'logger', 'system_log'}
STAGE_1_INTEGRATIONS = {
Expand Down Expand Up @@ -306,6 +307,15 @@ async def _async_set_up_integrations(
"""Set up all the integrations."""
domains = _get_domains(hass, config)

# Start up debuggers. Start these first in case they want to wait.
debuggers = domains & DEBUGGER_INTEGRATIONS
if debuggers:
_LOGGER.debug("Starting up debuggers %s", debuggers)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do this in info, in case one of the debuggers block?

await asyncio.gather(*[
async_setup_component(hass, domain, config)
for domain in debuggers])
domains -= DEBUGGER_INTEGRATIONS

# Resolve all dependencies of all components so we can find the logging
# and integrations that need faster initialization.
resolved_domains_task = asyncio.gather(*[
Expand Down
63 changes: 63 additions & 0 deletions homeassistant/components/ptvsd/__init__.py
@@ -0,0 +1,63 @@
"""
Enable ptvsd debugger to attach to HA.

Attach ptvsd debugger by default to port 5678.
"""

import logging
from threading import Thread
from asyncio import Event

import voluptuous as vol

from homeassistant.const import (
CONF_HOST, CONF_PORT)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import ConfigType, HomeAssistantType

DOMAIN = 'ptvsd'

CONF_WAIT = 'wait'

_LOGGER = logging.getLogger(__name__)

CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Optional(
CONF_HOST, default='0.0.0.0'
): cv.string,
vol.Optional(
CONF_PORT, default=5678
): cv.port,
vol.Optional(
CONF_WAIT, default=False
): cv.boolean,
})
}, extra=vol.ALLOW_EXTRA)


async def async_setup(hass: HomeAssistantType, config: ConfigType):
"""Set up ptvsd debugger."""
import ptvsd

conf = config[DOMAIN]
host = conf[CONF_HOST]
port = conf[CONF_PORT]

ptvsd.enable_attach((host, port))

wait = conf[CONF_WAIT]
if wait:
_LOGGER.warning("Waiting for ptvsd connection on %s:%s", host, port)
ready = Event()

def waitfor():
ptvsd.wait_for_attach()
hass.loop.call_soon_threadsafe(ready.set)
Thread(target=waitfor).start()

await ready.wait()
else:
_LOGGER.warning("Listening for ptvsd connection on %s:%s", host, port)

return True
10 changes: 10 additions & 0 deletions homeassistant/components/ptvsd/manifest.json
@@ -0,0 +1,10 @@
{
"domain": "ptvsd",
"name": "ptvsd",
"documentation": "https://www.home-assistant.io/components/ptvsd",
"requirements": [
"ptvsd==4.2.8"
],
"dependencies": [],
"codeowners": ["@swamp-ig"]
}
3 changes: 3 additions & 0 deletions requirements_all.txt
Expand Up @@ -881,6 +881,9 @@ protobuf==3.6.1
# homeassistant.components.systemmonitor
psutil==5.6.1

# homeassistant.components.ptvsd
ptvsd==4.2.8

# homeassistant.components.wink
pubnubsub-handler==1.0.3

Expand Down
3 changes: 3 additions & 0 deletions requirements_test_all.txt
Expand Up @@ -204,6 +204,9 @@ pmsensor==0.4
# homeassistant.components.prometheus
prometheus_client==0.2.0

# homeassistant.components.ptvsd
ptvsd==4.2.8

# homeassistant.components.pushbullet
pushbullet.py==0.11.0

Expand Down
1 change: 1 addition & 0 deletions script/gen_requirements_all.py
Expand Up @@ -94,6 +94,7 @@
'pilight',
'pmsensor',
'prometheus_client',
'ptvsd',
'pushbullet.py',
'py-canary',
'pyblackbird',
Expand Down
1 change: 1 addition & 0 deletions tests/components/ptvsd/__init__py
@@ -0,0 +1 @@
"""Tests for PTVSD Debugger"""
23 changes: 23 additions & 0 deletions tests/components/ptvsd/test_ptvsd.py
@@ -0,0 +1,23 @@
"""Tests for PTVSD Debugger."""

from unittest.mock import patch
from asynctest import CoroutineMock

import homeassistant.components.ptvsd as ptvsd_component
from homeassistant.bootstrap import _async_set_up_integrations


async def test_ptvsd_bootstrap(hass):
"""Test loading ptvsd component with wait."""
config = {
ptvsd_component.DOMAIN: {
ptvsd_component.CONF_WAIT: True
}
}

with patch(
'homeassistant.components.ptvsd.async_setup',
CoroutineMock()) as setup_mock:
await _async_set_up_integrations(hass, config)

setup_mock.assert_called_once()