Skip to content

Commit

Permalink
Merge pull request #20 from tpiekarski/feature/type-hints
Browse files Browse the repository at this point in the history
Merging feature/type-hints, resolves #17
  • Loading branch information
tpiekarski authored Jul 3, 2020
2 parents d0e349d + a991e69 commit f0c44e2
Show file tree
Hide file tree
Showing 23 changed files with 90 additions and 82 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ run:
$(info Testing if derl runs with $(TEST_DIRECTORY) (use args="" to pass arguments))
derl $(TEST_DIRECTORY) $(args)

show-function-signatures:
$(info Showing all function (and method) signatures)
find src/ tests/ -name "*.py" | xargs grep -E "def.*\(.*\).*:"

sonar:
$(info Running Sonar Scanner (only when automatic analysis is turned off))
sonar-scanner -Dsonar.login=${SONAR_KEY}
Expand Down
13 changes: 7 additions & 6 deletions src/derl/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import sys

from argparse import Namespace
from logging import getLogger
from os import path
from magic import from_file
Expand All @@ -18,32 +19,32 @@
_logger = getLogger(__name__)


def is_directory(value):
def is_directory(value: str) -> bool:
_logger.debug("Checking provided directory %s", value)

return path.isdir(value)


def is_retry_value(value):
def is_retry_value(value: str) -> bool:
return 0 < value <= 10


def is_text_file(file):
def is_text_file(file: str) -> bool:
_logger.debug("Checking file %s", file)
mimetype = from_file(str(file), mime=True)

return file.is_file() and mimetype[:4] == "text"


def is_timeout_value(value):
def is_timeout_value(value: int) -> bool:
return value > 0


def is_url(value):
def is_url(value: str) -> bool:
return url(value)


def check_arguments(args):
def check_arguments(args: Namespace):
if not is_timeout_value(args.timeout):
_logger.error("Invalid timeout, timeout must be greater than 0")
sys.exit(_INVALID_TIMEOUT)
Expand Down
6 changes: 4 additions & 2 deletions src/derl/collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@

from logging import getLogger

from derl.model.url import URL

_logger = getLogger(__name__)

_DEFAULT_ENCODING = "utf-8"


def _extract_context(url, lines):
def _extract_context(url: URL, lines: list) -> list:
context = []
line_index = url.line_number - 1

Expand All @@ -26,7 +28,7 @@ def _extract_context(url, lines):
return context


def collect_context(files):
def collect_context(files: list) -> list:
for current_file in files:
for current_url in current_file.urls:
with open(current_file.filename, "r", encoding=_DEFAULT_ENCODING) as open_file:
Expand Down
2 changes: 1 addition & 1 deletion src/derl/dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
_DEFAULT_TIMEOUT = 10


def request(files, retry=_DEFAULT_RETRY, timeout=_DEFAULT_TIMEOUT):
def request(files: list, retry: int = _DEFAULT_RETRY, timeout: int = _DEFAULT_TIMEOUT) -> list:
if len(files) == 0:
_logger.debug("No matches for HTTP requests")
return []
Expand Down
2 changes: 1 addition & 1 deletion src/derl/filterer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
_logger = getLogger(__name__)


def filter_not_matching(files):
def filter_not_matching(files: list) -> list:
filtered_files = []

for current_file in files:
Expand Down
4 changes: 2 additions & 2 deletions src/derl/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
_tracker = get_tracker()


def setup_logging(loglevel):
def setup_logging(loglevel: int):
basicConfig(
datefmt="%Y-%m-%d %H:%M:%S",
format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s",
Expand All @@ -36,7 +36,7 @@ def setup_logging(loglevel):
)


def main(args):
def main(args: list):
args = parse_args(args)
setup_logging(args.loglevel)
check_arguments(args)
Expand Down
10 changes: 5 additions & 5 deletions src/derl/model/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@ class File:
filename = None
urls: []

def __init__(self, filename):
def __init__(self: "File", filename: str):
self.filename = filename
self.urls = []

def __str__(self):
def __str__(self: "File") -> str:
output = ""

for current_url in self.urls:
output += "{}:{}\n".format(self.filename, current_url)

return output

def __repr__(self):
def __repr__(self: "File") -> str:
return self.__str__()

def append(self, url, line_number):
def append(self: "File", url: str, line_number: int):
self.urls.append(URL(url, line_number))

def contains_urls(self):
def contains_urls(self: "File") -> bool:
return len(self.urls) > 0
16 changes: 8 additions & 8 deletions src/derl/model/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Stats():
tokens = 0
urls = 0

def __str__(self):
def __str__(self: "Stats") -> str:
output = "Processed Directories/Files/Lines/Tokens/URLs: {0:d}/{1:d}/{2:d}/{3:d}/{4:d}".format(
self.directories, self.files, self.lines, self.tokens, self.urls
)
Expand All @@ -23,23 +23,23 @@ def __str__(self):

return output

def __repr__(self):
def __repr__(self: "Stats") -> str:
return self.__str__()

def inc_directories(self):
def inc_directories(self: "Stats"):
self.directories += 1

def inc_files(self):
def inc_files(self: "Stats"):
self.files += 1

def inc_lines(self):
def inc_lines(self: "Stats"):
self.lines += 1

def inc_tokens(self):
def inc_tokens(self: "Stats"):
self.tokens += 1

def inc_urls(self):
def inc_urls(self: "Stats"):
self.urls += 1

def inc_requests(self):
def inc_requests(self: "Stats"):
self.requests += 1
14 changes: 7 additions & 7 deletions src/derl/model/url.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
_CONTEXT_OUTPUT_MAP = {0: "", 1: " {}\n", 2: " {}\n {}\n", 3: " {}\n {}\n {}\n"}


