Do some linting

This commit is contained in:
Lucas Verney 2017-10-29 21:04:09 +01:00
parent 40e62baadf
commit 1baebffb87
6 changed files with 71 additions and 33 deletions

View File

@ -343,16 +343,16 @@ max-args=5
ignored-argument-names=_.* ignored-argument-names=_.*
# Maximum number of locals for function / method body # Maximum number of locals for function / method body
max-locals=15 max-locals=25
# Maximum number of return / yield for function / method body # Maximum number of return / yield for function / method body
max-returns=6 max-returns=6
# Maximum number of branch for function / method body # Maximum number of branch for function / method body
max-branches=12 max-branches=20
# Maximum number of statements in function / method body # Maximum number of statements in function / method body
max-statements=50 max-statements=100
# Maximum number of parents for a class (see R0901). # Maximum number of parents for a class (see R0901).
max-parents=7 max-parents=7

View File

@ -81,7 +81,7 @@ def filter_flats_list(config, constraint_name, flats_list, fetch_details=True):
# Do a third pass to deduplicate better # Do a third pass to deduplicate better
if config["passes"] > 2: if config["passes"] > 2:
third_pass_result = flatisfy.filters.third_pass( third_pass_result = flatisfy.filters.third_pass(
second_pass_result["new"], config second_pass_result["new"]
) )
else: else:
third_pass_result["new"] = second_pass_result["new"] third_pass_result["new"] = second_pass_result["new"]

View File

@ -231,7 +231,7 @@ def second_pass(flats_list, constraint, config):
} }
@tools.timeit @tools.timeit
def third_pass(flats_list, config): def third_pass(flats_list):
""" """
Third filtering pass. Third filtering pass.
@ -239,7 +239,6 @@ def third_pass(flats_list, config):
flats. flats.
:param flats_list: A list of flats dict to filter. :param flats_list: A list of flats dict to filter.
:param config: A config dict.
:return: A dict mapping flat status and list of flat objects. :return: A dict mapping flat status and list of flat objects.
""" """
LOGGER.info("Running third filtering pass.") LOGGER.info("Running third filtering pass.")

View File

@ -8,14 +8,31 @@ from __future__ import absolute_import, print_function, unicode_literals
import requests import requests
class MemoryCache(object): class MemoryCache(object):
"""
A cache in memory.
"""
def __init__(self, on_miss): def __init__(self, on_miss):
"""
Constructor
:param on_miss: Function to call to retrieve item when not already
cached.
"""
self.hits = 0 self.hits = 0
self.misses = 0 self.misses = 0
self.map = {} self.map = {}
self.on_miss = on_miss self.on_miss = on_miss
def get(self, key): def get(self, key):
"""
Get an element from cache. Eventually call ``on_miss`` if the item is
not already cached.
:param key: Key of the element to retrieve.
:return: Requested element.
"""
cached = self.map.get(key, None) cached = self.map.get(key, None)
if cached is not None: if cached is not None:
self.hits += 1 self.hits += 1
@ -26,20 +43,45 @@ class MemoryCache(object):
return item return item
def total(self): def total(self):
"""
Get the total number of calls (with hits to the cache, or miss and
fetching with ``on_miss``) to the cache.
:return: Total number of item accessing.
"""
return self.hits + self.misses return self.hits + self.misses
def hit_rate(self): def hit_rate(self):
"""
Get the hit rate, that is the rate at which we requested an item which
was already in the cache.
:return: The hit rate, in percents.
"""
assert self.total() > 0 assert self.total() > 0
return 100 * self.hits // self.total() return 100 * self.hits // self.total()
def miss_rate(self): def miss_rate(self):
"""
Get the miss rate, that is the rate at which we requested an item which
was not already in the cache.
:return: The miss rate, in percents.
"""
assert self.total() > 0 assert self.total() > 0
return 100 * self.misses // self.total() return 100 * self.misses // self.total()
class ImageCache(MemoryCache): class ImageCache(MemoryCache):
"""
A cache for images, stored in memory.
"""
@staticmethod @staticmethod
def retrieve_photo(url): def retrieve_photo(url):
"""
Helper to actually retrieve photos if not already cached.
"""
return requests.get(url) return requests.get(url)
def __init__(self): def __init__(self):
super(self.__class__, self).__init__(on_miss=ImageCache.retrieve_photo) super(ImageCache, self).__init__(on_miss=ImageCache.retrieve_photo)

