Re: [PATCH stable] py3: always flush ui streams on Python 3

2020-06-04 Thread Denis Laxalde
Yuya Nishihara a écrit :
> On Wed, 03 Jun 2020 05:46:05 +0200, Manuel Jacob wrote:
> > On 2020-06-03 00:04, Augie Fackler wrote:
> > >> On Jun 2, 2020, at 14:07, Manuel Jacob  wrote:
> > >> 
> > >> # HG changeset patch
> > >> # User Manuel Jacob 
> > >> # Date 1591120869 -7200
> > >> #  Tue Jun 02 20:01:09 2020 +0200
> > >> # Branch stable
> > >> # Node ID ebbc45544673c33ea3beb887ed4d5230b015102a
> > >> # Parent  91e509a12dbc4cd6cf2dcb9dae3ed383932132ac
> > >> py3: always flush ui streams on Python 3
> > >> 
> > >> On Python 2, we rely on that stdout and stderr are line buffered. 
> > >> Python 3’s
> > >> io module doesn’t offer line buffered binary streams.
> > > 
> > > We use the underlying non-buffer thing though for std{err, out}
> > > though, or so I thought. Are you observing  behavior that this
> > > corrects?
> > 
> > pycompat says:
> > 
> >  stdout = sys.stdout.buffer
> >  stderr = sys.stderr.buffer
> > 
> > They are <_io.BufferedWriter name=''> and <_io.BufferedWriter 
> > name=''>, respectively.
> > 
> > I observed the error in TortoiseHg, which is a long-running process.
> > 
> > To trigger the problem with the hg command, you would need to do 
> > something slow that prints on `self._fout`, e.g. `hg pull 
> > https://www.mercurial-scm.org/repo/hg --debug`.
> 
> Denis, do you have any idea? My assumption was sys.stdout.buffer was magically
> line-buffered, but it appears not at least with Python 3.8.3 on Linux.

sys.stdout is documented to be line-buffered in interactive mode.
But looking at the implementation of TextIOWrapper, line buffering is
apparently not handled at the underlying buffer level (which we use
IIRC):

  https://github.com/python/cpython/blob/v3.8.3/Lib/_pyio.py#L2210

This would mean that sys.stdout.buffer is not line-buffered.

So perhaps flushing using a similar logic as in TextIOWrapper.write(),
but at the buffer level, is the way go.


> https://www.mercurial-scm.org/repo/hg/rev/227ba1afcb65
> 
> > >> --- a/mercurial/ui.py
> > >> +++ b/mercurial/ui.py
> > >> @@ -1198,9 +1198,14 @@ class ui(object):
> > >> label = opts.get('label', b'')
> > >> msg = self.label(msg, label)
> > >> dest.write(msg)
> > >> +# On Python 2, stdout and stderr are usually line 
> > >> buffered, but
> > >> # stderr may be buffered under win32 when redirected to 
> > >> files,
> > >> # including stdout.
> > >> -if dest is self._ferr and not getattr(self._ferr, 
> > >> 'closed', False):
> > >> +# On Python 3, we use the underlying binary buffer, which 
> > >> does not
> > >> +# support line buffering.
> > >> +if (pycompat.ispy3 or dest is self._ferr) and not 
> > >> getattr(
> > >> +self._ferr, 'closed', False
> > >> +):
> > >> dest.flush()
> 
> Flushing stdout per write() sounds bad. If that's the only way to work
> around Py3 io module, we'll probably need to check if the stdout is
> a tty or not.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7384: commands: necessary annotations and suppresssions to pass pytype

2020-01-30 Thread dlax (Denis Laxalde)
dlax added a comment.


  In D7384#118739 , @marmoute 
wrote:
  
  > What's up on this ? It seemed on a good track, but I don't think it landed. 
@dlax I think you offer to use a context manager got a warm welcome, I would 
says, go ahead with it.
  
  The context manager got in through D7430 
.

INLINE COMMENTS

> commands.py:4741
> +# pytype isn't convinced, so we have to suppress the
> +# warning about list not having a max() method.
>  endrev = revs.max() + 1

I think this comment should be removed since the `# pytype: disable` got 
removed in the last version of the diff.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7384/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7384

To: durin42, #hg-reviewers, dlax
Cc: marmoute, dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7980: resourceutil: ensure `_rootpath` is defined under py2exe

2020-01-23 Thread dlax (Denis Laxalde)
dlax added inline comments.

INLINE COMMENTS

> resourceutil.py:39
>  datapath = os.path.dirname(os.path.dirname(pycompat.fsencode(__file__)))
>  _rootpath = os.path.dirname(datapath)
>  

`_rootpath` declaration could be moved after the `else` clause to avoid 
repetition.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7980/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7980

To: mharbison72, #hg-reviewers
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH STABLE v2] py3: force bytestr conversion of "reason" in scmutil.callcatch()

2019-12-18 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1576696641 -3600
#  Wed Dec 18 20:17:21 2019 +0100
# Branch stable
# Node ID 33249635134f8c3fdcd79b1a0da15880a2f57650
# Parent  743c69b393326ab82383638c1fed669794ac0ec1
py3: force bytestr conversion of "reason" in scmutil.callcatch()

For instance, reason may be an InvalidURL as shown in added test.

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -262,7 +262,7 @@ def callcatch(ui, func):
 if isinstance(reason, pycompat.unicode):
 # SSLError of Python 2.7.9 contains a unicode
 reason = encoding.unitolocal(reason)
-ui.error(_(b"abort: error: %s\n") % reason)
+ui.error(_(b"abort: error: %s\n") % 
stringutil.forcebytestr(reason))
 elif (
 util.safehasattr(inst, b"args")
 and inst.args
diff --git a/tests/test-clone.t b/tests/test-clone.t
--- a/tests/test-clone.t
+++ b/tests/test-clone.t
@@ -614,6 +614,12 @@ No local source
   abort: repository a not found!
   [255]
 
+Invalid URL
+
+  $ hg clone http://invalid:url/a b
+  abort: error: nonnumeric port: 'url'
+  [255]
+
 No remote source
 
 #if windows

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH STABLE] py3: force bytestr conversion of "reason" in scmutil.callcatch()

2019-12-18 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1576687426 -3600
#  Wed Dec 18 17:43:46 2019 +0100
# Branch stable
# Node ID b5ea9c258bedfc2ba12111e98c038076ded3ac6a
# Parent  b06cf2809ec3486b25187ac2c8e766d6ac18763b
py3: force bytestr conversion of "reason" in scmutil.callcatch()

For instance, reason may be InvalidURL.

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -262,7 +262,7 @@ def callcatch(ui, func):
 if isinstance(reason, pycompat.unicode):
 # SSLError of Python 2.7.9 contains a unicode
 reason = encoding.unitolocal(reason)
