Skip to content

Commit

Permalink
Added type annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimmetz committed May 31, 2020
1 parent 494e187 commit a831901
Show file tree
Hide file tree
Showing 25 changed files with 505 additions and 387 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
# Pycharm files
/.idea

# Type check files
/.mypy_cache

# Test coverage files
.coverage
tests-coverage.txt
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ dist: bionic
jobs:
include:
- name: "Pylint on Ubuntu Bionic (20.04) (Docker) with Python 3.8"
env: [TARGET="pylint", UBUNTU_VERSION="20.04"]
env: [TARGET="lint_and_type_check", UBUNTU_VERSION="20.04"]
group: edge
language: python
python: 3.8
Expand Down
8 changes: 4 additions & 4 deletions config/travis/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ then
else
RPM_PACKAGES="";

if test ${TARGET} = "pylint";
if test ${TARGET} = "lint_and_type_check";
then
RPM_PACKAGES="${RPM_PACKAGES} findutils pylint";
RPM_PACKAGES="${RPM_PACKAGES} findutils pylint python3-mypy";
fi
RPM_PACKAGES="${RPM_PACKAGES} python3 ${RPM_PYTHON3_DEPENDENCIES} ${RPM_PYTHON3_TEST_DEPENDENCIES}";
fi
Expand Down Expand Up @@ -87,9 +87,9 @@ then
then
DPKG_PACKAGES="${DPKG_PACKAGES} sudo";

elif test ${TARGET} = "pylint";
elif test ${TARGET} = "lint_and_type_check";
then
DPKG_PACKAGES="${DPKG_PACKAGES} python3-distutils pylint";
DPKG_PACKAGES="${DPKG_PACKAGES} pylint python3-distutils python3-mypy";
fi
if test "${TARGET}" != "jenkins3";
then
Expand Down
24 changes: 21 additions & 3 deletions config/travis/run_pylint.sh → config/travis/run_checks.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#!/bin/bash
#
# Script to run pylint on Travis-CI.
# Script to run lint and type checks on Travis-CI.
#
# This file is generated by l2tdevtools update-dependencies.py, any dependency
# related changes should be made in dependencies.ini.

# Exit on error.
set -e;
EXIT_SUCCESS=0;
EXIT_FAILURE=1;

RESULT=${EXIT_SUCCESS};

pylint --version

Expand All @@ -19,4 +21,20 @@ do
echo "Checking: ${FILE}";

pylint --rcfile=.pylintrc ${FILE};

if test $? -ne ${EXIT_SUCCESS};
then
REUSLT=${EXIT_SUCCESS};
fi
done

mypy --version

mypy --strict dfdatetime tests;

if test $? -ne ${EXIT_SUCCESS};
then
REUSLT=${EXIT_SUCCESS};
fi

exit ${RESULT};
8 changes: 4 additions & 4 deletions config/travis/runtests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ then
then
TEST_COMMAND="tox -e ${TOXENV}";

elif test "${TARGET}" = "pylint";
elif test "${TARGET}" = "lint_and_type_check";
then
TEST_COMMAND="./config/travis/run_pylint.sh";
TEST_COMMAND="./config/travis/run_checks.sh";
else
TEST_COMMAND="./config/travis/run_python3.sh";
fi
Expand Down Expand Up @@ -51,9 +51,9 @@ then
then
TEST_COMMAND="./config/jenkins/linux/run_end_to_end_tests_py3.sh travis";

elif test "${TARGET}" = "pylint";
elif test "${TARGET}" = "lint_and_type_check";
then
TEST_COMMAND="./config/travis/run_pylint.sh";
TEST_COMMAND="./config/travis/run_checks.sh";
else
TEST_COMMAND="./config/travis/run_python3.sh";
fi
Expand Down
13 changes: 7 additions & 6 deletions dfdatetime/apfs_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from __future__ import unicode_literals

import decimal
import typing

