Adding detect-raw-datetime-manipulation option

This commit is contained in:
Asim Goheer 2018-11-14 14:14:39 -08:00
parent 2dbaced650
commit 6932b83509
8 changed files with 161 additions and 1 deletions

View file

@ -105,6 +105,12 @@
entry: detect-private-key
language: python
types: [text]
- id: detect-datetime-raw-manipulation
name: Detect Raw datetime manipulation
description: Detects the raw manipulation of datetime.
entry: detect-datetime-raw-manipulation
language: python
types: [text]
- id: double-quote-string-fixer
name: Fix double quoted strings
description: This hook replaces double quoted strings with single quoted strings

View file

@ -64,6 +64,7 @@ Add this to your `.pre-commit-config.yaml`
- `--allow-missing-credentials` - Allow hook to pass when no credentials are
detected.
- `detect-private-key` - Checks for the existence of private keys.
- `detect-datetime-raw-manipulation` - Check for raw manipulation of datetime.
- `double-quote-string-fixer` - This hook replaces double quoted strings
with single quoted strings.
- `end-of-file-fixer` - Makes sure files end in a newline and only a newline.

View file

@ -0,0 +1,43 @@
from __future__ import print_function
from __future__ import unicode_literals
import argparse
import re
import sys
DT_MANIPULATION_RE = re.compile(
r'[+-]=?\s?datetime.timedelta\(|[+-]=?\s?timedelta\(|.replace\(.*tzinfo=|datetime\(.*tzinfo=',
)
def _check_file(filename):
return_value = 0
with open(filename, 'r') as f:
for i, line in enumerate(f, 1):
if DT_MANIPULATION_RE.search(line):
if line.strip().endswith(' # safe_dt_op') or line.strip().startswith('#'):
continue
sys.stdout.write('{}:{}: {}'.format(filename, i, line))
sys.stdout.flush()
return_value += 1
return return_value
def main(argv=None):
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*')
args = parser.parse_args(argv)
return_value = 0
for filename in args.filenames:
result = _check_file(filename)
return_value |= 1 if result > 0 else 0
return return_value
if __name__ == '__main__':
exit(main())

View file

@ -6,7 +6,7 @@ setup(
name='pre_commit_hooks',
description='Some out-of-the-box hooks for pre-commit.',
url='https://github.com/pre-commit/pre-commit-hooks',
version='2.0.0',
version='2.1.0',
author='Anthony Sottile',
author_email='asottile@umich.edu',
@ -47,6 +47,8 @@ setup(
'debug-statement-hook = pre_commit_hooks.debug_statement_hook:main',
'detect-aws-credentials = pre_commit_hooks.detect_aws_credentials:main',
'detect-private-key = pre_commit_hooks.detect_private_key:detect_private_key',
'detect-datetime-raw-manipulation = '
'pre_commit_hooks.detect_datetime_raw_manipulation:detect_datetime_raw_manipulation',
'double-quote-string-fixer = pre_commit_hooks.string_fixer:main',
'end-of-file-fixer = pre_commit_hooks.end_of_file_fixer:end_of_file_fixer',
'file-contents-sorter = pre_commit_hooks.file_contents_sorter:main',

View file

@ -0,0 +1,27 @@
import datetime
from datetime import timedelta
def dummy_func(inp):
print(inp)
def move_time_forward():
now = datetime.datetime.now()
# Check commented out lines
# now += timedelta(days=1)
# now += datetime.timedelta(weeks=1)
#
# now -= timedelta(weeks=1)
# now -= timedelta(weeks=2)
#
# now = now.replace(hour=2)
# now = now.replace(tzinfo=None)
# now = now.replace(hour=1, tzinfo=pytz.utc)
# Test regular usage of timedelta & datetime
dummy_func(timedelta(days=1))
dummy_func(datetime.datetime(2018, 10, 11, 2, 3, 4, 450000))
print(now)

View file

@ -0,0 +1,37 @@
import datetime
from datetime import timedelta
import pytz
def move_time_forward():
now = datetime.datetime.now()
timezone = pytz.utc
# 1
now = datetime.datetime(now.year, now.month, now.day, hour=8, minute=0, tzinfo=timezone)
# 2
now += timedelta(days=1)
# 3
now += datetime.timedelta(weeks=1)
# 4
now = now + timedelta(seconds=1)
# 5
now -= datetime.timedelta(weeks=1)
# 6
now -= timedelta(weeks=2)
# 7
now = now - timedelta(seconds=1)
now = now.replace(hour=2)
# 8
now = now.replace(tzinfo=None)
# 9
now = now.replace(hour=1, tzinfo=pytz.utc)
# 10
now = datetime.datetime(2018, 10, 11, 2, 3, 4, 450000, tzinfo=pytz.utc)
print(now)

View file

@ -0,0 +1,20 @@
import datetime
from datetime import timedelta
import pytz
def move_time_forward():
now = datetime.datetime.now()
now += timedelta(days=1) # safe_dt_op
now += datetime.timedelta(weeks=1) # safe_dt_op
now -= timedelta(weeks=1) # safe_dt_op
now -= timedelta(weeks=2) # safe_dt_op
now = now.replace(hour=2)
now = now.replace(tzinfo=None) # safe_dt_op
now = now.replace(hour=1, tzinfo=pytz.utc) # safe_dt_op
print(now)

View file

@ -0,0 +1,24 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from pre_commit_hooks.detect_datetime_raw_manipulation import _check_file
from pre_commit_hooks.detect_datetime_raw_manipulation import main
from testing.util import get_resource_path
def test_flagged_file():
rc = main([get_resource_path('detect_datetime_raw_manipulation/raw_timedelta_usage__flag.py')])
assert rc == 1
result = _check_file(get_resource_path('detect_datetime_raw_manipulation/raw_timedelta_usage__flag.py'))
assert result == 10
def test_flagged_ignore():
rc = main([get_resource_path('detect_datetime_raw_manipulation/raw_timedelta_usage__ignore.py')])
assert rc == 0
def test_flagged_clean():
rc = main([get_resource_path('detect_datetime_raw_manipulation/raw_timedelta_usage__clean.py')])
assert rc == 0