-ui.error(_(b"abort: error: %s\n") % reason)
+ui.error(_(b"abort: error: %s\n") % 
stringutil.forcebytestr(reason))
 elif (
 util.safehasattr(inst, b"args")
 and inst.args
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7682: patch: make __repr__() return str

2019-12-17 Thread dlax (Denis Laxalde)
dlax added inline comments.
dlax accepted this revision.

INLINE COMMENTS

> patch.py:966
>  def __repr__(self):
> -return b'' % (b' '.join(map(repr, self.files(
> +return '' % (' '.join(map(repr, self.files(
>  

Somehow unrelated, but `self.files()` returns a list of bytes I think. So this 
will lead to something like `""`. But maybe this is 
okay? (at least it wouldn't crash now)

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7682/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7682

To: mharbison72, #hg-reviewers, pulkit, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7633: clone: extract helper for checking mutually exclusive args

2019-12-13 Thread dlax (Denis Laxalde)
dlax added a comment.


  Useful refactoring!

INLINE COMMENTS

> cmdutil.py:263
>  
> +def check_unique_argument(opts, *args):
> +"""abort if more than one of the arguments are in opts"""

The function name is a bit misleading; it looks like it would check that an 
option wasn't specified multiple times. Perhaps `check_exclusive_arguments`?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7633/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7633

To: martinvonz, #hg-reviewers
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7620: merge: add commands.merge.require-rev to require an argument to hg merge

2019-12-13 Thread dlax (Denis Laxalde)
This revision now requires changes to proceed.
dlax added a comment.
dlax requested changes to this revision.


  This should be documented in `mercurial/helptext/config.txt` I think.
  
  Otherwise, this look sensible to me.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7620/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7620

To: spectral, #hg-reviewers, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7506: phabricator: add a "phabstatus" show view

2019-12-11 Thread dlax (Denis Laxalde)
dlax added a comment.


  In D7506#111947 , @spectral 
wrote:
  
  > I don't think `from . import show` works generally.
  
  I did that because `test-check-module-imports.t` complained otherwise when 
using `from hgext import show`:
  
hgext/phabricator.py:89: import should be relative: hgext
  
  Also, there's already a similar `from . import rebase` in `hgext/split.py` so 
I thought that relative import was fine.
  
  I'm happy to change if there's a solution, though.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7506/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7506

To: dlax, #hg-reviewers, pulkit
Cc: spectral, mharbison72, mjpieters, Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7506: phabricator: add a "phabstatus" show view

2019-12-11 Thread dlax (Denis Laxalde)
Closed by commit rHG70060915c3f2: phabricator: add a phabstatus 
show view (authored by dlax).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7506?vs=18589=18603

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7506/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7506

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -11,6 +11,10 @@
 revisions in a format suitable for :hg:`import`, and a ``phabupdate`` command
 to update statuses in batch.
 
+A "phabstatus" view for :hg:`show` is also provided; it displays status
+information of Phabricator differentials associated with unfinished
+changesets.
+
 By default, Phabricator requires ``Test Plan`` which might prevent some
 changeset from being sent. The requirement could be disabled by changing
 ``differential.require-test-plan-field`` config server side.
@@ -60,7 +64,9 @@
 encoding,
 error,
 exthelper,
+graphmod,
 httpconnection as httpconnectionmod,
+logcmdutil,
 match,
 mdiff,
 obsutil,
@@ -80,6 +86,8 @@
 procutil,
 stringutil,
 )
+from . import show
+
 
 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' 
for
 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
@@ -465,6 +473,29 @@
 return result
 
 
+def getdrevmap(repo, revs):
+"""Return a dict mapping each rev in `revs` to their Differential Revision
+ID or None.
+"""
+result = {}
+for rev in revs:
+result[rev] = None
+ctx = repo[rev]
+# Check commit message
+m = _differentialrevisiondescre.search(ctx.description())
+if m:
+result[rev] = int(m.group('id'))
+continue
+# Check tags
+for tag in repo.nodetags(ctx.node()):
+m = _differentialrevisiontagre.match(tag)
+if m:
+result[rev] = int(m.group(1))
+break
+
+return result
+
+
 def getdiff(ctx, diffopts):
 """plain-text diff without header (user, commit message, etc)"""
 output = util.stringio()
@@ -1651,3 +1682,42 @@
 
 return templateutil.hybriddict({b'url': url, b'id': t,})
 return None
+
+
+@show.showview(b'phabstatus', csettopic=b'work')
+def phabstatusshowview(ui, repo, displayer):
+"""Phabricator differiential status"""
+revs = repo.revs('sort(_underway(), topo)')
+drevmap = getdrevmap(repo, revs)
+unknownrevs, drevids, revsbydrevid = [], set([]), {}
+for rev, drevid in pycompat.iteritems(drevmap):
+if drevid is not None:
+drevids.add(drevid)
+revsbydrevid.setdefault(drevid, set([])).add(rev)
+else:
+unknownrevs.append(rev)
+
+drevs = callconduit(ui, b'differential.query', {b'ids': list(drevids)})
+drevsbyrev = {}
+for drev in drevs:
+for rev in revsbydrevid[int(drev[b'id'])]:
+drevsbyrev[rev] = drev
+
+def phabstatus(ctx):
+drev = drevsbyrev[ctx.rev()]
+ui.write(b"\n%(uri)s %(statusName)s\n" % drev)
+
+revs -= smartset.baseset(unknownrevs)
+revdag = graphmod.dagwalker(repo, revs)
+
+ui.setconfig(b'experimental', b'graphshorten', True)
+displayer._exthook = phabstatus
+nodelen = show.longestshortest(repo, revs)
+logcmdutil.displaygraph(
+ui,
+repo,
+revdag,
+displayer,
+graphmod.asciiedges,
+props={b'nodelen': nodelen},
+)



To: dlax, #hg-reviewers, pulkit
Cc: mharbison72, mjpieters, Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7507: phabricator: add a "phabstatus" template keyword

2019-12-11 Thread dlax (Denis Laxalde)
Closed by commit rHG79c0121220e3: phabricator: add a phabstatus 
template keyword (authored by dlax).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7507?vs=18590=18604

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7507/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7507

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -1684,6 +1684,28 @@
 return None
 
 
+@eh.templatekeyword(b'phabstatus', requires={b'ctx', b'repo', b'ui'})
+def template_status(context, mapping):
+""":phabstatus: String. Status of Phabricator differential.
+"""
+ctx = context.resource(mapping, b'ctx')
+repo = context.resource(mapping, b'repo')
+ui = context.resource(mapping, b'ui')
+
+rev = ctx.rev()
+try:
+drevid = getdrevmap(repo, [rev])[rev]
+except KeyError:
+return None
+drevs = callconduit(ui, b'differential.query', {b'ids': [drevid]})
+for drev in drevs:
+if int(drev[b'id']) == drevid:
+return templateutil.hybriddict(
+{b'url': drev[b'uri'], b'status': drev[b'statusName'],}
+)
+return None
+
+
 @show.showview(b'phabstatus', csettopic=b'work')
 def phabstatusshowview(ui, repo, displayer):
 """Phabricator differiential status"""



To: dlax, #hg-reviewers, pulkit
Cc: mharbison72, Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 2] crecord: repurpose "a" key to toggle all selections (BC)

2019-12-11 Thread Denis Laxalde
Jordi Gutiérrez Hermoso a écrit :
> # HG changeset patch
> # User Jordi Gutiérrez Hermoso 
> # Date 1576015329 18000
> #  Tue Dec 10 17:02:09 2019 -0500
> # Node ID bd10bc4bdb994b875040c0c58f1c341df66ddd46
> # Parent  ce088b38f92b6d480df2072dc45fb068443758dd
> crecord: repurpose "a" key to toggle all selections (BC)
> 
> I really don't like "a". I keep accidentally hitting it when I
> actually want "A", and then I'm suddenly in a state I don't want to be
> in. There's a big wall of text telling me that I've turned amend mode
> on or off (which one was I orginally in?), and this seems very
> useless.

Sounds reasonable to me. Also this 'amend mode' seems only useful for
'commit --interactive'; but it's currently also available for other
interactive commands (e.g. 'revert --interactive', which makes no
sense) so it's already weird.

> If I wanted to amend or not, I would have chosen that from the
> command-line, not change my mind after I've already started picking
> hunks apart.

Agreed as well on this. IMHO, interactive diff hunks selection module
should only be concerned about selecting hunks.

> It seems much better to repurpose this key to be a "weaker" version of
> "A". It toggles all selections. This is pretty harmless if hit
> accidentally, (can just hit "a" again to undo it), and has immediate
> visual feedback that something happened: all the x's and blank spaces
> get switched around. And unlike with amend, the current flipped state
> is also immediately visible without having to read a wall of text.

Does "pretty harmless" mean that you can actually toggle back to the
previous selection? (If not, I wouldn't say this is harmless since the
user may have spend a fair amount of time carefully selecting hunks.)

Also, this breaks tests in test-commit-interactive-curses.t (and it'd be
nice to have some new test for the new feature).

> I'm calling this a BC, however, because somewhere, someone out there
> has probably really fallen in love with the old use of "a" and will
> get angry that we took it away.
> 
> diff --git a/mercurial/crecord.py b/mercurial/crecord.py
> --- a/mercurial/crecord.py
> +++ b/mercurial/crecord.py
> @@ -990,6 +990,13 @@ class curseschunkselector(object):
>  self.toggleapply(item)
>  self.waslasttoggleallapplied = not self.waslasttoggleallapplied
>  
> +def flipselections(self):
> +b"flip all selections"

Triple " without 'b' would be nicer.

> +for header in self.headerlist:
> +for hunk in header.allchildren():
> +for line in hunk.allchildren():
> +self.toggleapply(line)
> +
>  def toggleallbetween(self):
>  """toggle applied on or off for all items in range [lastapplied,
>  current]. """
> @@ -1637,7 +1644,7 @@ the following are valid keystrokes:
>   ctrl-l : scroll the selected line to the top of the screen
>m : edit / resume editing the commit message
>e : edit the currently selected hunk
> -  a : toggle amend mode, only with commit -i
> +  a : toggle all selections
>c : confirm selected changes
>r : review/edit and confirm selected changes
>q : quit without confirming (no changes will be made)
> @@ -1913,7 +1920,7 @@ are you sure you want to review/edit and
>  elif keypressed in ["q"]:
>  raise error.Abort(_(b'user quit'))
>  elif keypressed in ['a']:
> -self.toggleamend(self.opts, test)
> +self.flipselections()
>  elif keypressed in ["c"]:
>  return True
>  elif keypressed in ["r"]:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7507: phabricator: add a "phabstatus" template keyword

2019-12-10 Thread dlax (Denis Laxalde)
dlax updated this revision to Diff 18590.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7507?vs=18321=18590

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7507/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7507

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -1684,6 +1684,28 @@
 return None
 
 
+@eh.templatekeyword(b'phabstatus', requires={b'ctx', b'repo', b'ui'})
+def template_status(context, mapping):
+""":phabstatus: String. Status of Phabricator differential.
+"""
+ctx = context.resource(mapping, b'ctx')
+repo = context.resource(mapping, b'repo')
+ui = context.resource(mapping, b'ui')
+
+rev = ctx.rev()
+try:
+drevid = getdrevmap(repo, [rev])[rev]
+except KeyError:
+return None
+drevs = callconduit(ui, b'differential.query', {b'ids': [drevid]})
+for drev in drevs:
+if int(drev[b'id']) == drevid:
+return templateutil.hybriddict(
+{b'url': drev[b'uri'], b'status': drev[b'statusName'],}
+)
+return None
+
+
 @show.showview(b'phabstatus', csettopic=b'work')
 def phabstatusshowview(ui, repo, displayer):
 """Phabricator differiential status"""



To: dlax, #hg-reviewers, pulkit
Cc: mharbison72, Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7506: phabricator: add a "phabstatus" show view

2019-12-10 Thread dlax (Denis Laxalde)
dlax updated this revision to Diff 18589.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7506?vs=18338=18589

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7506/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7506

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -11,6 +11,10 @@
 revisions in a format suitable for :hg:`import`, and a ``phabupdate`` command
 to update statuses in batch.
 
+A "phabstatus" view for :hg:`show` is also provided; it displays status
+information of Phabricator differentials associated with unfinished
+changesets.
+
 By default, Phabricator requires ``Test Plan`` which might prevent some
 changeset from being sent. The requirement could be disabled by changing
 ``differential.require-test-plan-field`` config server side.
@@ -60,7 +64,9 @@
 encoding,
 error,
 exthelper,
+graphmod,
 httpconnection as httpconnectionmod,
+logcmdutil,
 match,
 mdiff,
 obsutil,
@@ -80,6 +86,8 @@
 procutil,
 stringutil,
 )
+from . import show
+
 
 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' 
for
 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
@@ -465,6 +473,29 @@
 return result
 
 
+def getdrevmap(repo, revs):
+"""Return a dict mapping each rev in `revs` to their Differential Revision
+ID or None.
+"""
+result = {}
+for rev in revs:
+result[rev] = None
+ctx = repo[rev]
+# Check commit message
+m = _differentialrevisiondescre.search(ctx.description())
+if m:
+result[rev] = int(m.group('id'))
+continue
+# Check tags
+for tag in repo.nodetags(ctx.node()):
+m = _differentialrevisiontagre.match(tag)
+if m:
+result[rev] = int(m.group(1))
+break
+
+return result
+
+
 def getdiff(ctx, diffopts):
 """plain-text diff without header (user, commit message, etc)"""
 output = util.stringio()
@@ -1651,3 +1682,42 @@
 
 return templateutil.hybriddict({b'url': url, b'id': t,})
 return None
+
+
+@show.showview(b'phabstatus', csettopic=b'work')
+def phabstatusshowview(ui, repo, displayer):
+"""Phabricator differiential status"""
+revs = repo.revs('sort(_underway(), topo)')
+drevmap = getdrevmap(repo, revs)
+unknownrevs, drevids, revsbydrevid = [], set([]), {}
+for rev, drevid in pycompat.iteritems(drevmap):
+if drevid is not None:
+drevids.add(drevid)
+revsbydrevid.setdefault(drevid, set([])).add(rev)
+else:
+unknownrevs.append(rev)
+
+drevs = callconduit(ui, b'differential.query', {b'ids': list(drevids)})
+drevsbyrev = {}
+for drev in drevs:
+for rev in revsbydrevid[int(drev[b'id'])]:
+drevsbyrev[rev] = drev
+
+def phabstatus(ctx):
+drev = drevsbyrev[ctx.rev()]
+ui.write(b"\n%(uri)s %(statusName)s\n" % drev)
+
+revs -= smartset.baseset(unknownrevs)
+revdag = graphmod.dagwalker(repo, revs)
+
+ui.setconfig(b'experimental', b'graphshorten', True)
+displayer._exthook = phabstatus
+nodelen = show.longestshortest(repo, revs)
+logcmdutil.displaygraph(
+ui,
+repo,
+revdag,
+displayer,
+graphmod.asciiedges,
+props={b'nodelen': nodelen},
+)



To: dlax, #hg-reviewers, pulkit
Cc: mharbison72, mjpieters, Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7505: logcmdutil: call _exthook() in changesettemplater

2019-12-10 Thread dlax (Denis Laxalde)
Closed by commit rHG6331a6fc3304: logcmdutil: call _exthook() in 
changesettemplater (authored by dlax).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7505?vs=18312=18581

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7505/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7505

AFFECTED FILES
  mercurial/logcmdutil.py

CHANGE DETAILS

diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -598,6 +598,7 @@
 # write changeset metadata, then patch if requested
 key = self._parts[self._tref]
 self.ui.write(self.t.render(key, props))
+self._exthook(ctx)
 self._showpatch(ctx, graphwidth)
 
 if self._parts[b'footer']:



To: dlax, #hg-reviewers, pulkit
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7513: phabricator: fix processing of tags/desc in getoldnodedrevmap()

2019-12-10 Thread dlax (Denis Laxalde)
Closed by commit rHG16b607e9f714: phabricator: fix processing of tags/desc in 
getoldnodedrevmap() (authored by dlax).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7513?vs=18339=18580

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7513/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7513

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -403,12 +403,15 @@
 m = _differentialrevisiontagre.match(tag)
 if m:
 toconfirm[node] = (0, set(precnodes), int(m.group(1)))
-continue
-
-# Check commit message
-m = _differentialrevisiondescre.search(ctx.description())
-if m:
-toconfirm[node] = (1, set(precnodes), int(m.group('id')))
+break
+else:
+continue  # move to next predecessor
+break  # found a tag, stop
+else:
+# Check commit message
+m = _differentialrevisiondescre.search(ctx.description())
+if m:
+toconfirm[node] = (1, set(precnodes), int(m.group('id')))
 
 # Double check if tags are genuine by collecting all old nodes from
 # Phabricator, and expect precursors overlap with it.



To: dlax, #hg-reviewers, pulkit
Cc: Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7540: tests: cover revision conversion logic in githelp tests

2019-12-02 Thread dlax (Denis Laxalde)
Closed by commit rHG5470e63686ca: tests: cover revision conversion logic in 
githelp tests (authored by dlax).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7540?vs=18417=18432

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7540/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7540

AFFECTED FILES
  tests/test-githelp.t

CHANGE DETAILS

diff --git a/tests/test-githelp.t b/tests/test-githelp.t
--- a/tests/test-githelp.t
+++ b/tests/test-githelp.t
@@ -264,6 +264,10 @@
   $ hg githelp -- git commit --reuse-message deadbeef
   hg commit -M deadbeef
 
+githelp for reuse message using HEAD
+  $ hg githelp -- git commit --reuse-message HEAD~
+  hg commit -M .~1
+
 githelp for apply with no options
   $ hg githelp -- apply
   hg import --no-commit



To: dlax, #hg-reviewers, pulkit, mharbison72
Cc: mharbison72, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7540: tests: cover revision conversion logic in githelp tests

2019-12-02 Thread dlax (Denis Laxalde)
dlax created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  There was no test involving actual conversion of option values when they
  contain a git revision name (to be converted as a hg one by
  hgext.githelp.convert()). Adding one. This test would fail on Python 3
  without https://phab.mercurial-scm.org/D7537.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D7540

AFFECTED FILES
  tests/test-githelp.t

CHANGE DETAILS

diff --git a/tests/test-githelp.t b/tests/test-githelp.t
--- a/tests/test-githelp.t
+++ b/tests/test-githelp.t
@@ -264,6 +264,10 @@
   $ hg githelp -- git commit --reuse-message deadbeef
   hg commit -M deadbeef
 
+githelp for reuse message using HEAD
+  $ hg githelp -- git commit --reuse-message HEAD~
+  hg commit -M .~1
+
 githelp for apply with no options
   $ hg githelp -- apply
   hg import --no-commit



To: dlax, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7537: githelp: fix a `str` type conditional for py3

2019-12-02 Thread dlax (Denis Laxalde)
dlax added a comment.
dlax accepted this revision.


  There is apparently no test coverage for this.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7537/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7537

To: mharbison72, #hg-reviewers, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7533: repair: fix an `isinstance(nodelist, str)` check for py3

2019-12-01 Thread dlax (Denis Laxalde)
dlax added a comment.
dlax accepted this revision.


  All these API where one can pass either a list of "things" or just one 
"thing" is kind of ugly. We should only handle the list case, I think.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7533/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7533

To: mharbison72, #hg-reviewers, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH STABLE v3] log: map None rev to wdirrev when filtering revisions with --line-range

2019-11-30 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1575060193 -3600
#  Fri Nov 29 21:43:13 2019 +0100
# Branch stable
# Node ID 9bb01a946abc17328a28920ccea61f50d41d987b
# Parent  969e8a52e3842d19387d02e91d6a19a993950ac0
log: map None rev to wdirrev when filtering revisions with --line-range

When 'hg log -f --line-range ,' is invoked with 
containing uncommitted changes, the command crashes on Python 3 as
follows:

  [...]
  File "/usr/lib/python3/dist-packages/mercurial/commands.py", line 4725, 
in log
revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
  File "/usr/lib/python3/dist-packages/mercurial/logcmdutil.py", line 933, 
in getlinerangerevs
if rev not in userrevs:
  File "/usr/lib/python3/dist-packages/mercurial/smartset.py", line 969, in 
__contains__
if l < x:
TypeError: '<' not supported between instances of 'int' and 'NoneType'

The None value is because requested line range has uncommitted changes,
so 'rev' is the working directory revision. This only occurs in Python 3
as Python 2 allows comparing None with int.

As suggested by Yuya Nishihara, mapping None to node.wdirrev resolves
the issue and also make the '--line-range' option properly work with -r
'wdir()'. We add extra tests for non-regression and to illustrate
handling of 'wdir()'.

diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -930,6 +930,8 @@ def getlinerangerevs(repo, userrevs, opt
 fctx = wctx.filectx(fname)
 for fctx, linerange in dagop.blockancestors(fctx, fromline, toline):
 rev = fctx.introrev()
+if rev is None:
+rev = wdirrev
 if rev not in userrevs:
 continue
 linerangesbyrev.setdefault(rev, {}).setdefault(
@@ -940,7 +942,7 @@ def getlinerangerevs(repo, userrevs, opt
 return hunks
 
 def hunksfilter(ctx):
-fctxlineranges = linerangesbyrev.get(ctx.rev())
+fctxlineranges = linerangesbyrev.get(scmutil.intrev(ctx))
 if fctxlineranges is None:
 return nofilterhunksfn
 
@@ -960,7 +962,7 @@ def getlinerangerevs(repo, userrevs, opt
 return filterfn
 
 def filematcher(ctx):
-files = list(linerangesbyrev.get(ctx.rev(), []))
+files = list(linerangesbyrev.get(scmutil.intrev(ctx), []))
 return scmutil.matchfiles(repo, files)
 
 revs = sorted(linerangesbyrev, reverse=True)
diff --git a/tests/test-log-linerange.t b/tests/test-log-linerange.t
--- a/tests/test-log-linerange.t
+++ b/tests/test-log-linerange.t
@@ -898,6 +898,99 @@ Uncommitted changes with a rename
   date:Thu Jan 01 00:00:00 1970 +
   summary: init
   
+
+Uncommitted changes in requested line range
+
+  $ sed 's/2/  /' bazn > bazn.new
+  $ mv bazn.new bazn
+  $ hg diff
+  diff --git a/dir/baz b/dir/bazn
+  rename from dir/baz
+  rename to dir/bazn
+  --- a/dir/baz
+  +++ b/dir/bazn
+  @@ -3,7 +3,7 @@
+   0
+   0
+1+
+  -2+
+  +  +
+   3+
+   4
+   5
+  $ hg log -f -L bazn,5:7
+  changeset:   9:6af29c3a778f
+  tag: tip
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: foo -> dir/baz; 1-1+
+  
+  changeset:   5:cfdf972b3971
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+
+  
+  changeset:   4:eaec41c1a0c9
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: 11 -> 11+; leading space before "1"
+  
+  changeset:   2:63a884426fd0
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: 2 -> 2+; added bar
+  
+  changeset:   0:5ae1f82b9a00
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: init
+  
+
+Uncommitted changes in line-range + wdir()
+
+  $ hg log -r 'wdir()' -f -L bazn,5:7 --limit 2 -p
+  changeset:   2147483647:
+  parent:  9:6af29c3a778f
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  
+  diff --git a/dir/baz b/dir/bazn
+  copy from dir/baz
+  copy to dir/bazn
+  --- a/dir/baz
+  +++ b/dir/bazn
+  @@ -3,7 +3,7 @@
+   0
+   0
+1+
+  -2+
+  +  +
+   3+
+   4
+   5
+  
+  changeset:   9:6af29c3a778f
+  tag: tip
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: foo -> dir/baz; 1-1+
+  
+  diff --git a/foo b/dir/baz
+  copy from foo
+  copy to dir/baz
+  --- a/foo
+  +++ b/dir/baz
+  @@ -2,7 +2,7 @@
+   0
+   0
+   0
+  - 1
+  + 1+
+   2+
+   3+
+   4
+  
+
   $ hg revert -a -C -q
 
 Binary files work but without diff hunks filtering.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH STABLE v2] log: map None rev to wdirrev when filtering revisions with --line-range

2019-11-30 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1575060193 -3600
#  Fri Nov 29 21:43:13 2019 +0100
# Branch stable
# Node ID 411d301683935cb02d1c15adbe1d7ef58789da76
# Parent  969e8a52e3842d19387d02e91d6a19a993950ac0
log: map None rev to wdirrev when filtering revisions with --line-range

When 'hg log -f --line-range ,' is invoked with 
containing uncommitted changes, the command crashes on Python 3 as
follows:

  [...]
  File "/usr/lib/python3/dist-packages/mercurial/commands.py", line 4725, 
in log
revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
  File "/usr/lib/python3/dist-packages/mercurial/logcmdutil.py", line 933, 
in getlinerangerevs
if rev not in userrevs:
  File "/usr/lib/python3/dist-packages/mercurial/smartset.py", line 969, in 
__contains__
if l < x:
TypeError: '<' not supported between instances of 'int' and 'NoneType'

The None value is because requested line range has uncommitted changes,
so 'rev' is the working directory revision. This only occurs in Python 3
as Python 2 allows comparing None with int.

As suggested by Yuya Nishihara, mapping None to node.wdirrev resolves
the issue and also make the '--line-range' option properly work with -r
'wdir()'. We add extra tests for non-regression and to illustrate
handling of 'wdir()'.

diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -920,6 +920,11 @@ def getlinerangerevs(repo, userrevs, opt
 """
 wctx = repo[None]
 
+def mapwdir(rev):
+if rev is None:
+return wdirrev
+return rev
+
 # Two-levels map of "rev -> file ctx -> [line range]".
 linerangesbyrev = {}
 for fname, (fromline, toline) in _parselinerangeopt(repo, opts):
@@ -929,7 +934,7 @@ def getlinerangerevs(repo, userrevs, opt
 )
 fctx = wctx.filectx(fname)
 for fctx, linerange in dagop.blockancestors(fctx, fromline, toline):
-rev = fctx.introrev()
+rev = mapwdir(fctx.introrev())
 if rev not in userrevs:
 continue
 linerangesbyrev.setdefault(rev, {}).setdefault(
@@ -940,7 +945,7 @@ def getlinerangerevs(repo, userrevs, opt
 return hunks
 
 def hunksfilter(ctx):
-fctxlineranges = linerangesbyrev.get(ctx.rev())
+fctxlineranges = linerangesbyrev.get(mapwdir(ctx.rev()))
 if fctxlineranges is None:
 return nofilterhunksfn
 
@@ -960,7 +965,7 @@ def getlinerangerevs(repo, userrevs, opt
 return filterfn
 
 def filematcher(ctx):
-files = list(linerangesbyrev.get(ctx.rev(), []))
+files = list(linerangesbyrev.get(mapwdir(ctx.rev()), []))
 return scmutil.matchfiles(repo, files)
 
 revs = sorted(linerangesbyrev, reverse=True)
diff --git a/tests/test-log-linerange.t b/tests/test-log-linerange.t
--- a/tests/test-log-linerange.t
+++ b/tests/test-log-linerange.t
@@ -898,6 +898,99 @@ Uncommitted changes with a rename
   date:Thu Jan 01 00:00:00 1970 +
   summary: init
   
+
+Uncommitted changes in requested line range
+
+  $ sed 's/2/  /' bazn > bazn.new
+  $ mv bazn.new bazn
+  $ hg diff
+  diff --git a/dir/baz b/dir/bazn
+  rename from dir/baz
+  rename to dir/bazn
+  --- a/dir/baz
+  +++ b/dir/bazn
+  @@ -3,7 +3,7 @@
+   0
+   0
+1+
+  -2+
+  +  +
+   3+
+   4
+   5
+  $ hg log -f -L bazn,5:7
+  changeset:   9:6af29c3a778f
+  tag: tip
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: foo -> dir/baz; 1-1+
+  
+  changeset:   5:cfdf972b3971
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+
+  
+  changeset:   4:eaec41c1a0c9
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: 11 -> 11+; leading space before "1"
+  
+  changeset:   2:63a884426fd0
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: 2 -> 2+; added bar
+  
+  changeset:   0:5ae1f82b9a00
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: init
+  
+
+Uncommitted changes in line-range + wdir()
+
+  $ hg log -r 'wdir()' -f -L bazn,5:7 --limit 2 -p
+  changeset:   2147483647:
+  parent:  9:6af29c3a778f
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  
+  diff --git a/dir/baz b/dir/bazn
+  copy from dir/baz
+  copy to dir/bazn
+  --- a/dir/baz
+  +++ b/dir/bazn
+  @@ -3,7 +3,7 @@
+   0
+   0
+1+
+  -2+
+  +  +
+   3+
+   4
+   5
+  
+  changeset:   9:6af29c3a778f
+  tag: tip
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: foo -> dir/baz; 1-1+
+  
+  diff --git a/foo b/dir/baz
+  copy from foo
+  copy to dir/baz
+  --- a/foo
+  +++ b/dir/baz
+  @@ -2,7 +2,7 @@
+ 

[PATCH 1 of 2 STABLE] tests: check that 'log --line-range' follows uncommitted changes

2019-11-29 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1575059694 -3600
#  Fri Nov 29 21:34:54 2019 +0100
# Branch stable
# Node ID 969e8a52e3842d19387d02e91d6a19a993950ac0
# Parent  371765e775a2cb4c4b41eed10dbee0ceee8ab1f9
tests: check that 'log --line-range' follows uncommitted changes

The reason we start walking revisions from the working directory (None
revision) in logcmdutil.getlinerangerevs() is because we can follow
uncommitted changes. Adding a test to illustrate this based on an
uncommitted rename as there was none before. This helps understand the
fix in next changeset.

diff --git a/tests/test-log-linerange.t b/tests/test-log-linerange.t
--- a/tests/test-log-linerange.t
+++ b/tests/test-log-linerange.t
@@ -868,6 +868,38 @@ Renames are followed.
   +4
   
 
+Uncommitted changes with a rename
+
+  $ hg mv baz bazn
+  $ hg log -f -L bazn,5:7
+  changeset:   9:6af29c3a778f
+  tag: tip
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: foo -> dir/baz; 1-1+
+  
+  changeset:   5:cfdf972b3971
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+
+  
+  changeset:   4:eaec41c1a0c9
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: 11 -> 11+; leading space before "1"
+  
+  changeset:   2:63a884426fd0
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: 2 -> 2+; added bar
+  
+  changeset:   0:5ae1f82b9a00
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: init
+  
+  $ hg revert -a -C -q
+
 Binary files work but without diff hunks filtering.
 (Checking w/ and w/o diff.git option.)
 

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2 STABLE] py3: fix 'log --line-range' with uncommitted changes in range

2019-11-29 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1575060193 -3600
#  Fri Nov 29 21:43:13 2019 +0100
# Branch stable
# Node ID 8e65df8a972333c0d30b03f5dee4ce802088d799
# Parent  969e8a52e3842d19387d02e91d6a19a993950ac0
py3: fix 'log --line-range' with uncommitted changes in range

When 'hg log -f --line-range ,' is invoked with 
containing uncommitted changes, the command crashes on Python 3 as
follows:

  [...]
  File "/usr/lib/python3/dist-packages/mercurial/commands.py", line 4725, 
in log
revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
  File "/usr/lib/python3/dist-packages/mercurial/logcmdutil.py", line 933, 
in getlinerangerevs
if rev not in userrevs:
  File "/usr/lib/python3/dist-packages/mercurial/smartset.py", line 969, in 
__contains__
if l < x:
TypeError: '<' not supported between instances of 'int' and 'NoneType'

The None value is because requested line range has uncommitted changes.
This only occurs in Python 3 as Python 2 allows comparing None with int.
Skipping None while walking block ancestors in
logcmdutil.getlinerangerevs() resolves the problem.

diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -930,7 +930,7 @@ def getlinerangerevs(repo, userrevs, opt
 fctx = wctx.filectx(fname)
 for fctx, linerange in dagop.blockancestors(fctx, fromline, toline):
 rev = fctx.introrev()
-if rev not in userrevs:
+if rev is None or rev not in userrevs:
 continue
 linerangesbyrev.setdefault(rev, {}).setdefault(
 fctx.path(), []
diff --git a/tests/test-log-linerange.t b/tests/test-log-linerange.t
--- a/tests/test-log-linerange.t
+++ b/tests/test-log-linerange.t
@@ -898,6 +898,53 @@ Uncommitted changes with a rename
   date:Thu Jan 01 00:00:00 1970 +
   summary: init
   
+
+Uncommitted changes in requested line range
+
+  $ sed 's/2/  /' bazn > bazn.new
+  $ mv bazn.new bazn
+  $ hg diff
+  diff --git a/dir/baz b/dir/bazn
+  rename from dir/baz
+  rename to dir/bazn
+  --- a/dir/baz
+  +++ b/dir/bazn
+  @@ -3,7 +3,7 @@
+   0
+   0
+1+
+  -2+
+  +  +
+   3+
+   4
+   5
+  $ hg log -f -L bazn,5:7
+  changeset:   9:6af29c3a778f
+  tag: tip
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: foo -> dir/baz; 1-1+
+  
+  changeset:   5:cfdf972b3971
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+
+  
+  changeset:   4:eaec41c1a0c9
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: 11 -> 11+; leading space before "1"
+  
+  changeset:   2:63a884426fd0
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: 2 -> 2+; added bar
+  
+  changeset:   0:5ae1f82b9a00
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: init
+  
   $ hg revert -a -C -q
 
 Binary files work but without diff hunks filtering.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7517: filemerge: byteify the open() mode

2019-11-24 Thread dlax (Denis Laxalde)
dlax added a comment.


  > This is actually pycompat.open(), so it need bytes.
  
  I don't understand why this is needed. The default value for "mode" as bytes 
comes from a407f9009392 
, 
but I don't understand the rationale.
  Shouldn't we instead change all calls to `pycompat.open()` to use a native 
str for `mode`? (and drop `sysstr(mode)` in `pycompat.open()`).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7517/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7517

To: mharbison72, #hg-reviewers
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7516: webutil: add missing argument to join()

2019-11-24 Thread dlax (Denis Laxalde)
dlax added a comment.
dlax accepted this revision.


  Looks like dead code

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7516/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7516

To: mharbison72, #hg-reviewers, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7507: phabricator: add a "phabstatus" template keyword

2019-11-23 Thread dlax (Denis Laxalde)
dlax added a comment.


  >   I only have a superficial understanding about how templates work, but I 
assume that there's no global pre-resolution step where a single query could be 
done and the results stuffed into the context or something, is there?
  
  Not that I am aware. Using this keyword on large revsets is indeed slow.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7507/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7507

To: dlax, #hg-reviewers
Cc: mharbison72, Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7513: phabricator: fix processing of tags/desc in getoldnodedrevmap()

2019-11-23 Thread dlax (Denis Laxalde)
dlax created this revision.
Herald added subscribers: mercurial-devel, Kwan.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  It seems that the previous logic was wrong (it essentially comes
  from changeset 3ab0d5767b54 
 
where the result got accumulated instead of
  early returned).
  First of all, the "continue" in first "if m:" is useless because we're
  at the end of the loop. Then, the algorithm seems weird because we will
  process all predecessors of a node and possibly override
  `toconfirm[node]` for each of these having a tag (maybe this doesn't
  happen, but still). Finally, we would also override `toconfirm[node]`
  when the "Differential Revision: " is found in changeset description.
  Maybe this is not a big deal when there is no mix of local tag and
  changeset description update?
  
  The logic is changed so that the loop on predecessors stops upon first
  match of a tag and so that the changeset description is only checked if
  no tag was found. Therefore, `toconfirm[node]` is only set once.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D7513

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -403,12 +403,15 @@
 m = _differentialrevisiontagre.match(tag)
 if m:
 toconfirm[node] = (0, set(precnodes), int(m.group(1)))
-continue
-
-# Check commit message
-m = _differentialrevisiondescre.search(ctx.description())
-if m:
-toconfirm[node] = (1, set(precnodes), int(m.group('id')))
+break
+else:
+continue  # move to next predecessor
+break  # found a tag, stop
+else:
+# Check commit message
+m = _differentialrevisiondescre.search(ctx.description())
+if m:
+toconfirm[node] = (1, set(precnodes), int(m.group('id')))
 
 # Double check if tags are genuine by collecting all old nodes from
 # Phabricator, and expect precursors overlap with it.



To: dlax, #hg-reviewers
Cc: Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7506: phabricator: add a "phabstatus" show view

2019-11-23 Thread dlax (Denis Laxalde)
dlax edited the summary of this revision.
dlax updated this revision to Diff 18338.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7506?vs=18320=18338

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7506/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7506

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -11,6 +11,10 @@
 revisions in a format suitable for :hg:`import`, and a ``phabupdate`` command
 to update statuses in batch.
 
+A "phabstatus" view for :hg:`show` is also provided; it displays status
+information of Phabricator differentials associated with unfinished
+changesets.
+
 By default, Phabricator requires ``Test Plan`` which might prevent some
 changeset from being sent. The requirement could be disabled by changing
 ``differential.require-test-plan-field`` config server side.
@@ -60,9 +64,11 @@
 encoding,
 error,
 exthelper,
+graphmod,
 httpconnection as httpconnectionmod,
 match,
 mdiff,
+logcmdutil,
 obsutil,
 parser,
 patch,
@@ -80,6 +86,11 @@
 procutil,
 stringutil,
 )
+from hgext.show import (
+longestshortest,
+showview,
+)
+
 
 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' 
for
 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
@@ -462,6 +473,29 @@
 return result
 
 
+def getdrevmap(repo, revs):
+"""Return a dict mapping each rev in `revs` to their Differential Revision
+ID or None.
+"""
+result = {}
+for rev in revs:
+result[rev] = None
+ctx = repo[rev]
+# Check commit message
+m = _differentialrevisiondescre.search(ctx.description())
+if m:
+result[rev] = int(m.group('id'))
+continue
+# Check tags
+for tag in repo.nodetags(ctx.node()):
+m = _differentialrevisiontagre.match(tag)
+if m:
+result[rev] = int(m.group(1))
+break
+
+return result
+
+
 def getdiff(ctx, diffopts):
 """plain-text diff without header (user, commit message, etc)"""
 output = util.stringio()
@@ -1648,3 +1682,42 @@
 
 return templateutil.hybriddict({b'url': url, b'id': t,})
 return None
+
+
+@showview(b'phabstatus', csettopic=b'work')
+def phabstatusshowview(ui, repo, displayer):
+"""Phabricator differiential status"""
+revs = repo.revs('sort(_underway(), topo)')
+drevmap = getdrevmap(repo, revs)
+unknownrevs, drevids, revsbydrevid = [], set([]), {}
+for rev, drevid in pycompat.iteritems(drevmap):
+if drevid is not None:
+drevids.add(drevid)
+revsbydrevid.setdefault(drevid, set([])).add(rev)
+else:
+unknownrevs.append(rev)
+
+drevs = callconduit(ui, b'differential.query', {b'ids': list(drevids)})
+drevsbyrev = {}
+for drev in drevs:
+for rev in revsbydrevid[int(drev[b'id'])]:
+drevsbyrev[rev] = drev
+
+def phabstatus(ctx):
+drev = drevsbyrev[ctx.rev()]
+ui.write(b"\n%(uri)s %(statusName)s\n" % drev)
+
+revs -= smartset.baseset(unknownrevs)
+revdag = graphmod.dagwalker(repo, revs)
+
+ui.setconfig(b'experimental', b'graphshorten', True)
+displayer._exthook = phabstatus
+nodelen = longestshortest(repo, revs)
+logcmdutil.displaygraph(
+ui,
+repo,
+revdag,
+displayer,
+graphmod.asciiedges,
+props={b'nodelen': nodelen},
+)



To: dlax, #hg-reviewers
Cc: mharbison72, mjpieters, Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7506: phabricator: add a "phabstatus" show view

2019-11-23 Thread dlax (Denis Laxalde)
dlax added a comment.
dlax planned changes to this revision.


  In D7506#110321 , @mharbison72 
wrote:
  
  > In D7506#110288 , @mharbison72 
wrote:
  >
  >> I'm not sure why, but this version seems to also show obsolete revisions.  
I've got a bunch of `x` and `*` nodes in hg-committed right now.  I didn't see 
that before, although that was on a different clone that I don't have access to 
now.
  >
  > After further review, the obsolete revisions have unstable children going 
way back, so that's why they show.  But I'm super confused by the output.  This 
isn't the whole output, but the middle or so that corresponds to the latest(!) 
commits:
  
  Hm, I don't have this issue. Even with visible obsolete revisions with a phab 
differential, the output seem consistent with "show work".
  The revisions shown by the "phabstatus" view is just a subset of that of 
"work" view (subset of revisions with a differential). Do you see more 
revisions in "phabstatus" than in "work" or am I misunderstanding something?
  Or perhaps this is because of a wrong sorting of the filtered set? I'll make 
sure the final is still topo sorted and send another version in a moment.
  
  > Is the goal to limit to the current stack, or all non public commits?  I 
can see a use case for both.
  
  I don't use the "stack" view often, so my goal is to map to the "work" view 
which I use more. But perhaps it'd make sense to have "hg show phabwork" and 
"hg show phabstack"? (We can rename the view, and add the other one later on.)

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7506/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7506

To: dlax, #hg-reviewers
Cc: mharbison72, mjpieters, Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7507: phabricator: add a "phabstatus" template keyword

2019-11-22 Thread dlax (Denis Laxalde)
dlax updated this revision to Diff 18321.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7507?vs=18316=18321

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7507/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7507

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -1684,6 +1684,28 @@
 return None
 
 
+@eh.templatekeyword(b'phabstatus', requires={b'ctx', b'repo', b'ui'})
+def template_status(context, mapping):
+""":phabstatus: String. Status of Phabricator differential.
+"""
+ctx = context.resource(mapping, b'ctx')
+repo = context.resource(mapping, b'repo')
+ui = context.resource(mapping, b'ui')
+
+rev = ctx.rev()
+try:
+drevid = getdrevmap(repo, [rev])[rev]
+except KeyError:
+return None
+drevs = callconduit(ui, b'differential.query', {b'ids': [drevid]})
+for drev in drevs:
+if int(drev[b'id']) == drevid:
+return templateutil.hybriddict(
+{b'url': drev[b'uri'], b'status': drev[b'statusName'],}
+)
+return None
+
+
 @showview(b'phabstatus', csettopic=b'work')
 def phabstatusshowview(ui, repo, displayer):
 """Phabricator differiential status"""



To: dlax, #hg-reviewers
Cc: Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7506: phabricator: add a "phabstatus" show view

2019-11-22 Thread dlax (Denis Laxalde)
dlax updated this revision to Diff 18320.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7506?vs=18315=18320

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7506/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7506

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -11,6 +11,10 @@
 revisions in a format suitable for :hg:`import`, and a ``phabupdate`` command
 to update statuses in batch.
 
+A "phabstatus" view for :hg:`show` is also provided; it displays status
+information of Phabricator differentials associated with unfinished
+changesets.
+
 By default, Phabricator requires ``Test Plan`` which might prevent some
 changeset from being sent. The requirement could be disabled by changing
 ``differential.require-test-plan-field`` config server side.
@@ -60,9 +64,11 @@
 encoding,
 error,
 exthelper,
+graphmod,
 httpconnection as httpconnectionmod,
 match,
 mdiff,
+logcmdutil,
 obsutil,
 parser,
 patch,
@@ -80,6 +86,11 @@
 procutil,
 stringutil,
 )
+from hgext.show import (
+longestshortest,
+showview,
+)
+
 
 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' 
for
 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
@@ -462,6 +473,29 @@
 return result
 
 
+def getdrevmap(repo, revs):
+"""Return a dict mapping each rev in `revs` to their Differential
+Revision ID.
+"""
+result = {}
+for rev in revs:
+result[rev] = None
+ctx = repo[rev]
+# Check commit message
+m = _differentialrevisiondescre.search(ctx.description())
+if m:
+result[rev] = int(m.group('id'))
+continue
+# Check tags
+for tag in repo.nodetags(ctx.node()):
+m = _differentialrevisiontagre.match(tag)
+if m:
+result[rev] = int(m.group(1))
+break
+
+return result
+
+
 def getdiff(ctx, diffopts):
 """plain-text diff without header (user, commit message, etc)"""
 output = util.stringio()
@@ -1648,3 +1682,41 @@
 
 return templateutil.hybriddict({b'url': url, b'id': t,})
 return None
+
+
+@showview(b'phabstatus', csettopic=b'work')
+def phabstatusshowview(ui, repo, displayer):
+"""Phabricator differiential status"""
+revs = repo.revs('sort(_underway(), topo)')
+drevmap = getdrevmap(repo, revs)
+revs, drevids, revsbydrevid = [], set([]), {}
+for rev, drevid in pycompat.iteritems(drevmap):
+if drevid is not None:
+revs.append(rev)
+drevids.add(drevid)
+revsbydrevid.setdefault(drevid, set([])).add(rev)
+
+drevs = callconduit(ui, b'differential.query', {b'ids': list(drevids)})
+drevsbyrev = {}
+for drev in drevs:
+for rev in revsbydrevid[int(drev[b'id'])]:
+drevsbyrev[rev] = drev
+
+def phabstatus(ctx):
+drev = drevsbyrev[ctx.rev()]
+ui.write(b"\n%(uri)s %(statusName)s\n" % drev)
+
+revs = smartset.baseset(revs)
+revdag = graphmod.dagwalker(repo, revs)
+
+ui.setconfig(b'experimental', b'graphshorten', True)
+displayer._exthook = phabstatus
+nodelen = longestshortest(repo, revs)
+logcmdutil.displaygraph(
+ui,
+repo,
+revdag,
+displayer,
+graphmod.asciiedges,
+props={b'nodelen': nodelen},
+)



To: dlax, #hg-reviewers
Cc: mharbison72, mjpieters, Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7506: phabricator: add a "phabstatus" show view

2019-11-22 Thread dlax (Denis Laxalde)
dlax added a comment.
dlax planned changes to this revision.


  In D7506#110225 , @mharbison72 
wrote:
  
  > I like it.
  
  Thanks!
  
  > Any idea why the changeset isn't colored, unlike `hg show stack`?  It might 
also be a little more readable if the URI and status line were tabbed in, but 
maybe colored cset hashes would make that unnecessary?
  
  Yes, I messed up with adding a custom template whereas I can actually reuse 
"hg show"'s one. Will fix (along with another issue in the algorithm I just 
found out.)
  
  > I'm also interested in coloring the status value, but I can tinker with 
that after it's landed, unless you already have plans.
  
  You mean having a different color depending on status value, or a fixed one? 
I have no plan anyways, so if you have good ideas, I'll leave this up to you.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7506/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7506

To: dlax, #hg-reviewers
Cc: mharbison72, mjpieters, Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7508: relnotes: add note about changes to match.{explicit, reverse}dir

2019-11-22 Thread dlax (Denis Laxalde)
dlax added inline comments.

INLINE COMMENTS

> next:22
> +   also called when only `explicitdir` used to be called. That may
> +   mean that you can simple remove the use of `explicitdir` if you
> +   were already using `traversedir`.

simple -> simply?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7508/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7508

To: martinvonz, #hg-reviewers
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7507: phabricator: add a "phabstatus" template keyword

2019-11-22 Thread dlax (Denis Laxalde)
dlax updated this revision to Diff 18316.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7507?vs=18314=18316

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7507/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7507

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -1682,6 +1682,28 @@
 return None
 
 
+@eh.templatekeyword(b'phabstatus', requires={b'ctx', b'repo', b'ui'})
+def template_status(context, mapping):
+""":phabstatus: String. Status of Phabricator differential.
+"""
+ctx = context.resource(mapping, b'ctx')
+repo = context.resource(mapping, b'repo')
+ui = context.resource(mapping, b'ui')
+
+rev = ctx.rev()
+try:
+drevid = getdrevmap(repo, [rev])[rev]
+except KeyError:
+return None
+drevs = callconduit(ui, b'differential.query', {b'ids': [drevid]})
+for drev in drevs:
+if int(drev[b'id']) == drevid:
+return templateutil.hybriddict(
+{b'url': drev[b'uri'], b'status': drev[b'statusName'],}
+)
+return None
+
+
 phabstatus_tmpl = (
 b'{label("changeset.{phase}{if(troubles, \' changeset.troubled\')}", '
 b'shortest(node, 5))} '



To: dlax, #hg-reviewers
Cc: Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7506: phabricator: add a "phabstatus" show view

2019-11-22 Thread dlax (Denis Laxalde)
dlax updated this revision to Diff 18315.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7506?vs=18313=18315

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7506/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7506

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -11,6 +11,10 @@
 revisions in a format suitable for :hg:`import`, and a ``phabupdate`` command
 to update statuses in batch.
 
+A "phabstatus" view for :hg:`show` is also provided; it displays status
+information of Phabricator differentials associated with unfinished
+changesets.
+
 By default, Phabricator requires ``Test Plan`` which might prevent some
 changeset from being sent. The requirement could be disabled by changing
 ``differential.require-test-plan-field`` config server side.
@@ -60,9 +64,12 @@
 encoding,
 error,
 exthelper,
+formatter,
+graphmod,
 httpconnection as httpconnectionmod,
 match,
 mdiff,
+logcmdutil,
 obsutil,
 parser,
 patch,
@@ -80,6 +87,8 @@
 procutil,
 stringutil,
 )
+from hgext.show import showview
+
 
 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' 
for
 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
@@ -462,6 +471,29 @@
 return result
 
 
+def getdrevmap(repo, nodelist):
+"""Return a dict mapping each node in `nodelist` to their Differential
+Revision ID.
+"""
+result = {}
+for node in nodelist:
+result[node] = None
+ctx = repo[node]
+# Check commit message
+m = _differentialrevisiondescre.search(ctx.description())
+if m:
+result[node] = int(m.group('id'))
+continue
+# Check tags
+for tag in repo.nodetags(node):
+m = _differentialrevisiontagre.match(tag)
+if m:
+result[node] = int(m.group(1))
+break
+
+return result
+
+
 def getdiff(ctx, diffopts):
 """plain-text diff without header (user, commit message, etc)"""
 output = util.stringio()
@@ -1648,3 +1680,41 @@
 
 return templateutil.hybriddict({b'url': url, b'id': t,})
 return None
+
+
+phabstatus_tmpl = (
+b'{label("changeset.{phase}{if(troubles, \' changeset.troubled\')}", '
+b'shortest(node, 5))} '
+b'[{label("log.branch", branch)}] '
+b'{label("log.description", desc|firstline)} '
+b'({label("log.user", author|user)})\n'
+)
+
+
+@showview(b'phabstatus')
+def phabstatusshowview(ui, repo):
+"""Phabricator differiential status"""
+revs = repo.revs('sort(_underway(), topo)')
+drevmap = getdrevmap(repo, [repo[r].node() for r in revs])
+revs, drevids, revsbydrevid = [], [], {}
+for node, drevid in pycompat.iteritems(drevmap):
+if drevid is not None:
+revs.append(repo[node].rev())
+drevids.append(drevid)
+revsbydrevid[drevid] = repo[node].rev()
+
+revs = smartset.baseset(revs)
+drevs = callconduit(ui, b'differential.query', {b'ids': drevids})
+drevsbyrev = {revsbydrevid[int(drev[b'id'])]: drev for drev in drevs}
+
+def phabstatus(ctx):
+drev = drevsbyrev[ctx.rev()]
+ui.write(b"%(uri)s %(statusName)s\n" % drev)
+
+revdag = graphmod.dagwalker(repo, revs)
+
+ui.setconfig(b'experimental', b'graphshorten', True)
+spec = formatter.lookuptemplate(ui, None, phabstatus_tmpl)
+displayer = logcmdutil.changesettemplater(ui, repo, spec, buffered=True)
+displayer._exthook = phabstatus
+logcmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)



To: dlax, #hg-reviewers
Cc: mjpieters, Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7507: phabricator: add a "phabstatus" template keyword

2019-11-22 Thread dlax (Denis Laxalde)
dlax created this revision.
Herald added subscribers: mercurial-devel, Kwan.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  We add a "phabstatus" template keyword, returning an object with "url"
  and "status" keys. This is quite similar to "phabreview" template
  keyword, but it queries phabricator for each specified revision so it's
  going to be slow (as compared to the "phabstatus" show view from
  previous changeset).

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D7507

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -1682,6 +1682,28 @@
 return None
 
 
+@eh.templatekeyword(b'phabstatus', requires={b'ctx', b'repo', b'ui'})
+def template_status(context, mapping):
+""":phabstatus: String. Status of Phabricator differential.
+"""
+ctx = context.resource(mapping, b'ctx')
+repo = context.resource(mapping, b'repo')
+ui = context.resource(mapping, b'ui')
+
+rev = ctx.rev()
+try:
+drevid = getdrevmap(repo, [rev])[rev]
+except KeyError:
+return None
+drevs = callconduit(ui, b'differential.query', {b'ids': [drevid]})
+for drev in drevs:
+if int(drev[b'id']) == drevid:
+return templateutil.hybriddict(
+{b'url': drev[b'uri'], b'status': drev[b'statusName'],}
+)
+return None
+
+
 phabstatus_tmpl = (
 b'{label("changeset.{phase}{if(troubles, \' changeset.troubled\')}", '
 b'shortest(node, 5))} '



To: dlax, #hg-reviewers
Cc: Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7506: phabricator: add a "phabstatus" show view

2019-11-22 Thread dlax (Denis Laxalde)
dlax created this revision.
Herald added subscribers: mercurial-devel, Kwan, mjpieters.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  We add a "phabstatus" show view (called as "hg show phabstatus") which
  renders a dag with underway revisions associated with a differential
  revision and displays their status.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D7506

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -11,6 +11,10 @@
 revisions in a format suitable for :hg:`import`, and a ``phabupdate`` command
 to update statuses in batch.
 
+A "phabstatus" view for :hg:`show` is also provided; it displays status
+information of Phabricator differentials associated with unfinished
+changesets.
+
 By default, Phabricator requires ``Test Plan`` which might prevent some
 changeset from being sent. The requirement could be disabled by changing
 ``differential.require-test-plan-field`` config server side.
@@ -60,9 +64,12 @@
 encoding,
 error,
 exthelper,
+formatter,
+graphmod,
 httpconnection as httpconnectionmod,
 match,
 mdiff,
+logcmdutil,
 obsutil,
 parser,
 patch,
@@ -80,6 +87,8 @@
 procutil,
 stringutil,
 )
+from hgext.show import showview
+
 
 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' 
for
 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
@@ -462,6 +471,29 @@
 return result
 
 
+def getdrevmap(repo, nodelist):
+"""Return a dict mapping each node in `nodelist` to their Differential
+Revision ID (or None).
+"""
+result = {}
+for node in nodelist:
+result[node] = None
+ctx = repo[node]
+# Check commit message
+m = _differentialrevisiondescre.search(ctx.description())
+if m:
+result[node] = int(m.group('id'))
+continue
+# Check tags
+for tag in repo.nodetags(node):
+m = _differentialrevisiontagre.match(tag)
+if m:
+result[node] = int(m.group(1))
+break
+
+return result
+
+
 def getdiff(ctx, diffopts):
 """plain-text diff without header (user, commit message, etc)"""
 output = util.stringio()
@@ -1648,3 +1680,41 @@
 
 return templateutil.hybriddict({b'url': url, b'id': t,})
 return None
+
+
+phabstatus_tmpl = (
+b'{label("changeset.{phase}{if(troubles, \' changeset.troubled\')}", '
+b'shortest(node, 5))} '
+b'[{label("log.branch", branch)}] '
+b'{label("log.description", desc|firstline)} '
+b'({label("log.user", author|user)})\n'
+)
+
+
+@showview(b'phabstatus')
+def phabstatusshowview(ui, repo):
+"""Phabricator differiential status"""
+revs = repo.revs('sort(_underway(), topo)')
+drevmap = getdrevmap(repo, [repo[r].node() for r in revs])
+revs, drevids, revsbydrevid = [], [], {}
+for node, drevid in pycompat.iteritems(drevmap):
+if drevid is not None:
+revs.append(repo[node].rev())
+drevids.append(drevid)
+revsbydrevid[drevid] = repo[node].rev()
+
+revs = smartset.baseset(revs)
+drevs = callconduit(ui, b'differential.query', {b'ids': drevids})
+drevsbyrev = {revsbydrevid[int(drev[b'id'])]: drev for drev in drevs}
+
+def phabstatus(ctx):
+drev = drevsbyrev[ctx.rev()]
+ui.write(b"%(uri)s %(statusName)s\n" % drev)
+
+revdag = graphmod.dagwalker(repo, revs)
+
+ui.setconfig(b'experimental', b'graphshorten', True)
+spec = formatter.lookuptemplate(ui, None, phabstatus_tmpl)
+displayer = logcmdutil.changesettemplater(ui, repo, spec, buffered=True)
+displayer._exthook = phabstatus
+logcmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)



To: dlax, #hg-reviewers
Cc: mjpieters, Kwan, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7505: logcmdutil: call _exthook() in changesettemplater

2019-11-22 Thread dlax (Denis Laxalde)
dlax created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Class changesetprinter has an _exthook() method that is called in
  _show() before the patch is displayed. Call the method as well in
  changesettemplater._show().

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D7505

AFFECTED FILES
  mercurial/logcmdutil.py

CHANGE DETAILS

diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -597,6 +597,7 @@
 # write changeset metadata, then patch if requested
 key = self._parts[self._tref]
 self.ui.write(self.t.render(key, props))
+self._exthook(ctx)
 self._showpatch(ctx, graphwidth)
 
 if self._parts[b'footer']:



To: dlax, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7504: py3: replace %s by %r on binary format string when needed

2019-11-22 Thread dlax (Denis Laxalde)
This revision now requires changes to proceed.
dlax added a comment.
dlax requested changes to this revision.


  nit: the actual PEP is pep-0461 (https://www.python.org/dev/peps/pep-0461/)

INLINE COMMENTS

> localrepo.py:1571
> +b"unsupported changeid '%r' of type %r"
>  % (changeid, pycompat.sysstr(type(changeid)))
>  )

The first `%s` was correct I think because `changeid` can be a bytes.

For the second one, if `%r` is the way to go (I'm not sure), maybe we can drop 
`pycompat.sysstr()`?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7504/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7504

To: matclab, #hg-reviewers, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7051: phabricator: remove tests and all recordings

2019-11-22 Thread dlax (Denis Laxalde)
dlax added a comment.


  > The next commit is going to change the format of conduit API requests so 
none of the VCR recordings will match and all the tests will fail.
  
  @Kwan, it seems to me that there is no longer any recording data nor actual 
test from this changeset. Did you plan to add them back? (At the moment, it 
seems to me that test-phabricator.t tests nothing.)

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7051/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7051

To: Kwan, #hg-reviewers
Cc: dlax, mjpieters, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7460: tests: add more tests for "hg shelve --delete"

2019-11-21 Thread dlax (Denis Laxalde)
Closed by commit rHG4330851947fb: tests: add more tests for hg shelve 
--delete (authored by dlax).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7460?vs=18250=18258

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7460/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7460

AFFECTED FILES
  tests/test-shelve.t

CHANGE DETAILS

diff --git a/tests/test-shelve.t b/tests/test-shelve.t
--- a/tests/test-shelve.t
+++ b/tests/test-shelve.t
@@ -951,6 +951,16 @@
   +++ b/jungle
   @@ -0,0 +1,1 @@
   +babar
+
+Test shelve --delete
+
+  $ hg shelve --list
+  default (*s ago)changes to: create conflict (glob)
+  $ hg shelve --delete doesnotexist
+  abort: shelved change 'doesnotexist' not found
+  [255]
+  $ hg shelve --delete default
+
   $ cd ..
 
 Test visibility of in-memory changes inside transaction to external hook



To: dlax, #hg-reviewers, mharbison72, pulkit
Cc: mharbison72, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7465: filemerge: fix a missing attribute usage

2019-11-21 Thread dlax (Denis Laxalde)
dlax added inline comments.

INLINE COMMENTS

> mharbison72 wrote in filemerge.py:122
> I’m not sure how this works, but this was enough to make pytype happy.  Does 
> it make any sense to compare an absent file to an absent file?
> 
> Maybe the right thing is to add a ctx attribute here?

> Does it make any sense to compare an absent file to an absent file?

Not sure, but due to lazy evaluation `fctx.ctx() == self.ctx()` would only be 
evaluated if `fctx` is an absent file, hence also lacking the `ctx()` method.
I suggested to use `changectx()` because this is already implemented and also 
part of the basefilectx interface.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7465/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7465

To: mharbison72, #hg-reviewers
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] import: add a --secret option

2019-11-21 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1574324750 -3600
#  Thu Nov 21 09:25:50 2019 +0100
# Node ID f847210f92b94a13d7e260611e41d5508aeacb99
# Parent  039fbd14d4e2889be830cc114957c31972c6ea04
import: add a --secret option

Similarly to "hg commit", we add a --secret option to "hg import" for
committing with the secret phase. The option has no short form since
there already is a "-s" for "--similarity".

.. feature::

   ``hg import`` has a new --secret option for committing with the
secret phase.

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1773,6 +1773,8 @@ def tryimportone(ui, repo, patchdata, pa
 overrides = {}
 if partial:
 overrides[(b'ui', b'allowemptycommit')] = True
+if opts.get(b'secret'):
+overrides[(b'phases', b'new-commit')] = b'secret'
 with repo.ui.configoverride(overrides, b'import'):
 n = repo.commit(
 message, user, date, match=m, editor=editor, extra=extra
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4033,6 +4033,7 @@ def identify(
 _(b'NUM'),
 ),
 (b'b', b'base', b'', _(b'base path (DEPRECATED)'), _(b'PATH')),
+(b'', b'secret', None, _(b'use the secret phase for committing')),
 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
 (
 b'f',
@@ -4181,6 +4182,8 @@ def import_(ui, repo, patch1=None, *patc
 update = not opts.get(b'bypass')
 if not update and opts.get(b'no_commit'):
 raise error.Abort(_(b'cannot use --no-commit with --bypass'))
+if opts.get(b'secret') and opts.get(b'no_commit'):
+raise error.Abort(_(b'cannot use --no-commit with --secret'))
 try:
 sim = float(opts.get(b'similarity') or 0)
 except ValueError:
diff --git a/tests/test-import.t b/tests/test-import.t
--- a/tests/test-import.t
+++ b/tests/test-import.t
@@ -435,6 +435,49 @@ hg email --plain, should read X-Mercuria
   date:Thu Jan 01 00:00:00 1970 +
   summary: second change
   
+  $ hg --cwd b phase tip
+  1: draft
+  $ rm -r b
+
+
+hg import --secret
+
+  $ hg clone -r0 a b -q
+  $ hg --cwd b import --no-commit --secret ../exported-tip.patch
+  abort: cannot use --no-commit with --secret
+  [255]
+  $ hg --cwd b import --secret ../exported-tip.patch
+  applying ../exported-tip.patch
+  $ hg --cwd b diff -c . --nodates
+  diff -r 80971e65b431 -r 1d4bd90af0e4 a
+  --- a/a
+  +++ b/a
+  @@ -1,1 +1,2 @@
+   line 1
+  +line 2
+  $ hg --cwd b phase
+  1: secret
+  $ hg --cwd b --config extensions.strip= strip 1 --no-backup --quiet
+  $ HGEDITOR=cat hg --cwd b import --secret --edit ../exported-tip.patch
+  applying ../exported-tip.patch
+  second change
+  
+  
+  HG: Enter commit message.  Lines beginning with 'HG:' are removed.
+  HG: Leave message empty to abort commit.
+  HG: --
+  HG: user: someone
+  HG: branch 'default'
+  HG: changed a
+  $ hg --cwd b diff -c . --nodates
+  diff -r 80971e65b431 -r 1d4bd90af0e4 a
+  --- a/a
+  +++ b/a
+  @@ -1,1 +1,2 @@
+   line 1
+  +line 2
+  $ hg --cwd b phase
+  1: secret
   $ rm -r b
 
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7465: filemerge: fix a missing attribute usage

2019-11-21 Thread dlax (Denis Laxalde)
dlax added inline comments.

INLINE COMMENTS

> filemerge.py:122
>  fctx.isabsent()
> -and fctx.ctx() == self.ctx()
> +and fctx.ctx() == self._ctx
>  and fctx.path() == self.path()

What about `fctx`? It could also lack the `ctx()` method if an instance of 
`absentfilectx`.
I wonder if the intent was not `fctx.changectx() == self.changectx()`.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7465/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7465

To: mharbison72, #hg-reviewers
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7464: filemerge: drop a default argument to appease pytype

2019-11-21 Thread dlax (Denis Laxalde)
dlax added a comment.


  Shouldn't this be also done for all similar functions? (i.e. `_xmergeimm` and 
functions registered as a merge tool with `@internaltool`)

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7464/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7464

To: mharbison72, #hg-reviewers
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7460: tests: add more tests for "hg shelve --delete"

2019-11-20 Thread dlax (Denis Laxalde)
dlax updated this revision to Diff 18250.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7460?vs=18249=18250

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7460/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7460

AFFECTED FILES
  tests/test-shelve.t

CHANGE DETAILS

diff --git a/tests/test-shelve.t b/tests/test-shelve.t
--- a/tests/test-shelve.t
+++ b/tests/test-shelve.t
@@ -951,6 +951,16 @@
   +++ b/jungle
   @@ -0,0 +1,1 @@
   +babar
+
+Test shelve --delete
+
+  $ hg shelve --list
+  default (*s ago)changes to: create conflict (glob)
+  $ hg shelve --delete doesnotexist
+  abort: shelved change 'doesnotexist' not found
+  [255]
+  $ hg shelve --delete default
+
   $ cd ..
 
 Test visibility of in-memory changes inside transaction to external hook



To: dlax, #hg-reviewers
Cc: mharbison72, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7458: shelve: add the missing `create` parameter to the bundlerepo constructor

2019-11-20 Thread dlax (Denis Laxalde)
dlax added a comment.
dlax accepted this revision.


  Good catch.
  
  On the other hand, it's not clear to me what's the point of this "create" 
argument given `bundlerepo.instance()` will just use it to raise Abort if it is 
true.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7458/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7458

To: mharbison72, #hg-reviewers, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7460: tests: add more tests for "hg shelve --delete"

2019-11-20 Thread dlax (Denis Laxalde)
dlax created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  It appears that the only tests for "hg shelve --delete" concern command
  errors (e.g. incompatible command options). Adding some more to check
  that non-existent names are handled and a success case.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D7460

AFFECTED FILES
  tests/test-shelve.t

CHANGE DETAILS

diff --git a/tests/test-shelve.t b/tests/test-shelve.t
--- a/tests/test-shelve.t
+++ b/tests/test-shelve.t
@@ -951,6 +951,16 @@
   +++ b/jungle
   @@ -0,0 +1,1 @@
   +babar
+
+Test shelve --delete
+
+  $ hg shelve --list
+  default (1s ago)changes to: create conflict
+  $ hg shelve --delete doesnotexist
+  abort: shelved change 'doesnotexist' not found
+  [255]
+  $ hg shelve --delete default
+
   $ cd ..
 
 Test visibility of in-memory changes inside transaction to external hook



To: dlax, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7296: pycompat: kludge around pytype being confused by __new__

2019-11-19 Thread dlax (Denis Laxalde)
dlax added a comment.


  In D7296#109684 , @dlax wrote:
  
  > Looking closer at the error above, it mentions `bytestr.__init__`, not 
`__new__` (and there is in fact no type annotation for `__new__` in typeshed 
).
  
  https://github.com/python/typeshed/issues/2630

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7296/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7296

To: durin42, #hg-reviewers, indygreg, dlax
Cc: yuja, mjpieters, dlax, indygreg, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7296: pycompat: kludge around pytype being confused by __new__

2019-11-19 Thread dlax (Denis Laxalde)
dlax added a comment.
dlax added a subscriber: yuja.


  In D7296#109683 , @durin42 wrote:
  
  > In D7296#109672 , @dlax wrote:
  >
  >> Sorry, still not ok afaict :/
  >
  > So, I tried fixing this and it actually made things worse? dagparser.py no 
longer typechecks if I correct the syntax? Try the pytype invocation from the 
test at the end of the series and you'll see what I mean.
  
  Ok, trying `pytype mercurial/dagparser.py` I get a couple of those errors:
  
File ".../mercurial/dagparser.py", line 172, in parsedag: Function 
bytestr.__init__ was called with the wrong arguments [wrong-arg-types]
  Expected: (self, ints: Iterable[int])
  Actually passed: (self, ints: str)
  
  My point was that we need to keep "mercurial/pycompat.py" passing pytype 
before considering modules it depends on. Once the missing `type: ` is added 
and bytestr <-> _bytestr trick applied, it's okay but the error in dagparser.py 
persists...
  Looking closer at the error above, it mentions `bytestr.__init__`, not 
`__new__` (and there is in fact no type annotation for `__new__` in typeshed 
).
 So I suspect the "Callable" trick is not enough and we'd need a workaround 
similar to da925257 
 by 
@yuja .

INLINE COMMENTS

> pycompat.py:305
>  
> +bytestr = _bytestr  # Callable[[Union[bytes, str]], bytestr]
> +

Now the `type: ` is missing, so the comment is ignored.

Adding it, `pytype mercurial/pycompat.py` gives:

  mercurial/pycompat.py", line 305, in : Invalid type comment: 
Callable[[Union[bytes, str]], bytestr] [invalid-type-comment]
Name 'bytestr' is not defined

hence the kind of trick I suggested in my first comment on this line.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7296/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7296

To: durin42, #hg-reviewers, indygreg, dlax
Cc: yuja, mjpieters, dlax, indygreg, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 2] typing: fix return type of logcmdutil.getrevs()

2019-11-19 Thread Denis Laxalde
Yuya Nishihara a écrit :
> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1574175192 -32400
> #  Tue Nov 19 23:53:12 2019 +0900
> # Node ID 835d415c5a17258e2cf11e9fcd650441690dfbd4
> # Parent  75589cc751d7053a9852f7de88b35ec64909a46a
> typing: fix return type of logcmdutil.getrevs()
> 
> Fixes the following errors:
> 
>   Invalid type annotation "'Tuple[smartset.BaseSet, changesetdiffer]'"
>   [invalid-annotation]
> No attribute 'BaseSet' on module 'mercurial.smartset'
>   getrevs: bad option in return type [bad-return-type]
> Expected: Tuple[mercurial.smartset.abstractsmartset, changesetdiffer]
> Actually returned: Tuple[mercurial.smartset.baseset, None]

I don't get the second error (running "pytype mercurial/logcmdutil.py"),
but this is indeed correct.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7296: pycompat: kludge around pytype being confused by __new__

2019-11-19 Thread dlax (Denis Laxalde)
This revision now requires changes to proceed.
dlax added a comment.
dlax requested changes to this revision.


  Sorry, still not ok afaict :/

INLINE COMMENTS

> pycompat.py:305
>  
> +bytestr = _bytestr  # type: Callable[[Union[bytes, str], bytestr]]
> +

`]` is still at the wrong place, I think. Should be `Callable[[Union[bytes, 
str]], bytestr]`.
Then I still get the "Name 'bytestr' is not defined" error mentioned above.

> pycompat.py:414
>  byterepr = repr
> -bytestr = str
> +bytestr = str  # type: Callable[[Union[bytes, str], bytestr]
>  iterbytestr = iter

same here about missing `]`.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7296/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7296

To: durin42, #hg-reviewers, indygreg, dlax
Cc: mjpieters, dlax, indygreg, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7408: extensions: hide two confusing import statements from pytype

2019-11-18 Thread dlax (Denis Laxalde)
dlax added a comment.


  In D7408#109565 , @indygreg 
wrote:
  
  > Where does `hgext.__index__` come from?!
  
  This is generated by setup.py, apparently only when building with py2exe.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7408/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7408

To: durin42, #hg-reviewers, dlax, indygreg
Cc: indygreg, dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7296: pycompat: kludge around pytype being confused by __new__

2019-11-16 Thread dlax (Denis Laxalde)
This revision now requires changes to proceed.
dlax added inline comments.
dlax requested changes to this revision.

INLINE COMMENTS

> pycompat.py:294
>  
> +bytestr = _bytestr  # type: Callable[[Union[bytes, str], bytestr]
> +

A `]` is missing before `, bytestr`. Then, it's also missing `typing` imports.
But, even with this, I get:

  Invalid type comment: Callable[[Union[bytes, str]], bytestr] 
[invalid-type-comment]
Name 'bytestr' is not defined

I'm able to make this pass with:

  bytestr = _bytestr
  bytestr = bytestr  # type: Callable[[Union[bytes, str]], bytestr]

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7296/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7296

To: durin42, #hg-reviewers, indygreg, dlax
Cc: mjpieters, dlax, indygreg, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7410: extensions: suppress a pytype failure due to a typeshed bug

2019-11-15 Thread dlax (Denis Laxalde)
dlax added a comment.
dlax accepted this revision.


  meanwhile, https://github.com/python/typeshed/pull/3465

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7410/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7410

To: durin42, #hg-reviewers, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7296: pycompat: kludge around pytype being confused by __new__

2019-11-15 Thread dlax (Denis Laxalde)
dlax added a comment.


  black complains because inline comments have only one space before (esp. the 
first one produces a parse error).
  LGTM otherwise.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7296/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7296

To: durin42, #hg-reviewers, indygreg, dlax
Cc: mjpieters, dlax, indygreg, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7384: commands: necessary annotations and suppresssions to pass pytype

2019-11-15 Thread dlax (Denis Laxalde)
dlax added inline comments.

INLINE COMMENTS

> commands.py:4742
> +# warning about list not having a max() method.
> +endrev = revs.max() + 1  # pytype: disable=attribute-error
>  getcopies = scmutil.getcopiesfn(repo, endrev=endrev)

`revs` is always a `smartset.baseset` per af9c73f26371 
 so 
there should be no attribute error. Or is it because 
`logcmdutil.getlinerangerevs()` has no type annotation (whereas 
`logcmdutil.getrevs()` has some)?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7384/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7384

To: durin42, #hg-reviewers, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7430: bisect: replace try:/finally: by a "restore_state" context manager

2019-11-15 Thread dlax (Denis Laxalde)
Closed by commit rHGf37da59a36d9: bisect: replace try:/finally: by a 
restore_state context manager (authored by dlax).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7430?vs=18156=18160

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7430/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7430

AFFECTED FILES
  mercurial/commands.py
  mercurial/hbisect.py

CHANGE DETAILS

diff --git a/mercurial/hbisect.py b/mercurial/hbisect.py
--- a/mercurial/hbisect.py
+++ b/mercurial/hbisect.py
@@ -11,6 +11,7 @@
 from __future__ import absolute_import
 
 import collections
+import contextlib
 
 from .i18n import _
 from .node import (
@@ -180,6 +181,15 @@
 raise error.Abort(_(b'cannot bisect (no known bad revisions)'))
 
 
+@contextlib.contextmanager
+def restore_state(repo, state, node):
+try:
+yield
+finally:
+state[b'current'] = [node]
+save_state(repo, state)
+
+
 def get(repo, status):
 """
 Return a list of revision(s) that match the given status:
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1073,7 +1073,7 @@
 raise error.Abort(_(b'current bisect revision is a merge'))
 if rev:
 node = repo[scmutil.revsingle(repo, rev, node)].node()
-try:
+with hbisect.restore_state(repo, state, node):
 while changesets:
 # update state
 state[b'current'] = [node]
@@ -1105,9 +1105,6 @@
 # update to next check
 node = nodes[0]
 mayupdate(repo, node, show_stats=False)
-finally:
-state[b'current'] = [node]
-hbisect.save_state(repo, state)
 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
 return
 



To: dlax, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7410: extensions: suppress a strange pytype failure

2019-11-15 Thread dlax (Denis Laxalde)
dlax added inline comments.

INLINE COMMENTS

> dlax wrote in extensions.py:96
> the doc indeed says that "fd" is file object

In https://github.com/python/typeshed/blob/master/stdlib/3/imp.pyi type of 
`find_module` seems wrong.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7410/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7410

To: durin42, #hg-reviewers, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7410: extensions: suppress a strange pytype failure

2019-11-15 Thread dlax (Denis Laxalde)
dlax added inline comments.
dlax accepted this revision.

INLINE COMMENTS

> extensions.py:96
> +# pytype seems to think `fd` is a str, but I'm pretty sure
> +# it's wrong. This may be a bug we need to report upstream.
> +return imp.load_module(

the doc indeed says that "fd" is file object

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7410/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7410

To: durin42, #hg-reviewers, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7408: extensions: hide two confusing import statements from pytype

2019-11-15 Thread dlax (Denis Laxalde)
dlax added a comment.
dlax accepted this revision.


  Out of curiosity, where does this `__index__` value come from?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7408/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7408

To: durin42, #hg-reviewers, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7384: commands: necessary annotations and suppresssions to pass pytype

2019-11-15 Thread dlax (Denis Laxalde)
This revision now requires changes to proceed.
dlax added a comment.
dlax requested changes to this revision.


  D7430  makes this changes unnecessary I 
think.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7384/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7384

To: durin42, #hg-reviewers, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7296: pycompat: kludge around pytype being confused by __new__

2019-11-15 Thread dlax (Denis Laxalde)
This revision now requires changes to proceed.
dlax added a comment.
dlax requested changes to this revision.


  Rather `class bytestr(bytes):  # type: Callable[[Union[bytes, str], bytestr]` 
as @yuya suggested in D7380 .

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7296/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7296

To: durin42, #hg-reviewers, indygreg, dlax
Cc: mjpieters, dlax, indygreg, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7430: bisect: replace try:/finally: by a "restore_state" context manager

2019-11-15 Thread dlax (Denis Laxalde)
dlax created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This should help pytype to not consider "bgood" variable as NameError.
  See https://phab.mercurial-scm.org/D7384 for context.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D7430

AFFECTED FILES
  mercurial/commands.py
  mercurial/hbisect.py

CHANGE DETAILS

diff --git a/mercurial/hbisect.py b/mercurial/hbisect.py
--- a/mercurial/hbisect.py
+++ b/mercurial/hbisect.py
@@ -11,6 +11,7 @@
 from __future__ import absolute_import
 
 import collections
+import contextlib
 
 from .i18n import _
 from .node import (
@@ -180,6 +181,15 @@
 raise error.Abort(_(b'cannot bisect (no known bad revisions)'))
 
 
+@contextlib.contextmanager
+def restore_state(repo, state, node):
+try:
+yield
+finally:
+state[b'current'] = [node]
+save_state(repo, state)
+
+
 def get(repo, status):
 """
 Return a list of revision(s) that match the given status:
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1073,7 +1073,7 @@
 raise error.Abort(_(b'current bisect revision is a merge'))
 if rev:
 node = repo[scmutil.revsingle(repo, rev, node)].node()
-try:
+with hbisect.restore_state(repo, state, node):
 while changesets:
 # update state
 state[b'current'] = [node]
@@ -1105,9 +1105,6 @@
 # update to next check
 node = nodes[0]
 mayupdate(repo, node, show_stats=False)
-finally:
-state[b'current'] = [node]
-hbisect.save_state(repo, state)
 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
 return
 



To: dlax, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7296: pycompat: kludge around pytype being confused by __new__

2019-11-14 Thread dlax (Denis Laxalde)
dlax added a comment.


class bytestr(bytes):  # type: (Union[bytes,str]) -> bytestr
  [...]
  
  Does this work?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7296/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7296

To: durin42, #hg-reviewers, indygreg
Cc: mjpieters, dlax, indygreg, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7380: encoding: define per-use identity functions only in typechecking mode

2019-11-14 Thread dlax (Denis Laxalde)
dlax added a comment.


  Have you tried using variables annotations? Like:
  
strtolocal = pycompat.identity  # type: (str) -> bytes
strfromlocal = pycompat.identity  # type: (bytes) -> str

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7380/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7380

To: durin42, #hg-reviewers
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2] tests: test "hg log" with --line-range and --copies

2019-11-14 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573727585 -3600
#  Thu Nov 14 11:33:05 2019 +0100
# Node ID a0b29e94b386346d61e1549d5b8e47bec51b0783
# Parent  3386a6737e04d6a8cf4787f8a76765dcea5857de
tests: test "hg log" with --line-range and --copies

This now works (does not crash), due to previous changeset. Since
--line-range implies --follow, --copies option is redundant.

diff --git a/tests/test-log-linerange.t b/tests/test-log-linerange.t
--- a/tests/test-log-linerange.t
+++ b/tests/test-log-linerange.t
@@ -868,6 +868,112 @@ Renames are followed.
   +4
   
 
+Copies.
+
+  $ hg copy baz bbaz
+  $ sed 's/6/6+/' bbaz > bbaz.new
+  $ mv bbaz.new bbaz
+  $ hg commit -m 'cp baz bbaz; 6-6+'
+  $ hg diff -c .
+  diff --git a/dir/baz b/dir/bbaz
+  copy from dir/baz
+  copy to dir/bbaz
+  --- a/dir/baz
+  +++ b/dir/bbaz
+  @@ -7,7 +7,7 @@
+   3+
+   4
+   5
+  -6
+  +6+
+   7
+   8
+   9
+  $ hg log --copies -f -L bbaz,10:11 -p
+  changeset:   10:91a3d3b6c546
+  tag: tip
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: cp baz bbaz; 6-6+
+  
+  diff --git a/dir/baz b/dir/bbaz
+  copy from dir/baz
+  copy to dir/bbaz
+  --- a/dir/baz
+  +++ b/dir/bbaz
+  @@ -7,7 +7,7 @@
+   3+
+   4
+   5
+  -6
+  +6+
+   7
+   8
+   9
+  
+  changeset:   3:730a61fbaecf
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: to 11
+  
+  diff --git a/foo b/foo
+  --- a/foo
+  +++ b/foo
+  @@ -6,3 +6,10 @@
+   2+
+   3
+   4
+  +5
+  +6
+  +7
+  +8
+  +9
+  +10
+  +11
+  
+  $ hg log -f -L bbaz,10:11 -p
+  changeset:   10:91a3d3b6c546
+  tag: tip
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: cp baz bbaz; 6-6+
+  
+  diff --git a/dir/baz b/dir/bbaz
+  copy from dir/baz
+  copy to dir/bbaz
+  --- a/dir/baz
+  +++ b/dir/bbaz
+  @@ -7,7 +7,7 @@
+   3+
+   4
+   5
+  -6
+  +6+
+   7
+   8
+   9
+  
+  changeset:   3:730a61fbaecf
+  user:test
+  date:Thu Jan 01 00:00:00 1970 +
+  summary: to 11
+  
+  diff --git a/foo b/foo
+  --- a/foo
+  +++ b/foo
+  @@ -6,3 +6,10 @@
+   2+
+   3
+   4
+  +5
+  +6
+  +7
+  +8
+  +9
+  +10
+  +11
+  
+
 Binary files work but without diff hunks filtering.
 (Checking w/ and w/o diff.git option.)
 
@@ -875,7 +981,7 @@ Binary files work but without diff hunks
   $ hg add binary
   $ hg ci -m 'add a binary file' --quiet
   $ hg log -f -L binary,1:2 -p
-  changeset:   10:c96381c229df
+  changeset:   11:dc865b608edf
   tag: tip
   user:test
   date:Thu Jan 01 00:00:00 1970 +
@@ -890,13 +996,13 @@ Binary files work but without diff hunks
   
   
   $ hg log -f -L binary,1:2 -p --config diff.git=false
-  changeset:   10:c96381c229df
+  changeset:   11:dc865b608edf
   tag: tip
   user:test
   date:Thu Jan 01 00:00:00 1970 +
   summary: add a binary file
   
-  diff -r 6af29c3a778f -r c96381c229df dir/binary
+  diff -r 91a3d3b6c546 -r dc865b608edf dir/binary
   Binary file dir/binary has changed
   
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 2] logcmdutil: let getlinerangerevs() return "revs" as a smartset

2019-11-14 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573726298 -3600
#  Thu Nov 14 11:11:38 2019 +0100
# Node ID 3386a6737e04d6a8cf4787f8a76765dcea5857de
# Parent  ec53ea01c9e6c64ff1e4ffc5ce5b8623c5dae9da
logcmdutil: let getlinerangerevs() return "revs" as a smartset

This makes it consistent in "hg log" command where 'revs' can come from
logcmdutil.getrevs() as a smartset or from getlinerangerevs(),
previously as a list. This will help type hinting as noticed in
https://phab.mercurial-scm.org/D7377.

diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -968,7 +968,7 @@ def getlinerangerevs(repo, userrevs, opt
 differ = changesetdiffer()
 differ._makefilematcher = filematcher
 differ._makehunksfilter = hunksfilter
-return revs, differ
+return smartset.baseset(revs), differ
 
 
 def _graphnodeformatter(ui, displayer):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7385: debugcommands: suppress import errors for pytype

2019-11-14 Thread dlax (Denis Laxalde)
dlax added a comment.
dlax accepted this revision.


  I wonder if using `importlib.import_module()` wouldn't help. Or is it 
something we avoid in Mercurial?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7385/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7385

To: durin42, #hg-reviewers, dlax
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7384: commands: necessary annotations and suppresssions to pass pytype

2019-11-14 Thread dlax (Denis Laxalde)
dlax added inline comments.

INLINE COMMENTS

> commands.py:1127
> +bgood,  # pytype: disable=name-error
> +)
>  return

This one is sad. I think this can be sorted out by replacing the 
`try:/finally:` with a context manager. (Can send a patch, if it sounds good to 
you.)

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7384/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7384

To: durin42, #hg-reviewers
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7289: branchmap: always copy closednodes to a set

2019-11-14 Thread dlax (Denis Laxalde)
dlax added a comment.


  On second thought, it's not obvious why it'd be better than annotating 
`__init__()`. Is this because this would require many changes in callers?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7289/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7289

To: durin42, #hg-reviewers, indygreg, dlax
Cc: indygreg, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7381: cmdutil: add a pytype annotation to help out some callsites

2019-11-14 Thread dlax (Denis Laxalde)
dlax added inline comments.

INLINE COMMENTS

> cmdutil.py:3970
>  def readgraftstate(repo, graftstate):
> +# type: (Any, statemod.cmdstate) -> Dict[bytes, Any]
>  """read the graft state file and return a dict of the data stored in 
> it"""

Wouldn't `-> Dict[bytes, List[bytes]]` be okay? (Not sure why "Any" you're 
referering to in commit message, though I understand `Dict[bytes, Any]` comes 
from `state.cmdstate.read()` return type in D7383 
.)

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7381/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7381

To: durin42, #hg-reviewers
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7377: commands: log --line-range is incompatible with --copies

2019-11-14 Thread dlax (Denis Laxalde)
dlax added a comment.


  Nice pytype catch!
  
  That's a bug, I think. `logcmdutil.getlinerangerevs()` should return `revs` 
as a smartset, not as list. I'll work on a fix.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7377/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7377

To: durin42, #hg-reviewers
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 6] patchbomb: fix wrong argument type when calling mail generator.flatten()

2019-11-13 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573661165 -3600
#  Wed Nov 13 17:06:05 2019 +0100
# Node ID 9ebd700f9dc4e27c0bd45dce1108f7a2255b
# Parent  11d514fd71855ace61c549d3154f52569cea9264
patchbomb: fix wrong argument type when calling mail generator.flatten()

diff --git a/hgext/patchbomb.py b/hgext/patchbomb.py
--- a/hgext/patchbomb.py
+++ b/hgext/patchbomb.py
@@ -958,7 +958,7 @@ def email(ui, repo, *revs, **opts):
 ui.pager(b'email')
 generator = mail.Generator(ui, mangle_from_=False)
 try:
-generator.flatten(m, 0)
+generator.flatten(m, False)
 ui.write(b'\n')
 except IOError as inst:
 if inst.errno != errno.EPIPE:
@@ -973,7 +973,7 @@ def email(ui, repo, *revs, **opts):
 del m['Bcc']
 fp = stringio()
 generator = mail.Generator(fp, mangle_from_=False)
-generator.flatten(m, 0)
+generator.flatten(m, False)
 alldests = to + bcc + cc
 sendmail(sender_addr, alldests, fp.getvalue())
 

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 6] mail: use a native string for "subtype" value

2019-11-13 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573654984 -3600
#  Wed Nov 13 15:23:04 2019 +0100
# Node ID 6f035c6bb911f36cd2459272843388a218be120d
# Parent  f84d980d58cd3e1bdf2b19aa03b419e438eff808
mail: use a native string for "subtype" value

This is somehow similar to previous changeset and avoids one str
conversion.

diff --git a/hgext/patchbomb.py b/hgext/patchbomb.py
--- a/hgext/patchbomb.py
+++ b/hgext/patchbomb.py
@@ -285,7 +285,7 @@ def makepatch(
 if body:
 msg.attach(mail.mimeencode(ui, body, _charsets, opts.get(b'test')))
 p = mail.mimetextpatch(
-b'\n'.join(patchlines), b'x-patch', opts.get(b'test')
+b'\n'.join(patchlines), 'x-patch', opts.get(b'test')
 )
 binnode = nodemod.bin(node)
 # if node is mq patch, it will have the patch file's name as a tag
diff --git a/mercurial/mail.py b/mercurial/mail.py
--- a/mercurial/mail.py
+++ b/mercurial/mail.py
@@ -263,8 +263,8 @@ def codec2iana(cs):
 return cs
 
 
-def mimetextpatch(s, subtype=b'plain', display=False):
-# type: (bytes, bytes, bool) -> email.message.Message
+def mimetextpatch(s, subtype='plain', display=False):
+# type: (bytes, str, bool) -> email.message.Message
 '''Return MIME message suitable for a patch.
 Charset will be detected by first trying to decode as us-ascii, then utf-8,
 and finally the global encodings. If all those fail, fall back to
@@ -290,13 +290,13 @@ def mimetextpatch(s, subtype=b'plain', d
 
 
 def mimetextqp(body, subtype, charset):
-# type: (bytes, bytes, str) -> email.message.Message
+# type: (bytes, str, str) -> email.message.Message
 '''Return MIME message.
 Quoted-printable transfer encoding will be used if necessary.
 '''
 cs = email.charset.Charset(charset)
 msg = email.message.Message()
-msg.set_type(pycompat.sysstr(b'text/' + subtype))
+msg.set_type('text/' + subtype)
 
 for line in body.splitlines():
 if len(line) > 950:
@@ -450,7 +450,7 @@ def mimeencode(ui, s, charsets=None, dis
 cs = 'us-ascii'
 if not display:
 s, cs = _encode(ui, s, charsets)
-return mimetextqp(s, b'plain', cs)
+return mimetextqp(s, 'plain', cs)
 
 
 if pycompat.ispy3:

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 6] mail: let all charset values be native strings

2019-11-13 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573595550 -3600
#  Tue Nov 12 22:52:30 2019 +0100
# Node ID f84d980d58cd3e1bdf2b19aa03b419e438eff808
# Parent  ff60edae8bb65ef213f9d83b6065c161d57f2a51
mail: let all charset values be native strings

Charset values will typically be used to build email.header.Header
instances, which takes str (though it tolerates bytes) or passed to
decode()/encode() methods of string values (which want str). It seems
that using native str involves less conversions than before and this
also helps type hinting (as illustrates removal of pytype disabling
instructions).

diff --git a/mercurial/mail.py b/mercurial/mail.py
--- a/mercurial/mail.py
+++ b/mercurial/mail.py
@@ -253,17 +253,13 @@ def validateconfig(ui):
 
 
 def codec2iana(cs):
-# type: (bytes) -> bytes
+# type: (str) -> str
 ''
-cs = pycompat.sysbytes(
-email.charset.Charset(
-cs  # pytype: disable=wrong-arg-types
-).input_charset.lower()
-)
+cs = email.charset.Charset(cs).input_charset.lower()
 
 # "latin1" normalizes to "iso8859-1", standard calls for "iso-8859-1"
-if cs.startswith(b"iso") and not cs.startswith(b"iso-"):
-return b"iso-" + cs[3:]
+if cs.startswith("iso") and not cs.startswith("iso-"):
+return "iso-" + cs[3:]
 return cs
 
 
@@ -275,27 +271,30 @@ def mimetextpatch(s, subtype=b'plain', d
 ISO-8859-1, an encoding with that allows all byte sequences.
 Transfer encodings will be used if necessary.'''
 
-cs = [b'us-ascii', b'utf-8', encoding.encoding, encoding.fallbackencoding]
+cs = [
+'us-ascii',
+'utf-8',
+pycompat.sysstr(encoding.encoding),
+pycompat.sysstr(encoding.fallbackencoding),
+]
 if display:
-cs = [b'us-ascii']
+cs = ['us-ascii']
 for charset in cs:
 try:
-s.decode(pycompat.sysstr(charset))
+s.decode(charset)
 return mimetextqp(s, subtype, codec2iana(charset))
 except UnicodeDecodeError:
 pass
 
-return mimetextqp(s, subtype, b"iso-8859-1")
+return mimetextqp(s, subtype, "iso-8859-1")
 
 
 def mimetextqp(body, subtype, charset):
-# type: (bytes, bytes, bytes) -> email.message.Message
+# type: (bytes, bytes, str) -> email.message.Message
 '''Return MIME message.
 Quoted-printable transfer encoding will be used if necessary.
 '''
-# Experimentally charset is okay as a bytes even if the type
-# stubs disagree.
-cs = email.charset.Charset(charset)  # pytype: disable=wrong-arg-types
+cs = email.charset.Charset(charset)
 msg = email.message.Message()
 msg.set_type(pycompat.sysstr(b'text/' + subtype))
 
@@ -317,24 +316,25 @@ def mimetextqp(body, subtype, charset):
 
 
 def _charsets(ui):
-# type: (Any) -> List[bytes]
+# type: (Any) -> List[str]
 '''Obtains charsets to send mail parts not containing patches.'''
 charsets = [
-cs.lower() for cs in ui.configlist(b'email', b'charsets')
-]  # type: List[bytes]
+pycompat.sysstr(cs.lower())
+for cs in ui.configlist(b'email', b'charsets')
+]
 fallbacks = [
-encoding.fallbackencoding.lower(),
-encoding.encoding.lower(),
-b'utf-8',
-]  # type: List[bytes]
+pycompat.sysstr(encoding.fallbackencoding.lower()),
+pycompat.sysstr(encoding.encoding.lower()),
+'utf-8',
+]
 for cs in fallbacks:  # find unique charsets while keeping order
 if cs not in charsets:
 charsets.append(cs)
-return [cs for cs in charsets if not cs.endswith(b'ascii')]
+return [cs for cs in charsets if not cs.endswith('ascii')]
 
 
 def _encode(ui, s, charsets):
-# type: (Any, bytes, List[bytes]) -> Tuple[bytes, bytes]
+# type: (Any, bytes, List[str]) -> Tuple[bytes, str]
 '''Returns (converted) string, charset tuple.
 Finds out best charset by cycling through sendcharsets in descending
 order. Tries both encoding and fallbackencoding for input. Only as
@@ -347,14 +347,17 @@ def _encode(ui, s, charsets):
 # wants, and fall back to garbage-in-ascii.
 for ocs in sendcharsets:
 try:
-return s.encode(pycompat.sysstr(ocs)), ocs
+return s.encode(ocs), ocs
 except UnicodeEncodeError:
 pass
 except LookupError:
-ui.warn(_(b'ignoring invalid sendcharset: %s\n') % ocs)
+ui.warn(
+_(b'ignoring invalid sendcharset: %s\n')
+% pycompat.sysbytes(ocs)
+)
 else:
 # Everything failed, ascii-armor what we've got and send it.
-return s.encode('ascii', 'backslashreplace'), b'us-ascii'
+return s.encode('ascii',

[PATCH 5 of 6] mail: move strtolocal call in _addressencode()

2019-11-13 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573659988 -3600
#  Wed Nov 13 16:46:28 2019 +0100
# Node ID 11d514fd71855ace61c549d3154f52569cea9264
# Parent  6f035c6bb911f36cd2459272843388a218be120d
mail: move strtolocal call in _addressencode()

diff --git a/mercurial/mail.py b/mercurial/mail.py
--- a/mercurial/mail.py
+++ b/mercurial/mail.py
@@ -395,8 +395,8 @@ def headencode(ui, s, charsets=None, dis
 
 
 def _addressencode(ui, name, addr, charsets=None):
-# type: (Any, str, bytes, List[str]) -> str
-assert isinstance(addr, bytes)
+# type: (Any, str, str, List[str]) -> str
+addr = encoding.strtolocal(addr)
 name = headencode(ui, name, charsets)
 try:
 acc, dom = addr.split(b'@')
@@ -420,7 +420,7 @@ def addressencode(ui, address, charsets=
 if display or not address:
 return encoding.strfromlocal(address or b'')
 name, addr = email.utils.parseaddr(encoding.strfromlocal(address))
-return _addressencode(ui, name, encoding.strtolocal(addr), charsets)
+return _addressencode(ui, name, addr, charsets)
 
 
 def addrlistencode(ui, addrs, charsets=None, display=False):
@@ -438,7 +438,7 @@ def addrlistencode(ui, addrs, charsets=N
 result = []
 for name, addr in email.utils.getaddresses(straddrs):
 if name or addr:
-r = _addressencode(ui, name, encoding.strtolocal(addr), charsets)
+r = _addressencode(ui, name, addr, charsets)
 result.append(r)
 return result
 

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 6] mail: fix a bad return type in _encode()

2019-11-13 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573575136 -3600
#  Tue Nov 12 17:12:16 2019 +0100
# Node ID a57f3ab9661af30fd20d6a69d872448afa4612bd
# Parent  c207c46a86b92ad7be05de2bf85bb36757e8ae3a
mail: fix a bad return type in _encode()

This particular instruction returned only a string and omitted the
charset value.

diff --git a/mercurial/mail.py b/mercurial/mail.py
--- a/mercurial/mail.py
+++ b/mercurial/mail.py
@@ -336,7 +336,7 @@ def _encode(ui, s, charsets):
 ui.warn(_(b'ignoring invalid sendcharset: %s\n') % ocs)
 else:
 # Everything failed, ascii-armor what we've got and send it.
-return s.encode('ascii', 'backslashreplace')
+return s.encode('ascii', 'backslashreplace'), b'us-ascii'
 # We have a bytes of unknown encoding. We'll try and guess a valid
 # encoding, falling back to pretending we had ascii even though we
 # know that's wrong.

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 6] mail: add type hints for pytype

2019-11-13 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573680044 -3600
#  Wed Nov 13 22:20:44 2019 +0100
# Node ID ff60edae8bb65ef213f9d83b6065c161d57f2a51
# Parent  a57f3ab9661af30fd20d6a69d872448afa4612bd
mail: add type hints for pytype

We essentially annotate functions in which handling of bytes/str is not
obvious in order to hopefully clear things out. See also changeset
2ade00f3b03b introducing typing hints in Mercurial.

Most types are straightforward but a few is wrong, and we need to
either disable pytype on respective instructions or use wrong
annotations. These will be fixed in next changesets. Notice the type
Union[bytes, str] of "s" parameter of headencode(), this reflects how
email.header.Header.append() behaves.

diff --git a/mercurial/mail.py b/mercurial/mail.py
--- a/mercurial/mail.py
+++ b/mercurial/mail.py
@@ -36,6 +36,12 @@ from .utils import (
 stringutil,
 )
 
+if not globals():  # hide this from non-pytype users
+from typing import Any, List, Tuple, Union
+
+# keep pyflakes happy
+assert all((Any, List, Tuple, Union))
+
 
 class STARTTLS(smtplib.SMTP):
 '''Derived class to verify the peer certificate for STARTTLS.
@@ -99,6 +105,7 @@ class SMTPS(smtplib.SMTP):
 
 
 def _pyhastls():
+# type: () -> bool
 """Returns true iff Python has TLS support, false otherwise."""
 try:
 import ssl
@@ -246,8 +253,13 @@ def validateconfig(ui):
 
 
 def codec2iana(cs):
+# type: (bytes) -> bytes
 ''
-cs = pycompat.sysbytes(email.charset.Charset(cs).input_charset.lower())
+cs = pycompat.sysbytes(
+email.charset.Charset(
+cs  # pytype: disable=wrong-arg-types
+).input_charset.lower()
+)
 
 # "latin1" normalizes to "iso8859-1", standard calls for "iso-8859-1"
 if cs.startswith(b"iso") and not cs.startswith(b"iso-"):
@@ -256,6 +268,7 @@ def codec2iana(cs):
 
 
 def mimetextpatch(s, subtype=b'plain', display=False):
+# type: (bytes, bytes, bool) -> email.message.Message
 '''Return MIME message suitable for a patch.
 Charset will be detected by first trying to decode as us-ascii, then utf-8,
 and finally the global encodings. If all those fail, fall back to
@@ -276,6 +289,7 @@ def mimetextpatch(s, subtype=b'plain', d
 
 
 def mimetextqp(body, subtype, charset):
+# type: (bytes, bytes, bytes) -> email.message.Message
 '''Return MIME message.
 Quoted-printable transfer encoding will be used if necessary.
 '''
@@ -303,13 +317,16 @@ def mimetextqp(body, subtype, charset):
 
 
 def _charsets(ui):
+# type: (Any) -> List[bytes]
 '''Obtains charsets to send mail parts not containing patches.'''
-charsets = [cs.lower() for cs in ui.configlist(b'email', b'charsets')]
+charsets = [
+cs.lower() for cs in ui.configlist(b'email', b'charsets')
+]  # type: List[bytes]
 fallbacks = [
 encoding.fallbackencoding.lower(),
 encoding.encoding.lower(),
 b'utf-8',
-]
+]  # type: List[bytes]
 for cs in fallbacks:  # find unique charsets while keeping order
 if cs not in charsets:
 charsets.append(cs)
@@ -317,6 +334,7 @@ def _charsets(ui):
 
 
 def _encode(ui, s, charsets):
+# type: (Any, bytes, List[bytes]) -> Tuple[bytes, bytes]
 '''Returns (converted) string, charset tuple.
 Finds out best charset by cycling through sendcharsets in descending
 order. Tries both encoding and fallbackencoding for input. Only as
@@ -361,15 +379,19 @@ def _encode(ui, s, charsets):
 
 
 def headencode(ui, s, charsets=None, display=False):
+# type: (Any, Union[bytes, str], List[bytes], bool) -> str
 '''Returns RFC-2047 compliant header from given string.'''
 if not display:
 # split into words?
 s, cs = _encode(ui, s, charsets)
-return email.header.Header(s, cs).encode()
+return email.header.Header(
+s, cs  # pytype: disable=wrong-arg-types
+).encode()
 return encoding.strfromlocal(s)
 
 
 def _addressencode(ui, name, addr, charsets=None):
+# type: (Any, str, bytes, List[bytes]) -> str
 assert isinstance(addr, bytes)
 name = headencode(ui, name, charsets)
 try:
@@ -389,6 +411,7 @@ def _addressencode(ui, name, addr, chars
 
 
 def addressencode(ui, address, charsets=None, display=False):
+# type: (Any, bytes, List[bytes], bool) -> str
 '''Turns address into RFC-2047 compliant header.'''
 if display or not address:
 return encoding.strfromlocal(address or b'')
@@ -397,6 +420,7 @@ def addressencode(ui, address, charsets=
 
 
 def addrlistencode(ui, addrs, charsets=None, display=False):
+# type: (Any, List[bytes], List[bytes], bool) -> List[str]
 '''Turns a list of addresses into a list of RFC-2047 compliant headers.
 A single element of input list may contain multiple addresses, but output
   

D7373: py3: pass a bytes value for "msg" to nouideprecwarn()

2019-11-13 Thread dlax (Denis Laxalde)
Closed by commit rHGc207c46a86b9: py3: pass a bytes value for msg 
to nouideprecwarn() (authored by dlax).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7373?vs=18051=18053

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7373/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7373

AFFECTED FILES
  mercurial/pure/parsers.py
  mercurial/revlog.py

CHANGE DETAILS

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -207,7 +207,7 @@
 class revlogoldindex(list):
 @property
 def nodemap(self):
-msg = "index.nodemap is deprecated, " "use 
index.[has_node|rev|get_rev]"
+msg = b"index.nodemap is deprecated, use index.[has_node|rev|get_rev]"
 util.nouideprecwarn(msg, b'5.3', stacklevel=2)
 return self._nodemap
 
@@ -657,15 +657,15 @@
 @property
 def nodemap(self):
 msg = (
-"revlog.nodemap is deprecated, "
-"use revlog.index.[has_node|rev|get_rev]"
+b"revlog.nodemap is deprecated, "
+b"use revlog.index.[has_node|rev|get_rev]"
 )
 util.nouideprecwarn(msg, b'5.3', stacklevel=2)
 return self.index.nodemap
 
 @property
 def _nodecache(self):
-msg = "revlog._nodecache is deprecated, use revlog.index.nodemap"
+msg = b"revlog._nodecache is deprecated, use revlog.index.nodemap"
 util.nouideprecwarn(msg, b'5.3', stacklevel=2)
 return self.index.nodemap
 
diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -49,7 +49,7 @@
 class BaseIndexObject(object):
 @property
 def nodemap(self):
-msg = "index.nodemap is deprecated, " "use 
index.[has_node|rev|get_rev]"
+msg = b"index.nodemap is deprecated, use index.[has_node|rev|get_rev]"
 util.nouideprecwarn(msg, b'5.3', stacklevel=2)
 return self._nodemap
 



To: dlax, indygreg, #hg-reviewers, pulkit
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7373: py3: pass a bytes value for "msg" to nouideprecwarn()

2019-11-13 Thread dlax (Denis Laxalde)
dlax added a comment.


  should fix tracebacks in https://ci.octobus.net/job/EvolvePy3/278/console

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7373/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7373

To: dlax, indygreg, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7373: py3: pass a bytes value for "msg" to nouideprecwarn()

2019-11-13 Thread dlax (Denis Laxalde)
dlax created this revision.
Herald added a reviewer: indygreg.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  That function formats "msg" with the "version" value. On Python 3, this
  leads to "TypeError: can only concatenate str (not "bytes") to str".
  
  Also eliminate spurious strings concatenation in single-line
  declarations.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D7373

AFFECTED FILES
  mercurial/pure/parsers.py
  mercurial/revlog.py

CHANGE DETAILS

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -207,7 +207,7 @@
 class revlogoldindex(list):
 @property
 def nodemap(self):
-msg = "index.nodemap is deprecated, " "use 
index.[has_node|rev|get_rev]"
+msg = b"index.nodemap is deprecated, use index.[has_node|rev|get_rev]"
 util.nouideprecwarn(msg, b'5.3', stacklevel=2)
 return self._nodemap
 
@@ -657,15 +657,15 @@
 @property
 def nodemap(self):
 msg = (
-"revlog.nodemap is deprecated, "
-"use revlog.index.[has_node|rev|get_rev]"
+b"revlog.nodemap is deprecated, "
+b"use revlog.index.[has_node|rev|get_rev]"
 )
 util.nouideprecwarn(msg, b'5.3', stacklevel=2)
 return self.index.nodemap
 
 @property
 def _nodecache(self):
-msg = "revlog._nodecache is deprecated, use revlog.index.nodemap"
+msg = b"revlog._nodecache is deprecated, use revlog.index.nodemap"
 util.nouideprecwarn(msg, b'5.3', stacklevel=2)
 return self.index.nodemap
 
diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -49,7 +49,7 @@
 class BaseIndexObject(object):
 @property
 def nodemap(self):
-msg = "index.nodemap is deprecated, " "use 
index.[has_node|rev|get_rev]"
+msg = b"index.nodemap is deprecated, use index.[has_node|rev|get_rev]"
 util.nouideprecwarn(msg, b'5.3', stacklevel=2)
 return self._nodemap
 



To: dlax, indygreg, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH STABLE] py3: avoid iterating over a literal bytes in highlight

2019-11-12 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573553103 -3600
#  Tue Nov 12 11:05:03 2019 +0100
# Branch stable
# Node ID 430d80ba9271920ca6da8db62b507390f65d20d1
# Parent  e513e87b0476cc9a6eb31abe420448877fa9c902
py3: avoid iterating over a literal bytes in highlight

In Python 3, iterating over a bytes literal yields integers. Since we
use the value in `text.replace()`, this fails on Python 3 with the
following trackback:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/mercurial/hgweb/hgwebdir_mod.py", 
line 378, in run_wsgi
for r in self._runwsgi(req, res):
  File "/usr/lib/python3/dist-packages/mercurial/hgweb/hgweb_mod.py", line 
326, in run_wsgi
for r in self._runwsgi(req, res, repo):
  File "/usr/lib/python3/dist-packages/mercurial/hgweb/hgweb_mod.py", line 
449, in _runwsgi
return getattr(webcommands, cmd)(rctx)
  File "/usr/lib/python3/dist-packages/mercurial/hgweb/webcommands.py", 
line 211, in file
return _filerevision(web, webutil.filectx(web.repo, web.req))
  File "/usr/lib/python3/dist-packages/hgext/highlight/__init__.py", line 
72, in filerevision_highlight
pygmentize(web, b'fileline', fctx, web.tmpl)
  File "/usr/lib/python3/dist-packages/hgext/highlight/__init__.py", line 
58, in pygmentize
field, fctx, style, tmpl, guessfilenameonly=filenameonly
  File "/usr/lib/python3/dist-packages/hgext/highlight/highlight.py", line 
62, in pygmentize
text = text.replace(c, b'')
TypeError: a bytes-like object is required, not 'int'

diff --git a/hgext/highlight/highlight.py b/hgext/highlight/highlight.py
--- a/hgext/highlight/highlight.py
+++ b/hgext/highlight/highlight.py
@@ -57,7 +57,7 @@ def pygmentize(field, fctx, style, tmpl,
 return
 
 # str.splitlines() != unicode.splitlines() because "reasons"
-for c in b"\x0c\x1c\x1d\x1e":
+for c in b"\x0c", b"\x1c", b"\x1d", b"\x1e":
 if c in text:
 text = text.replace(c, b'')
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2 v2] py3: use native strings when forming email headers in patchbomb

2019-11-10 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573312591 -3600
#  Sat Nov 09 16:16:31 2019 +0100
# Node ID fa028d890b185176d23c580a2cc020fbcb62bd4a
# Parent  9a59fd5811220d3d2742b041dbdc9a0d0f5f2992
py3: use native strings when forming email headers in patchbomb

Per previous changesets, encoded header's values are native str. We
complete the change in patchbomb extension to have literal header values
native str as well. Then we can also change headers' keys to be str. In
_msgid(), we still need to use encoding.strfromlocal() because usage of
os.environ is not allowed by check-code.

This finally removes the "if pycompat.ispy3:" TODO.

---
In contrast with the first version of this change [1], usage of
encoding.strfromlocal() remains limited thanks to previous changesets in
the series.

[1]: 
https://www.mercurial-scm.org/pipermail/mercurial-devel/2019-October/135472.html

diff --git a/hgext/patchbomb.py b/hgext/patchbomb.py
--- a/hgext/patchbomb.py
+++ b/hgext/patchbomb.py
@@ -321,10 +321,10 @@ def makepatch(
 subj = b' '.join([prefix, opts.get(b'subject') or subj])
 else:
 subj = b' '.join([prefix, subj])
-msg[b'Subject'] = mail.headencode(ui, subj, _charsets, opts.get(b'test'))
-msg[b'X-Mercurial-Node'] = node
-msg[b'X-Mercurial-Series-Index'] = b'%i' % idx
-msg[b'X-Mercurial-Series-Total'] = b'%i' % total
+msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get(b'test'))
+msg['X-Mercurial-Node'] = pycompat.sysstr(node)
+msg['X-Mercurial-Series-Index'] = '%i' % idx
+msg['X-Mercurial-Series-Total'] = '%i' % total
 return msg, subj, ds
 
 
@@ -421,7 +421,7 @@ def _getbundlemsgs(repo, sender, bundle,
 )
 emailencoders.encode_base64(datapart)
 msg.attach(datapart)
-msg[b'Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test'))
+msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test'))
 return [(msg, subj, None)]
 
 
@@ -454,7 +454,7 @@ def _makeintro(repo, sender, revs, patch
 
 body = _getdescription(repo, body, sender, **opts)
 msg = mail.mimeencode(ui, body, _charsets, opts.get('test'))
-msg[b'Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test'))
+msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test'))
 return (msg, subj, diffstat)
 
 
@@ -522,9 +522,11 @@ def _getoutgoing(repo, dest, revs):
 
 
 def _msgid(node, timestamp):
-hostname = encoding.strtolocal(socket.getfqdn())
-hostname = encoding.environ.get(b'HGHOSTNAME', hostname)
-return b'<%s.%d@%s>' % (node, timestamp, hostname)
+try:
+hostname = encoding.strfromlocal(encoding.environ[b'HGHOSTNAME'])
+except KeyError:
+hostname = socket.getfqdn()
+return '<%s.%d@%s>' % (node, timestamp, hostname)
 
 
 emailopts = [
@@ -912,10 +914,11 @@ def email(ui, repo, *revs, **opts):
 parent = opts.get(b'in_reply_to') or None
 # angle brackets may be omitted, they're not semantically part of the 
msg-id
 if parent is not None:
-if not parent.startswith(b'<'):
-parent = b'<' + parent
-if not parent.endswith(b'>'):
-parent += b'>'
+parent = encoding.strfromlocal(parent)
+if not parent.startswith('<'):
+parent = '<' + parent
+if not parent.endswith('>'):
+parent += '>'
 
 sender_addr = eutil.parseaddr(encoding.strfromlocal(sender))[1]
 sender = mail.addressencode(ui, sender, _charsets, opts.get(b'test'))
@@ -926,50 +929,30 @@ def email(ui, repo, *revs, **opts):
 )
 for i, (m, subj, ds) in enumerate(msgs):
 try:
-m[b'Message-Id'] = genmsgid(m[b'X-Mercurial-Node'])
+m['Message-Id'] = genmsgid(m['X-Mercurial-Node'])
 if not firstpatch:
-firstpatch = m[b'Message-Id']
-m[b'X-Mercurial-Series-Id'] = firstpatch
+firstpatch = m['Message-Id']
+m['X-Mercurial-Series-Id'] = firstpatch
 except TypeError:
-m[b'Message-Id'] = genmsgid(b'patchbomb')
+m['Message-Id'] = genmsgid('patchbomb')
 if parent:
-m[b'In-Reply-To'] = parent
-m[b'References'] = parent
-if not parent or b'X-Mercurial-Node' not in m:
-parent = m[b'Message-Id']
+m['In-Reply-To'] = parent
+m['References'] = parent
+if not parent or 'X-Mercurial-Node' not in m:
+parent = m['Message-Id']
 
-m[b'User-Agent'] = b'Mercurial-patchbomb/%s' % util.version()
-m[b'Date'] = eutil.formatdate(start_time[0], localtime=True)
+m['User-Agent'] = 'Mercurial-patchbomb/%s' % util.version().decode()
+m['Date'] = eutil.formatdate(start_time[0], localtime=True)
 
 start_time = (start_time[0] + 1, start_time[1])
-m[b'From'] = sender
-m[b'To'] = ', '.join(to)
+m['From'] = sender
+

[PATCH 1 of 2 v2] mail: convert addr to str early in addrlistencode()

2019-11-10 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573314873 -3600
#  Sat Nov 09 16:54:33 2019 +0100
# Node ID 9a59fd5811220d3d2742b041dbdc9a0d0f5f2992
# Parent  b8e4d65733c52d2425e571a6148dbfbafe9ebab3
mail: convert addr to str early in addrlistencode()

diff --git a/mercurial/mail.py b/mercurial/mail.py
--- a/mercurial/mail.py
+++ b/mercurial/mail.py
@@ -400,15 +400,15 @@ def addrlistencode(ui, addrs, charsets=N
 '''Turns a list of addresses into a list of RFC-2047 compliant headers.
 A single element of input list may contain multiple addresses, but output
 always has one address per item'''
+straddrs = []
 for a in addrs:
 assert isinstance(a, bytes), '%r unexpectedly not a bytestr' % a
+straddrs.append(encoding.strfromlocal(a))
 if display:
-return [encoding.strfromlocal(a.strip()) for a in addrs if a.strip()]
+return [a.strip() for a in straddrs if a.strip()]
 
 result = []
-for name, addr in email.utils.getaddresses(
-[encoding.strfromlocal(a) for a in addrs]
-):
+for name, addr in email.utils.getaddresses(straddrs):
 if name or addr:
 r = _addressencode(ui, name, encoding.strtolocal(addr), charsets)
 result.append(r)

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 4] py3: use native strings when forming email headers in patchbomb

2019-11-09 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573312591 -3600
#  Sat Nov 09 16:16:31 2019 +0100
# Node ID cc7ee463d94f42083eee0bbda497beb6a1f4eb6d
# Parent  068618bc1ae197973b082742a3446aeaab02cad9
py3: use native strings when forming email headers in patchbomb

Per previous changesets, encoded header's values are native str. We
complete the change in patchbomb extension to have literal header values
native str as well. Then we can also change headers' keys to be str. In
_msgid(), we still need to use encoding.strfromlocal() because usage of
os.environ is not allowed by check-code.

This finally removes the "if pycompat.ispy3:" TODO.

---
In contrast with the first version of this change [1], usage of
encoding.strfromlocal() remains limited thanks to previous changesets in
the series.

[1]: 
https://www.mercurial-scm.org/pipermail/mercurial-devel/2019-October/135472.html

diff --git a/hgext/patchbomb.py b/hgext/patchbomb.py
--- a/hgext/patchbomb.py
+++ b/hgext/patchbomb.py
@@ -321,10 +321,10 @@ def makepatch(
 subj = b' '.join([prefix, opts.get(b'subject') or subj])
 else:
 subj = b' '.join([prefix, subj])
-msg[b'Subject'] = mail.headencode(ui, subj, _charsets, opts.get(b'test'))
-msg[b'X-Mercurial-Node'] = node
-msg[b'X-Mercurial-Series-Index'] = b'%i' % idx
-msg[b'X-Mercurial-Series-Total'] = b'%i' % total
+msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get(b'test'))
+msg['X-Mercurial-Node'] = pycompat.sysstr(node)
+msg['X-Mercurial-Series-Index'] = '%i' % idx
+msg['X-Mercurial-Series-Total'] = '%i' % total
 return msg, subj, ds
 
 
@@ -421,7 +421,7 @@ def _getbundlemsgs(repo, sender, bundle,
 )
 emailencoders.encode_base64(datapart)
 msg.attach(datapart)
-msg[b'Subject'] = mail.headencode(ui, subj, _charsets, opts.get(r'test'))
+msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get(r'test'))
 return [(msg, subj, None)]
 
 
@@ -454,7 +454,7 @@ def _makeintro(repo, sender, revs, patch
 
 body = _getdescription(repo, body, sender, **opts)
 msg = mail.mimeencode(ui, body, _charsets, opts.get(r'test'))
-msg[b'Subject'] = mail.headencode(ui, subj, _charsets, opts.get(r'test'))
+msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get(r'test'))
 return (msg, subj, diffstat)
 
 
@@ -522,9 +522,11 @@ def _getoutgoing(repo, dest, revs):
 
 
 def _msgid(node, timestamp):
-hostname = encoding.strtolocal(socket.getfqdn())
-hostname = encoding.environ.get(b'HGHOSTNAME', hostname)
-return b'<%s.%d@%s>' % (node, timestamp, hostname)
+try:
+hostname = encoding.strfromlocal(encoding.environ[b'HGHOSTNAME'])
+except KeyError:
+hostname = socket.getfqdn()
+return '<%s.%d@%s>' % (node, timestamp, hostname)
 
 
 emailopts = [
@@ -912,10 +914,11 @@ def email(ui, repo, *revs, **opts):
 parent = opts.get(b'in_reply_to') or None
 # angle brackets may be omitted, they're not semantically part of the 
msg-id
 if parent is not None:
-if not parent.startswith(b'<'):
-parent = b'<' + parent
-if not parent.endswith(b'>'):
-parent += b'>'
+parent = encoding.strfromlocal(parent)
+if not parent.startswith('<'):
+parent = '<' + parent
+if not parent.endswith('>'):
+parent += '>'
 
 sender_addr = eutil.parseaddr(encoding.strfromlocal(sender))[1]
 sender = mail.addressencode(ui, sender, _charsets, opts.get(b'test'))
@@ -926,50 +929,30 @@ def email(ui, repo, *revs, **opts):
 )
 for i, (m, subj, ds) in enumerate(msgs):
 try:
-m[b'Message-Id'] = genmsgid(m[b'X-Mercurial-Node'])
+m['Message-Id'] = genmsgid(m['X-Mercurial-Node'])
 if not firstpatch:
-firstpatch = m[b'Message-Id']
-m[b'X-Mercurial-Series-Id'] = firstpatch
+firstpatch = m['Message-Id']
+m['X-Mercurial-Series-Id'] = firstpatch
 except TypeError:
-m[b'Message-Id'] = genmsgid(b'patchbomb')
+m['Message-Id'] = genmsgid('patchbomb')
 if parent:
-m[b'In-Reply-To'] = parent
-m[b'References'] = parent
-if not parent or b'X-Mercurial-Node' not in m:
-parent = m[b'Message-Id']
+m['In-Reply-To'] = parent
+m['References'] = parent
+if not parent or 'X-Mercurial-Node' not in m:
+parent = m['Message-Id']
 
-m[b'User-Agent'] = b'Mercurial-patchbomb/%s' % util.version()
-m[b'Date'] = eutil.formatdate(start_time[0], localtime=True)
+m['User-Agent'] = 'Mercurial-patchbomb/%s' % util.version().decode()
+m['Date'] = eutil.formatdate(start_time[0], localtime=True)
 
 start_time = (start_time[0] + 1, start_time[1])
-m[b'From'] = sender
-m[b'To'] = ', '.join(to)
+m['From'] = sender
+

[PATCH 2 of 4] mail: let addressencode() / addrlistencode() return native strings

2019-11-09 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573309012 -3600
#  Sat Nov 09 15:16:52 2019 +0100
# Node ID 36c4ef3894cdb62ae0a63b7b266f1b07df6dcb12
# Parent  1c7a66bf3315f69036420e2b07b584abacfef881
mail: let addressencode() / addrlistencode() return native strings

Avoids conversion to "str" on py3.

diff --git a/hgext/notify.py b/hgext/notify.py
--- a/hgext/notify.py
+++ b/hgext/notify.py
@@ -430,14 +430,14 @@ class notifier(object):
 sender = self.ui.config(b'email', b'from') or self.ui.username()
 if b'@' not in sender or b'@localhost' in sender:
 sender = self.fixmail(sender)
-msg[r'From'] = encoding.strfromlocal(
-mail.addressencode(self.ui, sender, self.charsets, self.test)
+msg[r'From'] = mail.addressencode(
+self.ui, sender, self.charsets, self.test
 )
 
 msg[r'X-Hg-Notification'] = r'changeset %s' % ctx
 if not msg[r'Message-Id']:
 msg[r'Message-Id'] = messageid(ctx, self.domain, 
self.messageidseed)
-msg[r'To'] = encoding.strfromlocal(b', '.join(sorted(subs)))
+msg[r'To'] = ', '.join(sorted(subs))
 
 msgtext = msg.as_bytes() if pycompat.ispy3 else msg.as_string()
 if self.test:
diff --git a/hgext/patchbomb.py b/hgext/patchbomb.py
--- a/hgext/patchbomb.py
+++ b/hgext/patchbomb.py
@@ -943,13 +943,13 @@ def email(ui, repo, *revs, **opts):
 
 start_time = (start_time[0] + 1, start_time[1])
 m[b'From'] = sender
-m[b'To'] = b', '.join(to)
+m[b'To'] = ', '.join(to)
 if cc:
-m[b'Cc'] = b', '.join(cc)
+m[b'Cc'] = ', '.join(cc)
 if bcc:
-m[b'Bcc'] = b', '.join(bcc)
+m[b'Bcc'] = ', '.join(bcc)
 if replyto:
-m[b'Reply-To'] = b', '.join(replyto)
+m[b'Reply-To'] = ', '.join(replyto)
 # Fix up all headers to be native strings.
 # TODO(durin42): this should probably be cleaned up above in the 
future.
 if pycompat.ispy3:
@@ -992,7 +992,6 @@ def email(ui, repo, *revs, **opts):
 generator = mail.Generator(fp, mangle_from_=False)
 generator.flatten(m, 0)
 alldests = to + bcc + cc
-alldests = [encoding.strfromlocal(d) for d in alldests]
 sendmail(sender_addr, alldests, fp.getvalue())
 
 progress.complete()
diff --git a/mercurial/mail.py b/mercurial/mail.py
--- a/mercurial/mail.py
+++ b/mercurial/mail.py
@@ -385,15 +385,13 @@ def _addressencode(ui, name, addr, chars
 addr.decode('ascii')
 except UnicodeDecodeError:
 raise error.Abort(_(b'invalid local address: %s') % addr)
-return pycompat.bytesurl(
-email.utils.formataddr((name, encoding.strfromlocal(addr)))
-)
+return email.utils.formataddr((name, encoding.strfromlocal(addr)))
 
 
 def addressencode(ui, address, charsets=None, display=False):
 '''Turns address into RFC-2047 compliant header.'''
 if display or not address:
-return address or b''
+return encoding.strfromlocal(address or b'')
 name, addr = email.utils.parseaddr(encoding.strfromlocal(address))
 return _addressencode(ui, name, encoding.strtolocal(addr), charsets)
 
@@ -405,7 +403,7 @@ def addrlistencode(ui, addrs, charsets=N
 for a in addrs:
 assert isinstance(a, bytes), r'%r unexpectedly not a bytestr' % a
 if display:
-return [a.strip() for a in addrs if a.strip()]
+return [encoding.strfromlocal(a.strip()) for a in addrs if a.strip()]
 
 result = []
 for name, addr in email.utils.getaddresses(

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 4] mail: convert addr to str early in addrlistencode()

2019-11-09 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573314873 -3600
#  Sat Nov 09 16:54:33 2019 +0100
# Node ID 068618bc1ae197973b082742a3446aeaab02cad9
# Parent  36c4ef3894cdb62ae0a63b7b266f1b07df6dcb12
mail: convert addr to str early in addrlistencode()

diff --git a/mercurial/mail.py b/mercurial/mail.py
--- a/mercurial/mail.py
+++ b/mercurial/mail.py
@@ -400,15 +400,14 @@ def addrlistencode(ui, addrs, charsets=N
 '''Turns a list of addresses into a list of RFC-2047 compliant headers.
 A single element of input list may contain multiple addresses, but output
 always has one address per item'''
-for a in addrs:
+for idx, a in enumerate(addrs):
 assert isinstance(a, bytes), r'%r unexpectedly not a bytestr' % a
+addrs[idx] = encoding.strfromlocal(a)
 if display:
-return [encoding.strfromlocal(a.strip()) for a in addrs if a.strip()]
+return [a.strip() for a in addrs if a.strip()]
 
 result = []
-for name, addr in email.utils.getaddresses(
-[encoding.strfromlocal(a) for a in addrs]
-):
+for name, addr in email.utils.getaddresses(addrs):
 if name or addr:
 r = _addressencode(ui, name, encoding.strtolocal(addr), charsets)
 result.append(r)

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4] mail: let headencode() return a native string

2019-11-09 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573299914 -3600
#  Sat Nov 09 12:45:14 2019 +0100
# Node ID 1c7a66bf3315f69036420e2b07b584abacfef881
# Parent  a78a65c33b5aa84cc9c3ae5f7dad636d371f149c
mail: let headencode() return a native string

This is to avoid conversion to/from str on py3.

diff --git a/hgext/notify.py b/hgext/notify.py
--- a/hgext/notify.py
+++ b/hgext/notify.py
@@ -421,8 +421,8 @@ class notifier(object):
 maxsubject = int(self.ui.config(b'notify', b'maxsubject'))
 if maxsubject:
 subject = stringutil.ellipsis(subject, maxsubject)
-msg[r'Subject'] = encoding.strfromlocal(
-mail.headencode(self.ui, subject, self.charsets, self.test)
+msg[r'Subject'] = mail.headencode(
+self.ui, subject, self.charsets, self.test
 )
 
 # try to make message have proper sender
diff --git a/mercurial/mail.py b/mercurial/mail.py
--- a/mercurial/mail.py
+++ b/mercurial/mail.py
@@ -365,13 +365,13 @@ def headencode(ui, s, charsets=None, dis
 if not display:
 # split into words?
 s, cs = _encode(ui, s, charsets)
-return encoding.strtolocal(email.header.Header(s, cs).encode())
-return s
+return email.header.Header(s, cs).encode()
+return encoding.strfromlocal(s)
 
 
 def _addressencode(ui, name, addr, charsets=None):
 assert isinstance(addr, bytes)
-name = encoding.strfromlocal(headencode(ui, name, charsets))
+name = headencode(ui, name, charsets)
 try:
 acc, dom = addr.split(b'@')
 acc.decode('ascii')

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH STABLE] py3: fix sorting of obsolete markers in obsutil (issue6217)

2019-11-09 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573291918 -3600
#  Sat Nov 09 10:31:58 2019 +0100
# Branch stable
# Node ID e513e87b0476cc9a6eb31abe420448877fa9c902
# Parent  be0f77fd274dfeaf47a2104b178039894532c425
py3: fix sorting of obsolete markers in obsutil (issue6217)

This is similar to 01e8eefd9434 and others. We move the sortedmarkers()
function from exchange module to obsutil.

diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -28,6 +28,7 @@ from . import (
 logexchange,
 narrowspec,
 obsolete,
+obsutil,
 phases,
 pushkey,
 pycompat,
@@ -99,11 +100,6 @@ class bundlespec(object):
 contentopts = attr.ib()
 
 
-def _sortedmarkers(markers):
-# last item of marker tuple ('parents') may be None or a tuple
-return sorted(markers, key=lambda m: m[:-1] + (m[-1] or (),))
-
-
 def parsebundlespec(repo, spec, strict=True):
 """Parse a bundle string specification into parts.
 
@@ -1140,7 +1136,7 @@ def _pushb2obsmarkers(pushop, bundler):
 return
 pushop.stepsdone.add(b'obsmarkers')
 if pushop.outobsmarkers:
-markers = _sortedmarkers(pushop.outobsmarkers)
+markers = obsutil.sortedmarkers(pushop.outobsmarkers)
 bundle2.buildobsmarkerspart(bundler, markers)
 
 
@@ -1475,7 +1471,7 @@ def _pushobsolete(pushop):
 if pushop.outobsmarkers:
 pushop.ui.debug(b'try to push obsolete markers to remote\n')
 rslts = []
-markers = _sortedmarkers(pushop.outobsmarkers)
+markers = obsutil.sortedmarkers(pushop.outobsmarkers)
 remotedata = obsolete._pushkeyescape(markers)
 for key in sorted(remotedata, reverse=True):
 # reverse sort to ensure we end with dump0
@@ -2573,7 +2569,7 @@ def _getbundleobsmarkerpart(
 heads = repo.heads()
 subset = [c.node() for c in repo.set(b'::%ln', heads)]
 markers = repo.obsstore.relevantmarkers(subset)
-markers = _sortedmarkers(markers)
+markers = obsutil.sortedmarkers(markers)
 bundle2.buildobsmarkerspart(bundler, markers)
 
 
diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py
--- a/mercurial/obsutil.py
+++ b/mercurial/obsutil.py
@@ -112,6 +112,11 @@ def getmarkers(repo, nodes=None, exclusi
 yield marker(repo, markerdata)
 
 
+def sortedmarkers(markers):
+# last item of marker tuple ('parents') may be None or a tuple
+return sorted(markers, key=lambda m: m[:-1] + (m[-1] or (),))
+
+
 def closestpredecessors(repo, nodeid):
 """yield the list of next predecessors pointing on visible changectx nodes
 
@@ -675,7 +680,7 @@ def successorssets(repo, initialnode, cl
 #   Having none means pruned node, multiple successors means split,
 #   single successors are standard replacement.
 #
-for mark in sorted(succmarkers[current]):
+for mark in sortedmarkers(succmarkers[current]):
 for suc in mark[1]:
 if suc not in cache:
 if suc in stackedset:
@@ -712,7 +717,7 @@ def successorssets(repo, initialnode, cl
 # duplicated entry and successors set that are strict subset of
 # another one.
 succssets = []
-for mark in sorted(succmarkers[current]):
+for mark in sortedmarkers(succmarkers[current]):
 # successors sets contributed by this marker
 base = _succs()
 base.markers.add(mark)

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 3 of 3 STABLE] py3: fix handling of ctrl keys in crecord (issue6213)

2019-11-08 Thread Denis Laxalde
Yuya Nishihara a écrit :
> On Wed, 06 Nov 2019 17:23:29 +0100, Denis Laxalde wrote:
> > # HG changeset patch
> > # User Denis Laxalde 
> > # Date 1573055674 -3600
> > #  Wed Nov 06 16:54:34 2019 +0100
> > # Branch stable
> > # Node ID f4415c4f24f879845f5dc631d592440e88d2afee
> > # Parent  5802765e3828e3b3f1396b92ed7ef18a1eca6456
> > py3: fix handling of ctrl keys in crecord (issue6213)
> > 
> > The "keypressed" value in handlekeypressed() is a key name obtained by
> > curses's getkey(); this can be a multibyte string for special keys
> > like CTRL keys. Calling curses.unctrl() with such a value fails on
> > Python 3 with a TypeError as described in issue6213. (On Python 2, this
> > does not crash, but I'm not sure the result is correct, though it does
> > no matter here.)
> > 
> > So instead of calling unctrl(), we compare "keypressed" with the
> > expected "^L" obtained by curses.ascii.ctrl("L").
> > 
> > diff --git a/mercurial/crecord.py b/mercurial/crecord.py
> > --- a/mercurial/crecord.py
> > +++ b/mercurial/crecord.py
> > @@ -59,6 +59,7 @@ patchhelptext = _(
> >  
> >  try:
> >  import curses
> > +import curses.ascii
> >  
> >  curses.error
> >  except ImportError:
> 
> Maybe need to import wcurses.ascii? I don't know if that works, though.

I don't know either. If wcurses is https://github.com/idobatter/wcurses,
there does not appear to be an "ascii" module.
Does anybody use crecord on windows?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH STABLE] py3: compare http server's command with a native string

2019-11-07 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573113506 -3600
#  Thu Nov 07 08:58:26 2019 +0100
# Branch stable
# Node ID aa65668163280666889f40b335a2a3f9144bb3b2
# Parent  be384a2052aa864733b3f75c357bb2bc7cd42ae4
py3: compare http server's command with a native string

The "command" attribute is an str, so comparing with a bytes would not
work on Python 3. This might solve issues in test-lfs-serve-access.t
that happens sometimes (especially in CI):

--- /hgwork/src/tests/test-lfs-serve-access.t
+++ /hgwork/src/tests/test-lfs-serve-access.t.err
@@ -163,11 +163,13 @@

   $ cat $TESTTMP/access.log $TESTTMP/errors.log
   $LOCALIP - - [$LOGDATE$] "POST /missing/objects/batch HTTP/1.1" 404 - 
(glob)
+  $LOCALIP - - [05/Nov/2019 16:32:34] "{"objects": [{"oid": 
"f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e", "size": 
20}], "operation": "download"}" HTTPStatus.BAD_REQUEST -
   $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=capabilities 
HTTP/1.1" 200 - (glob)
   $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=batch HTTP/1.1" 
200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 
comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
   $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=getbundle 
HTTP/1.1" 200 - 
x-hgarg-1:bookmarks=1=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2=1==525251863cad618e55d483555f3d00a2ca99597e=bookmarks=1
 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
   $LOCALIP - - [$LOGDATE$] "POST 
/subdir/mount/point/.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
   $LOCALIP - - [$LOGDATE$] "GET 
/subdir/mount/point/.hg/lfs/objects/f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
 HTTP/1.1" 200 - (glob)
+  $LOCALIP - - [05/Nov/2019 16:32:34] code 400, message Bad request 
version ('"download"}')

 Blobs that already exist in the usercache are linked into the repo store, 
even
 though the client doesn't send the blob.
@@ -195,6 +197,7 @@
   
server2/.hg/store/lfs/objects/f0/3217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
   $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
   $ cat $TESTTMP/errors.log
+  $LOCALIP - - [05/Nov/2019 16:32:34] code 400, message Bad request 
version ('"download"}')

   $ cat >> $TESTTMP/lfsstoreerror.py < import errno

(from 
https://ci.hg.gregoryszorc.com/job-info/hg-committed-ca3dca416f8d5863ca6f5a4a6a6bb835dcd5feeb-debian10-cpython-3.7-0)

diff --git a/mercurial/hgweb/server.py b/mercurial/hgweb/server.py
--- a/mercurial/hgweb/server.py
+++ b/mercurial/hgweb/server.py
@@ -160,7 +160,7 @@ class _httprequesthandler(httpservermod.
 self.server.prefix + b'/'
 ):
 self._start_response(pycompat.strurl(common.statusmessage(404)), 
[])
-if self.command == b'POST':
+if self.command == r'POST':
 # Paranoia: tell the client we're going to close the
 # socket so they don't try and reuse a socket that
 # might have a POST body waiting to confuse us. We do
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7262: templateutil: fix a missing ABCMeta assignment

2019-11-07 Thread dlax (Denis Laxalde)
dlax added inline comments.

INLINE COMMENTS

> dlax wrote in templateutil.py:114
> This is ignored on Python 3 (meaning it's possible to instantiate `mappable` 
> directly, despite some methods being abstract). It should be `class 
> mappable(metaclass=abc.ABCMeta)` on Python 3. 
> But I realize that there are other `__metaclass__ = abc.ABCMeta` in the code 
> base. Do we handle this somehow or has this been overlooked?

Just seen D7272  and others which explain 
this. Nevermind.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7262/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7262

To: durin42, #hg-reviewers, indygreg
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7262: templateutil: fix a missing ABCMeta assignment

2019-11-07 Thread dlax (Denis Laxalde)
dlax added inline comments.

INLINE COMMENTS

> templateutil.py:114
>  
> +__metaclass__ = abc.ABCMeta
> +

This is ignored on Python 3 (meaning it's possible to instantiate `mappable` 
directly, despite some methods being abstract). It should be `class 
mappable(metaclass=abc.ABCMeta)` on Python 3. 
But I realize that there are other `__metaclass__ = abc.ABCMeta` in the code 
base. Do we handle this somehow or has this been overlooked?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7262/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7262

To: durin42, #hg-reviewers, indygreg
Cc: dlax, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 3 STABLE] py3: keep "keypressed" a native str in crecord

2019-11-06 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573055581 -3600
#  Wed Nov 06 16:53:01 2019 +0100
# Branch stable
# Node ID 5802765e3828e3b3f1396b92ed7ef18a1eca6456
# Parent  ae3e67359e0bf045ae1bb797d8f4e043fa55042b
py3: keep "keypressed" a native str in crecord

This will help in the next changeset by avoiding a decode step. Also,
the actual bytes conversion seems superfluous since values coming from
curses's getkey() will be a native string. As a consequence, we open the
"testcommands" file (used in test-interactive-curses.t) in text mode.

diff --git a/mercurial/crecord.py b/mercurial/crecord.py
--- a/mercurial/crecord.py
+++ b/mercurial/crecord.py
@@ -24,7 +24,6 @@ from . import (
 encoding,
 error,
 patch as patchmod,
-pycompat,
 scmutil,
 util,
 )
@@ -607,8 +606,8 @@ def testchunkselector(testfn, ui, header
 
 chunkselector.stdscr = dummystdscr()
 if testfn and os.path.exists(testfn):
-testf = open(testfn, b'rb')
-testcommands = [x.rstrip(b'\n') for x in testf.readlines()]
+testf = open(testfn, 'r')
+testcommands = [x.rstrip('\n') for x in testf.readlines()]
 testf.close()
 while True:
 if chunkselector.handlekeypressed(testcommands.pop(0), test=True):
@@ -1887,60 +1886,59 @@ are you sure you want to review/edit and
 
 Return true to exit the main loop.
 """
-keypressed = pycompat.bytestr(keypressed)
-if keypressed in [b"k", b"KEY_UP"]:
+if keypressed in ["k", "KEY_UP"]:
 self.uparrowevent()
-elif keypressed in [b"K", b"KEY_PPAGE"]:
+elif keypressed in ["K", "KEY_PPAGE"]:
 self.uparrowshiftevent()
-elif keypressed in [b"j", b"KEY_DOWN"]:
+elif keypressed in ["j", "KEY_DOWN"]:
 self.downarrowevent()
-elif keypressed in [b"J", b"KEY_NPAGE"]:
+elif keypressed in ["J", "KEY_NPAGE"]:
 self.downarrowshiftevent()
-elif keypressed in [b"l", b"KEY_RIGHT"]:
+elif keypressed in ["l", "KEY_RIGHT"]:
 self.rightarrowevent()
-elif keypressed in [b"h", b"KEY_LEFT"]:
+elif keypressed in ["h", "KEY_LEFT"]:
 self.leftarrowevent()
-elif keypressed in [b"H", b"KEY_SLEFT"]:
+elif keypressed in ["H", "KEY_SLEFT"]:
 self.leftarrowshiftevent()
-elif keypressed in [b"q"]:
+elif keypressed in ["q"]:
 raise error.Abort(_(b'user quit'))
-elif keypressed in [b'a']:
+elif keypressed in ['a']:
 self.toggleamend(self.opts, test)
-elif keypressed in [b"c"]:
+elif keypressed in ["c"]:
 return True
-elif keypressed in [b"r"]:
+elif keypressed in ["r"]:
 if self.reviewcommit():
 self.opts[b'review'] = True
 return True
-elif test and keypressed in [b'R']:
+elif test and keypressed in ["R"]:
 self.opts[b'review'] = True
 return True
-elif keypressed in [b' ', b'x']:
+elif keypressed in [" ", "x"]:
 self.toggleapply()
-elif keypressed in [b'\n', b'KEY_ENTER']:
+elif keypressed in ["\n", "KEY_ENTER"]:
 self.toggleapply()
 self.nextsametype(test=test)
-elif keypressed in [b'X']:
+elif keypressed in ["X"]:
 self.toggleallbetween()
-elif keypressed in [b'A']:
+elif keypressed in ["A"]:
 self.toggleall()
-elif keypressed in [b'e']:
+elif keypressed in ["e"]:
 self.toggleedit(test=test)
-elif keypressed in [b"f"]:
+elif keypressed in ["f"]:
 self.togglefolded()
-elif keypressed in [b"F"]:
+elif keypressed in ["F"]:
 self.togglefolded(foldparent=True)
-elif keypressed in [b"m"]:
+elif keypressed in ["m"]:
 self.commitMessageWindow()
-elif keypressed in [b"g", b"KEY_HOME"]:
+elif keypressed in ["g", "KEY_HOME"]:
 self.handlefirstlineevent()
-elif keypressed in [b"G", b"KEY_END"]:
+elif keypressed in ["G", "KEY_END"]:
 self.handlelastlineevent()
-elif keypressed in [b"?"]:
+elif keypressed in ["?"]:
 self.helpwindow()
 self.stdscr.clear()
 self.stdscr.refresh()
-elif curses.unctrl(keypressed) in [b"^L"]:
+elif curses.unctrl(keypressed) in ["^L"]:
 # scroll the current line to the top of the screen, and redraw
 # everything
 self.scrolllines(self.selecteditemstartline)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 3 STABLE] py3: compare response of crecord's confirmationwindow with str

2019-11-06 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573056733 -3600
#  Wed Nov 06 17:12:13 2019 +0100
# Branch stable
# Node ID ae3e67359e0bf045ae1bb797d8f4e043fa55042b
# Parent  be384a2052aa864733b3f75c357bb2bc7cd42ae4
py3: compare response of crecord's confirmationwindow with str

confirmationwindow() returns a native string, as a result of calling
chr() on getch(). On Python 3, response.lower().startswith(b"y") leads
to a TypeError.

This fixes a crash when typing "r" in the curses interface of
interactive commit.

diff --git a/mercurial/crecord.py b/mercurial/crecord.py
--- a/mercurial/crecord.py
+++ b/mercurial/crecord.py
@@ -1741,8 +1741,8 @@ are you sure you want to review/edit and
 with self.ui.timeblockedsection(b'crecord'):
 response = self.confirmationwindow(confirmtext)
 if response is None:
-response = b"n"
-if response.lower().startswith(b"y"):
+response = "n"
+if response.lower().startswith("y"):
 return True
 else:
 return False
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 3 STABLE] py3: fix handling of ctrl keys in crecord (issue6213)

2019-11-06 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1573055674 -3600
#  Wed Nov 06 16:54:34 2019 +0100
# Branch stable
# Node ID f4415c4f24f879845f5dc631d592440e88d2afee
# Parent  5802765e3828e3b3f1396b92ed7ef18a1eca6456
py3: fix handling of ctrl keys in crecord (issue6213)

The "keypressed" value in handlekeypressed() is a key name obtained by
curses's getkey(); this can be a multibyte string for special keys
like CTRL keys. Calling curses.unctrl() with such a value fails on
Python 3 with a TypeError as described in issue6213. (On Python 2, this
does not crash, but I'm not sure the result is correct, though it does
no matter here.)

So instead of calling unctrl(), we compare "keypressed" with the
expected "^L" obtained by curses.ascii.ctrl("L").

diff --git a/mercurial/crecord.py b/mercurial/crecord.py
--- a/mercurial/crecord.py
+++ b/mercurial/crecord.py
@@ -59,6 +59,7 @@ patchhelptext = _(
 
 try:
 import curses
+import curses.ascii
 
 curses.error
 except ImportError:
@@ -1938,7 +1939,7 @@ are you sure you want to review/edit and
 self.helpwindow()
 self.stdscr.clear()
 self.stdscr.refresh()
-elif curses.unctrl(keypressed) in ["^L"]:
+elif keypressed in [curses.ascii.ctrl("L")]:
 # scroll the current line to the top of the screen, and redraw
 # everything
 self.scrolllines(self.selecteditemstartline)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 2 STABLE] py3: add Python 3 exception output to test-lfs-serve-access.t

2019-11-04 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1572879849 -3600
#  Mon Nov 04 16:04:09 2019 +0100
# Branch stable
# Node ID cb58293505fa65d1b7f2a7d0e3fc3b3320122ac6
# Parent  1edf620a37a32755c413ca4f3a9745b0458fc1bc
py3: add Python 3 exception output to test-lfs-serve-access.t

Similar to a973a75e92bf or 3e9c6cef949b.

diff --git a/tests/test-lfs-serve-access.t b/tests/test-lfs-serve-access.t
--- a/tests/test-lfs-serve-access.t
+++ b/tests/test-lfs-serve-access.t
@@ -354,7 +354,8 @@ Test a checksum failure during the proce
   $LOCALIP - - [$ERRDATE$] HG error:  localstore.download(oid, req.bodyfh) 
(glob)
   $LOCALIP - - [$ERRDATE$] HG error:  super(badstore, self).download(oid, 
src) (glob)
   $LOCALIP - - [$ERRDATE$] HG error:  _(b'corrupt remote lfs object: %s') 
% oid (glob)
-  $LOCALIP - - [$ERRDATE$] HG error:  LfsCorruptionError: corrupt remote lfs 
object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c (glob)
+  $LOCALIP - - [$ERRDATE$] HG error:  LfsCorruptionError: corrupt remote lfs 
object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c 
(no-py3 !)
+  $LOCALIP - - [$ERRDATE$] HG error:  hgext.lfs.blobstore.LfsCorruptionError: 
b'corrupt remote lfs object: 
b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c' (py3 !)
   $LOCALIP - - [$ERRDATE$] HG error:   (glob)
   $LOCALIP - - [$ERRDATE$] Exception happened during processing request 
'/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d':
 (glob)
   Traceback (most recent call last):
@@ -376,7 +377,8 @@ Test a checksum failure during the proce
   $LOCALIP - - [$ERRDATE$] HG error:  blob = self._read(self.vfs, oid, 
verify) (glob)
   $LOCALIP - - [$ERRDATE$] HG error:  blobstore._verify(oid, b'dummy 
content') (glob)
   $LOCALIP - - [$ERRDATE$] HG error:  hint=_(b'run hg verify'), (glob)
-  $LOCALIP - - [$ERRDATE$] HG error:  LfsCorruptionError: detected corrupt lfs 
object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d (glob)
+  $LOCALIP - - [$ERRDATE$] HG error:  LfsCorruptionError: detected corrupt lfs 
object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d 
(no-py3 !)
+  $LOCALIP - - [$ERRDATE$] HG error:  hgext.lfs.blobstore.LfsCorruptionError: 
b'detected corrupt lfs object: 
276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d' (py3 !)
   $LOCALIP - - [$ERRDATE$] HG error:   (glob)
 
 Basic Authorization headers are returned by the Batch API, and sent back with

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 3 STABLE] py3: encode strings before setting rev summary in gnuarch converter

2019-11-04 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1572858548 -3600
#  Mon Nov 04 10:09:08 2019 +0100
# Branch stable
# Node ID b760c0afe8e8cc864b069b4f56d6548e004131d2
# Parent  e0e912bb2453e033807000be5a5c648efef72d59
py3: encode strings before setting rev summary in gnuarch converter

---
This makes test-convert-tla.t pass on Python 3.7.

diff --git a/hgext/convert/gnuarch.py b/hgext/convert/gnuarch.py
--- a/hgext/convert/gnuarch.py
+++ b/hgext/convert/gnuarch.py
@@ -310,7 +310,10 @@ class gnuarch_source(common.converter_so
 
 # Commit description
 self.changes[rev].summary = b'\n\n'.join(
-(catlog[r'Summary'], catlog.get_payload())
+(
+self.recode(catlog[r'Summary']),
+self.recode(catlog.get_payload()),
+)
 )
 self.changes[rev].summary = self.recode(self.changes[rev].summary)
 

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


  1   2   3   4   5   6   >