View File

@ -5,10 +5,10 @@ This modules defines an SQLAlchemy ORM model for a flat.
# pylint: disable=locally-disabled,invalid-name,too-few-public-methods # pylint: disable=locally-disabled,invalid-name,too-few-public-methods
from __future__ import absolute_import, print_function, unicode_literals from __future__ import absolute_import, print_function, unicode_literals
import enum
import logging import logging
import arrow import arrow
import enum
from sqlalchemy import ( from sqlalchemy import (
Column, DateTime, Enum, Float, SmallInteger, String, Text Column, DateTime, Enum, Float, SmallInteger, String, Text

View File

@ -18,18 +18,6 @@ import time
import requests import requests
import unidecode import unidecode
try:
from functools import wraps
except ImportError:
try:
from functools32 import wraps
except ImportError:
def wraps(func):
"""
Identity implementation of ``wraps`` for fallback.
"""
return lambda func: func
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
@ -52,14 +40,20 @@ def hash_dict(func):
def __hash__(self): def __hash__(self):
return hash(json.dumps(self)) return hash(json.dumps(self))
@wraps(func)
def wrapped(*args, **kwargs): def wrapped(*args, **kwargs):
"""
The wrapped function
"""
args = tuple( args = tuple(
[HDict(arg) if isinstance(arg, dict) else arg [
HDict(arg) if isinstance(arg, dict) else arg
for arg in args for arg in args
]) ]
kwargs = {k: HDict(v) if isinstance(v, dict) else v )
for k, v in kwargs.items()} kwargs = {
k: HDict(v) if isinstance(v, dict) else v
for k, v in kwargs.items()
}
return func(*args, **kwargs) return func(*args, **kwargs)
return wrapped return wrapped
@ -281,7 +275,7 @@ def get_travel_time_between(latlng_from, latlng_to, config):
.. note :: Uses the Navitia API. Requires a ``navitia_api_key`` field to be .. note :: Uses the Navitia API. Requires a ``navitia_api_key`` field to be
filled-in in the ``config``. filled-in in the ``config``.
""" """
time = None travel_time = None
# Check that Navitia API key is available # Check that Navitia API key is available
if config["navitia_api_key"]: if config["navitia_api_key"]:
@ -300,7 +294,7 @@ def get_travel_time_between(latlng_from, latlng_to, config):
req.raise_for_status() req.raise_for_status()
journeys = req.json()["journeys"][0] journeys = req.json()["journeys"][0]
time = journeys["durations"]["total"] travel_time = journeys["durations"]["total"]
sections = [] sections = []
for section in journeys["sections"]: for section in journeys["sections"]:
if section["type"] == "public_transport": if section["type"] == "public_transport":
@ -333,22 +327,25 @@ def get_travel_time_between(latlng_from, latlng_to, config):
"No API key available for travel time lookup. Please provide " "No API key available for travel time lookup. Please provide "
"a Navitia API key. Skipping travel time lookup." "a Navitia API key. Skipping travel time lookup."
) )
if time: if travel_time:
return { return {
"time": time, "time": travel_time,
"sections": sections "sections": sections
} }
return None return None
def timeit(f): def timeit(func):
""" """
A decorator that logs how much time was spent in the function. A decorator that logs how much time was spent in the function.
""" """
def wrapped(*args, **kwargs): def wrapped(*args, **kwargs):
"""
The wrapped function
"""
before = time.time() before = time.time()
res = f(*args, **kwargs) res = func(*args, **kwargs)
runtime = time.time() - before runtime = time.time() - before
LOGGER.info("%s -- Execution took %s seconds.", f.__name__, runtime) LOGGER.info("%s -- Execution took %s seconds.", func.__name__, runtime)
return res return res
return wrapped return wrapped