Skip to content

Commit

Permalink
Merge d2acf23 into b274f34
Browse files Browse the repository at this point in the history
  • Loading branch information
okin committed Dec 31, 2018
2 parents b274f34 + d2acf23 commit 55a9d4e
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 2 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@
* Michael Milton - https://github.com/tmiguelt
* Mike Pagel - https://github.com/moltob
* Marijn van Vliet - https://github.com/wmvanvliet
* Niko Wenselowski - https://github.com/okin
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Changes
Using json instead of repr.
- Fix #261: help organize command options in sections, and improve formatting.
- Fix #267: `doit list` now has a `--sort` parameter to determine the order in which the tasks are listed.
- Make it possible to use a custom encoder when using config_changed with a dict.


0.31.1 (*2018-03-18*)
Expand Down
3 changes: 3 additions & 0 deletions doc/uptodate.rst
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ changed. Config values can be a string or dict.
For dict's the values are converted to string (using `json.dumps()` with `sort_key=True`)
and only a digest/checksum of the dictionaries keys and values are saved.

If converting the values of the dict requires a special encoder this can be
passed with the argument ``encoder=...``. This will be passed on to `json.dumps()`.

.. literalinclude:: samples/config_params.py


Expand Down
6 changes: 4 additions & 2 deletions doit/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,18 @@ def save_executed():
class config_changed(object):
"""check if passed config was modified
@var config (str) or (dict)
@var encoder (json.JSONEncoder) Encoder used to convert non-default values.
"""
def __init__(self, config):
def __init__(self, config, encoder=None):
self.config = config
self.config_digest = None
self.encoder = encoder

def _calc_digest(self):
if isinstance(self.config, str):
return self.config
elif isinstance(self.config, dict):
data = json.dumps(self.config, sort_keys=True)
data = json.dumps(self.config, sort_keys=True, cls=self.encoder)
byte_data = data.encode("utf-8")
return hashlib.md5(byte_data).hexdigest()
else:
Expand Down
16 changes: 16 additions & 0 deletions tests/test_tools.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import datetime
import json
import operator
from sys import executable

Expand Down Expand Up @@ -101,6 +102,21 @@ def test_nested_dict(self):
assert True == c1a(t1, t1.values)
assert True == c1b(t1, t1.values)

def test_using_custom_encoder(self):

class DatetimeJSONEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, datetime.datetime):
return o.isoformat()

ua = tools.config_changed({'a': datetime.datetime(2018, 12, 10, 10, 33, 55, 478421), 'b': 'bb'}, encoder=DatetimeJSONEncoder)
ub = tools.config_changed({'a': datetime.datetime.now(), 'b': 'bb'}, encoder=DatetimeJSONEncoder)
t1 = task.Task("TaskX", None, uptodate=[ua])
assert ua(t1, t1.values) is False
assert ub(t1, t1.values) is False
t1.save_extra_values()
assert ua(t1, t1.values) is True
assert ub(t1, t1.values) is False


class TestTimeout(object):
Expand Down

0 comments on commit 55a9d4e

Please sign in to comment.