diff --git a/homeassistant/util/__init__.py b/homeassistant/util/__init__.py index ca89226846e..c19f08b6a79 100644 --- a/homeassistant/util/__init__.py +++ b/homeassistant/util/__init__.py @@ -1,9 +1,4 @@ -""" -homeassistant.util -~~~~~~~~~~~~~~~~~~ - -Helper methods for various modules. -""" +"""Helper methods for various modules.""" import collections from itertools import chain import threading @@ -25,24 +20,24 @@ RE_SLUGIFY = re.compile(r'[^a-z0-9_]+') def sanitize_filename(filename): - """ Sanitizes a filename by removing .. / and \\. """ + r"""Sanitize a filename by removing .. / and \\.""" return RE_SANITIZE_FILENAME.sub("", filename) def sanitize_path(path): - """ Sanitizes a path by removing ~ and .. """ + """Sanitize a path by removing ~ and ..""" return RE_SANITIZE_PATH.sub("", path) def slugify(text): - """ Slugifies a given text. """ + """Slugify a given text.""" text = text.lower().replace(" ", "_") return RE_SLUGIFY.sub("", text) def repr_helper(inp): - """ Helps creating a more readable string representation of objects. """ + """Help creating a more readable string representation of objects.""" if isinstance(inp, (dict, MappingProxyType)): return ", ".join( repr_helper(key)+"="+repr_helper(item) for key, item @@ -54,7 +49,7 @@ def repr_helper(inp): def convert(value, to_type, default=None): - """ Converts value to to_type, returns default if fails. """ + """Convert value to to_type, returns default if fails.""" try: return default if value is None else to_type(value) except (ValueError, TypeError): @@ -63,8 +58,10 @@ def convert(value, to_type, default=None): def ensure_unique_string(preferred_string, current_strings): - """ Returns a string that is not present in current_strings. - If preferred string exists will append _2, _3, .. """ + """Return a string that is not present in current_strings. + + If preferred string exists will append _2, _3, .. + """ test_string = preferred_string current_strings = set(current_strings) @@ -79,7 +76,7 @@ def ensure_unique_string(preferred_string, current_strings): # Taken from: http://stackoverflow.com/a/11735897 def get_local_ip(): - """ Tries to determine the local IP address of the machine. """ + """Try to determine the local IP address of the machine.""" try: sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) @@ -95,7 +92,7 @@ def get_local_ip(): # Taken from http://stackoverflow.com/a/23728630 def get_random_string(length=10): - """ Returns a random string with letters and digits. """ + """Return a random string with letters and digits.""" generator = random.SystemRandom() source_chars = string.ascii_letters + string.digits @@ -103,34 +100,39 @@ def get_random_string(length=10): class OrderedEnum(enum.Enum): - """ Taken from Python 3.4.0 docs. """ - # pylint: disable=no-init, too-few-public-methods + """Taken from Python 3.4.0 docs.""" + # pylint: disable=no-init, too-few-public-methods def __ge__(self, other): + """Return the greater than element.""" if self.__class__ is other.__class__: return self.value >= other.value return NotImplemented def __gt__(self, other): + """Return the greater element.""" if self.__class__ is other.__class__: return self.value > other.value return NotImplemented def __le__(self, other): + """Return the lower than element.""" if self.__class__ is other.__class__: return self.value <= other.value return NotImplemented def __lt__(self, other): + """Return the lower element.""" if self.__class__ is other.__class__: return self.value < other.value return NotImplemented class OrderedSet(collections.MutableSet): - """ Ordered set taken from http://code.activestate.com/recipes/576694/ """ + """Ordered set taken from http://code.activestate.com/recipes/576694/.""" def __init__(self, iterable=None): + """Initialize the set.""" self.end = end = [] end += [None, end, end] # sentinel node for doubly linked list self.map = {} # key --> [key, prev, next] @@ -138,20 +140,22 @@ class OrderedSet(collections.MutableSet): self |= iterable def __len__(self): + """Return the length of the set.""" return len(self.map) def __contains__(self, key): + """Check if key is in set.""" return key in self.map def add(self, key): - """ Add an element to the end of the set. """ + """Add an element to the end of the set.""" if key not in self.map: end = self.end curr = end[1] curr[2] = end[1] = self.map[key] = [key, curr, end] def promote(self, key): - """ Promote element to beginning of the set, add if not there. """ + """Promote element to beginning of the set, add if not there.""" if key in self.map: self.discard(key) @@ -160,13 +164,14 @@ class OrderedSet(collections.MutableSet): curr[2] = begin[1] = self.map[key] = [key, curr, begin] def discard(self, key): - """ Discard an element from the set. """ + """Discard an element from the set.""" if key in self.map: key, prev_item, next_item = self.map.pop(key) prev_item[2] = next_item next_item[1] = prev_item def __iter__(self): + """Iteration of the set.""" end = self.end curr = end[2] while curr is not end: @@ -174,6 +179,7 @@ class OrderedSet(collections.MutableSet): curr = curr[2] def __reversed__(self): + """reverse the ordering.""" end = self.end curr = end[1] while curr is not end: @@ -181,8 +187,8 @@ class OrderedSet(collections.MutableSet): curr = curr[1] def pop(self, last=True): # pylint: disable=arguments-differ - """ - Pops element of the end of the set. + """Pop element of the end of the set. + Set last=False to pop from the beginning. """ if not self: @@ -192,24 +198,27 @@ class OrderedSet(collections.MutableSet): return key def update(self, *args): - """ Add elements from args to the set. """ + """Add elements from args to the set.""" for item in chain(*args): self.add(item) def __repr__(self): + """Return the representation.""" if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, list(self)) def __eq__(self, other): + """Return the comparision.""" if isinstance(other, OrderedSet): return len(self) == len(other) and list(self) == list(other) return set(self) == set(other) class Throttle(object): - """ - A method decorator to add a cooldown to a method to prevent it from being + """A class for throttling the execution of tasks. + + This method decorator adds a cooldown to a method to prevent it from being called more then 1 time within the timedelta interval `min_time` after it returned its result. @@ -223,13 +232,15 @@ class Throttle(object): Adds a datetime attribute `last_call` to the method. """ - # pylint: disable=too-few-public-methods + # pylint: disable=too-few-public-methods def __init__(self, min_time, limit_no_throttle=None): + """Initialize the throttle.""" self.min_time = min_time self.limit_no_throttle = limit_no_throttle def __call__(self, method): + """Caller for the throttle.""" if self.limit_no_throttle is not None: method = Throttle(self.limit_no_throttle)(method) @@ -248,8 +259,8 @@ class Throttle(object): @wraps(method) def wrapper(*args, **kwargs): - """ - Wrapper that allows wrapped to be called only once per min_time. + """Wrapper that allows wrapped to be called only once per min_time. + If we cannot acquire the lock, it is running so return None. """ # pylint: disable=protected-access @@ -288,10 +299,11 @@ class Throttle(object): class ThreadPool(object): """A priority queue-based thread pool.""" - # pylint: disable=too-many-instance-attributes + # pylint: disable=too-many-instance-attributes def __init__(self, job_handler, worker_count=0, busy_callback=None): - """ + """Initialize the pool. + job_handler: method to be called from worker thread to handle job worker_count: number of threads to run that handle jobs busy_callback: method to be called when queue gets too big. @@ -338,18 +350,18 @@ class ThreadPool(object): self.busy_warning_limit = self.worker_count * 3 def add_job(self, priority, job): - """ Add a job to the queue. """ + """Add a job to the queue.""" with self._lock: if not self.running: raise RuntimeError("ThreadPool not running") self._work_queue.put(PriorityQueueItem(priority, job)) - # check if our queue is getting too big + # Check if our queue is getting too big. if self._work_queue.qsize() > self.busy_warning_limit \ and self._busy_callback is not None: - # Increase limit we will issue next warning + # Increase limit we will issue next warning. self.busy_warning_limit *= 2 self._busy_callback( @@ -404,12 +416,14 @@ class ThreadPool(object): class PriorityQueueItem(object): - """ Holds a priority and a value. Used within PriorityQueue. """ + """Holds a priority and a value. Used within PriorityQueue.""" # pylint: disable=too-few-public-methods def __init__(self, priority, item): + """Initialize the queue.""" self.priority = priority self.item = item def __lt__(self, other): + """Return the ordering.""" return self.priority < other.priority diff --git a/homeassistant/util/dt.py b/homeassistant/util/dt.py index 604777399ec..ff4fd6e13bd 100644 --- a/homeassistant/util/dt.py +++ b/homeassistant/util/dt.py @@ -1,10 +1,4 @@ -""" -homeassistant.util.dt -~~~~~~~~~~~~~~~~~~~~~ - -Provides helper methods to handle the time in HA. - -""" +"""Provides helper methods to handle the time in HA.""" import datetime as dt import pytz @@ -16,7 +10,7 @@ UTC = DEFAULT_TIME_ZONE = pytz.utc def set_default_time_zone(time_zone): - """ Sets a default time zone to be used when none is specified. """ + """Set a default time zone to be used when none is specified.""" global DEFAULT_TIME_ZONE # pylint: disable=global-statement assert isinstance(time_zone, dt.tzinfo) @@ -25,7 +19,7 @@ def set_default_time_zone(time_zone): def get_time_zone(time_zone_str): - """ Get time zone from string. Return None if unable to determine. """ + """Get time zone from string. Return None if unable to determine.""" try: return pytz.timezone(time_zone_str) except pytz.exceptions.UnknownTimeZoneError: @@ -33,18 +27,20 @@ def get_time_zone(time_zone_str): def utcnow(): - """ Get now in UTC time. """ + """Get now in UTC time.""" return dt.datetime.now(UTC) def now(time_zone=None): - """ Get now in specified time zone. """ + """Get now in specified time zone.""" return dt.datetime.now(time_zone or DEFAULT_TIME_ZONE) def as_utc(dattim): - """ Return a datetime as UTC time. - Assumes datetime without tzinfo to be in the DEFAULT_TIME_ZONE. """ + """Return a datetime as UTC time. + + Assumes datetime without tzinfo to be in the DEFAULT_TIME_ZONE. + """ if dattim.tzinfo == UTC: return dattim elif dattim.tzinfo is None: @@ -54,7 +50,7 @@ def as_utc(dattim): def as_local(dattim): - """ Converts a UTC datetime object to local time_zone. """ + """Convert a UTC datetime object to local time zone.""" if dattim.tzinfo == DEFAULT_TIME_ZONE: return dattim elif dattim.tzinfo is None: @@ -64,12 +60,12 @@ def as_local(dattim): def utc_from_timestamp(timestamp): - """ Returns a UTC time from a timestamp. """ + """Return a UTC time from a timestamp.""" return dt.datetime.utcfromtimestamp(timestamp).replace(tzinfo=UTC) def start_of_local_day(dt_or_d=None): - """ Return local datetime object of start of day from date or datetime. """ + """Return local datetime object of start of day from date or datetime.""" if dt_or_d is None: dt_or_d = now().date() elif isinstance(dt_or_d, dt.datetime): @@ -80,12 +76,12 @@ def start_of_local_day(dt_or_d=None): def datetime_to_local_str(dattim): - """ Converts datetime to specified time_zone and returns a string. """ + """Convert datetime to specified time_zone and returns a string.""" return datetime_to_str(as_local(dattim)) def datetime_to_str(dattim): - """ Converts datetime to a string format. + """Convert datetime to a string format. @rtype : str """ @@ -93,7 +89,7 @@ def datetime_to_str(dattim): def datetime_to_time_str(dattim): - """ Converts datetime to a string containing only the time. + """Convert datetime to a string containing only the time. @rtype : str """ @@ -101,7 +97,7 @@ def datetime_to_time_str(dattim): def datetime_to_date_str(dattim): - """ Converts datetime to a string containing only the date. + """Convert datetime to a string containing only the date. @rtype : str """ @@ -109,7 +105,7 @@ def datetime_to_date_str(dattim): def str_to_datetime(dt_str, dt_format=DATETIME_STR_FORMAT): - """ Converts a string to a UTC datetime object. + """Convert a string to a UTC datetime object. @rtype: datetime """ @@ -121,7 +117,7 @@ def str_to_datetime(dt_str, dt_format=DATETIME_STR_FORMAT): def date_str_to_date(dt_str): - """ Converts a date string to a date object. """ + """Convert a date string to a date object.""" try: return dt.datetime.strptime(dt_str, DATE_STR_FORMAT).date() except ValueError: # If dt_str did not match our format @@ -129,13 +125,14 @@ def date_str_to_date(dt_str): def strip_microseconds(dattim): - """ Returns a copy of dattime object but with microsecond set to 0. """ + """Return a copy of dattime object but with microsecond set to 0.""" return dattim.replace(microsecond=0) def parse_time_str(time_str): - """ Parse a time string (00:20:00) into Time object. - Return None if invalid. + """Parse a time string (00:20:00) into Time object. + + Return None if invalid. """ parts = str(time_str).split(':') if len(parts) < 2: diff --git a/homeassistant/util/package.py b/homeassistant/util/package.py index 91ef15cc7a0..6894524d963 100644 --- a/homeassistant/util/package.py +++ b/homeassistant/util/package.py @@ -1,8 +1,4 @@ -""" -homeassistant.util.package -~~~~~~~~~~~~~~~~~~~~~~~~~~ -Helpers to install PyPi packages. -""" +"""Helpers to install PyPi packages.""" import logging import os import subprocess @@ -17,8 +13,8 @@ INSTALL_LOCK = threading.Lock() def install_package(package, upgrade=True, target=None): - """ - Install a package on PyPi. Accepts pip compatible package strings. + """Install a package on PyPi. Accepts pip compatible package strings. + Return boolean if install successful. """ # Not using 'import pip; pip.main([])' because it breaks the logger @@ -41,8 +37,8 @@ def install_package(package, upgrade=True, target=None): def check_package_exists(package, lib_dir): - """ - Check if a package is installed globally or in lib_dir. + """Check if a package is installed globally or in lib_dir. + Returns True when the requirement is met. Returns False when the package is not installed or doesn't meet req. """ diff --git a/homeassistant/util/temperature.py b/homeassistant/util/temperature.py index 943744597b1..99a524c5212 100644 --- a/homeassistant/util/temperature.py +++ b/homeassistant/util/temperature.py @@ -1,15 +1,11 @@ -""" -homeassistant.util.temperature -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Temperature util functions. -""" +"""Temperature util functions.""" def fahrenheit_to_celcius(fahrenheit): - """ Convert a Fahrenheit temperature to Celcius. """ + """Convert a Fahrenheit temperature to Celsius.""" return (fahrenheit - 32.0) / 1.8 def celcius_to_fahrenheit(celcius): - """ Convert a Celcius temperature to Fahrenheit. """ + """Convert a Celsius temperature to Fahrenheit.""" return celcius * 1.8 + 32.0 diff --git a/homeassistant/util/yaml.py b/homeassistant/util/yaml.py index fa7783d7e83..517ed6c4fb0 100644 --- a/homeassistant/util/yaml.py +++ b/homeassistant/util/yaml.py @@ -1,6 +1,4 @@ -""" -YAML utility functions. -""" +"""YAML utility functions.""" import logging import os from collections import OrderedDict @@ -26,8 +24,7 @@ def load_yaml(fname): def _include_yaml(loader, node): - """ - Loads another YAML file and embeds it using the !include tag. + """Load another YAML file and embeds it using the !include tag. Example: device_tracker: !include device_tracker.yaml @@ -37,9 +34,7 @@ def _include_yaml(loader, node): def _ordered_dict(loader, node): - """ - Loads YAML mappings into an ordered dict to preserve key order. - """ + """Load YAML mappings into an ordered dict to preserve key order.""" loader.flatten_mapping(node) return OrderedDict(loader.construct_pairs(node))