def _normalize_context(context):
def _normalize_context(context: list) -> list:
normalized_context = []

for current_line in context:
Expand All @@ -22,11 +22,11 @@ class URL:
line_number = None
context = []

def __init__(self, location, line_number):
def __init__(self: "URL", location: str, line_number: int):
self.location = location
self.line_number = line_number

def __str__(self):
def __str__(self: "URL") -> str:
if self.status_code is None:
output = "{}, {}".format(self.line_number, self.location)
else:
Expand All @@ -38,11 +38,11 @@ def __str__(self):

return output

def __repr__(self):
def __repr__(self: "URL") -> str:
return self.__str__()

def is_context_present(self):
return len(self.context)
def is_context_present(self: "URL") -> bool:
return len(self.context) > 0

def set_context(self, context):
def set_context(self: "URL", context: list):
self.context = _normalize_context(context)
2 changes: 1 addition & 1 deletion src/derl/outputer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
_tracker = get_tracker()


def output(files, stats=False):
def output(files: list, stats: bool = False):
if len(files) == 0:
_logger.debug("No matched files for output")
return
Expand Down
4 changes: 2 additions & 2 deletions src/derl/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
# Copyright 2020 Thomas Piekarski <[email protected]>
#

from argparse import ArgumentParser, HelpFormatter
from argparse import ArgumentParser, HelpFormatter, Namespace
from logging import DEBUG, INFO

from derl import __version__
from derl.dispatcher import _DEFAULT_RETRY, _DEFAULT_TIMEOUT


def parse_args(args):
def parse_args(args: list) -> Namespace:
parser = ArgumentParser(
prog="derl",
formatter_class=lambda prog: HelpFormatter(prog, max_help_position=35, width=90),
Expand Down
11 changes: 6 additions & 5 deletions src/derl/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from logging import getLogger
from pathlib import Path
from re import compile as rcompile, IGNORECASE
from typing import TextIO

from derl.checker import is_text_file, is_url
from derl.model.file import File
Expand All @@ -20,7 +21,7 @@
_tracker = get_tracker()


def process_file(file):
def process_file(file: TextIO) -> list:
_logger.debug("Spliting current file %s into lines...", file.name)
_tracker.stats.inc_files()

Expand All @@ -44,7 +45,7 @@ def process_file(file):
return urls


def process_line(file, line, urls):
def process_line(file: TextIO, line: tuple, urls: list) -> list:
_logger.debug("Splitting current line into tokens...")
_tracker.stats.inc_lines()

Expand All @@ -66,7 +67,7 @@ def process_line(file, line, urls):
return urls


def process_token(file, token, line_number):
def process_token(file: TextIO, token: str, line_number: int) -> URL:
_tracker.stats.inc_tokens()

match = _pattern.match(token)
Expand All @@ -80,7 +81,7 @@ def process_token(file, token, line_number):
return url


def process_directory(directory, files):
def process_directory(directory: str, files: list) -> list:
_logger.info("Starting to process directory '%s'", directory)
_tracker.stats.inc_directories()

Expand All @@ -89,7 +90,7 @@ def process_directory(directory, files):
for current in path.iterdir():
if current.is_dir():
_logger.debug("'%s' is a directory, descending...", current.name)
files = process_directory(current, files)
files = process_directory(str(current), files)
elif is_text_file(current):
_logger.debug("Appending file '%s'", current.name)
files.append(File(current))
Expand Down
2 changes: 1 addition & 1 deletion src/derl/searcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
_DEFAULT_ENCODING = "utf-8"


def search_urls(files):
def search_urls(files: list) -> list:
_logger.info("Starting to search for URLs in %i files...", len(files))

if len(files) == 0:
Expand Down
18 changes: 9 additions & 9 deletions src/derl/tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
class Singleton(type):
_instances = {}

def __call__(cls, *args, **kwargs):
def __call__(cls: "Singleton", *args: tuple, **kwargs: dict) -> "Tracker":
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)

Expand All @@ -25,29 +25,29 @@ class Tracker(metaclass=Singleton):
stats = Stats()
test = False

def start(self):
def start(self: "Tracker"):
if self.start_time is None:
self.start_time = perf_counter()

def stop(self):
def stop(self: "Tracker"):
if self.stop_time is None:
self.stop_time = perf_counter()

def calc_time(self):
def calc_time(self: "Tracker") -> float:
if self.test:
return -1

return round(self.stop_time - self.start_time)

def reset(self):
def reset(self: "Tracker"):
self.start_time = 0
self.stop_time = 0
self.stats = Stats()

def set_test(self):
def set_test(self: "Tracker"):
self.test = True

def __str__(self):
def __str__(self: "Tracker") -> str:
output = ""

if self.start_time is not None and self.stop_time is not None:
Expand All @@ -57,9 +57,9 @@ def __str__(self):

return output

def __repr__(self):
def __repr__(self: "Tracker") -> str:
return self.__str__()


def get_tracker():
def get_tracker() -> "Tracker":
return Tracker()
4 changes: 2 additions & 2 deletions tests/test_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@

class CheckerTest(TestCase):

def test_is_directory(self):
def test_is_directory(self: "CheckerTest"):
self.assertTrue(is_directory("tests/test-directory"))
self.assertFalse(is_directory("tests/not-existent-directory"))

def test_is_text_file(self):
def test_is_text_file(self: "CheckerTest"):
self.assertTrue(is_text_file(Path("tests/test-files/plain-text")))
self.assertFalse(is_text_file(Path("tests/test-files/binary-data")))
Loading

0 comments on commit f0c44e2

Please sign in to comment.