(sorry for the length of this reply)

> On Sep 14, 2016, at 11:30, Yuya Nishihara <y...@tcha.org> wrote:
> 
> On Wed, 14 Sep 2016 11:05:40 -0400, Augie Fackler wrote:
>>> On Sep 14, 2016, at 11:03, Yuya Nishihara <y...@tcha.org> wrote:
>>> 
>>> On Tue, 13 Sep 2016 23:11:18 -0400, Augie Fackler wrote:
>>>> # HG changeset patch
>>>> # User Augie Fackler <au...@google.com>
>>>> # Date 1472584421 14400
>>>> #      Tue Aug 30 15:13:41 2016 -0400
>>>> # Node ID 828f260114a3a55e246cb5de434e75bdc782e4ad
>>>> # Parent  600be3c9acee0ec14bd19c032cc0480e4501fe8c
>>>> fancyopts: disallow true as a boolean flag default (API)

[...]

> But that can be changed incrementally. We need tristate for diffopts because
> they are computed from command and config options, but many other commands 
> take
> None and False as the same value so they can remain to default to None/False.
> 
> I think --no-git is the most important stuff, which won't be difficult to
> port to <unset> since opts are processed by patch.diff*opts().

Is the idea something like:

fancyopts.py:

unsetbool = object()

in commands.py:

 diffopts = [
-     ('a', 'text', None, _('treat all files as text')),
+     ('a', 'text', fancyopts.unsetbool, _('treat all files as text')),
-     ('g', 'git', None, _('use git extended diff format')),
+     ('g', 'git', fancyopts.unsetbool, _('use git extended diff format')),
-     ('', 'nodates', None, _('omit dates from diff headers'))
+     ('', 'nodates', fancyopts.unsetbool, _('omit dates from diff headers'))
 ]

And then we could synthesize negated versions only for booleans that have 
fancyopts.unsetbool as the default? That'd be less generic (and so require a 
lot more cleanup work on a per-option basis), but maybe that's a good thing? 
Note that changing these entries in diffopts do stand to be at least a little 
bit risky for extensions (they may not be ready for the fancyopts.unsetbool 
part of the tai-state), but I don't think that's something we should worry 
about overmuch.

I could also see room for something like

class unsetbool(object):
  default = True
  def __init__(self, v):
    self._v = v
  def __bool__(self):
    return self._v

and then you'd have your default value be specified as 
fancyopts.unsetbool(True|False). I don't like this as well, but I can't put my 
finger on why (a previous round of this series between v2 and v3 actually went 
down this route and it got somewhat messy, but I was trying to be more generic 
and automatic about it).

Regardless, both of these new proposed approaches still leave us in the awkward 
place of having to figure out how to describe the default for a boolean flag in 
the help. 


If we go ahead with what I've got, that pretty well ties our hands in the 
future. I'd still rather do this[1] (it's already done, and means boolean flags 
are globally consistent behavior-wise) than have to go through and tweak the 
default value on nearly boolean flag in the codebase (and still have extensions 
get zero benefit). It also makes documentation simpler[0] - the default mode of 
a flag is the opposite of what shows up in help (so if the default of 'check' 
is false, then we show --check, but if the default is --check, we describe the 
flag as --no-check in the help output.)

How do people want to proceed?

AF

0: although still hard - even just notating that a flag can be negated without 
true-default as a possibility doesn't have an obvious correct answer yet. See 
patch 7.

1: I don't want to rush this through, even if it sort of sounds like that from 
this mail.
_______________________________________________
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Reply via email to