# HG changeset patch # User Yuya Nishihara # Date 1572147059 -32400 # Node ID 242ad45b60b3ad3f9824b5c8d3c649c239792ffe # Parent 4128ffba4431e516d0e2c5d7c31b0c4ca32679e7 config: fix -Tjson to not crash due to unsupported defaultvalue types Maybe it isn't great to ignore unsupported types at all, but otherwise "hg config -Tjson" would crash. diff -r 4128ffba4431 -r 242ad45b60b3 mercurial/commands.py --- a/mercurial/commands.py Sun Oct 27 18:12:24 2019 +0100 +++ b/mercurial/commands.py Sun Oct 27 12:30:59 2019 +0900 @@ -2267,7 +2267,9 @@ fm.write(b'value', b'%s\n', value) else: fm.write(b'name value', b'%s=%s\n', entryname, value) - fm.data(defaultvalue=defaultvalue) + if formatter.isprintable(defaultvalue): + fm.data(defaultvalue=defaultvalue) + # TODO: no idea how to process unsupported defaultvalue types matched = True fm.end() if matched: diff -r 4128ffba4431 -r 242ad45b60b3 mercurial/formatter.py --- a/mercurial/formatter.py Sun Oct 27 18:12:24 2019 +0100 +++ b/mercurial/formatter.py Sun Oct 27 12:30:59 2019 +0900 @@ -136,6 +136,16 @@ pickle = util.pickle +def isprintable(obj): + """Check if the given object can be directly passed in to formatter's + write() and data() functions + + Returns False if the object is unsupported or must be pre-processed by + formatdate(), formatdict(), or formatlist(). + """ + return isinstance(obj, (type(None), bool, int, pycompat.long, float, bytes)) + + class _nullconverter(object): '''convert non-primitive data types to be processed by formatter''' diff -r 4128ffba4431 -r 242ad45b60b3 tests/test-config.t --- a/tests/test-config.t Sun Oct 27 18:12:24 2019 +0100 +++ b/tests/test-config.t Sun Oct 27 12:30:59 2019 +0900 @@ -87,6 +87,170 @@ } ] +Test config default of various types: + + {"defaultvalue": ""} for -T'json(defaultvalue)' looks weird, but that's + how the templater works. Unknown keywords are evaluated to "". + + dynamicdefault + + $ hg config --config alias.foo= alias -Tjson + [ + { + "name": "alias.foo", + "source": "--config", + "value": "" + } + ] + $ hg config --config alias.foo= alias -T'json(defaultvalue)' + [ + {"defaultvalue": ""} + ] + $ hg config --config alias.foo= alias -T'{defaultvalue}\n' + + + null + + $ hg config --config auth.cookiefile= auth -Tjson + [ + { + "defaultvalue": null, + "name": "auth.cookiefile", + "source": "--config", + "value": "" + } + ] + $ hg config --config auth.cookiefile= auth -T'json(defaultvalue)' + [ + {"defaultvalue": ""} + ] + $ hg config --config auth.cookiefile= auth -T'{defaultvalue}\n' + + + false + + $ hg config --config commands.commit.post-status= commands -Tjson + [ + { + "defaultvalue": false, + "name": "commands.commit.post-status", + "source": "--config", + "value": "" + } + ] + $ hg config --config commands.commit.post-status= commands -T'json(defaultvalue)' + [ + {"defaultvalue": false} + ] + $ hg config --config commands.commit.post-status= commands -T'{defaultvalue}\n' + False + + true + + $ hg config --config format.dotencode= format -Tjson + [ + { + "defaultvalue": true, + "name": "format.dotencode", + "source": "--config", + "value": "" + } + ] + $ hg config --config format.dotencode= format -T'json(defaultvalue)' + [ + {"defaultvalue": true} + ] + $ hg config --config format.dotencode= format -T'{defaultvalue}\n' + True + + bytes + + $ hg config --config commands.resolve.mark-check= commands -Tjson + [ + { + "defaultvalue": "none", + "name": "commands.resolve.mark-check", + "source": "--config", + "value": "" + } + ] + $ hg config --config commands.resolve.mark-check= commands -T'json(defaultvalue)' + [ + {"defaultvalue": "none"} + ] + $ hg config --config commands.resolve.mark-check= commands -T'{defaultvalue}\n' + none + + empty list + + $ hg config --config commands.show.aliasprefix= commands -Tjson + [ + { + "name": "commands.show.aliasprefix", + "source": "--config", + "value": "" + } + ] + $ hg config --config commands.show.aliasprefix= commands -T'json(defaultvalue)' + [ + {"defaultvalue": ""} + ] + $ hg config --config commands.show.aliasprefix= commands -T'{defaultvalue}\n' + + + nonempty list + + $ hg config --config progress.format= progress -Tjson + [ + { + "name": "progress.format", + "source": "--config", + "value": "" + } + ] + $ hg config --config progress.format= progress -T'json(defaultvalue)' + [ + {"defaultvalue": ""} + ] + $ hg config --config progress.format= progress -T'{defaultvalue}\n' + + + int + + $ hg config --config profiling.freq= profiling -Tjson + [ + { + "defaultvalue": 1000, + "name": "profiling.freq", + "source": "--config", + "value": "" + } + ] + $ hg config --config profiling.freq= profiling -T'json(defaultvalue)' + [ + {"defaultvalue": 1000} + ] + $ hg config --config profiling.freq= profiling -T'{defaultvalue}\n' + 1000 + + float + + $ hg config --config profiling.showmax= profiling -Tjson + [ + { + "defaultvalue": 0.999, + "name": "profiling.showmax", + "source": "--config", + "value": "" + } + ] + $ hg config --config profiling.showmax= profiling -T'json(defaultvalue)' + [ + {"defaultvalue": 0.999} + ] + $ hg config --config profiling.showmax= profiling -T'{defaultvalue}\n' + 0.999 + Test empty config source: $ cat < emptysource.py