from dfdatetime import definitions
from dfdatetime import posix_time
Expand All @@ -19,14 +20,14 @@ class APFSTime(posix_time.PosixTimeInNanoseconds):
is_local_time (bool): True if the date and time value is in local time.
"""

def _GetNormalizedTimestamp(self):
def _GetNormalizedTimestamp(self) -> typing.Union[decimal.Decimal, None]:
"""Retrieves the normalized timestamp.
Returns:
decimal.Decimal: normalized timestamp, which contains the number of
seconds since January 1, 1970 00:00:00 and a fraction of second used
for increased precision, or None if the normalized timestamp cannot be
determined.
seconds since January 1, 1970 00:00:00 and a fraction of second
used for increased precision, or None if the normalized timestamp
cannot be determined.
"""
if self._normalized_timestamp is None:
if (self._timestamp is not None and self._timestamp >= self._INT64_MIN and
Expand All @@ -37,7 +38,7 @@ def _GetNormalizedTimestamp(self):

return self._normalized_timestamp

def CopyFromDateTimeString(self, time_string):
def CopyFromDateTimeString(self, time_string: str) -> None:
"""Copies a APFS timestamp from a date and time string.
Args:
Expand All @@ -58,7 +59,7 @@ def CopyFromDateTimeString(self, time_string):
self._timestamp > self._INT64_MAX):
raise ValueError('Date time value not supported.')

def CopyToDateTimeString(self):
def CopyToDateTimeString(self) -> typing.Union[str, None]:
"""Copies the APFS timestamp to a date and time string.
Returns:
Expand Down
33 changes: 18 additions & 15 deletions dfdatetime/cocoa_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from __future__ import unicode_literals

import decimal
import typing

from dfdatetime import definitions
from dfdatetime import interface
Expand All @@ -12,7 +13,7 @@
class CocoaTimeEpoch(interface.DateTimeEpoch):
"""Cocoa time epoch."""

def __init__(self):
def __init__(self) -> None:
"""Initializes a Cocoa time epoch."""
super(CocoaTimeEpoch, self).__init__(2001, 1, 1)

Expand All @@ -36,28 +37,29 @@ class CocoaTime(interface.DateTimeValues):

_EPOCH = CocoaTimeEpoch()

def __init__(self, timestamp=None):
def __init__(self, timestamp: typing.Optional[float] = None) -> None:
"""Initializes a Cocoa timestamp.
Args:
timestamp (Optional[float]): Cocoa timestamp.
"""
super(CocoaTime, self).__init__()
self._precision = definitions.PRECISION_1_SECOND
self._timestamp = timestamp
self._precision: str = definitions.PRECISION_1_SECOND
self._timestamp: typing.Union[float, None] = timestamp

@property
def timestamp(self):
def timestamp(self) -> typing.Union[float, None]:
"""float: Cocoa timestamp or None if timestamp is not set."""
return self._timestamp

def _GetNormalizedTimestamp(self):
def _GetNormalizedTimestamp(self) -> typing.Union[decimal.Decimal, None]:
"""Retrieves the normalized timestamp.
Returns:
float: normalized timestamp, which contains the number of seconds since
January 1, 1970 00:00:00 and a fraction of second used for increased
precision, or None if the normalized timestamp cannot be determined.
decimal.Decimal: normalized timestamp, which contains the number of
seconds since January 1, 1970 00:00:00 and a fraction of second
used for increased precision, or None if the normalized timestamp
cannot be determined.
"""
if self._normalized_timestamp is None:
if self._timestamp is not None:
Expand All @@ -66,7 +68,7 @@ def _GetNormalizedTimestamp(self):

return self._normalized_timestamp

def CopyFromDateTimeString(self, time_string):
def CopyFromDateTimeString(self, time_string: str) -> None:
"""Copies a Cocoa timestamp from a date and time string.
Args:
Expand All @@ -92,19 +94,20 @@ def CopyFromDateTimeString(self, time_string):
microseconds = date_time_values.get('microseconds', None)
time_zone_offset = date_time_values.get('time_zone_offset', 0)

timestamp = self._GetNumberOfSecondsFromElements(
year, month, day_of_month, hours, minutes, seconds, time_zone_offset)
timestamp += self._COCOA_TO_POSIX_BASE
number_of_seconds = self._GetNumberOfSecondsFromElements(
year, month, day_of_month, hours, minutes, seconds,
time_zone_offset=time_zone_offset)
number_of_seconds += self._COCOA_TO_POSIX_BASE

timestamp = float(timestamp)
timestamp = float(number_of_seconds)
if microseconds is not None:
timestamp += float(microseconds) / definitions.MICROSECONDS_PER_SECOND

self._normalized_timestamp = None
self._timestamp = timestamp
self._time_zone_offset = time_zone_offset

def CopyToDateTimeString(self):
def CopyToDateTimeString(self) -> typing.Union[str, None]:
"""Copies the Cocoa timestamp to a date and time string.
Returns:
Expand Down
11 changes: 9 additions & 2 deletions dfdatetime/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@
from __future__ import unicode_literals

import warnings
import typing


def deprecated(function): # pylint: disable=invalid-name
# pylint: disable=invalid-name
RETURN_TYPE = typing.TypeVar('RETURN_TYPE')


def deprecated(function: typing.Callable[..., RETURN_TYPE]) -> typing.Callable[
..., RETURN_TYPE]:
"""Decorator to mark functions or methods as deprecated."""

def IssueDeprecationWarning(*args, **kwargs):
def IssueDeprecationWarning(
*args: typing.Any, **kwargs: typing.Any) -> RETURN_TYPE:
"""Issue a deprecation warning."""
warnings.simplefilter('default', DeprecationWarning)
warnings.warn('Call to deprecated function: {0:s}.'.format(
Expand Down
30 changes: 16 additions & 14 deletions dfdatetime/delphi_date_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from __future__ import unicode_literals

import decimal
import typing

from dfdatetime import definitions
from dfdatetime import interface
Expand All @@ -12,7 +13,7 @@
class DelphiDateTimeEpoch(interface.DateTimeEpoch):
"""Delphi TDateTime epoch."""

def __init__(self):
def __init__(self) -> None:
"""Initializes a Delphi TDateTime epoch."""
super(DelphiDateTimeEpoch, self).__init__(1899, 12, 30)

Expand All @@ -38,29 +39,29 @@ class DelphiDateTime(interface.DateTimeValues):

_EPOCH = DelphiDateTimeEpoch()

def __init__(self, timestamp=None):
def __init__(self, timestamp: typing.Optional[float] = None) -> None:
"""Initializes a Delphi TDateTime timestamp.
Args:
timestamp (Optional[float]): Delphi TDateTime timestamp.
"""
super(DelphiDateTime, self).__init__()
self._precision = definitions.PRECISION_1_MILLISECOND
self._timestamp = timestamp
self._precision: str = definitions.PRECISION_1_MILLISECOND
self._timestamp: typing.Union[float, None] = timestamp

@property
def timestamp(self):
def timestamp(self) -> typing.Union[float, None]:
"""float: Delphi TDateTime timestamp or None if timestamp is not set."""
return self._timestamp

def _GetNormalizedTimestamp(self):
def _GetNormalizedTimestamp(self) -> typing.Union[decimal.Decimal, None]:
"""Retrieves the normalized timestamp.
Returns:
decimal.Decimal: normalized timestamp, which contains the number of
seconds since January 1, 1970 00:00:00 and a fraction of second used
for increased precision, or None if the normalized timestamp cannot be
determined.
seconds since January 1, 1970 00:00:00 and a fraction of second
used for increased precision, or None if the normalized timestamp
cannot be determined.
"""
if self._normalized_timestamp is None:
if self._timestamp is not None:
Expand All @@ -70,7 +71,7 @@ def _GetNormalizedTimestamp(self):

return self._normalized_timestamp

def CopyFromDateTimeString(self, time_string):
def CopyFromDateTimeString(self, time_string: str) -> None:
"""Copies a Delphi TDateTime timestamp from a string.
Args:
Expand Down Expand Up @@ -99,10 +100,11 @@ def CopyFromDateTimeString(self, time_string):
if year > 9999:
raise ValueError('Unsupported year value: {0:d}.'.format(year))

timestamp = self._GetNumberOfSecondsFromElements(
year, month, day_of_month, hours, minutes, seconds, time_zone_offset)
number_of_seconds = self._GetNumberOfSecondsFromElements(
year, month, day_of_month, hours, minutes, seconds,
time_zone_offset=time_zone_offset)

timestamp = float(timestamp) / definitions.SECONDS_PER_DAY
timestamp = float(number_of_seconds) / definitions.SECONDS_PER_DAY
timestamp += self._DELPHI_TO_POSIX_BASE
if microseconds is not None:
timestamp += float(microseconds) / definitions.MICROSECONDS_PER_DAY
Expand All @@ -111,7 +113,7 @@ def CopyFromDateTimeString(self, time_string):
self._timestamp = timestamp
self._time_zone_offset = time_zone_offset

def CopyToDateTimeString(self):
def CopyToDateTimeString(self) -> typing.Union[str, None]:
"""Copies the Delphi TDateTime timestamp to a date and time string.
Returns:
Expand Down
Loading

0 comments on commit a831901

Please sign in to comment.