Re: [PATCH 1 of 8 V2] context: don't use mutable default argument value

2017-03-12 Thread Gregory Szorc
On Sun, Mar 12, 2017 at 9:57 PM, Gregory Szorc 
wrote:

> # HG changeset patch
> # User Gregory Szorc 
> # Date 1489380642 25200
> #  Sun Mar 12 21:50:42 2017 -0700
> # Node ID 265102f455de6451e493024fb8a9f24d816ce1c2
> # Parent  1c48a8278b2f015fca607dfc652823560a5ac580
> context: don't use mutable default argument value
>
> Mutable default argument values are a Python gotcha and can
> represent subtle, hard-to-find bugs. Lets rid our code base
> of them.
>

There was bikeshedding the last time I sent this series. Most of it was
over the code to enforce this with an automatic checker. Since the existing
code represents bugs, I've decided to drop that patch and just fix the code.

The previous send also involved some concerns around how to do this and
whether "foo or []" is the right pattern (versus say a dummy object you
could "is" compare against). Martijn uses the "foo or []" pattern in
d30fb3de4b40 and he knows more about Python than practically anyone. So
I'll use that to justify my opinion that "foo or []" is acceptable.


>
> diff --git a/mercurial/context.py b/mercurial/context.py
> --- a/mercurial/context.py
> +++ b/mercurial/context.py
> @@ -298,10 +298,10 @@ class basectx(object):
>  '''
>  return subrepo.subrepo(self, path, allowwdir=True)
>
> -def match(self, pats=[], include=None, exclude=None, default='glob',
> +def match(self, pats=None, include=None, exclude=None, default='glob',
>listsubrepos=False, badfn=None):
>  r = self._repo
> -return matchmod.match(r.root, r.getcwd(), pats,
> +return matchmod.match(r.root, r.getcwd(), pats or [],
>include, exclude, default,
>auditor=r.nofsauditor, ctx=self,
>listsubrepos=listsubrepos, badfn=badfn)
> @@ -1515,16 +1515,16 @@ class workingctx(committablectx):
>  self._repo.dirstate.normallookup(dest)
>  self._repo.dirstate.copy(source, dest)
>
> -def match(self, pats=[], include=None, exclude=None, default='glob',
> +def match(self, pats=None, include=None, exclude=None, default='glob',
>listsubrepos=False, badfn=None):
>  r = self._repo
>
>  # Only a case insensitive filesystem needs magic to translate
> user input
>  # to actual case in the filesystem.
>  if not util.fscasesensitive(r.root):
> -return matchmod.icasefsmatcher(r.root, r.getcwd(), pats,
> include,
> -   exclude, default, r.auditor,
> self,
> -   listsubrepos=listsubrepos,
> +return matchmod.icasefsmatcher(r.root, r.getcwd(), pats or
> [],
> +   include, exclude, default,
> r.auditor,
> +   self,
> listsubrepos=listsubrepos,
> badfn=badfn)
>  return matchmod.match(r.root, r.getcwd(), pats,
>include, exclude, default,
>
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 8 V2] mq: don't use mutable default argument value

2017-03-12 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1489380946 25200
#  Sun Mar 12 21:55:46 2017 -0700
# Node ID c9cfed31ea6d38b60f50c4af5efe850e3d7f4be7
# Parent  e379f89d119b7b1cd40c313693912b5fdc4a3360
mq: don't use mutable default argument value

diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -721,7 +721,8 @@ class queue(object):
 util.rename(absf, absorig)
 
 def printdiff(self, repo, diffopts, node1, node2=None, files=None,
-  fp=None, changes=None, opts={}):
+  fp=None, changes=None, opts=None):
+opts = opts or {}
 stat = opts.get('stat')
 m = scmutil.match(repo[node1], files, opts)
 cmdutil.diffordiffstat(self.ui, repo, diffopts, node1, node2,  m,
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 8 of 8 V2] rebase: don't use mutable default argument value

2017-03-12 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1489380999 25200
#  Sun Mar 12 21:56:39 2017 -0700
# Node ID 080024492aa477ad75df0cb585d8040e7ab81aa6
# Parent  c9cfed31ea6d38b60f50c4af5efe850e3d7f4be7
rebase: don't use mutable default argument value

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -721,10 +721,12 @@ def rebase(ui, repo, **opts):
 finally:
 release(lock, wlock)
 
-def _definesets(ui, repo, destf=None, srcf=None, basef=None, revf=[],
+def _definesets(ui, repo, destf=None, srcf=None, basef=None, revf=None,
 destspace=None):
 """use revisions argument to define destination and rebase set
 """
+revf = revf or []
+
 # destspace is here to work around issues with `hg pull --rebase` see
 # issue5214 for details
 if srcf and basef:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 8 V2] util: don't use mutable default argument value

2017-03-12 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1489380872 25200
#  Sun Mar 12 21:54:32 2017 -0700
# Node ID e379f89d119b7b1cd40c313693912b5fdc4a3360
# Parent  f72bef9154d773c05fa8b2ae30d7db55861fa639
util: don't use mutable default argument value

I don't think this is any tight loops and we'd need to worry about
PyObject creation overhead. Also, I'm pretty sure strptime()
will be much slower than PyObject creation (date parsing is
surprisingly slow).

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1827,9 +1827,11 @@ def parsetimezone(s):
 
 return None, s
 
-def strdate(string, format, defaults=[]):
+def strdate(string, format, defaults=None):
 """parse a localized time string and return a (unixtime, offset) tuple.
 if the string cannot be parsed, ValueError is raised."""
+defaults = defaults or []
+
 # NOTE: unixtime = localunixtime + offset
 offset, date = parsetimezone(string)
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 8 V2] match: don't use mutable default argument value

2017-03-12 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1489380783 25200
#  Sun Mar 12 21:53:03 2017 -0700
# Node ID f72bef9154d773c05fa8b2ae30d7db55861fa639
# Parent  14122c7b97163496df5ac6b98f7c2459259673b9
match: don't use mutable default argument value

There shouldn't be a big perf hit creating a new object because
this function is complicated and does things that dwarf the cost
of creating a new PyObject.

diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -85,7 +85,7 @@ def _kindpatsalwaysmatch(kindpats):
 return True
 
 class match(object):
-def __init__(self, root, cwd, patterns, include=[], exclude=[],
+def __init__(self, root, cwd, patterns, include=None, exclude=None,
  default='glob', exact=False, auditor=None, ctx=None,
  listsubrepos=False, warn=None, badfn=None):
 """build an object to match a set of file patterns
@@ -117,6 +117,8 @@ class match(object):
   the same directory
 '' - a pattern of the specified default type
 """
+include = include or []
+exclude = exclude or []
 
 self._root = root
 self._cwd = cwd
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 8 V2] hgweb: don't use mutable default argument value

2017-03-12 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1489380737 25200
#  Sun Mar 12 21:52:17 2017 -0700
# Node ID 14122c7b97163496df5ac6b98f7c2459259673b9
# Parent  735405d42d45801c7b75448e0263088327cac4af
hgweb: don't use mutable default argument value

diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py
+++ b/mercurial/hgweb/webutil.py
@@ -142,8 +142,8 @@ class filerevnav(revnav):
 return hex(self._changelog.node(self._revlog.linkrev(rev)))
 
 class _siblings(object):
-def __init__(self, siblings=[], hiderev=None):
-self.siblings = [s for s in siblings if s.node() != nullid]
+def __init__(self, siblings=None, hiderev=None):
+self.siblings = [s for s in siblings or [] if s.node() != nullid]
 if len(self.siblings) == 1 and self.siblings[0].rev() == hiderev:
 self.siblings = []
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 8 V2] filemerge: don't use mutable default argument value

2017-03-12 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1482796473 25200
#  Mon Dec 26 16:54:33 2016 -0700
# Node ID f3927785d168824ac04c4eb44361337775286e01
# Parent  265102f455de6451e493024fb8a9f24d816ce1c2
filemerge: don't use mutable default argument value

diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py
--- a/mercurial/filemerge.py
+++ b/mercurial/filemerge.py
@@ -35,8 +35,8 @@ def _toolstr(ui, tool, part, default="")
 def _toolbool(ui, tool, part, default=False):
 return ui.configbool("merge-tools", tool + "." + part, default)
 
-def _toollist(ui, tool, part, default=[]):
-return ui.configlist("merge-tools", tool + "." + part, default)
+def _toollist(ui, tool, part, default=None):
+return ui.configlist("merge-tools", tool + "." + part, default or [])
 
 internals = {}
 # Merge tools to document.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 8 V2] context: don't use mutable default argument value

2017-03-12 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1489380642 25200
#  Sun Mar 12 21:50:42 2017 -0700
# Node ID 265102f455de6451e493024fb8a9f24d816ce1c2
# Parent  1c48a8278b2f015fca607dfc652823560a5ac580
context: don't use mutable default argument value

Mutable default argument values are a Python gotcha and can
represent subtle, hard-to-find bugs. Lets rid our code base
of them.

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -298,10 +298,10 @@ class basectx(object):
 '''
 return subrepo.subrepo(self, path, allowwdir=True)
 
-def match(self, pats=[], include=None, exclude=None, default='glob',
+def match(self, pats=None, include=None, exclude=None, default='glob',
   listsubrepos=False, badfn=None):
 r = self._repo
-return matchmod.match(r.root, r.getcwd(), pats,
+return matchmod.match(r.root, r.getcwd(), pats or [],
   include, exclude, default,
   auditor=r.nofsauditor, ctx=self,
   listsubrepos=listsubrepos, badfn=badfn)
@@ -1515,16 +1515,16 @@ class workingctx(committablectx):
 self._repo.dirstate.normallookup(dest)
 self._repo.dirstate.copy(source, dest)
 
-def match(self, pats=[], include=None, exclude=None, default='glob',
+def match(self, pats=None, include=None, exclude=None, default='glob',
   listsubrepos=False, badfn=None):
 r = self._repo
 
 # Only a case insensitive filesystem needs magic to translate user 
input
 # to actual case in the filesystem.
 if not util.fscasesensitive(r.root):
-return matchmod.icasefsmatcher(r.root, r.getcwd(), pats, include,
-   exclude, default, r.auditor, self,
-   listsubrepos=listsubrepos,
+return matchmod.icasefsmatcher(r.root, r.getcwd(), pats or [],
+   include, exclude, default, 
r.auditor,
+   self, listsubrepos=listsubrepos,
badfn=badfn)
 return matchmod.match(r.root, r.getcwd(), pats,
   include, exclude, default,
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 8 V2] hgweb: don't use mutable default argument value

2017-03-12 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1482796547 25200
#  Mon Dec 26 16:55:47 2016 -0700
# Node ID 735405d42d45801c7b75448e0263088327cac4af
# Parent  f3927785d168824ac04c4eb44361337775286e01
hgweb: don't use mutable default argument value

diff --git a/mercurial/hgweb/common.py b/mercurial/hgweb/common.py
--- a/mercurial/hgweb/common.py
+++ b/mercurial/hgweb/common.py
@@ -91,12 +91,12 @@ permhooks = [checkauthz]
 
 
 class ErrorResponse(Exception):
-def __init__(self, code, message=None, headers=[]):
+def __init__(self, code, message=None, headers=None):
 if message is None:
 message = _statusmessage(code)
 Exception.__init__(self, message)
 self.code = code
-self.headers = headers
+self.headers = headers or []
 
 class continuereader(object):
 def __init__(self, f, write):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] show: new extension for displaying various repository data

2017-03-12 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1489378362 25200
#  Sun Mar 12 21:12:42 2017 -0700
# Node ID d30057d358076cbe7d632cd573095af97543f932
# Parent  1c3352d7eaf24533ad52d4b8a024211e9189fb0b
show: new extension for displaying various repository data

Currently, Mercurial has a number of commands to show information. And,
there are features coming down the pipe that will introduce more
commands for showing information.

Currently, when introducing a new class of data or a view that we
wish to expose to the user, the strategy is to introduce a new command
or overload an existing command, sometimes both. For example, there is
a desire to formalize the wip/smartlog/underway/mine functionality that
many have devised. There is also a desire to introduce a "topics"
concept. Others would like views of "the current stack." In the
current model, we'd need a new command for wip/smartlog/etc (that
behaves a lot like a pre-defined alias of `hg log`). For topics,
we'd likely overload `hg topic[s]` to both display and manipulate
topics.

Adding new commands for every pre-defined query doesn't scale well
and pollutes `hg help`. Overloading commands to perform read-only and
write operations is arguably an UX anti-pattern: while having all
functionality for a given concept in one command is nice, having a
single command doing multiple discrete operations is not. Furthermore,
a user may be surprised that a command they thought was read-only
actually changes something.

We discussed this at the Mercurial 4.0 Sprint in Paris and decided that
having a single command where we could hang pre-defined views of
various data would be a good idea. Having such a command would:

* Help prevent an explosion of new query-related commands
* Create a clear separation between read and write operations
  (mitigates footguns)
* Avoids overloading the meaning of commands that manipulate data
  (bookmark, tag, branch, etc) (while we can't take away the
  existing behavior for BC reasons, we now won't introduce this
  behavior on new commands)
* Allows users to discover informational views more easily by
  aggregating them in a single location
* Lowers the barrier to creating the new views (since the barrier
  to creating a top-level command is relatively high)

So, this commit introduces the `hg show` command via the "show"
extension. This command accepts a positional argument of the
"view" to show. New views can be registered with a decorator. To
prove it works, we implement the "bookmarks" view, which shows a
table of bookmarks and their associated nodes.

We introduce a new style to hold everything used by `hg show`.

For our initial bookmarks view, the output varies from `hg bookmarks`:

* Padding is performed in the template itself as opposed to Python
* Revision integers are not shown
* shortest() is used to display a 5 character node by default (as
  opposed to static 12 characters)

I chose to implement the "bookmarks" view first because it is simple
and shouldn't invite too much bikeshedding that detracts from the
evaluation of `hg show` itself. But there is an important point
to consider: we now have 2 ways to show a list of bookmarks. I'm not
a fan of introducing multiple ways to do very similar things. So it
might be worth discussing how we wish to tackle this issue for
bookmarks, tags, branches, MQ series, etc.

I also made the choice of explicitly declaring the default show
template not part of the standard BC guarantees. History has shown
that we make mistakes and poor choices with output formatting but
can't fix these mistakes later because random tools are parsing
output and we don't want to break these tools. Optimizing for human
consumption is one of my goals for `hg show`. So, by not covering
the formatting as part of BC, the barrier to future change is much
lower and humans benefit.

At the aforementioned Sprint, we discussed and discarded various
alternatives to `hg show`.

We considered making `hg log ` perform this behavior. The main
reason we can't do this is because a positional argument to `hg log`
can be a file path and if there is a conflict between a path name and
a view name, behavior is ambiguous. We could have introduced
`hg log --view` or similar, but we felt that required too much typing
(we don't want to require a command flag to show a view) and wasn't
very discoverable. Furthermore, `hg log` is optimized for showing
changelog data and there are things that `hg display` could display
that aren't changelog centric.

There were concerns about using "show" as the command name.

Some users already have a "show" alias that is similar to `hg export`.

There were also concerns that Git users adapted to `git show` would
be confused by `hg show`'s different behavior. The main difference
here is `git show` prints an `hg export` like view of the current
commit by default and `hg show` requires an argument. `git show`
can also display any Git object. `git show` does not support

Re: stdio handling is broken

2017-03-12 Thread Gregory Szorc
On Sun, Mar 12, 2017 at 7:59 PM, Bryan O'Sullivan 
wrote:

> For complicated historical reasons, Mercurial doesn't handle errors upon
> writes to stdout or stderr correctly.
>
> You can test this on a Linux box very easily. Correct behaviour involves
> trying to print an error message, followed by an error exit:
>
> $ /bin/echo a > /dev/full
> /bin/echo: write error: No space left on device
>
> Meanwhile, Mercurial goes "what, me worry?":
>
> $ hg status >/dev/full
> $ echo $?
> 0
>
> Eek!
>
> I have a patch series that purports to fix this, but /dev/full is a
> Linux-specific thing, and I am scratching my head over how to test the fix
> portably.
>
> So far, the "best" idea I have is to create a fake file object that raises
> an ENOSPC IOError upon flush, but by the time I can use the extension
> mechanism to cram this into place, the early dispatch code already has the
> stdio handles stuffed away the request object, which extension code can't
> get at.
>
> If you have any better ideas, I'm all ... eyes?
>

You aren't going to like this answer but it works.

You can change dispatch.py:run() to assign the request instance to a local
variable. Then, when your extension loads it can walk the stack, find the
frame for run(), then swap out request.{fin,fout,ferr}. If you promise not
to tell anyone I wrote it, you can find an example for doing this in an
extension at
https://hg.mozilla.org/hgcustom/version-control-tools/file/6d3e12142e2f/hgext/serverlog/__init__.py#l376
.

That being said, I thought ui.{fin,fout,ferr} were just refs to the
setbinary'd streams canonically available in util. Can't you just swap out
ui.{fin,fout,ferr} in a uisetup() for the purposes of testing?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: stdio handling is broken

2017-03-12 Thread Augie Fackler
Add a check to hghave for dev/full existing, then use a #if guard in a
test.

(On phone from biergarten, sorry for top post)

On Mar 12, 2017 19:59, "Bryan O'Sullivan"  wrote:

> For complicated historical reasons, Mercurial doesn't handle errors upon
> writes to stdout or stderr correctly.
>
> You can test this on a Linux box very easily. Correct behaviour involves
> trying to print an error message, followed by an error exit:
>
> $ /bin/echo a > /dev/full
> /bin/echo: write error: No space left on device
>
> Meanwhile, Mercurial goes "what, me worry?":
>
> $ hg status >/dev/full
> $ echo $?
> 0
>
> Eek!
>
> I have a patch series that purports to fix this, but /dev/full is a
> Linux-specific thing, and I am scratching my head over how to test the fix
> portably.
>
> So far, the "best" idea I have is to create a fake file object that raises
> an ENOSPC IOError upon flush, but by the time I can use the extension
> mechanism to cram this into place, the early dispatch code already has the
> stdio handles stuffed away the request object, which extension code can't
> get at.
>
> If you have any better ideas, I'm all ... eyes?
>
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>
>
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


stdio handling is broken

2017-03-12 Thread Bryan O'Sullivan
For complicated historical reasons, Mercurial doesn't handle errors upon
writes to stdout or stderr correctly.

You can test this on a Linux box very easily. Correct behaviour involves
trying to print an error message, followed by an error exit:

$ /bin/echo a > /dev/full
/bin/echo: write error: No space left on device

Meanwhile, Mercurial goes "what, me worry?":

$ hg status >/dev/full
$ echo $?
0

Eek!

I have a patch series that purports to fix this, but /dev/full is a
Linux-specific thing, and I am scratching my head over how to test the fix
portably.

So far, the "best" idea I have is to create a fake file object that raises
an ENOSPC IOError upon flush, but by the time I can use the extension
mechanism to cram this into place, the early dispatch code already has the
stdio handles stuffed away the request object, which extension code can't
get at.

If you have any better ideas, I'm all ... eyes?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] extensions: formalize concept of experimental extensions

2017-03-12 Thread Jun Wu
Excerpts from Gregory Szorc's message of 2017-03-12 19:48:35 -0700:
> 
> > On Mar 12, 2017, at 19:28, Jun Wu  wrote:
> > 
> > If I read it correctly, this means an "experimental" extension will end up
> > with:
> > 
> > | ext=| ext=!beta
> >  
> >  old client | load| do not load
> >  new client | do not load | load
> > 
> > I think that's confusing.
> > 
> > I think we can have an "[extensions:experimental]" section instead, which
> > will only be processed by new mercurial.
> 
> For extensions distributed with Mercurial, old clients won't have the
> extension. So the old client plus ext= scenario results in no load.

I think it's better to make the "experimental" thing usable for 3rd party
extensions too.

Another concern is for hg developers / testers running different versions of
hg - they may share hgrc.

> Of course, you probably didn't have ext= in the first place because it
> would emit an annoying warning on every command. So I doubt ext= for
> experimental extensions will occur much in the wild.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] extensions: formalize concept of experimental extensions

2017-03-12 Thread Gregory Szorc


> On Mar 12, 2017, at 19:28, Jun Wu  wrote:
> 
> If I read it correctly, this means an "experimental" extension will end up
> with:
> 
> | ext=| ext=!beta
>  
>  old client | load| do not load
>  new client | do not load | load
> 
> I think that's confusing.
> 
> I think we can have an "[extensions:experimental]" section instead, which
> will only be processed by new mercurial.

For extensions distributed with Mercurial, old clients won't have the 
extension. So the old client plus ext= scenario results in no load.

Of course, you probably didn't have ext= in the first place because it would 
emit an annoying warning on every command. So I doubt ext= for experimental 
extensions will occur much in the wild.

> 
> Excerpts from Gregory Szorc's message of 2017-03-12 17:41:49 -0700:
>> # HG changeset patch
>> # User Gregory Szorc 
>> # Date 1489364702 25200
>> #  Sun Mar 12 17:25:02 2017 -0700
>> # Node ID 6a85d5031daf1ab3a5cb3c6705a46367d5e0de29
>> # Parent  1c3352d7eaf24533ad52d4b8a024211e9189fb0b
>> extensions: formalize concept of experimental extensions
>> 
>> Per discussions at the Sprint, we would like to be more
>> welcoming to shipping experimental extensions with the official
>> Mercurial distribution so they are more easily available to
>> end-users.
>> 
>> A concern with "experimental" extensions is where to put them and
>> how to differentiate them as "experimental" to end-users.
>> 
>> One idea is to put them in a special location or name them in
>> such a way that "experimental" (or some other label) is in the
>> name end-users use to load them. A problem with this is that if
>> the extension "graduates" to fully-supported status, users have to
>> update their configs to load the extension at the new name (or
>> Mercurial maintains a mapping table, which excludes 3rd party
>> extensions from having this benefit).
>> 
>> This patch formalizes the concept of experimental extensions and
>> does so in a way that is user-friendly and allows experimental
>> extensions to gracefully graduate to non-experimental status without
>> end-user intervention. It does so through 2 mechanisms:
>> 
>> 1. Extensions now set the "experimental" attribute to mark themselves
>>   as experimental
>> 2. The extension loader only loads experimental extensions if the
>>   config option value of the extension is "!beta"
>> 
>> If a user attempts to load an experimental mechanism using the
>> normal "extensions.=" syntax, a warning message is printed
>> saying the extension is "in trial mode" and tells them how to
>> activate it. If the value is "!beta" (e.g. extensions.foo=!beta),
>> the extension is loaded. This requires explicit affirmation from
>> the end-user that an extension is "beta." This should mitigate
>> any surprises from a user using an extension without realizing it
>> is experimental.
>> 
>> Because the old extension loading code interpreted a leading "!"
>> as "do not load," the "!beta" syntax results in old clients not
>> loading experimental extensions. This is a graceful failure.
>> 
>> A drawback of using "!beta" is that an explicit path to the
>> extension cannot be specified at this time. This means the
>> extension's name must correspond to a module in the "hgext" or
>> "hgext3rd" packages. I think this is acceptable.
>> 
>> I purposefully chose to use "beta" for the end-user facing value.
>> From my experience, users are scared of the "experimental" label.
>> In most cases, "experimental" features in Mercurial are more stable
>> than the other end of the spectrum. So I wanted to use a label
>> that is more reflective of reality, isn't scary, and doesn't
>> require strong English knowledge. I consulted a thesaurus for
>> suitable synonyms of "experimental" and couldn't find anything
>> "just right." So, I used "beta." This is a common technical term
>> that most people relate to (thanks, Gmail!) and it accurately
>> reflects the state of most extensions that Mercurial will
>> distribute in "experimental" form. For users who don't know
>> what it means, the translated message printed without "!beta"
>> can provide more context.
>> 
>> diff --git a/mercurial/extensions.py b/mercurial/extensions.py
>> --- a/mercurial/extensions.py
>> +++ b/mercurial/extensions.py
>> @@ -119,9 +119,9 @@ def _reportimporterror(ui, err, failed, 
>>  % (failed, _forbytes(err), next))
>> if ui.debugflag:
>> ui.traceback()
>> 
>> -def load(ui, name, path):
>> +def load(ui, name, path, allowexperimental=False):
>> if name.startswith('hgext.') or name.startswith('hgext/'):
>> shortname = name[6:]
>> else:
>> shortname = name
>> @@ -141,8 +141,15 @@ def load(ui, name, path):
>> ui.warn(_('(third party extension %s requires version %s or newer '
>>   'of Mercurial; disabling)\n') % (shortname, minver))
>> return
>> 
>> +experimental = 

Re: [PATCH] extensions: formalize concept of experimental extensions

2017-03-12 Thread Jun Wu
If I read it correctly, this means an "experimental" extension will end up
with:

 | ext=| ext=!beta
  
  old client | load| do not load
  new client | do not load | load

I think that's confusing.

I think we can have an "[extensions:experimental]" section instead, which
will only be processed by new mercurial.

Excerpts from Gregory Szorc's message of 2017-03-12 17:41:49 -0700:
> # HG changeset patch
> # User Gregory Szorc 
> # Date 1489364702 25200
> #  Sun Mar 12 17:25:02 2017 -0700
> # Node ID 6a85d5031daf1ab3a5cb3c6705a46367d5e0de29
> # Parent  1c3352d7eaf24533ad52d4b8a024211e9189fb0b
> extensions: formalize concept of experimental extensions
> 
> Per discussions at the Sprint, we would like to be more
> welcoming to shipping experimental extensions with the official
> Mercurial distribution so they are more easily available to
> end-users.
> 
> A concern with "experimental" extensions is where to put them and
> how to differentiate them as "experimental" to end-users.
> 
> One idea is to put them in a special location or name them in
> such a way that "experimental" (or some other label) is in the
> name end-users use to load them. A problem with this is that if
> the extension "graduates" to fully-supported status, users have to
> update their configs to load the extension at the new name (or
> Mercurial maintains a mapping table, which excludes 3rd party
> extensions from having this benefit).
> 
> This patch formalizes the concept of experimental extensions and
> does so in a way that is user-friendly and allows experimental
> extensions to gracefully graduate to non-experimental status without
> end-user intervention. It does so through 2 mechanisms:
> 
> 1. Extensions now set the "experimental" attribute to mark themselves
>as experimental
> 2. The extension loader only loads experimental extensions if the
>config option value of the extension is "!beta"
> 
> If a user attempts to load an experimental mechanism using the
> normal "extensions.=" syntax, a warning message is printed
> saying the extension is "in trial mode" and tells them how to
> activate it. If the value is "!beta" (e.g. extensions.foo=!beta),
> the extension is loaded. This requires explicit affirmation from
> the end-user that an extension is "beta." This should mitigate
> any surprises from a user using an extension without realizing it
> is experimental.
> 
> Because the old extension loading code interpreted a leading "!"
> as "do not load," the "!beta" syntax results in old clients not
> loading experimental extensions. This is a graceful failure.
> 
> A drawback of using "!beta" is that an explicit path to the
> extension cannot be specified at this time. This means the
> extension's name must correspond to a module in the "hgext" or
> "hgext3rd" packages. I think this is acceptable.
> 
> I purposefully chose to use "beta" for the end-user facing value.
> From my experience, users are scared of the "experimental" label.
> In most cases, "experimental" features in Mercurial are more stable
> than the other end of the spectrum. So I wanted to use a label
> that is more reflective of reality, isn't scary, and doesn't
> require strong English knowledge. I consulted a thesaurus for
> suitable synonyms of "experimental" and couldn't find anything
> "just right." So, I used "beta." This is a common technical term
> that most people relate to (thanks, Gmail!) and it accurately
> reflects the state of most extensions that Mercurial will
> distribute in "experimental" form. For users who don't know
> what it means, the translated message printed without "!beta"
> can provide more context.
> 
> diff --git a/mercurial/extensions.py b/mercurial/extensions.py
> --- a/mercurial/extensions.py
> +++ b/mercurial/extensions.py
> @@ -119,9 +119,9 @@ def _reportimporterror(ui, err, failed, 
>   % (failed, _forbytes(err), next))
>  if ui.debugflag:
>  ui.traceback()
>  
> -def load(ui, name, path):
> +def load(ui, name, path, allowexperimental=False):
>  if name.startswith('hgext.') or name.startswith('hgext/'):
>  shortname = name[6:]
>  else:
>  shortname = name
> @@ -141,8 +141,15 @@ def load(ui, name, path):
>  ui.warn(_('(third party extension %s requires version %s or newer '
>'of Mercurial; disabling)\n') % (shortname, minver))
>  return
>  
> +experimental = getattr(mod, 'experimental', None)
> +if experimental and not allowexperimental:
> +ui.warn(_('(extension %s is in trial mode and requires explicit '
> +  'opt-in by setting extensions.%s=!beta; disabling)\n') %
> +(name, name))
> +return
> +
>  _extensions[shortname] = mod
>  _order.append(shortname)
>  for fn in _aftercallbacks.get(shortname, []):
>  fn(loaded=True)
> @@ -166,14 +173,18 @@ def _runextsetup(name, ui):

Re: [PATCH 4 of 4] py3: fix slicing of bytes in revset.formatspec()

2017-03-12 Thread Augie Fackler
On Sun, Mar 12, 2017 at 05:41:56PM -0700, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1489364203 25200
> #  Sun Mar 12 17:16:43 2017 -0700
> # Node ID 3594ddbad77badd70e96afaab32b6a9010406cc3
> # Parent  99d5a74ec8d5fb6396ca940708e4b9922d96edf6
> py3: fix slicing of bytes in revset.formatspec()

queued thanks

>
> diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py
> --- a/mercurial/revsetlang.py
> +++ b/mercurial/revsetlang.py
> @@ -644,10 +644,10 @@ def formatspec(expr, *args):
>  pos = 0
>  arg = 0
>  while pos < len(expr):
> -c = expr[pos]
> +c = expr[pos:pos + 1]
>  if c == '%':
>  pos += 1
> -d = expr[pos]
> +d = expr[pos:pos + 1]
>  if d == '%':
>  ret += d
>  elif d in 'dsnbr':
> @@ -656,7 +656,7 @@ def formatspec(expr, *args):
>  elif d == 'l':
>  # a list of some type
>  pos += 1
> -d = expr[pos]
> +d = expr[pos:pos + 1]
>  ret += listexp(list(args[arg]), d)
>  arg += 1
>  else:
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/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] rebase: add flag to require destination

2017-03-12 Thread Gregory Szorc
On Sun, Mar 12, 2017 at 12:06 PM, Augie Fackler  wrote:

> On Sat, Mar 11, 2017 at 06:03:13PM -0800, Ryan McElroy wrote:
> > # HG changeset patch
> > # User Ryan McElroy 
> > # Date 1489283611 28800
> > #  Sat Mar 11 17:53:31 2017 -0800
> > # Node ID 7c7f442027b6a0cd51b1f06b01913f53f4f9e9cd
> > # Parent  a788a4660443dfc33c5c1c58eec78e20150404d9
> > rebase: add flag to require destination
>
> These both look mechanically fine to me, but I'm a little skeptical
> about the configuration sections in play (update and rebase
> respectively), so I'll leave them for other parties to examine and
> bikeshed.
>

The ship has likely already sailed, but IMO it would be nice if there a
unified [command] (or similar) section that controls behavior of commands,
specifically with regards to command arguments. But, a section per command
sharing the name of the command is acceptable. I just don't think options
for command argument behavior appearing in random sections is very user
friendly.


>
> >
> > diff --git a/hgext/rebase.py b/hgext/rebase.py
> > --- a/hgext/rebase.py
> > +++ b/hgext/rebase.py
> > @@ -650,6 +650,16 @@ def rebase(ui, repo, **opts):
> >
> >hg rebase -r "branch(featureX)" -d 1.3 --keepbranches
> >
> > +Configuration Options:
> > +
> > +You can make rebase require a destination if you set the following
> config
> > +option:
> > +
> > +  [rebase]
> > +  requiredest = False
> > +
> > +Return Values:
> > +
> >  Returns 0 on success, 1 if nothing to rebase or there are
> >  unresolved conflicts.
> >
> > @@ -663,6 +673,12 @@ def rebase(ui, repo, **opts):
> >
> >  # Validate input and define rebasing points
> >  destf = opts.get('dest', None)
> > +
> > +if ui.config('rebase', 'requiredest', False):
> > +if not destf:
> > +raise error.Abort(_('you must specify a destination'),
> > +  hint=_('use: hg rebase -d REV'))
> > +
> >  srcf = opts.get('source', None)
> >  basef = opts.get('base', None)
> >  revf = opts.get('rev', [])
> > diff --git a/tests/test-rebase-base.t b/tests/test-rebase-base.t
> > --- a/tests/test-rebase-base.t
> > +++ b/tests/test-rebase-base.t
> > @@ -391,3 +391,25 @@ Multiple roots. Two children share two p
> > /
> >o  0: A
> >
> > +Require a destination
> > +  $ cat >> $HGRCPATH < > +  > [rebase]
> > +  > requiredest = True
> > +  > EOF
> > +  $ hg init repo
> > +  $ cd repo
> > +  $ echo a >> a
> > +  $ hg commit -qAm aa
> > +  $ echo b >> b
> > +  $ hg commit -qAm bb
> > +  $ hg up ".^"
> > +  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
> > +  $ echo c >> c
> > +  $ hg commit -qAm cc
> > +  $ hg rebase
> > +  abort: you must specify a destination
> > +  (use: hg rebase -d REV)
> > +  [255]
> > +  $ hg rebase -d 1
> > +  rebasing 2:5db65b93a12b "cc" (tip)
> > +  saved backup bundle to $TESTTMP/repo/.hg/strip-
> backup/5db65b93a12b-4fb789ec-backup.hg (glob)
> > ___
> > Mercurial-devel mailing list
> > Mercurial-devel@mercurial-scm.org
> > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4] pycompat: add helper to iterate each char in bytes

2017-03-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1489363485 25200
#  Sun Mar 12 17:04:45 2017 -0700
# Node ID 75c128696f8dbc4aaa56f0e2200ebd7f560a36d5
# Parent  7359157b9e46908645cc9cef62a5cf46224dba71
pycompat: add helper to iterate each char in bytes

diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py
--- a/mercurial/pycompat.py
+++ b/mercurial/pycompat.py
@@ -76,6 +76,10 @@ if ispy3:
 def bytechr(i):
 return bytes([i])
 
+def iterbytestr(s):
+"""Iterate bytes as if it were a str object of Python 2"""
+return iter(s[i:i + 1] for i in range(len(s)))
+
 def sysstr(s):
 """Return a keyword str to be passed to Python functions such as
 getattr() and str.encode()
@@ -142,6 +146,7 @@ else:
 import cStringIO
 
 bytechr = chr
+iterbytestr = iter
 
 def sysstr(s):
 return s
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 4] py3: make set of revset operators and quotes in bytes

2017-03-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1489364034 25200
#  Sun Mar 12 17:13:54 2017 -0700
# Node ID 99d5a74ec8d5fb6396ca940708e4b9922d96edf6
# Parent  06527fc4ae45e3950b098a2509a6a55b4a275a2f
py3: make set of revset operators and quotes in bytes

diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py
--- a/mercurial/revsetlang.py
+++ b/mercurial/revsetlang.py
@@ -45,6 +45,9 @@ elements = {
 
 keywords = set(['and', 'or', 'not'])
 
+_quoteletters = set(['"', "'"])
+_simpleopletters = set(pycompat.iterbytestr("():=,-|&+!~^%"))
+
 # default set of valid characters for the initial letter of symbols
 _syminitletters = set(pycompat.iterbytestr(
 string.ascii_letters.encode('ascii') +
@@ -109,9 +112,9 @@ def tokenize(program, lookup=None, symin
 elif c == '#' and program[pos:pos + 2] == '##': # look ahead carefully
 yield ('##', None, pos)
 pos += 1 # skip ahead
-elif c in "():=,-|&+!~^%": # handle simple operators
+elif c in _simpleopletters: # handle simple operators
 yield (c, None, pos)
-elif (c in '"\'' or c == 'r' and
+elif (c in _quoteletters or c == 'r' and
   program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
 if c == 'r':
 pos += 1
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 4] py3: fix slicing of bytes in revset.formatspec()

2017-03-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1489364203 25200
#  Sun Mar 12 17:16:43 2017 -0700
# Node ID 3594ddbad77badd70e96afaab32b6a9010406cc3
# Parent  99d5a74ec8d5fb6396ca940708e4b9922d96edf6
py3: fix slicing of bytes in revset.formatspec()

diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py
--- a/mercurial/revsetlang.py
+++ b/mercurial/revsetlang.py
@@ -644,10 +644,10 @@ def formatspec(expr, *args):
 pos = 0
 arg = 0
 while pos < len(expr):
-c = expr[pos]
+c = expr[pos:pos + 1]
 if c == '%':
 pos += 1
-d = expr[pos]
+d = expr[pos:pos + 1]
 if d == '%':
 ret += d
 elif d in 'dsnbr':
@@ -656,7 +656,7 @@ def formatspec(expr, *args):
 elif d == 'l':
 # a list of some type
 pos += 1
-d = expr[pos]
+d = expr[pos:pos + 1]
 ret += listexp(list(args[arg]), d)
 arg += 1
 else:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 4] py3: convert set of revset initial symbols back to bytes

2017-03-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1489363814 25200
#  Sun Mar 12 17:10:14 2017 -0700
# Node ID 06527fc4ae45e3950b098a2509a6a55b4a275a2f
# Parent  75c128696f8dbc4aaa56f0e2200ebd7f560a36d5
py3: convert set of revset initial symbols back to bytes

Otherwise tokenize() would fail due to comparison between unicode and bytes.

diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py
--- a/mercurial/revsetlang.py
+++ b/mercurial/revsetlang.py
@@ -46,12 +46,13 @@ elements = {
 keywords = set(['and', 'or', 'not'])
 
 # default set of valid characters for the initial letter of symbols
-_syminitletters = set(
-string.ascii_letters +
-string.digits + pycompat.sysstr('._@')) | set(map(chr, xrange(128, 256)))
+_syminitletters = set(pycompat.iterbytestr(
+string.ascii_letters.encode('ascii') +
+string.digits.encode('ascii') +
+'._@')) | set(map(pycompat.bytechr, xrange(128, 256)))
 
 # default set of valid characters for non-initial letters of symbols
-_symletters = _syminitletters | set(pycompat.sysstr('-/'))
+_symletters = _syminitletters | set(pycompat.iterbytestr('-/'))
 
 def tokenize(program, lookup=None, syminitletters=None, symletters=None):
 '''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] extensions: formalize concept of experimental extensions

2017-03-12 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1489364702 25200
#  Sun Mar 12 17:25:02 2017 -0700
# Node ID 6a85d5031daf1ab3a5cb3c6705a46367d5e0de29
# Parent  1c3352d7eaf24533ad52d4b8a024211e9189fb0b
extensions: formalize concept of experimental extensions

Per discussions at the Sprint, we would like to be more
welcoming to shipping experimental extensions with the official
Mercurial distribution so they are more easily available to
end-users.

A concern with "experimental" extensions is where to put them and
how to differentiate them as "experimental" to end-users.

One idea is to put them in a special location or name them in
such a way that "experimental" (or some other label) is in the
name end-users use to load them. A problem with this is that if
the extension "graduates" to fully-supported status, users have to
update their configs to load the extension at the new name (or
Mercurial maintains a mapping table, which excludes 3rd party
extensions from having this benefit).

This patch formalizes the concept of experimental extensions and
does so in a way that is user-friendly and allows experimental
extensions to gracefully graduate to non-experimental status without
end-user intervention. It does so through 2 mechanisms:

1. Extensions now set the "experimental" attribute to mark themselves
   as experimental
2. The extension loader only loads experimental extensions if the
   config option value of the extension is "!beta"

If a user attempts to load an experimental mechanism using the
normal "extensions.=" syntax, a warning message is printed
saying the extension is "in trial mode" and tells them how to
activate it. If the value is "!beta" (e.g. extensions.foo=!beta),
the extension is loaded. This requires explicit affirmation from
the end-user that an extension is "beta." This should mitigate
any surprises from a user using an extension without realizing it
is experimental.

Because the old extension loading code interpreted a leading "!"
as "do not load," the "!beta" syntax results in old clients not
loading experimental extensions. This is a graceful failure.

A drawback of using "!beta" is that an explicit path to the
extension cannot be specified at this time. This means the
extension's name must correspond to a module in the "hgext" or
"hgext3rd" packages. I think this is acceptable.

I purposefully chose to use "beta" for the end-user facing value.
From my experience, users are scared of the "experimental" label.
In most cases, "experimental" features in Mercurial are more stable
than the other end of the spectrum. So I wanted to use a label
that is more reflective of reality, isn't scary, and doesn't
require strong English knowledge. I consulted a thesaurus for
suitable synonyms of "experimental" and couldn't find anything
"just right." So, I used "beta." This is a common technical term
that most people relate to (thanks, Gmail!) and it accurately
reflects the state of most extensions that Mercurial will
distribute in "experimental" form. For users who don't know
what it means, the translated message printed without "!beta"
can provide more context.

diff --git a/mercurial/extensions.py b/mercurial/extensions.py
--- a/mercurial/extensions.py
+++ b/mercurial/extensions.py
@@ -119,9 +119,9 @@ def _reportimporterror(ui, err, failed, 
  % (failed, _forbytes(err), next))
 if ui.debugflag:
 ui.traceback()
 
-def load(ui, name, path):
+def load(ui, name, path, allowexperimental=False):
 if name.startswith('hgext.') or name.startswith('hgext/'):
 shortname = name[6:]
 else:
 shortname = name
@@ -141,8 +141,15 @@ def load(ui, name, path):
 ui.warn(_('(third party extension %s requires version %s or newer '
   'of Mercurial; disabling)\n') % (shortname, minver))
 return
 
+experimental = getattr(mod, 'experimental', None)
+if experimental and not allowexperimental:
+ui.warn(_('(extension %s is in trial mode and requires explicit '
+  'opt-in by setting extensions.%s=!beta; disabling)\n') %
+(name, name))
+return
+
 _extensions[shortname] = mod
 _order.append(shortname)
 for fn in _aftercallbacks.get(shortname, []):
 fn(loaded=True)
@@ -166,14 +173,18 @@ def _runextsetup(name, ui):
 def loadall(ui):
 result = ui.configitems("extensions")
 newindex = len(_order)
 for (name, path) in result:
+allowexperimental = False
 if path:
-if path[0:1] == '!':
+if path.startswith('!beta'):
+allowexperimental = True
+path = ''
+elif path[0:1] == '!':
 _disabledextensions[name] = path[1:]
 continue
 try:
-load(ui, name, path)
+load(ui, name, path, allowexperimental=allowexperimental)
 except KeyboardInterrupt:
 raise
 except Exception as inst:
  

Re: [PATCH py26-fix] branchmap: fix python 2.6 by using util.buffer() instead of passing bytearray

2017-03-12 Thread Yuya Nishihara
On Sun, 12 Mar 2017 20:15:13 -0400, Augie Fackler wrote:
> # HG changeset patch
> # User Augie Fackler 
> # Date 1489362471 14400
> #  Sun Mar 12 19:47:51 2017 -0400
> # Node ID df3fd1d493739948ba39c85072a09c5fee06480b
> # Parent  52ee1b5ac277bd5569a8d3e3ae3e11dff0543323
> branchmap: fix python 2.6 by using util.buffer() instead of passing bytearray

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


Re: [PATCH] exewrapper: add an ability to always load python from hg-python subdir

2017-03-12 Thread Mads Kiilerich

On 03/12/2017 04:02 PM, Kostia Balytskyi wrote:

# HG changeset patch
# User Kostia Balytskyi 
# Date 1489359573 25200
#  Sun Mar 12 15:59:33 2017 -0700
# Node ID bdd61a3470df08b09bd18bbb40e33a8f7cabe188
# Parent  7548522742b5f4f9f5c0881ae4a2783ecda2f969
exewrapper: add an ability to always load python from hg-python subdir

Currently hg.exe will only try to load python27.dll from hg-python
subdir if PYTHONHOME environment variable is not set and if this
approach fails, proceed to load it from whereever possible. I want
to be able to compile a version of hg.exe which will only use
hg-python and not other options, regardless of its environment. This
patch makes it so running 'python setup.py build_hgexe --usehgpython'
builds such version.


It would be nice if we didn't need this compile flag.

I guess the opposite search order would be perfectly fine: *if* there is 
a hg-python sub folder, then use it. If not, use PYTHONHOME ... or 
search in $PATH.


Do you think that would work?


It also breaks test-check-commit.t becuase it introduces a function
named 'initialize_options', but that is a function from parent class,
so there's not much we can do about it.


Breaks ... how?

And if it breaks it, then it must be fixed or "fixed". That doesn't seem 
to be a part of this.



diff --git a/mercurial/exewrapper.c b/mercurial/exewrapper.c
--- a/mercurial/exewrapper.c
+++ b/mercurial/exewrapper.c
@@ -29,6 +29,14 @@ static char pyhome[MAX_PATH + 10];
  static char envpyhome[MAX_PATH + 10];
  static char pydllfile[MAX_PATH + 10];
  
+/* Compiling with /DUSEHGPYTHON makes Mercurial load Python from hg-python

+subdir regardless of environment in which hg.exe is ran. */
+#ifdef USEHGPYTHON
+static int usehgpython = 1;
+#else
+static int usehgpython = 0;
+#endif
+
  int main(int argc, char *argv[])
  {
char *p;
@@ -71,15 +79,13 @@ int main(int argc, char *argv[])
We first check, that environment variable PYTHONHOME is *not* set.
This just mimicks the behavior of the regular python.exe, which uses
PYTHONHOME to find its installation directory (if it has been set).
-   Note: Users of HackableMercurial are expected to *not* set PYTHONHOME!
+   Note: Users of HackableMercurial are expected to *not* set PYTHONHOME
+   or compile exewrapper.c with /DUSEHGPYTHON.
*/
-   if (GetEnvironmentVariable("PYTHONHOME", envpyhome,
-  sizeof(envpyhome)) == 0)
+   if (usehgpython || (GetEnvironmentVariable("PYTHONHOME", envpyhome,
+  sizeof(envpyhome)) == 0))
{
-   /*
-   Environment var PYTHONHOME is *not* set. Let's see if we are
-   running inside a HackableMercurial.
-   */
+   /* We should try to load Python from hg-python subdir */
  
  		p = strrchr(pyhome, '\\');

if (p == NULL) {
@@ -112,6 +118,14 @@ int main(int argc, char *argv[])
}
Py_SetPythonHome(pyhome);
}
+   else
+   {
+   if (pydll == NULL && usehgpython)
+   {
+   err = "can't find hg-python subdir in Mercurial 
dir";
+   goto bail;
+   }
+   }
}
  
  	if (pydll == NULL) {

diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -405,6 +405,17 @@ class buildhgextindex(Command):
  class buildhgexe(build_ext):
  description = 'compile hg.exe from mercurial/exewrapper.c'
  
+user_options = build_ext.user_options + [

+('usehgpython', None, 'always load python dll from hg-python subdir'),
+]
+
+boolean_options = build_ext.boolean_options + ['usehgpython']
+
+def initialize_options(self):
+self.usehgpython = False
+return build_ext.initialize_options(self)
+
+
  def build_extensions(self):
  if os.name != 'nt':
  return
@@ -442,8 +453,10 @@ class buildhgexe(build_ext):
  with open('mercurial/hgpythonlib.h', 'wb') as f:
  f.write('/* this file is autogenerated by setup.py */\n')
  f.write('#define HGPYTHONLIB "%s"\n' % pythonlib)
+extra_preargs = [] if not self.usehgpython else ["/DUSEHGPYTHON"]
  objects = self.compiler.compile(['mercurial/exewrapper.c'],
- output_dir=self.build_temp)
+ output_dir=self.build_temp,
+ extra_preargs=extra_preargs)
  dir = os.path.dirname(self.get_ext_fullpath('dummy'))
  target = os.path.join(dir, 'hg')
  self.compiler.link_executable(objects, target,
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org

[PATCH py26-fix] branchmap: fix python 2.6 by using util.buffer() instead of passing bytearray

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489362471 14400
#  Sun Mar 12 19:47:51 2017 -0400
# Node ID df3fd1d493739948ba39c85072a09c5fee06480b
# Parent  52ee1b5ac277bd5569a8d3e3ae3e11dff0543323
branchmap: fix python 2.6 by using util.buffer() instead of passing bytearray

diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -408,7 +408,8 @@ class revbranchcache(object):
 
 # fast path: extract data from cache, use it if node is matching
 reponode = changelog.node(rev)[:_rbcnodelen]
-cachenode, branchidx = unpack_from(_rbcrecfmt, self._rbcrevs, 
rbcrevidx)
+cachenode, branchidx = unpack_from(
+_rbcrecfmt, util.buffer(self._rbcrevs), rbcrevidx)
 close = bool(branchidx & _rbccloseflag)
 if close:
 branchidx &= _rbcbranchidxmask
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 2] rebase: allow rebasing children of wd to wd if a new branch has been set

2017-03-12 Thread Augie Fackler
On Sun, Mar 12, 2017 at 04:44:06PM -0700, Mads Kiilerich wrote:
> # HG changeset patch
> # User Mads Kiilerich 
> # Date 1489362241 25200
> #  Sun Mar 12 16:44:01 2017 -0700
> # Node ID e3ac848788e45a0530abfa8705740824db6f3444
> # Parent  42083ac9c3ed1b3be205e0f3a621787071587ae5
> rebase: allow rebasing children of wd to wd if a new branch has been set

Queued, but added a (bc) on this one. Thanks!

>
> The named branch of the leaf changeset can be changed by updating to it,
> setting the branch, and amending.
>
> But previously, there was no good way to *just* change the branch of several
> linear changes. If rebasing changes with another parent to '.', it would pick
> up a pending branch change up. But when rebasing changes that have the same
> parent, it would fail with 'nothing to rebase', even when the branch name was
> set differently.
>
> To fix this, allow rebasing to same parent when a branch has been set.
>
> diff --git a/hgext/rebase.py b/hgext/rebase.py
> --- a/hgext/rebase.py
> +++ b/hgext/rebase.py
> @@ -1224,7 +1224,12 @@ def buildstate(repo, dest, rebaseset, co
>  if commonbase == root:
>  raise error.Abort(_('source is ancestor of destination'))
>  if commonbase == dest:
> -samebranch = root.branch() == dest.branch()
> +wctx = repo[None]
> +if dest == wctx.p1():
> +# when rebasing to '.', it will use the current wd branch 
> name
> +samebranch = root.branch() == wctx.branch()
> +else:
> +samebranch = root.branch() == dest.branch()
>  if not collapse and samebranch and root in dest.children():
>  repo.ui.debug('source is a child of destination\n')
>  return None
> diff --git a/tests/test-rebase-named-branches.t 
> b/tests/test-rebase-named-branches.t
> --- a/tests/test-rebase-named-branches.t
> +++ b/tests/test-rebase-named-branches.t
> @@ -387,4 +387,23 @@ rebase 'c1' to the branch head 'c2' that
>o  0: '0'
>
>
> +  $ hg up -cr 1
> +  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  $ hg branch x
> +  marked working directory as branch x
> +  $ hg rebase -r 3:: -d .
> +  rebasing 3:76abc1c6f8c7 "b1"
> +  rebasing 4:8427af5d86f2 "c2 closed" (tip)
> +  note: rebase of 4:8427af5d86f2 created no changes to commit
> +  saved backup bundle to 
> $TESTTMP/case2/.hg/strip-backup/76abc1c6f8c7-cd698d13-backup.hg (glob)
> +  $ hg tglog
> +  o  3: 'b1' x
> +  |
> +  | o  2: 'c1' c
> +  | |
> +  @ |  1: 'b2' b
> +  |/
> +  o  0: '0'
> +
> +
>$ cd ..
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] lock: do not encode result of gethostname on Python 2

2017-03-12 Thread Augie Fackler
On Sun, Mar 12, 2017 at 04:35:42PM -0700, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1489361194 25200
> #  Sun Mar 12 16:26:34 2017 -0700
> # Node ID 197708ab23f80bec7fd9cf70beb96eb759f2e59d
> # Parent  52ee1b5ac277bd5569a8d3e3ae3e11dff0543323
> lock: do not encode result of gethostname on Python 2

Derp, queued, thanks.

>
> If a hostname contained non-ascii character, str.encode() would first try
> to decode it to a unicode and raise UnicodeDecodeError.
>
> diff --git a/mercurial/lock.py b/mercurial/lock.py
> --- a/mercurial/lock.py
> +++ b/mercurial/lock.py
> @@ -28,8 +28,9 @@ def _getlockprefix():
>  confidence. Typically it's just hostname. On modern linux, we include an
>  extra Linux-specific pid namespace identifier.
>  """
> -result = socket.gethostname().encode(
> -pycompat.sysstr(encoding.encoding), 'replace')
> +result = socket.gethostname()
> +if pycompat.ispy3:
> +result = result.encode(pycompat.sysstr(encoding.encoding), 'replace')
>  if pycompat.sysplatform.startswith('linux'):
>  try:
>  result += '/%x' % os.stat('/proc/self/ns/pid').st_ino
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2] rebase: allow rebasing children of wd to wd if a new branch has been set

2017-03-12 Thread Mads Kiilerich
# HG changeset patch
# User Mads Kiilerich 
# Date 1489362241 25200
#  Sun Mar 12 16:44:01 2017 -0700
# Node ID e3ac848788e45a0530abfa8705740824db6f3444
# Parent  42083ac9c3ed1b3be205e0f3a621787071587ae5
rebase: allow rebasing children of wd to wd if a new branch has been set

The named branch of the leaf changeset can be changed by updating to it,
setting the branch, and amending.

But previously, there was no good way to *just* change the branch of several
linear changes. If rebasing changes with another parent to '.', it would pick
up a pending branch change up. But when rebasing changes that have the same
parent, it would fail with 'nothing to rebase', even when the branch name was
set differently.

To fix this, allow rebasing to same parent when a branch has been set.

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -1224,7 +1224,12 @@ def buildstate(repo, dest, rebaseset, co
 if commonbase == root:
 raise error.Abort(_('source is ancestor of destination'))
 if commonbase == dest:
-samebranch = root.branch() == dest.branch()
+wctx = repo[None]
+if dest == wctx.p1():
+# when rebasing to '.', it will use the current wd branch name
+samebranch = root.branch() == wctx.branch()
+else:
+samebranch = root.branch() == dest.branch()
 if not collapse and samebranch and root in dest.children():
 repo.ui.debug('source is a child of destination\n')
 return None
diff --git a/tests/test-rebase-named-branches.t 
b/tests/test-rebase-named-branches.t
--- a/tests/test-rebase-named-branches.t
+++ b/tests/test-rebase-named-branches.t
@@ -387,4 +387,23 @@ rebase 'c1' to the branch head 'c2' that
   o  0: '0'
   
 
+  $ hg up -cr 1
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg branch x
+  marked working directory as branch x
+  $ hg rebase -r 3:: -d .
+  rebasing 3:76abc1c6f8c7 "b1"
+  rebasing 4:8427af5d86f2 "c2 closed" (tip)
+  note: rebase of 4:8427af5d86f2 created no changes to commit
+  saved backup bundle to 
$TESTTMP/case2/.hg/strip-backup/76abc1c6f8c7-cd698d13-backup.hg (glob)
+  $ hg tglog
+  o  3: 'b1' x
+  |
+  | o  2: 'c1' c
+  | |
+  @ |  1: 'b2' b
+  |/
+  o  0: '0'
+  
+
   $ cd ..
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] lock: do not encode result of gethostname on Python 2

2017-03-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1489361194 25200
#  Sun Mar 12 16:26:34 2017 -0700
# Node ID 197708ab23f80bec7fd9cf70beb96eb759f2e59d
# Parent  52ee1b5ac277bd5569a8d3e3ae3e11dff0543323
lock: do not encode result of gethostname on Python 2

If a hostname contained non-ascii character, str.encode() would first try
to decode it to a unicode and raise UnicodeDecodeError.

diff --git a/mercurial/lock.py b/mercurial/lock.py
--- a/mercurial/lock.py
+++ b/mercurial/lock.py
@@ -28,8 +28,9 @@ def _getlockprefix():
 confidence. Typically it's just hostname. On modern linux, we include an
 extra Linux-specific pid namespace identifier.
 """
-result = socket.gethostname().encode(
-pycompat.sysstr(encoding.encoding), 'replace')
+result = socket.gethostname()
+if pycompat.ispy3:
+result = result.encode(pycompat.sysstr(encoding.encoding), 'replace')
 if pycompat.sysplatform.startswith('linux'):
 try:
 result += '/%x' % os.stat('/proc/self/ns/pid').st_ino
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 4 py3 v2] encoding: make encoding.encoding be a native str and add encodingb

2017-03-12 Thread Yuya Nishihara
On Sun, 12 Mar 2017 15:42:06 -0700, Augie Fackler wrote:
> > On Mar 12, 2017, at 15:10, Augie Fackler  wrote:
> >> On Mar 12, 2017, at 15:08, Yuya Nishihara  wrote:
> >> On Sun, 12 Mar 2017 17:51:15 -0400, Augie Fackler wrote:
> >>> # HG changeset patch
> >>> # User Augie Fackler 
> >>> # Date 1489303712 14400
> >>> #  Sun Mar 12 03:28:32 2017 -0400
> >>> # Node ID 4455c6cdbf1e9cd524b43c69ecefef819e0b4e30
> >>> # Parent  7dd2f51f38ac224cec522d093ff6f805beb0dd3e
> >>> encoding: make encoding.encoding be a native str and add encodingb
> >>> 
> >>> It turns out we need the encoding name both ways. Ugh.
> >>> 
> >>> diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
> >>> --- a/mercurial/debugcommands.py
> >>> +++ b/mercurial/debugcommands.py
> >>> @@ -965,7 +965,7 @@ def debuginstall(ui, **opts):
> >>>fm.startitem()
> >>> 
> >>># encoding
> >>> -fm.write('encoding', _("checking encoding (%s)...\n"), 
> >>> encoding.encoding)
> >>> +fm.write('encoding', _("checking encoding (%s)...\n"), 
> >>> encoding.encodingb())
> >> 
> >> We have much more uses of encoding.encoding expecting bytes. Better to make
> >> encodingu() a function?
> >> 
> >> % grep encoding.encoding **/*.py | grep -v sysstr | wc -l
> >> 41
> > 
> > Sure, I'll roll a v3.
> 
> I decided to drop the encoding{b,u} idea for now, but maybe we should do it 
> since a lot of places use sysstr()? Anyway, v3 coming shortly.

Yeah, we'll need a handful of encoding helpers so people can stop thinking
about unicodes.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] exewrapper: add an ability to always load python from hg-python subdir

2017-03-12 Thread Kostia Balytskyi
# HG changeset patch
# User Kostia Balytskyi 
# Date 1489359573 25200
#  Sun Mar 12 15:59:33 2017 -0700
# Node ID bdd61a3470df08b09bd18bbb40e33a8f7cabe188
# Parent  7548522742b5f4f9f5c0881ae4a2783ecda2f969
exewrapper: add an ability to always load python from hg-python subdir

Currently hg.exe will only try to load python27.dll from hg-python
subdir if PYTHONHOME environment variable is not set and if this
approach fails, proceed to load it from whereever possible. I want
to be able to compile a version of hg.exe which will only use
hg-python and not other options, regardless of its environment. This
patch makes it so running 'python setup.py build_hgexe --usehgpython'
builds such version.

It also breaks test-check-commit.t becuase it introduces a function
named 'initialize_options', but that is a function from parent class,
so there's not much we can do about it.

diff --git a/mercurial/exewrapper.c b/mercurial/exewrapper.c
--- a/mercurial/exewrapper.c
+++ b/mercurial/exewrapper.c
@@ -29,6 +29,14 @@ static char pyhome[MAX_PATH + 10];
 static char envpyhome[MAX_PATH + 10];
 static char pydllfile[MAX_PATH + 10];
 
+/* Compiling with /DUSEHGPYTHON makes Mercurial load Python from hg-python
+subdir regardless of environment in which hg.exe is ran. */
+#ifdef USEHGPYTHON
+static int usehgpython = 1;
+#else
+static int usehgpython = 0;
+#endif
+
 int main(int argc, char *argv[])
 {
char *p;
@@ -71,15 +79,13 @@ int main(int argc, char *argv[])
We first check, that environment variable PYTHONHOME is *not* set.
This just mimicks the behavior of the regular python.exe, which uses
PYTHONHOME to find its installation directory (if it has been set).
-   Note: Users of HackableMercurial are expected to *not* set PYTHONHOME!
+   Note: Users of HackableMercurial are expected to *not* set PYTHONHOME
+   or compile exewrapper.c with /DUSEHGPYTHON.
*/
-   if (GetEnvironmentVariable("PYTHONHOME", envpyhome,
-  sizeof(envpyhome)) == 0)
+   if (usehgpython || (GetEnvironmentVariable("PYTHONHOME", envpyhome,
+  sizeof(envpyhome)) == 0))
{
-   /*
-   Environment var PYTHONHOME is *not* set. Let's see if we are
-   running inside a HackableMercurial.
-   */
+   /* We should try to load Python from hg-python subdir */
 
p = strrchr(pyhome, '\\');
if (p == NULL) {
@@ -112,6 +118,14 @@ int main(int argc, char *argv[])
}
Py_SetPythonHome(pyhome);
}
+   else
+   {
+   if (pydll == NULL && usehgpython)
+   {
+   err = "can't find hg-python subdir in Mercurial 
dir";
+   goto bail;
+   }
+   }
}
 
if (pydll == NULL) {
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -405,6 +405,17 @@ class buildhgextindex(Command):
 class buildhgexe(build_ext):
 description = 'compile hg.exe from mercurial/exewrapper.c'
 
+user_options = build_ext.user_options + [
+('usehgpython', None, 'always load python dll from hg-python subdir'),
+]
+
+boolean_options = build_ext.boolean_options + ['usehgpython']
+
+def initialize_options(self):
+self.usehgpython = False
+return build_ext.initialize_options(self)
+
+
 def build_extensions(self):
 if os.name != 'nt':
 return
@@ -442,8 +453,10 @@ class buildhgexe(build_ext):
 with open('mercurial/hgpythonlib.h', 'wb') as f:
 f.write('/* this file is autogenerated by setup.py */\n')
 f.write('#define HGPYTHONLIB "%s"\n' % pythonlib)
+extra_preargs = [] if not self.usehgpython else ["/DUSEHGPYTHON"]
 objects = self.compiler.compile(['mercurial/exewrapper.c'],
- output_dir=self.build_temp)
+ output_dir=self.build_temp,
+ extra_preargs=extra_preargs)
 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
 target = os.path.join(dir, 'hg')
 self.compiler.link_executable(objects, target,
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 3 py3 v3] lock: encode result of gethostname into a bytestring

2017-03-12 Thread Yuya Nishihara
On Sun, 12 Mar 2017 18:42:24 -0400, Augie Fackler wrote:
> # HG changeset patch
> # User Augie Fackler 
> # Date 1489303730 14400
> #  Sun Mar 12 03:28:50 2017 -0400
> # Node ID a8f3bbc6259aebdeeef9f58309800f4070081214
> # Parent  7548522742b5f4f9f5c0881ae4a2783ecda2f969
> lock: encode result of gethostname into a bytestring

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


Re: config: avoid using a mutable default

2017-03-12 Thread Augie Fackler
On Sun, Mar 12, 2017 at 12:56:20PM -0700, Martijn Pieters wrote:
> # HG changeset patch
> # User Martijn Pieters 
> # Date 1489348572 25200
> #  Sun Mar 12 12:56:12 2017 -0700
> # Node ID 22c38e571b5ccf3bb6d9f075526170954843f37a
> # Parent  719e64bf9ec2d7b8e86b6550a5d193b3c67944d1
> config: avoid using a mutable default

Queued, thanks.

>
> Nothing *currently* mutates this list, but the moment something does it'll be
> shared between all config instances. Avoid this eventuality.
>
> diff --git a/mercurial/config.py b/mercurial/config.py
> --- a/mercurial/config.py
> +++ b/mercurial/config.py
> @@ -18,11 +18,11 @@
>  )
>
>  class config(object):
> -def __init__(self, data=None, includepaths=[]):
> +def __init__(self, data=None, includepaths=None):
>  self._data = {}
>  self._source = {}
>  self._unset = []
> -self._includepaths = includepaths
> +self._includepaths = includepaths or []
>  if data:
>  for k in data._data:
>  self._data[k] = data[k].copy()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 3 of 3 V3] chgcache: implement repocache

2017-03-12 Thread Yuya Nishihara
On Sat, 11 Mar 2017 17:21:41 -0800, Jun Wu wrote:
> Excerpts from Yuya Nishihara's message of 2017-03-11 15:50:43 -0800:
> > On Sat, 11 Mar 2017 14:54:54 -0800, Jun Wu wrote:
> > > Unlike the current "start new server for new extensions" behavior. The new
> > > design allows us to serve the request using the old server sub-optimally,
> > > and start a more efficient server in the background to replace the current
> > > one soon.
> > > 
> > > A fb-only example is that remotefilelog uses repo-independent packfiles.
> > > 
> > > I think the cache state is conceptually attached to the current process,
> > > instead of repo. Thus a global may actually be a better fit.
> > 
> > Yeah, it will live longer than a repo, and will reside in dispatcher level,
> > which I don't think mean the data should be globally accessible by anyone.
> 
> It sounds like it could be done by split the "global" in chgcache states
> into different modules: chgserver, dispatch, ...
> 
> In that case, adding a new parameter to "smartcache" to decouple it from
> chgcache._cache seems to address the issue.
> 
> It sounds possible, but I need more time to make sure it works.

Maybe something like that. Since most data to be cached would be repo-dependent,
we don't need a global namespace for cache content. We can just attach repocache
per repo and its content can be managed by the server.

  cache = {repo.root: repostrage}# managed by chg server
  repo.repocache = cache[repo.root]  # maybe by chg ui/req hook?
  changelog.repocache = repo.repocache  # passed by repo

For remotefilelog which prefers wider cache, maybe it can manage its own cache
storage? I haven't consider well how it should be invalidated, though.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 3 py3 v3] tests: make a variable for hg binary location in test-check-py3-commands

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489304265 14400
#  Sun Mar 12 03:37:45 2017 -0400
# Node ID 2cd4d7ea0b19c4d5c55ccf8026ff1d7aa493a8cb
# Parent  a8f3bbc6259aebdeeef9f58309800f4070081214
tests: make a variable for hg binary location in test-check-py3-commands

The number of which calls in here is starting to get silly.

diff --git a/tests/test-check-py3-commands.t b/tests/test-check-py3-commands.t
--- a/tests/test-check-py3-commands.t
+++ b/tests/test-check-py3-commands.t
@@ -3,10 +3,11 @@
 This test helps in keeping a track on which commands we can run on
 Python 3 and see what kind of errors are coming up.
 The full traceback is hidden to have a stable output.
+  $ HGBIN=`which hg`
 
   $ for cmd in version debuginstall ; do
   >   echo $cmd
-  >   $PYTHON3 `which hg` $cmd 2>&1 2>&1 | tail -1
+  >   $PYTHON3 $HGBIN $cmd 2>&1 2>&1 | tail -1
   > done
   version
   warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -20,7 +21,7 @@ The full traceback is hidden to have a s
   $ cat >> $HGRCPATH < %include $TESTTMP/included-hgrc
   > EOF
-  $ $PYTHON3 `which hg` version | tail -1
+  $ $PYTHON3 $HGBIN version | tail -1
   *** failed to import extension babar from imaginary_elephant: *: 
'imaginary_elephant' (glob)
   warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 3 py3 v3] lock: encode result of gethostname into a bytestring

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489303730 14400
#  Sun Mar 12 03:28:50 2017 -0400
# Node ID a8f3bbc6259aebdeeef9f58309800f4070081214
# Parent  7548522742b5f4f9f5c0881ae4a2783ecda2f969
lock: encode result of gethostname into a bytestring

diff --git a/mercurial/lock.py b/mercurial/lock.py
--- a/mercurial/lock.py
+++ b/mercurial/lock.py
@@ -15,6 +15,7 @@ import time
 import warnings
 
 from . import (
+encoding,
 error,
 pycompat,
 util,
@@ -27,7 +28,8 @@ def _getlockprefix():
 confidence. Typically it's just hostname. On modern linux, we include an
 extra Linux-specific pid namespace identifier.
 """
-result = socket.gethostname()
+result = socket.gethostname().encode(
+pycompat.sysstr(encoding.encoding), 'replace')
 if pycompat.sysplatform.startswith('linux'):
 try:
 result += '/%x' % os.stat('/proc/self/ns/pid').st_ino
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 3 py3 v3] py3: prove `hg files --rev` works

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489304018 14400
#  Sun Mar 12 03:33:38 2017 -0400
# Node ID 0469a0ef78c613b1dcb533db0cff288f0871e7a8
# Parent  2cd4d7ea0b19c4d5c55ccf8026ff1d7aa493a8cb
py3: prove `hg files --rev` works

diff --git a/tests/test-check-py3-commands.t b/tests/test-check-py3-commands.t
--- a/tests/test-check-py3-commands.t
+++ b/tests/test-check-py3-commands.t
@@ -14,6 +14,46 @@ The full traceback is hidden to have a s
   debuginstall
   no problems detected
 
+#if test-repo
+Make a clone so that any features in the developer's .hg/hgrc that
+might confuse Python 3 don't break this test. When we can do commit in
+Python 3, we'll stop doing this. We use e76ed1e480ef for the clone
+because it has different files than 273ce12ad8f1, so we can test both
+`files` from dirstate and `files` loaded from a specific revision.
+
+  $ hg clone -r e76ed1e480ef "`dirname "$TESTDIR"`" testrepo 2>&1 | tail -1
+  15 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+Test using -R, which exercises some URL code:
+  $ $PYTHON3 $HGBIN -R testrepo files -r 273ce12ad8f1 | tail -1
+  testrepo/tkmerge
+
+Now prove `hg files` is reading the whole manifest. We have to grep
+out some potential warnings that come from hgrc as yet.
+  $ cd testrepo
+  $ $PYTHON3 $HGBIN files -r 273ce12ad8f1
+  .hgignore
+  PKG-INFO
+  README
+  hg
+  mercurial/__init__.py
+  mercurial/byterange.py
+  mercurial/fancyopts.py
+  mercurial/hg.py
+  mercurial/mdiff.py
+  mercurial/revlog.py
+  mercurial/transaction.py
+  notes.txt
+  setup.py
+  tkmerge
+
+  $ $PYTHON3 $HGBIN files -r 273ce12ad8f1 | wc -l
+  \s*14 (re)
+  $ $PYTHON3 $HGBIN files | wc -l
+  \s*15 (re)
+  $ cd ..
+#endif
+
   $ cat > included-hgrc < [extensions]
   > babar = imaginary_elephant
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 10 of 10 RFC v2] compat: add ui.interface=curses to latest

2017-03-12 Thread David Soria Parra
# HG changeset patch
# User David Soria Parra 
# Date 1489358250 25200
#  Sun Mar 12 15:37:30 2017 -0700
# Node ID 4ae47aa5224bbca0f9bc35b2b0aef0ab01059ccc
# Parent  b114907de6ce0f3d07c7be37e6570cc0a9456df6
compat: add ui.interface=curses to latest

diff --git a/mercurial/compat.py b/mercurial/compat.py
--- a/mercurial/compat.py
+++ b/mercurial/compat.py
@@ -22,6 +22,7 @@
 },
 'ui': {
 'color': 'auto',
+'interface': 'curses',
 },
 })],
 )
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 05 of 10 RFC v2] help: document compat mode

2017-03-12 Thread David Soria Parra
# HG changeset patch
# User David Soria Parra 
# Date 1489349206 25200
#  Sun Mar 12 13:06:46 2017 -0700
# Node ID d402acdf7c439dc369b6ab3a6888078a2895978a
# Parent  0986fb7be0f584f5169f93377f9d013f87381ea7
help: document compat mode

diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -1837,6 +1837,13 @@
 changes, abort the commit.
 (default: False)
 
+``compat``
+String: Compatibility mode for the ui. Possible values are compat
+or latest (default: compat). ``compat`` provides backwards compatible
+ui behavior. ``latest`` enables additional config settings aiming to
+improve user experience. (see ``HGPLAIN`` for compatibility modes in
+non-interactive environments)
+
 ``debug``
 Print debugging information. (default: False)
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 08 of 10 RFC v2] compat: add diff.showfunc=True to latest

2017-03-12 Thread David Soria Parra
# HG changeset patch
# User David Soria Parra 
# Date 1489358226 25200
#  Sun Mar 12 15:37:06 2017 -0700
# Node ID 8d4b79f7c6012aa1595fa3fbe184bc6849e3d81c
# Parent  7256c598a7f493bcc999259a4cbd88d86077746d
compat: add diff.showfunc=True to latest

diff --git a/mercurial/compat.py b/mercurial/compat.py
--- a/mercurial/compat.py
+++ b/mercurial/compat.py
@@ -18,6 +18,7 @@
 ('latest', {
 'diff': {
 'git': 'True',
+'showfunc': 'True',
 },
 })],
 )
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 01 of 10 RFC v2] ui: refactoring handling of trusted, user and overlay

2017-03-12 Thread David Soria Parra
# HG changeset patch
# User David Soria Parra 
# Date 1489349204 25200
#  Sun Mar 12 13:06:44 2017 -0700
# Node ID 99514a82d5b23c75bd6da38e522acfd14a618c14
# Parent  1c3352d7eaf24533ad52d4b8a024211e9189fb0b
ui: refactoring handling of trusted, user and overlay

We are using obscure names such as _ocfg for overlay-config in the UI. This is
sometimes confusing and not very flexible. We are moving this into a dictionary
now that has a specific ordering in which we would apply multiple layers of
configuration. At the moment this is not needed as we always pick either
user-config or trusted-config and overlay it, but it gets us a good machinery to
add a defaults layer for ui.compat.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -146,9 +146,7 @@
 self._bufferapplylabels = None
 self.quiet = self.verbose = self.debugflag = self.tracebackflag = False
 self._reportuntrusted = True
-self._ocfg = config.config() # overlay
-self._tcfg = config.config() # trusted
-self._ucfg = config.config() # untrusted
+self._cfg = self.cfg()
 self._trustusers = set()
 self._trustgroups = set()
 self.callhooks = True
@@ -167,10 +165,6 @@
 self.fin = src.fin
 self.pageractive = src.pageractive
 self._disablepager = src._disablepager
-
-self._tcfg = src._tcfg.copy()
-self._ucfg = src._ucfg.copy()
-self._ocfg = src._ocfg.copy()
 self._trustusers = src._trustusers.copy()
 self._trustgroups = src._trustgroups.copy()
 self.environ = src.environ
@@ -179,6 +173,8 @@
 self._colormode = src._colormode
 self._terminfoparams = src._terminfoparams.copy()
 self._styles = src._styles.copy()
+for k in self._cfg.keys():
+self._cfg[k] = src._cfg[k].copy()
 
 self.fixconfig()
 
@@ -296,21 +292,28 @@
 del cfg['templatealias'][k]
 
 if trusted:
-self._tcfg.update(cfg)
-self._tcfg.update(self._ocfg)
-self._ucfg.update(cfg)
-self._ucfg.update(self._ocfg)
+self._cfg['trusted'].update(cfg)
+self._cfg['trusted'].update(self._cfg['overlay'])
+self._cfg['user'].update(cfg)
+self._cfg['user'].update(self._cfg['overlay'])
 
 if root is None:
 root = os.path.expanduser('~')
 self.fixconfig(root=root)
 
+def cfg(self):
+# Ordered in ascneding order of preference.
+return util.sortdict(
+[('user', config.config()),
+('trusted', config.config()),
+('overlay', config.config())])
+
 def fixconfig(self, root=None, section=None):
 if section in (None, 'paths'):
 # expand vars and ~
 # translate paths relative to root (or home) into absolute paths
 root = root or pycompat.getcwd()
-for c in self._tcfg, self._ucfg, self._ocfg:
+for c in self._cfg.values():
 for n, p in c.items('paths'):
 # Ignore sub-options.
 if ':' in n:
@@ -345,21 +348,22 @@
 self._trustgroups.update(self.configlist('trusted', 'groups'))
 
 def backupconfig(self, section, item):
-return (self._ocfg.backup(section, item),
-self._tcfg.backup(section, item),
-self._ucfg.backup(section, item),)
+return {k: cfg.backup(section, item) for k, cfg in self._cfg.items()}
+
 def restoreconfig(self, data):
-self._ocfg.restore(data[0])
-self._tcfg.restore(data[1])
-self._ucfg.restore(data[2])
+for k, d in data.items():
+self._cfg[k].restore(d)
 
 def setconfig(self, section, name, value, source=''):
-for cfg in (self._ocfg, self._tcfg, self._ucfg):
+for cfg in self._cfg.values():
 cfg.set(section, name, value, source)
 self.fixconfig(section=section)
 
 def _data(self, untrusted):
-return untrusted and self._ucfg or self._tcfg
+if untrusted:
+return self._cfg['user']
+else:
+return self._cfg['trusted']
 
 def configsource(self, section, name, untrusted=False):
 return self._data(untrusted).source(section, name)
@@ -380,7 +384,7 @@
 
 if self.debugflag and not untrusted and self._reportuntrusted:
 for n in alternates:
-uvalue = self._ucfg.get(section, n)
+uvalue = self._cfg['user'].get(section, n)
 if uvalue is not None and uvalue != value:
 self.debug("ignoring untrusted configuration option "
"%s.%s = %s\n" % (section, n, uvalue))
@@ -399,7 +403,7 @@
 data = self._data(untrusted)
 main = data.get(section, name, default)
 if 

[PATCH 06 of 10 RFC v2] dispatch: modernize the ui after finalizing config loading

2017-03-12 Thread David Soria Parra
# HG changeset patch
# User David Soria Parra 
# Date 1489349206 25200
#  Sun Mar 12 13:06:46 2017 -0700
# Node ID 63065d4cb13dc3acb9177473896fc3c9c9c7993b
# Parent  d402acdf7c439dc369b6ab3a6888078a2895978a
dispatch: modernize the ui after finalizing config loading

We have to carefuly load the defaults layer in the ui object after we have read
configurations and set --config, as we are modifying configurations based on a
config settings. In our case we have to ensure that 'ui.compat=' can be set from
--config or any hgrc, but when we detect it have to add our setting as early as
possible. Therefore we choose dispatch to add it, right after we finalize
--config parsing.

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -26,6 +26,7 @@
 cmdutil,
 color,
 commands,
+compat,
 debugcommands,
 demandimport,
 encoding,
@@ -178,6 +179,7 @@
 for sec, name, val in cfgs:
 req.repo.ui.setconfig(sec, name, val, source='--config')
 
+compat.modernize(ui)
 # developer config: ui.debugger
 debugger = ui.config("ui", "debugger")
 debugmod = pdb
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 09 of 10 RFC v2] compat: add ui.color=auto to latest

2017-03-12 Thread David Soria Parra
# HG changeset patch
# User David Soria Parra 
# Date 1489358241 25200
#  Sun Mar 12 15:37:21 2017 -0700
# Node ID b114907de6ce0f3d07c7be37e6570cc0a9456df6
# Parent  8d4b79f7c6012aa1595fa3fbe184bc6849e3d81c
compat: add ui.color=auto to latest

diff --git a/mercurial/compat.py b/mercurial/compat.py
--- a/mercurial/compat.py
+++ b/mercurial/compat.py
@@ -20,6 +20,9 @@
 'git': 'True',
 'showfunc': 'True',
 },
+'ui': {
+'color': 'auto',
+},
 })],
 )
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 04 of 10 RFC v2] compat: module to handle different ui.compat settings

2017-03-12 Thread David Soria Parra
# HG changeset patch
# User David Soria Parra 
# Date 1489349206 25200
#  Sun Mar 12 13:06:46 2017 -0700
# Node ID 0986fb7be0f584f5169f93377f9d013f87381ea7
# Parent  ef5ce5325596fe5fef014a320abae0f0d5980f3d
compat: module to handle different ui.compat settings

We are introducing ui.compat. It defaults to 'compat' which means Mercurial is
supposed to behave backwards compatible. At the moment it supports another mode
called 'latest' which can enable bc-breaking configurations to change the
default behavior of commands. The layer provides an ordered list of
compatibility levels and returns a combined list of configurations up to a given
compatibility level. For example, given settings 'compat', 'hg4.2',
'hg4.3', 'latest', a request for 'hg4.3' will return the combined settings for
'compat', 'hg4.2' and 'hg4.3' with later levels overwrriten existing
configurations.

diff --git a/mercurial/compat.py b/mercurial/compat.py
new file mode 100644
--- /dev/null
+++ b/mercurial/compat.py
@@ -0,0 +1,40 @@
+# compat.py - handlign compatibility settings
+#
+# Copyright 2005-2017 Mercurial Steering Committee
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+from __future__ import absolute_import
+
+import collections
+from . import (
+util,
+)
+
+# The initialization msut be done with a list and not a dict, as a list
+# is sorted while a dictionary is not.
+COMPAT = util.sortdict([
+('compat', {}),
+('latest', {})],
+)
+
+def modernize(ui):
+compats = compatlevel(ui)
+for section, d in compats.items():
+for key, value in d.items():
+ui._cfg['defaults'].set(section, key, value)
+
+def compatlevel(ui):
+if ui.plain('compat'):
+requested = 'compat'
+else:
+requested = ui.config('ui', 'compat', 'compat')
+
+result = {}
+for level, configs in COMPAT.items():
+result.update(configs)
+if level == requested:
+# defaults is sorted. We can abort once we reached
+# the requested level.
+break
+return result
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] py3: initial type hinting stubs

2017-03-12 Thread Martijn Pieters
# HG changeset patch
# User Martijn Pieters 
# Date 1489356745 25200
#  Sun Mar 12 15:12:25 2017 -0700
# Node ID c363e933a66bb85ddbfe8301bbfd246ecaad95d6
# Parent  719e64bf9ec2d7b8e86b6550a5d193b3c67944d1
py3: initial type hinting stubs

These are stub files to be used by mypy and future tooling to check type hints
in Python 3. These files are complete for the current state of the covered
modules. Future tooling should ensure that these are kept in sync.

diff --git a/types/.flake8 b/types/.flake8
new file mode 100644
--- /dev/null
+++ b/types/.flake8
@@ -0,0 +1,13 @@
+# Some PEP8 deviations are considered irrelevant to stub files:
+# E704 multiple statements on one line (def)
+# E301 expected 1 blank line
+# E302 expected 2 blank lines
+# E501 line too long
+# F401 imported but unused
+# E701 multiple statements on one line (colon)
+# F811 redefinition
+# E305 expected 2 blank lines
+
+[flake8]
+ignore = F401, F811, E301, E302, E305, E501, E701, E704, B303
+
diff --git a/types/mercurial/__init__.pyi b/types/mercurial/__init__.pyi
new file mode 100644
--- /dev/null
+++ b/types/mercurial/__init__.pyi
@@ -0,0 +1,22 @@
+# Stubs for mercurial (Python 3.5)
+#
+# NOTE: This dynamically typed stub was automatically generated by stubgen.
+
+from tokenize import TokenInfo
+from types import ModuleType
+from typing import Any, Generator, Optional, Sequence, Union
+import importlib.abc
+import importlib.machinery
+
+modulepolicy = ...  # type: str
+
+# hgimporter is only used in Python 2
+# class hgimporter: ...
+
+class hgpathentryfinder(importlib.abc.MetaPathFinder): ...
+
+def replacetokens(tokens: Sequence[TokenInfo], fullname: str) -> 
Generator[TokenInfo, None, None]: ...
+
+BYTECODEHEADER = ...  # type: bytes
+
+class hgloader(importlib.machinery.SourceFileLoader): ...
diff --git a/types/mercurial/config.pyi b/types/mercurial/config.pyi
new file mode 100644
--- /dev/null
+++ b/types/mercurial/config.pyi
@@ -0,0 +1,27 @@
+# Stubs for mercurial.config (Python 3.6)
+#
+# NOTE: This dynamically typed stub was automatically generated by stubgen.
+
+from typing import Any, BinaryIO, Callable, Container, Generator, ItemsView, 
List, Mapping, Optional, Sequence, Tuple, Union
+from .i18n import _ as _
+
+# Config is backed up as a (section, item, value, source) tuple; a two-item 
tuple models a missing entry
+_CfgBackup = Union[Tuple[bytes, bytes, Any, bytes], Tuple[bytes, bytes]]
+
+class config:
+def __init__(self, data: Optional[config] = ..., includepaths: 
Optional[Sequence[bytes]] = ...) -> None: ...
+def copy(self) -> config: ...
+def __contains__(self, section: bytes): ...
+def hasitem(self, section: bytes, item: bytes): ...
+def __getitem__(self, section: bytes): ...
+def __iter__(self) -> Generator[bytes, None, None]: ...
+def update(self, src: config) -> None: ...
+def get(self, section: bytes, item: bytes, default: Optional[Any] = ...) 
-> Optional[Any]: ...
+def backup(self, section: bytes, item: bytes) -> _CfgBackup: ...
+def source(self, section: bytes, item: bytes) -> bytes: ...
+def sections(self) -> List[bytes]: ...
+def items(self, section: bytes) -> ItemsView[bytes, Any]: ...
+def set(self, section: bytes, item: bytes, value: Any, source: bytes = 
...) -> None: ...
+def restore(self, data: _CfgBackup) -> None: ...
+def parse(self, src: bytes, data: bytes, sections: 
Optional[Container[bytes]] = ..., remap: Optional[Mapping[bytes, bytes]] = ..., 
include: Optional[Callable[..., None]] = ...): ...
+def read(self, path: bytes, fp: Optional[BinaryIO] = ..., sections: 
Optional[Container[bytes]] = ..., remap: Optional[Mapping[bytes, bytes]] = ...) 
-> None: ...
diff --git a/types/mercurial/policy.pyi b/types/mercurial/policy.pyi
new file mode 100644
--- /dev/null
+++ b/types/mercurial/policy.pyi
@@ -0,0 +1,9 @@
+# Stubs for mercurial.policy (Python 3.5)
+#
+# NOTE: This dynamically typed stub was automatically generated by stubgen.
+
+from typing import Any, Tuple
+
+policy = ...  # type: bytes
+policynoc = ...  # type: Tuple[bytes, ...]
+policynocffi = ...  # type: Tuple[bytes, ...]
diff --git a/types/mercurial/ui.pyi b/types/mercurial/ui.pyi
new file mode 100644
--- /dev/null
+++ b/types/mercurial/ui.pyi
@@ -0,0 +1,119 @@
+# Stubs for mercurial.ui (Python 3.5)
+#
+# NOTE: This dynamically typed stub was automatically generated by stubgen.
+
+from types import TracebackType
+from typing import Any, BinaryIO, Callable, Container, ContextManager, 
Generator, ItemsView, List, Mapping, MutableMapping, Optional, Sequence, 
SupportsInt, Tuple, Type, Union
+from .config import _CfgBackup
+from .formatter import baseformatter
+from .i18n import _ as _
+from .node import hex as hex
+from .progress import progbar
+from .url import url
+
+import urllib.request as urlreq
+
+_OneNameOrMultiple = Union[bytes, Sequence[bytes]]
+
+samplehgrcs = ...  # type: MutableMapping[bytes, bytes]
+
+class httppasswordmgrdbproxy:
+def 

Re: [PATCH 1 of 4 py3 v2] encoding: make encoding.encoding be a native str and add encodingb

2017-03-12 Thread Augie Fackler

> On Mar 12, 2017, at 15:08, Yuya Nishihara  wrote:
> 
> On Sun, 12 Mar 2017 17:51:15 -0400, Augie Fackler wrote:
>> # HG changeset patch
>> # User Augie Fackler 
>> # Date 1489303712 14400
>> #  Sun Mar 12 03:28:32 2017 -0400
>> # Node ID 4455c6cdbf1e9cd524b43c69ecefef819e0b4e30
>> # Parent  7dd2f51f38ac224cec522d093ff6f805beb0dd3e
>> encoding: make encoding.encoding be a native str and add encodingb
>> 
>> It turns out we need the encoding name both ways. Ugh.
>> 
>> diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
>> --- a/mercurial/debugcommands.py
>> +++ b/mercurial/debugcommands.py
>> @@ -965,7 +965,7 @@ def debuginstall(ui, **opts):
>> fm.startitem()
>> 
>> # encoding
>> -fm.write('encoding', _("checking encoding (%s)...\n"), 
>> encoding.encoding)
>> +fm.write('encoding', _("checking encoding (%s)...\n"), 
>> encoding.encodingb())
> 
> We have much more uses of encoding.encoding expecting bytes. Better to make
> encodingu() a function?
> 
> % grep encoding.encoding **/*.py | grep -v sysstr | wc -l
> 41

Sure, I'll roll a v3.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 4 py3 v2] encoding: make encoding.encoding be a native str and add encodingb

2017-03-12 Thread Yuya Nishihara
On Sun, 12 Mar 2017 17:51:15 -0400, Augie Fackler wrote:
> # HG changeset patch
> # User Augie Fackler 
> # Date 1489303712 14400
> #  Sun Mar 12 03:28:32 2017 -0400
> # Node ID 4455c6cdbf1e9cd524b43c69ecefef819e0b4e30
> # Parent  7dd2f51f38ac224cec522d093ff6f805beb0dd3e
> encoding: make encoding.encoding be a native str and add encodingb
> 
> It turns out we need the encoding name both ways. Ugh.
> 
> diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
> --- a/mercurial/debugcommands.py
> +++ b/mercurial/debugcommands.py
> @@ -965,7 +965,7 @@ def debuginstall(ui, **opts):
>  fm.startitem()
>  
>  # encoding
> -fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
> +fm.write('encoding', _("checking encoding (%s)...\n"), 
> encoding.encodingb())

We have much more uses of encoding.encoding expecting bytes. Better to make
encodingu() a function?

% grep encoding.encoding **/*.py | grep -v sysstr | wc -l
41
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] localrepo: deprecate 'repo.join' in favor of 'repo.vfs.join'

2017-03-12 Thread Augie Fackler
On Sun, Mar 12, 2017 at 01:17:34PM -0700, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David 
> # Date 1470398944 -7200
> #  Fri Aug 05 14:09:04 2016 +0200
> # Node ID 1e79d966aa2bdc9e13c62b94b0e12cfc469b5eb5
> # Parent  8a17c541177f32348e248608b6a9dfd7fefdf517
> # EXP-Topic vfs.cleanup
> # Available At https://www.mercurial-scm.org/repo/users/marmoute/mercurial/
> #  hg pull 
> https://www.mercurial-scm.org/repo/users/marmoute/mercurial/ -r 1e79d966aa2b
> localrepo: deprecate 'repo.join' in favor of 'repo.vfs.join'

Queued, thanks

>
> localrepo have an insane amount of method. Accessing the feature through the
> vfs is not really harder and allow us to schedule that method for removal.
>
> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -932,6 +932,7 @@ class localrepository(object):
>  return None
>
>  def join(self, f, *insidef):
> +self.ui.deprecwarn("use 'repo.vfs.join' instead of 'repo.join'", 
> '4.0')
>  return self.vfs.join(os.path.join(f, *insidef))
>
>  def wjoin(self, f, *insidef):
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] pycompat: move imports of cStringIO/io to where they are used

2017-03-12 Thread Augie Fackler
On Sun, Mar 12, 2017 at 01:16:43PM -0700, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1489348451 25200
> #  Sun Mar 12 12:54:11 2017 -0700
> # Node ID 442615c97b9787fd864d8a59b4076eca3a15a0b0
> # Parent  8a17c541177f32348e248608b6a9dfd7fefdf517
> pycompat: move imports of cStringIO/io to where they are used

queued, thanks

>
> There's no point to import cStringIO as io since we have to select StringIO
> or BytesIO conditionally.
>
> diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py
> --- a/mercurial/pycompat.py
> +++ b/mercurial/pycompat.py
> @@ -19,7 +19,6 @@ ispy3 = (sys.version_info[0] >= 3)
>
>  if not ispy3:
>  import cPickle as pickle
> -import cStringIO as io
>  import httplib
>  import Queue as _queue
>  import SocketServer as socketserver
> @@ -28,7 +27,6 @@ if not ispy3:
>  import xmlrpclib
>  else:
>  import http.client as httplib
> -import io
>  import pickle
>  import queue as _queue
>  import socketserver
> @@ -39,6 +37,8 @@ else:
>  if ispy3:
>  import builtins
>  import functools
> +import io
> +
>  fsencode = os.fsencode
>  fsdecode = os.fsdecode
>  # A bytes version of os.name.
> @@ -139,6 +139,8 @@ if ispy3:
>  return [a.encode('latin-1') for a in ret]
>
>  else:
> +import cStringIO
> +
>  bytechr = chr
>
>  def sysstr(s):
> @@ -181,7 +183,7 @@ else:
>  getcwd = os.getcwd
>  sysexecutable = sys.executable
>  shlexsplit = shlex.split
> -stringio = io.StringIO
> +stringio = cStringIO.StringIO
>
>  empty = _queue.Empty
>  queue = _queue.Queue
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] debugfsinfo: print fstype information

2017-03-12 Thread Augie Fackler

> On Mar 12, 2017, at 12:26, Jun Wu  wrote:
> 
> Sorry. It's meant to be PATCH 8 of 8. Next time I'll use "--in-reply-to" to
> attach it to an existing thread.

It's better to either resend the whole series or wait until the first batch 
lands, otherwise you'll confuse people that are doing things like looking at 
patchbot or patchwork.

Thanks!

> 
> Excerpts from Augie Fackler's message of 2017-03-12 11:54:15 -0700:
>> 
>>> On Mar 12, 2017, at 11:53, Yuya Nishihara  wrote:
>>> 
>>> On Sun, 12 Mar 2017 14:12:03 -0400, Augie Fackler wrote:
 On Sun, Mar 12, 2017 at 01:34:53AM -0800, Jun Wu wrote:
> # HG changeset patch
> # User Jun Wu 
> # Date 1489311257 28800
> #  Sun Mar 12 01:34:17 2017 -0800
> # Node ID ff9af50d033388f74cbaf1eeac1509b3e75da07b
> # Parent  9da40a9e54c419490a2ff23b9dda7acc109f81cd
> # Available At https://bitbucket.org/quark-zju/hg-draft 
> #  hg pull https://bitbucket.org/quark-zju/hg-draft  -r 
> ff9af50d0333
> debugfsinfo: print fstype information
 
 Queued, thanks.
 
> 
> Since we have util.getfstype, it'll be handy to use "debugfsinfo" to test
> it.
> 
> diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
> --- a/mercurial/debugcommands.py
> +++ b/mercurial/debugcommands.py
> @@ -791,4 +791,5 @@ def debugfsinfo(ui, path="."):
>util.writefile('.debugfsinfo', '')
>ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
> +ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
>>> 
>>> It appears debugfsinfo isn't covered by tests.
>>> 
>>> $ hg debugfsinfo
>>> exec: yes
>>> ...
>>> ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
>>> AttributeError: 'module' object has no attribute 'getfstype'
>> 
>> Sigh. Pruning and we'll come back to this. Jun, you'll want to 'hg touch' 
>> this patch locally.

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


[PATCH 3 of 4 py3 v2] tests: make a variable for hg binary location in test-check-py3-commands

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489304265 14400
#  Sun Mar 12 03:37:45 2017 -0400
# Node ID d1352bf3a81a39261a29ffc461ff8d25f28e713e
# Parent  81927dc713bc65e5f449fbdf4f9e2e966d068e56
tests: make a variable for hg binary location in test-check-py3-commands

The number of which calls in here is starting to get silly.

diff --git a/tests/test-check-py3-commands.t b/tests/test-check-py3-commands.t
--- a/tests/test-check-py3-commands.t
+++ b/tests/test-check-py3-commands.t
@@ -3,10 +3,11 @@
 This test helps in keeping a track on which commands we can run on
 Python 3 and see what kind of errors are coming up.
 The full traceback is hidden to have a stable output.
+  $ HGBIN=`which hg`
 
   $ for cmd in version debuginstall ; do
   >   echo $cmd
-  >   $PYTHON3 `which hg` $cmd 2>&1 2>&1 | tail -1
+  >   $PYTHON3 $HGBIN $cmd 2>&1 2>&1 | tail -1
   > done
   version
   warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -20,7 +21,7 @@ The full traceback is hidden to have a s
   $ cat >> $HGRCPATH < %include $TESTTMP/included-hgrc
   > EOF
-  $ $PYTHON3 `which hg` version | tail -1
+  $ $PYTHON3 $HGBIN version | tail -1
   *** failed to import extension babar from imaginary_elephant: *: 
'imaginary_elephant' (glob)
   warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 4 py3 v2] py3: prove `hg files --rev` works

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489304018 14400
#  Sun Mar 12 03:33:38 2017 -0400
# Node ID bf857f481983d067419eb48b524db6e906a0147d
# Parent  d1352bf3a81a39261a29ffc461ff8d25f28e713e
py3: prove `hg files --rev` works

diff --git a/tests/test-check-py3-commands.t b/tests/test-check-py3-commands.t
--- a/tests/test-check-py3-commands.t
+++ b/tests/test-check-py3-commands.t
@@ -14,6 +14,46 @@ The full traceback is hidden to have a s
   debuginstall
   no problems detected
 
+#if test-repo
+Make a clone so that any features in the developer's .hg/hgrc that
+might confuse Python 3 don't break this test. When we can do commit in
+Python 3, we'll stop doing this. We use e76ed1e480ef for the clone
+because it has different files than 273ce12ad8f1, so we can test both
+`files` from dirstate and `files` loaded from a specific revision.
+
+  $ hg clone -r e76ed1e480ef "`dirname "$TESTDIR"`" testrepo 2>&1 | tail -1
+  15 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+Test using -R, which exercises some URL code:
+  $ $PYTHON3 $HGBIN -R testrepo files -r 273ce12ad8f1 | tail -1
+  testrepo/tkmerge
+
+Now prove `hg files` is reading the whole manifest. We have to grep
+out some potential warnings that come from hgrc as yet.
+  $ cd testrepo
+  $ $PYTHON3 $HGBIN files -r 273ce12ad8f1
+  .hgignore
+  PKG-INFO
+  README
+  hg
+  mercurial/__init__.py
+  mercurial/byterange.py
+  mercurial/fancyopts.py
+  mercurial/hg.py
+  mercurial/mdiff.py
+  mercurial/revlog.py
+  mercurial/transaction.py
+  notes.txt
+  setup.py
+  tkmerge
+
+  $ $PYTHON3 $HGBIN files -r 273ce12ad8f1 | wc -l
+  \s*14 (re)
+  $ $PYTHON3 $HGBIN files | wc -l
+  \s*15 (re)
+  $ cd ..
+#endif
+
   $ cat > included-hgrc < [extensions]
   > babar = imaginary_elephant
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4 py3 v2] encoding: make encoding.encoding be a native str and add encodingb

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489303712 14400
#  Sun Mar 12 03:28:32 2017 -0400
# Node ID 4455c6cdbf1e9cd524b43c69ecefef819e0b4e30
# Parent  7dd2f51f38ac224cec522d093ff6f805beb0dd3e
encoding: make encoding.encoding be a native str and add encodingb

It turns out we need the encoding name both ways. Ugh.

diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -965,7 +965,7 @@ def debuginstall(ui, **opts):
 fm.startitem()
 
 # encoding
-fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
+fm.write('encoding', _("checking encoding (%s)...\n"), 
encoding.encodingb())
 err = None
 try:
 encoding.fromlocal("test")
diff --git a/mercurial/encoding.py b/mercurial/encoding.py
--- a/mercurial/encoding.py
+++ b/mercurial/encoding.py
@@ -100,6 +100,15 @@ except locale.Error:
 encodingmode = environ.get("HGENCODINGMODE", "strict")
 fallbackencoding = 'ISO-8859-1'
 
+if pycompat.ispy3:
+def encodingb():
+return encoding.encode('ascii')
+# TODO: are all encodings sure to be ascii names?
+encoding = encoding.decode('ascii')
+else:
+def encodingb():
+return encoding
+
 class localstr(str):
 '''This class allows strings that are unmodified to be
 round-tripped to the local encoding and back'''
diff --git a/tests/test-check-code.t b/tests/test-check-code.t
--- a/tests/test-check-code.t
+++ b/tests/test-check-code.t
@@ -22,7 +22,7 @@ New errors are not allowed. Warnings are
   mercurial/encoding.py:61:
>for k, v in os.environ.items())
use encoding.environ instead (py3)
-  mercurial/encoding.py:203:
+  mercurial/encoding.py:212:
>for k, v in os.environ.items())
use encoding.environ instead (py3)
   Skipping mercurial/httpclient/__init__.py it has no-che?k-code (glob)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 4 py3 v2] lock: encode result of gethostname into a bytestring

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489303730 14400
#  Sun Mar 12 03:28:50 2017 -0400
# Node ID 81927dc713bc65e5f449fbdf4f9e2e966d068e56
# Parent  4455c6cdbf1e9cd524b43c69ecefef819e0b4e30
lock: encode result of gethostname into a bytestring

diff --git a/mercurial/lock.py b/mercurial/lock.py
--- a/mercurial/lock.py
+++ b/mercurial/lock.py
@@ -15,6 +15,7 @@ import time
 import warnings
 
 from . import (
+encoding,
 error,
 pycompat,
 util,
@@ -27,7 +28,7 @@ def _getlockprefix():
 confidence. Typically it's just hostname. On modern linux, we include an
 extra Linux-specific pid namespace identifier.
 """
-result = socket.gethostname()
+result = socket.gethostname().encode(encoding.encoding, 'replace')
 if pycompat.sysplatform.startswith('linux'):
 try:
 result += '/%x' % os.stat('/proc/self/ns/pid').st_ino
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 01 of 12 py3] store: fix many single-byte ops to use slicing in _auxencode

2017-03-12 Thread Yuya Nishihara
On Sun, 12 Mar 2017 13:17:54 -0700, Gregory Szorc wrote:
> On Sun, Mar 12, 2017 at 12:49 PM, Augie Fackler  wrote:
> 
> > # HG changeset patch
> > # User Augie Fackler 
> > # Date 1489297844 18000
> > #  Sun Mar 12 00:50:44 2017 -0500
> > # Node ID 90b52b8ab62de4417fe13b06e52e9ff312bb30f9
> > # Parent  8a17c541177f32348e248608b6a9dfd7fefdf517
> > store: fix many single-byte ops to use slicing in _auxencode
> >
> >
> This series LGTM

Queued 1-7 and 12, thanks.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] localrepo: deprecate 'repo.join' in favor of 'repo.vfs.join'

2017-03-12 Thread Pierre-Yves David
# HG changeset patch
# User Pierre-Yves David 
# Date 1470398944 -7200
#  Fri Aug 05 14:09:04 2016 +0200
# Node ID 1e79d966aa2bdc9e13c62b94b0e12cfc469b5eb5
# Parent  8a17c541177f32348e248608b6a9dfd7fefdf517
# EXP-Topic vfs.cleanup
# Available At https://www.mercurial-scm.org/repo/users/marmoute/mercurial/
#  hg pull 
https://www.mercurial-scm.org/repo/users/marmoute/mercurial/ -r 1e79d966aa2b
localrepo: deprecate 'repo.join' in favor of 'repo.vfs.join'

localrepo have an insane amount of method. Accessing the feature through the
vfs is not really harder and allow us to schedule that method for removal.

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -932,6 +932,7 @@ class localrepository(object):
 return None
 
 def join(self, f, *insidef):
+self.ui.deprecwarn("use 'repo.vfs.join' instead of 'repo.join'", '4.0')
 return self.vfs.join(os.path.join(f, *insidef))
 
 def wjoin(self, f, *insidef):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 01 of 12 py3] store: fix many single-byte ops to use slicing in _auxencode

2017-03-12 Thread Gregory Szorc
On Sun, Mar 12, 2017 at 12:49 PM, Augie Fackler  wrote:

> # HG changeset patch
> # User Augie Fackler 
> # Date 1489297844 18000
> #  Sun Mar 12 00:50:44 2017 -0500
> # Node ID 90b52b8ab62de4417fe13b06e52e9ff312bb30f9
> # Parent  8a17c541177f32348e248608b6a9dfd7fefdf517
> store: fix many single-byte ops to use slicing in _auxencode
>
>
This series LGTM


> diff --git a/mercurial/store.py b/mercurial/store.py
> --- a/mercurial/store.py
> +++ b/mercurial/store.py
> @@ -193,22 +193,22 @@ def _auxencode(path, dotencode):
>  if not n:
>  continue
>  if dotencode and n[0] in '. ':
> -n = "~%02x" % ord(n[0]) + n[1:]
> +n = "~%02x" % ord(n[0:1]) + n[1:]
>  path[i] = n
>  else:
>  l = n.find('.')
>  if l == -1:
>  l = len(n)
>  if ((l == 3 and n[:3] in _winres3) or
> -(l == 4 and n[3] <= '9' and n[3] >= '1'
> +(l == 4 and n[3:4] <= '9' and n[3:4] >= '1'
>  and n[:3] in _winres4)):
>  # encode third letter ('aux' -> 'au~78')
> -ec = "~%02x" % ord(n[2])
> +ec = "~%02x" % ord(n[2:3])
>  n = n[0:2] + ec + n[3:]
>  path[i] = n
>  if n[-1] in '. ':
>  # encode last period or space ('foo...' -> 'foo..~2e')
> -path[i] = n[:-1] + "~%02x" % ord(n[-1])
> +path[i] = n[:-1] + "~%02x" % ord(n[-1:])
>  return path
>
>  _maxstorepathlen = 120
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/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] rbc: empty (and invalid) rbc-names file should give an empty name list

2017-03-12 Thread Augie Fackler
On Sun, Mar 12, 2017 at 12:33:56PM -0700, Mads Kiilerich wrote:
> # HG changeset patch
> # User Mads Kiilerich 
> # Date 1489346250 25200
> #  Sun Mar 12 12:17:30 2017 -0700
> # Node ID 1b5144a87e936fc8071463956816a89041478126
> # Parent  023b6f7456b3622cc81332ae9d6e30b7ecc37415
> rbc: empty (and invalid) rbc-names file should give an empty name list

queued these, thanks

>
> An empty file (if it somehow should exist) used to give a list with an empty
> name. That didn't do any harm, but it was "wrong". Fix that.
>
> diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
> --- a/mercurial/branchmap.py
> +++ b/mercurial/branchmap.py
> @@ -362,7 +362,9 @@ class revbranchcache(object):
>  try:
>  bndata = repo.vfs.read(_rbcnames)
>  self._rbcsnameslen = len(bndata) # for verification before 
> writing
> -self._names = [encoding.tolocal(bn) for bn in bndata.split('\0')]
> +if bndata:
> +self._names = [encoding.tolocal(bn)
> +   for bn in bndata.split('\0')]
>  except (IOError, OSError):
>  if readonly:
>  # don't try to use cache - fall back to the slow path
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] pycompat: move imports of cStringIO/io to where they are used

2017-03-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1489348451 25200
#  Sun Mar 12 12:54:11 2017 -0700
# Node ID 442615c97b9787fd864d8a59b4076eca3a15a0b0
# Parent  8a17c541177f32348e248608b6a9dfd7fefdf517
pycompat: move imports of cStringIO/io to where they are used

There's no point to import cStringIO as io since we have to select StringIO
or BytesIO conditionally.

diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py
--- a/mercurial/pycompat.py
+++ b/mercurial/pycompat.py
@@ -19,7 +19,6 @@ ispy3 = (sys.version_info[0] >= 3)
 
 if not ispy3:
 import cPickle as pickle
-import cStringIO as io
 import httplib
 import Queue as _queue
 import SocketServer as socketserver
@@ -28,7 +27,6 @@ if not ispy3:
 import xmlrpclib
 else:
 import http.client as httplib
-import io
 import pickle
 import queue as _queue
 import socketserver
@@ -39,6 +37,8 @@ else:
 if ispy3:
 import builtins
 import functools
+import io
+
 fsencode = os.fsencode
 fsdecode = os.fsdecode
 # A bytes version of os.name.
@@ -139,6 +139,8 @@ if ispy3:
 return [a.encode('latin-1') for a in ret]
 
 else:
+import cStringIO
+
 bytechr = chr
 
 def sysstr(s):
@@ -181,7 +183,7 @@ else:
 getcwd = os.getcwd
 sysexecutable = sys.executable
 shlexsplit = shlex.split
-stringio = io.StringIO
+stringio = cStringIO.StringIO
 
 empty = _queue.Empty
 queue = _queue.Queue
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 08 of 12 py3] encoding: make encoding.encoding be a native str and add encodingb

2017-03-12 Thread Yuya Nishihara
On Sun, 12 Mar 2017 15:49:57 -0400, Augie Fackler wrote:
> # HG changeset patch
> # User Augie Fackler 
> # Date 1489303712 14400
> #  Sun Mar 12 03:28:32 2017 -0400
> # Node ID 19f6f41baa5ef326d3cc953093c5d7ff5dcc4427
> # Parent  84996257b560fa41535e4d0360cb33436662581c
> encoding: make encoding.encoding be a native str and add encodingb
> 
> It turns out we need the encoding name both ways. Ugh.
> 
> diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
> --- a/mercurial/debugcommands.py
> +++ b/mercurial/debugcommands.py
> @@ -965,7 +965,7 @@ def debuginstall(ui, **opts):
>  fm.startitem()
>  
>  # encoding
> -fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
> +fm.write('encoding', _("checking encoding (%s)...\n"), 
> encoding.encodingb)
>  err = None
>  try:
>  encoding.fromlocal("test")
> diff --git a/mercurial/encoding.py b/mercurial/encoding.py
> --- a/mercurial/encoding.py
> +++ b/mercurial/encoding.py
> @@ -100,6 +100,11 @@ except locale.Error:
>  encodingmode = environ.get("HGENCODINGMODE", "strict")
>  fallbackencoding = 'ISO-8859-1'
>  
> +encodingb = encoding
> +if pycompat.ispy3:
> +# TODO: are all encodings sure to be ascii names?
> +encoding = encoding.decode('ascii')

Unfortunately encoding.encoding isn't readonly. dispatch, hgweb and convert
overwrite it.

Maybe we can add unicode variants of encoding.from/tolocal() instead?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 6 RFC] dispatch: modernize the ui after finalizing config loading

2017-03-12 Thread David Soria Parra
# HG changeset patch
# User David Soria Parra 
# Date 1489349206 25200
#  Sun Mar 12 13:06:46 2017 -0700
# Node ID 9eca95dec659b3ff37608fd257d888520599124d
# Parent  2dfa752cf0751010867944aa707bd7a722d3ea87
dispatch: modernize the ui after finalizing config loading

We have to carefuly load the defaults layer in the ui object after we have read
configurations and set --config, as we are modifying configurations based on a
config settings. In our case we have to ensure that 'ui.compat=' can be set from
--config or any hgrc, but when we detect it have to add our setting as early as
possible. Therefore we choose dispatch to add it, right after we finalize
--config parsing.

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -26,6 +26,7 @@
 cmdutil,
 color,
 commands,
+compat,
 debugcommands,
 demandimport,
 encoding,
@@ -178,6 +179,7 @@
 for sec, name, val in cfgs:
 req.repo.ui.setconfig(sec, name, val, source='--config')
 
+compat.modernize(ui)
 # developer config: ui.debugger
 debugger = ui.config("ui", "debugger")
 debugmod = pdb
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 6 RFC] compat: module to handle different ui.compat settings

2017-03-12 Thread David Soria Parra
# HG changeset patch
# User David Soria Parra 
# Date 1489349206 25200
#  Sun Mar 12 13:06:46 2017 -0700
# Node ID 8efd04667ba8d2939a937f549e803bc3b56f70a7
# Parent  ef5ce5325596fe5fef014a320abae0f0d5980f3d
compat: module to handle different ui.compat settings

We are introducing ui.compat. It defaults to 'compat' which means Mercurial is
supposed to behave backwards compatible. At the moment it supports another mode
called 'latest' which can enable bc-breaking configurations to change the
default behavior of commands. The layer provides an ordered list of
compatibility levels and returns a combined list of configurations up to a given
compatibility level. For example, given settings 'compat', 'hg4.2',
'hg4.3', 'latest', a request for 'hg4.3' will return the combined settings for
'compat', 'hg4.2' and 'hg4.3' with later levels overwrriten existing
configurations.

diff --git a/mercurial/compat.py b/mercurial/compat.py
new file mode 100644
--- /dev/null
+++ b/mercurial/compat.py
@@ -0,0 +1,48 @@
+# compat.py - handlign compatibility settings
+#
+# Copyright 2005-2017 Mercurial Steering Committee
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+from __future__ import absolute_import
+
+import collections
+from . import (
+util,
+)
+
+# The initialization msut be done with a list and not a dict, as a list
+# is sorted while a dictionary is not.
+COMPAT = util.sortdict([
+('latest', {
+'diff': {
+'git': 'True',
+'showfunc': 'True',
+},
+'ui': {
+'color': 'auto',
+'interface': 'curses',
+},
+})],
+)
+
+def modernize(ui):
+compats = compatlevel(ui)
+for section, d in compats.items():
+for key, value in d.items():
+ui._cfg['defaults'].set(section, key, value)
+
+def compatlevel(ui):
+if ui.plain('compat'):
+requested = 'compat'
+else:
+requested = ui.config('ui', 'compat', 'compat')
+
+result = {}
+for level, configs in COMPAT.items():
+result.update(configs)
+if level == requested:
+# defaults is sorted. We can abort once we reached
+# the requested level.
+break
+return result
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 6 RFC] ui: don't return certain layers when they are supposed to be displayed

2017-03-12 Thread David Soria Parra
# HG changeset patch
# User David Soria Parra 
# Date 1489349206 25200
#  Sun Mar 12 13:06:46 2017 -0700
# Node ID ef5ce5325596fe5fef014a320abae0f0d5980f3d
# Parent  084a30b54810d05c8b44d22fcab2ef6f783a9f7c
ui: don't return certain layers when they are supposed to be displayed

This is a hack to distinguish visibility for a certain configuration. As we have
layers in place, we can give them a visibility, allowing us to have internal
settings switched on without them showing up in `hg showconfig`. This is useful
for extension to set a list of default flags to trigger behavior.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -360,11 +360,15 @@
 cfg.set(section, name, value, source)
 self.fixconfig(section=section)
 
-def _data(self, untrusted):
+def _data(self, untrusted, includeinternal=True):
+res = {}
+if includeinternal:
+res = self._cfg['defaults']
 if untrusted:
-return self._cfg['user']
+res.update(self._cfg['user'])
 else:
-return self._cfg['trusted']
+res.update(self._cfg['trusted'])
+return res
 
 def configsource(self, section, name, untrusted=False):
 return self._data(untrusted).source(section, name)
@@ -670,7 +674,7 @@
 return items
 
 def walkconfig(self, untrusted=False):
-cfg = self._data(untrusted)
+cfg = self._data(untrusted, includeinternal=False)
 for section in cfg.sections():
 for name, value in self.configitems(section, untrusted):
 yield section, name, value
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 6 RFC] help: document compat mode

2017-03-12 Thread David Soria Parra
# HG changeset patch
# User David Soria Parra 
# Date 1489349206 25200
#  Sun Mar 12 13:06:46 2017 -0700
# Node ID 2dfa752cf0751010867944aa707bd7a722d3ea87
# Parent  8efd04667ba8d2939a937f549e803bc3b56f70a7
help: document compat mode

diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -1837,6 +1837,13 @@
 changes, abort the commit.
 (default: False)
 
+``compat``
+String: Compatibility mode for the ui. Possible values are compat
+or latest (default: compat). ``compat`` provides backwards compatible
+ui behavior. ``latest`` enables additional config settings aiming to
+improve user experience. (see ``HGPLAIN`` for compatibility modes in
+non-interactive environments)
+
 ``debug``
 Print debugging information. (default: False)
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 6 RFC] ui: refactoring handling of trusted, user and overlay

2017-03-12 Thread David Soria Parra
# HG changeset patch
# User David Soria Parra 
# Date 1489349204 25200
#  Sun Mar 12 13:06:44 2017 -0700
# Node ID 99514a82d5b23c75bd6da38e522acfd14a618c14
# Parent  1c3352d7eaf24533ad52d4b8a024211e9189fb0b
ui: refactoring handling of trusted, user and overlay

We are using obscure names such as _ocfg for overlay-config in the UI. This is
sometimes confusing and not very flexible. We are moving this into a dictionary
now that has a specific ordering in which we would apply multiple layers of
configuration. At the moment this is not needed as we always pick either
user-config or trusted-config and overlay it, but it gets us a good machinery to
add a defaults layer for ui.compat.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -146,9 +146,7 @@
 self._bufferapplylabels = None
 self.quiet = self.verbose = self.debugflag = self.tracebackflag = False
 self._reportuntrusted = True
-self._ocfg = config.config() # overlay
-self._tcfg = config.config() # trusted
-self._ucfg = config.config() # untrusted
+self._cfg = self.cfg()
 self._trustusers = set()
 self._trustgroups = set()
 self.callhooks = True
@@ -167,10 +165,6 @@
 self.fin = src.fin
 self.pageractive = src.pageractive
 self._disablepager = src._disablepager
-
-self._tcfg = src._tcfg.copy()
-self._ucfg = src._ucfg.copy()
-self._ocfg = src._ocfg.copy()
 self._trustusers = src._trustusers.copy()
 self._trustgroups = src._trustgroups.copy()
 self.environ = src.environ
@@ -179,6 +173,8 @@
 self._colormode = src._colormode
 self._terminfoparams = src._terminfoparams.copy()
 self._styles = src._styles.copy()
+for k in self._cfg.keys():
+self._cfg[k] = src._cfg[k].copy()
 
 self.fixconfig()
 
@@ -296,21 +292,28 @@
 del cfg['templatealias'][k]
 
 if trusted:
-self._tcfg.update(cfg)
-self._tcfg.update(self._ocfg)
-self._ucfg.update(cfg)
-self._ucfg.update(self._ocfg)
+self._cfg['trusted'].update(cfg)
+self._cfg['trusted'].update(self._cfg['overlay'])
+self._cfg['user'].update(cfg)
+self._cfg['user'].update(self._cfg['overlay'])
 
 if root is None:
 root = os.path.expanduser('~')
 self.fixconfig(root=root)
 
+def cfg(self):
+# Ordered in ascneding order of preference.
+return util.sortdict(
+[('user', config.config()),
+('trusted', config.config()),
+('overlay', config.config())])
+
 def fixconfig(self, root=None, section=None):
 if section in (None, 'paths'):
 # expand vars and ~
 # translate paths relative to root (or home) into absolute paths
 root = root or pycompat.getcwd()
-for c in self._tcfg, self._ucfg, self._ocfg:
+for c in self._cfg.values():
 for n, p in c.items('paths'):
 # Ignore sub-options.
 if ':' in n:
@@ -345,21 +348,22 @@
 self._trustgroups.update(self.configlist('trusted', 'groups'))
 
 def backupconfig(self, section, item):
-return (self._ocfg.backup(section, item),
-self._tcfg.backup(section, item),
-self._ucfg.backup(section, item),)
+return {k: cfg.backup(section, item) for k, cfg in self._cfg.items()}
+
 def restoreconfig(self, data):
-self._ocfg.restore(data[0])
-self._tcfg.restore(data[1])
-self._ucfg.restore(data[2])
+for k, d in data.items():
+self._cfg[k].restore(d)
 
 def setconfig(self, section, name, value, source=''):
-for cfg in (self._ocfg, self._tcfg, self._ucfg):
+for cfg in self._cfg.values():
 cfg.set(section, name, value, source)
 self.fixconfig(section=section)
 
 def _data(self, untrusted):
-return untrusted and self._ucfg or self._tcfg
+if untrusted:
+return self._cfg['user']
+else:
+return self._cfg['trusted']
 
 def configsource(self, section, name, untrusted=False):
 return self._data(untrusted).source(section, name)
@@ -380,7 +384,7 @@
 
 if self.debugflag and not untrusted and self._reportuntrusted:
 for n in alternates:
-uvalue = self._ucfg.get(section, n)
+uvalue = self._cfg['user'].get(section, n)
 if uvalue is not None and uvalue != value:
 self.debug("ignoring untrusted configuration option "
"%s.%s = %s\n" % (section, n, uvalue))
@@ -399,7 +403,7 @@
 data = self._data(untrusted)
 main = data.get(section, name, default)
 if 

[PATCH 2 of 6 RFC] ui: add a defaults layer to the config

2017-03-12 Thread David Soria Parra
# HG changeset patch
# User David Soria Parra 
# Date 1489349206 25200
#  Sun Mar 12 13:06:46 2017 -0700
# Node ID 084a30b54810d05c8b44d22fcab2ef6f783a9f7c
# Parent  99514a82d5b23c75bd6da38e522acfd14a618c14
ui: add a defaults layer to the config

Add a defaults layer to the config that has the least precedence. This will
allow us to load defaults based on compatibility settings without interferring
with trusted or user.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -304,7 +304,8 @@
 def cfg(self):
 # Ordered in ascneding order of preference.
 return util.sortdict(
-[('user', config.config()),
+[('defaults', config.config()),
+('user', config.config()),
 ('trusted', config.config()),
 ('overlay', config.config())])
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] rebase: move state serialization to use unfiltered repo

2017-03-12 Thread Augie Fackler
On Sun, Mar 12, 2017 at 12:41:25PM -0700, Durham Goode wrote:
> # HG changeset patch
> # User Durham Goode 
> # Date 1489347215 25200
> #  Sun Mar 12 12:33:35 2017 -0700
> # Node ID ec3731bcacca0a6c65da08e20f7784bdd210161d
> # Parent  718a57e95a897f4ac407ae3733a7d41e87354acb
> rebase: move state serialization to use unfiltered repo

queued

>
> Now that rebasestate is serialized as part of the transaction, the repo state 
> it
> sees is the version at the end of the transaction, which may have hidden 
> nodes.
> Therefore, it's possible parts of the rebase commit set are no longer visible 
> by
> the time the transaction is closing, which causes a filtered revision error in
> this code. I don't think state serialization should be blocked from accessing
> commits it knows exist, especially if all it's trying to do is get the hex of
> them, so let's use an unfiltered repo here.
>
> Unfortunately, the only known repro is with the fbamend Facebook extension, so
> I'm not sure how to repro it in core Mercurial for a test.
>
> diff --git a/hgext/rebase.py b/hgext/rebase.py
> --- a/hgext/rebase.py
> +++ b/hgext/rebase.py
> @@ -169,7 +169,7 @@ class rebaseruntime(object):
>  self._writestatus(f)
>
>  def _writestatus(self, f):
> -repo = self.repo
> +repo = self.repo.unfiltered()
>  f.write(repo[self.originalwd].hex() + '\n')
>  f.write(repo[self.target].hex() + '\n')
>  f.write(repo[self.external].hex() + '\n')
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] config: avoid using a mutable default

2017-03-12 Thread Martijn Pieters
# HG changeset patch
# User Martijn Pieters 
# Date 1489348572 25200
#  Sun Mar 12 12:56:12 2017 -0700
# Node ID 22c38e571b5ccf3bb6d9f075526170954843f37a
# Parent  719e64bf9ec2d7b8e86b6550a5d193b3c67944d1
config: avoid using a mutable default

Nothing *currently* mutates this list, but the moment something does it'll be
shared between all config instances. Avoid this eventuality.

diff --git a/mercurial/config.py b/mercurial/config.py
--- a/mercurial/config.py
+++ b/mercurial/config.py
@@ -18,11 +18,11 @@
 )
 
 class config(object):
-def __init__(self, data=None, includepaths=[]):
+def __init__(self, data=None, includepaths=None):
 self._data = {}
 self._source = {}
 self._unset = []
-self._includepaths = includepaths
+self._includepaths = includepaths or []
 if data:
 for k in data._data:
 self._data[k] = data[k].copy()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 02 of 12 py3] files: use native string type to load rev opt from dict

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489297860 18000
#  Sun Mar 12 00:51:00 2017 -0500
# Node ID 82cbf9cd26c318c4f3efa2e01d32f226c492cd11
# Parent  90b52b8ab62de4417fe13b06e52e9ff312bb30f9
files: use native string type to load rev opt from dict

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2083,7 +2083,7 @@ def files(ui, repo, *pats, **opts):
 Returns 0 if a match is found, 1 otherwise.
 
 """
-ctx = scmutil.revsingle(repo, opts.get('rev'), None)
+ctx = scmutil.revsingle(repo, opts.get(r'rev'), None)
 
 end = '\n'
 if opts.get('print0'):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 11 of 12 py3] py3: prove `hg files --rev` works

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489304018 14400
#  Sun Mar 12 03:33:38 2017 -0400
# Node ID a7ce480c925f8f904bdbf590a4e94529956cc48f
# Parent  1791e8b68cec47943ca97fc58c45fb69f2fa895c
py3: prove `hg files --rev` works

diff --git a/tests/test-check-py3-commands.t b/tests/test-check-py3-commands.t
--- a/tests/test-check-py3-commands.t
+++ b/tests/test-check-py3-commands.t
@@ -14,6 +14,46 @@ The full traceback is hidden to have a s
   debuginstall
   no problems detected
 
+#if test-repo
+Make a clone so that any features in the developer's .hg/hgrc that
+might confuse Python 3 don't break this test. When we can do commit in
+Python 3, we'll stop doing this. We use e76ed1e480ef for the clone
+because it has different files than 273ce12ad8f1, so we can test both
+`files` from dirstate and `files` loaded from a specific revision.
+
+  $ hg clone -r e76ed1e480ef "`dirname "$TESTDIR"`" testrepo 2>&1 | tail -1
+  15 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+Test using -R, which exercises some URL code:
+  $ $PYTHON3 $HGBIN -R testrepo files -r 273ce12ad8f1 | tail -1
+  testrepo/tkmerge
+
+Now prove `hg files` is reading the whole manifest. We have to grep
+out some potential warnings that come from hgrc as yet.
+  $ cd testrepo
+  $ $PYTHON3 $HGBIN files -r 273ce12ad8f1
+  .hgignore
+  PKG-INFO
+  README
+  hg
+  mercurial/__init__.py
+  mercurial/byterange.py
+  mercurial/fancyopts.py
+  mercurial/hg.py
+  mercurial/mdiff.py
+  mercurial/revlog.py
+  mercurial/transaction.py
+  notes.txt
+  setup.py
+  tkmerge
+
+  $ $PYTHON3 $HGBIN files -r 273ce12ad8f1 | wc -l
+  \s*14 (re)
+  $ $PYTHON3 $HGBIN files | wc -l
+  \s*15 (re)
+  $ cd ..
+#endif
+
   $ cat > included-hgrc < [extensions]
   > babar = imaginary_elephant
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 04 of 12 py3] manifest: use node.bin instead of .decode('hex')

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489303788 14400
#  Sun Mar 12 03:29:48 2017 -0400
# Node ID 65576cf9d641ace0f86c3b359cf9baa07c8a100d
# Parent  90450bdc25b4adba9e4941b62f3b77c264636842
manifest: use node.bin instead of .decode('hex')

The latter doesn't work in Python 3.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -12,6 +12,7 @@ import os
 import struct
 
 from .i18n import _
+from .node import bin
 from . import (
 error,
 mdiff,
@@ -151,7 +152,7 @@ class lazymanifestiterentries(object):
 __next__ = next
 
 def unhexlify(data, extra, pos, length):
-s = data[pos:pos + length].decode('hex')
+s = bin(data[pos:pos + length])
 if extra:
 s += chr(extra & 0xff)
 return s
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 05 of 12 py3] manifest: now that node.bin is available, use it directly

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489303815 14400
#  Sun Mar 12 03:30:15 2017 -0400
# Node ID 9b0c4bba327a1c1809fc5e7da184c695561e272c
# Parent  65576cf9d641ace0f86c3b359cf9baa07c8a100d
manifest: now that node.bin is available, use it directly

Previously we were getting it through revlog, which is a little unusual.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -38,9 +38,9 @@ def _parsev1(data):
 prev = l
 f, n = l.split('\0')
 if len(n) > 40:
-yield f, revlog.bin(n[:40]), n[40:]
+yield f, bin(n[:40]), n[40:]
 else:
-yield f, revlog.bin(n), ''
+yield f, bin(n), ''
 
 def _parsev2(data):
 metadataend = data.find('\n')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 10 of 12 py3] tests: make a variable for hg binary location in test-check-py3-commands

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489304265 14400
#  Sun Mar 12 03:37:45 2017 -0400
# Node ID 1791e8b68cec47943ca97fc58c45fb69f2fa895c
# Parent  600b4b0de4f01e4cdafb538805cb46e933b8c2a9
tests: make a variable for hg binary location in test-check-py3-commands

The number of which calls in here is starting to get silly.

diff --git a/tests/test-check-py3-commands.t b/tests/test-check-py3-commands.t
--- a/tests/test-check-py3-commands.t
+++ b/tests/test-check-py3-commands.t
@@ -3,10 +3,11 @@
 This test helps in keeping a track on which commands we can run on
 Python 3 and see what kind of errors are coming up.
 The full traceback is hidden to have a stable output.
+  $ HGBIN=`which hg`
 
   $ for cmd in version debuginstall ; do
   >   echo $cmd
-  >   $PYTHON3 `which hg` $cmd 2>&1 2>&1 | tail -1
+  >   $PYTHON3 $HGBIN $cmd 2>&1 2>&1 | tail -1
   > done
   version
   warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -20,7 +21,7 @@ The full traceback is hidden to have a s
   $ cat >> $HGRCPATH < %include $TESTTMP/included-hgrc
   > EOF
-  $ $PYTHON3 `which hg` version | tail -1
+  $ $PYTHON3 $HGBIN version | tail -1
   *** failed to import extension babar from imaginary_elephant: *: 
'imaginary_elephant' (glob)
   warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 06 of 12 py3] manifest: ensure paths are bytes (not str) in pure parser

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489303914 14400
#  Sun Mar 12 03:31:54 2017 -0400
# Node ID 5a0a53d127726a34013a34156d47ab873f6dc8df
# Parent  9b0c4bba327a1c1809fc5e7da184c695561e272c
manifest: ensure paths are bytes (not str) in pure parser

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -255,8 +255,8 @@ class _lazymanifest(object):
 return self.data[start:end]
 
 def __getitem__(self, key):
-if not isinstance(key, str):
-raise TypeError("getitem: manifest keys must be a string.")
+if not isinstance(key, bytes):
+raise TypeError("getitem: manifest keys must be a bytes.")
 needle = self.bsearch(key)
 if needle == -1:
 raise KeyError
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 03 of 12 py3] manifest: add __next__ methods for Python 3

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489297400 18000
#  Sun Mar 12 00:43:20 2017 -0500
# Node ID 90450bdc25b4adba9e4941b62f3b77c264636842
# Parent  82cbf9cd26c318c4f3efa2e01d32f226c492cd11
manifest: add __next__ methods for Python 3

Python 3 renamed .next() in the iterator protocol to __next__().

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -123,6 +123,8 @@ class lazymanifestiter(object):
 zeropos = data.find('\x00', pos)
 return data[pos:zeropos]
 
+__next__ = next
+
 class lazymanifestiterentries(object):
 def __init__(self, lm):
 self.lm = lm
@@ -146,6 +148,8 @@ class lazymanifestiterentries(object):
 self.pos += 1
 return (data[pos:zeropos], hashval, flags)
 
+__next__ = next
+
 def unhexlify(data, extra, pos, length):
 s = data[pos:pos + length].decode('hex')
 if extra:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 12 of 12 py3] revlog: use bytes() instead of str() to get data from memoryview

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489346822 14400
#  Sun Mar 12 15:27:02 2017 -0400
# Node ID 6c5c0c483a25af9a1a2ebdbc6acadfdd072354d6
# Parent  a7ce480c925f8f904bdbf590a4e94529956cc48f
revlog: use bytes() instead of str() to get data from memoryview

Fixes `files -v` on Python 3.

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -1234,7 +1234,7 @@ class revlog(object):
 def revdiff(self, rev1, rev2):
 """return or calculate a delta between two revisions"""
 if rev1 != nullrev and self.deltaparent(rev2) == rev1:
-return str(self._chunk(rev2))
+return bytes(self._chunk(rev2))
 
 return mdiff.textdiff(self.revision(rev1),
   self.revision(rev2))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 01 of 12 py3] store: fix many single-byte ops to use slicing in _auxencode

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489297844 18000
#  Sun Mar 12 00:50:44 2017 -0500
# Node ID 90b52b8ab62de4417fe13b06e52e9ff312bb30f9
# Parent  8a17c541177f32348e248608b6a9dfd7fefdf517
store: fix many single-byte ops to use slicing in _auxencode

diff --git a/mercurial/store.py b/mercurial/store.py
--- a/mercurial/store.py
+++ b/mercurial/store.py
@@ -193,22 +193,22 @@ def _auxencode(path, dotencode):
 if not n:
 continue
 if dotencode and n[0] in '. ':
-n = "~%02x" % ord(n[0]) + n[1:]
+n = "~%02x" % ord(n[0:1]) + n[1:]
 path[i] = n
 else:
 l = n.find('.')
 if l == -1:
 l = len(n)
 if ((l == 3 and n[:3] in _winres3) or
-(l == 4 and n[3] <= '9' and n[3] >= '1'
+(l == 4 and n[3:4] <= '9' and n[3:4] >= '1'
 and n[:3] in _winres4)):
 # encode third letter ('aux' -> 'au~78')
-ec = "~%02x" % ord(n[2])
+ec = "~%02x" % ord(n[2:3])
 n = n[0:2] + ec + n[3:]
 path[i] = n
 if n[-1] in '. ':
 # encode last period or space ('foo...' -> 'foo..~2e')
-path[i] = n[:-1] + "~%02x" % ord(n[-1])
+path[i] = n[:-1] + "~%02x" % ord(n[-1:])
 return path
 
 _maxstorepathlen = 120
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 08 of 12 py3] encoding: make encoding.encoding be a native str and add encodingb

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489303712 14400
#  Sun Mar 12 03:28:32 2017 -0400
# Node ID 19f6f41baa5ef326d3cc953093c5d7ff5dcc4427
# Parent  84996257b560fa41535e4d0360cb33436662581c
encoding: make encoding.encoding be a native str and add encodingb

It turns out we need the encoding name both ways. Ugh.

diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -965,7 +965,7 @@ def debuginstall(ui, **opts):
 fm.startitem()
 
 # encoding
-fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
+fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encodingb)
 err = None
 try:
 encoding.fromlocal("test")
diff --git a/mercurial/encoding.py b/mercurial/encoding.py
--- a/mercurial/encoding.py
+++ b/mercurial/encoding.py
@@ -100,6 +100,11 @@ except locale.Error:
 encodingmode = environ.get("HGENCODINGMODE", "strict")
 fallbackencoding = 'ISO-8859-1'
 
+encodingb = encoding
+if pycompat.ispy3:
+# TODO: are all encodings sure to be ascii names?
+encoding = encoding.decode('ascii')
+
 class localstr(str):
 '''This class allows strings that are unmodified to be
 round-tripped to the local encoding and back'''
diff --git a/tests/test-check-code.t b/tests/test-check-code.t
--- a/tests/test-check-code.t
+++ b/tests/test-check-code.t
@@ -22,7 +22,7 @@ New errors are not allowed. Warnings are
   mercurial/encoding.py:61:
>for k, v in os.environ.items())
use encoding.environ instead (py3)
-  mercurial/encoding.py:203:
+  mercurial/encoding.py:208:
>for k, v in os.environ.items())
use encoding.environ instead (py3)
   Skipping mercurial/httpclient/__init__.py it has no-che?k-code (glob)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 09 of 12 py3] lock: encode result of gethostname into a bytestring

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489303730 14400
#  Sun Mar 12 03:28:50 2017 -0400
# Node ID 600b4b0de4f01e4cdafb538805cb46e933b8c2a9
# Parent  19f6f41baa5ef326d3cc953093c5d7ff5dcc4427
lock: encode result of gethostname into a bytestring

diff --git a/mercurial/lock.py b/mercurial/lock.py
--- a/mercurial/lock.py
+++ b/mercurial/lock.py
@@ -15,6 +15,7 @@ import time
 import warnings
 
 from . import (
+encoding,
 error,
 pycompat,
 util,
@@ -27,7 +28,7 @@ def _getlockprefix():
 confidence. Typically it's just hostname. On modern linux, we include an
 extra Linux-specific pid namespace identifier.
 """
-result = socket.gethostname()
+result = socket.gethostname().encode(encoding.encoding, 'replace')
 if pycompat.sysplatform.startswith('linux'):
 try:
 result += '/%x' % os.stat('/proc/self/ns/pid').st_ino
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 07 of 12 py3] util: teach url object about __bytes__

2017-03-12 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1489304002 14400
#  Sun Mar 12 03:33:22 2017 -0400
# Node ID 84996257b560fa41535e4d0360cb33436662581c
# Parent  5a0a53d127726a34013a34156d47ab873f6dc8df
util: teach url object about __bytes__

__str__ tries to do something reasonable, but someone else more
familiar with encoding bugs should check my work.

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -2651,6 +2651,11 @@ class url(object):
 >>> print url(r'file:///D:\data\hg')
 file:///D:\data\hg
 """
+if pycompat.ispy3:
+return encoding.fromlocal(self.__bytes__()).decode('utf-8')
+return self.__bytes__()
+
+def __bytes__(self):
 if self._localpath:
 s = self.path
 if self.scheme == 'bundle':
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 4 of 5 V2] util: add a getfstype method

2017-03-12 Thread Jun Wu
Excerpts from Yuya Nishihara's message of 2017-03-12 12:26:57 -0700:
> On Sun, 12 Mar 2017 12:06:32 -0700, Jun Wu wrote:
> > Excerpts from Yuya Nishihara's message of 2017-03-12 11:58:40 -0700:
> > > > That's good to know. I actually had 3 patches to move it to vfs, but was
> > > > concerned about the future "repostorage" layer holding vfs objects that
> > > > won't get invalidated across chg workers.
> > > 
> > > If the filesystem at the cached repository location changed, cache should 
> > > be
> > > invalidated and repostorage would be recreated anyway.
> > 
> > Even if location does not change, the user can run "mount" to change the
> > "mtab" that affects us.
> 
> My point is that the repository should be considered changed if he mounted
> another filesystem onto that location. vfs caches cansymlink, execflag, etc.,
> which are all invalid.

My very early idea about chgcache is that we cache things at a very
low-level and vfs is only used to help calculate the hash, vfs is not
cached.

It's like:

# in master's preload process
def preloadfunc(repo, )
hash = repo.vfs # vfs is constructed by the preloading framework
# repo is a faked one which will be dropped

# in the worker
def preloading(repo, ...)
hash = repo.vfs # vfs is new, different from the above
# repo is the real one

To be clear, it seems there are two objects that "repostorage" may want to
do:

1. A cheap object with vfs, svfs etc. helping to calculate hashes, but
   is designed to be dropped by the preloading process and not reused by
   workers.

   My current plan is to just use a "faked" localrepository object in
   the master. With some methods patched to reduce features.

   It seems that may be actually cleaner as the faked repo cannot be
   reused, and vfs will be dropped correctly.

2. An object providing accesses to chg caches.

   That is the "chgcacche.repocache" object in this series.
> 
> > Querying "mtab" confidently is expensive. And "mtab" can answer all vfs
> > queries. So I think it's better to cache "mtab" per process, instead of
> > caching "fstype" per vfs.
> 
> I won't object to it if it can be implemented cleanly.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] rebase: move state serialization to use unfiltered repo

2017-03-12 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1489347215 25200
#  Sun Mar 12 12:33:35 2017 -0700
# Node ID ec3731bcacca0a6c65da08e20f7784bdd210161d
# Parent  718a57e95a897f4ac407ae3733a7d41e87354acb
rebase: move state serialization to use unfiltered repo

Now that rebasestate is serialized as part of the transaction, the repo state it
sees is the version at the end of the transaction, which may have hidden nodes.
Therefore, it's possible parts of the rebase commit set are no longer visible by
the time the transaction is closing, which causes a filtered revision error in
this code. I don't think state serialization should be blocked from accessing
commits it knows exist, especially if all it's trying to do is get the hex of
them, so let's use an unfiltered repo here.

Unfortunately, the only known repro is with the fbamend Facebook extension, so
I'm not sure how to repro it in core Mercurial for a test.

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -169,7 +169,7 @@ class rebaseruntime(object):
 self._writestatus(f)
 
 def _writestatus(self, f):
-repo = self.repo
+repo = self.repo.unfiltered()
 f.write(repo[self.originalwd].hex() + '\n')
 f.write(repo[self.target].hex() + '\n')
 f.write(repo[self.external].hex() + '\n')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH V2] py3: add "b" prefix to string literals related to module policy

2017-03-12 Thread Augie Fackler
On Mon, Mar 13, 2017 at 04:13:55AM +0900, FUJIWARA Katsunori wrote:
> # HG changeset patch
> # User FUJIWARA Katsunori 
> # Date 1489345596 -32400
> #  Mon Mar 13 04:06:36 2017 +0900
> # Node ID 2526bffdc7f01acb4e0f77865fce0ffab675250f
> # Parent  62939e0148f170b67ca8c7374f36c413b67fd387
> py3: add "b" prefix to string literals related to module policy

Queued, thanks.

>
> String literals without explicit prefix in __init__.py and policy.py
> are treated as unicode object on Python3, because these modules are
> loaded before setup of our specific code transformation (the later
> module is imported at the beginning of __init__.py).
>
> BTW, "modulepolicy" in __init__.py is initialized by "policy.policy".
>
> This causes issues below;
>
>   - checking "policy" value in other modules causes unintentional result
>
> For example, "b'py' not in (u'c', u'py')" returns True
> unintentionally on Python3.
>
>   - writing "policy" out fails at conversion from unicode to bytes
>
> 62939e0148f1 fixed this issue for default code path, but "policy"
> can be overridden by HGMODULEPOLICY environment variable (it should
> be rare case for developer using Python3, though).
>
> This patch does:
>
>   - add "b" prefix to all string literals, which are related to module
> policy, in modules above.
>
>   - check existence of HGMODULEPOLICY, and overwrite "policy" only if
> it exists
>
> For simplicity, this patch omits checking "supports_bytes_environ",
> switching os.environ/os.environb, and so on (Yuya agreed this in
> personal talking)
>
> diff --git a/mercurial/__init__.py b/mercurial/__init__.py
> --- a/mercurial/__init__.py
> +++ b/mercurial/__init__.py
> @@ -68,7 +68,7 @@ class hgimporter(object):
>  # indicates the type of module. So just assume what we found
>  # is OK (even though it could be a pure Python module).
>  except ImportError:
> -if modulepolicy == 'c':
> +if modulepolicy == b'c':
>  raise
>  zl = ziploader('mercurial', 'pure')
>  mod = zl.load_module(name)
> @@ -106,7 +106,7 @@ class hgimporter(object):
>'version should exist' % name)
>
>  except ImportError:
> -if modulepolicy == 'c':
> +if modulepolicy == b'c':
>  raise
>
>  # Could not load the C extension and pure Python is allowed. So
> diff --git a/mercurial/policy.py b/mercurial/policy.py
> --- a/mercurial/policy.py
> +++ b/mercurial/policy.py
> @@ -19,9 +19,9 @@ import sys
>  #py - only load pure Python modules
>  #
>  # By default, require the C extensions for performance reasons.
> -policy = 'c'
> -policynoc = ('cffi', 'cffi-allow', 'py')
> -policynocffi = ('c', 'py')
> +policy = b'c'
> +policynoc = (b'cffi', b'cffi-allow', b'py')
> +policynocffi = (b'c', b'py')
>
>  try:
>  from . import __modulepolicy__
> @@ -42,4 +42,8 @@ if sys.version_info[0] >= 3:
>  policy = b'py'
>
>  # Environment variable can always force settings.
> -policy = os.environ.get('HGMODULEPOLICY', policy)
> +if sys.version_info[0] >= 3:
> +if 'HGMODULEPOLICY' in os.environ:
> +policy = os.environ['HGMODULEPOLICY'].encode('utf-8')
> +else:
> +policy = os.environ.get('HGMODULEPOLICY', policy)
> diff --git a/tests/test-check-code.t b/tests/test-check-code.t
> --- a/tests/test-check-code.t
> +++ b/tests/test-check-code.t
> @@ -27,8 +27,14 @@ New errors are not allowed. Warnings are
> use encoding.environ instead (py3)
>Skipping mercurial/httpclient/__init__.py it has no-che?k-code (glob)
>Skipping mercurial/httpclient/_readers.py it has no-che?k-code (glob)
> -  mercurial/policy.py:45:
> -   > policy = os.environ.get('HGMODULEPOLICY', policy)
> +  mercurial/policy.py:46:
> +   > if 'HGMODULEPOLICY' in os.environ:
> +   use encoding.environ instead (py3)
> +  mercurial/policy.py:47:
> +   > policy = os.environ['HGMODULEPOLICY'].encode('utf-8')
> +   use encoding.environ instead (py3)
> +  mercurial/policy.py:49:
> +   > policy = os.environ.get('HGMODULEPOLICY', policy)
> use encoding.environ instead (py3)
>Skipping mercurial/statprof.py it has no-che?k-code (glob)
>[1]
> diff --git a/tests/test-check-py3-commands.t b/tests/test-check-py3-commands.t
> --- a/tests/test-check-py3-commands.t
> +++ b/tests/test-check-py3-commands.t
> @@ -23,3 +23,10 @@ The full traceback is hidden to have a s
>$ $PYTHON3 `which hg` version | tail -1
>*** failed to import extension babar from imaginary_elephant: *: 
> 'imaginary_elephant' (glob)
>warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> +
> +Test bytes-ness of policy.policy with HGMODULEPOLICY
> +
> +  $ HGMODULEPOLICY=py
> +  $ export HGMODULEPOLICY
> +  $ $PYTHON3 `which hg` debuginstall 2>&1 2>&1 | tail -1
> +  no problems detected
> 

Re: [PATCH RFC] ui: introduce sysdefault section for pager and editor configuration

2017-03-12 Thread Jun Wu
What if instead of reading environments directly, introduce a new config
layer which is converted from environment variables? Like:

  - (Top)layer: command line config flags
  -  layer: user configs
  -  layer: config converted from environment variables
like, convert "HGEDITOR" to "ui.editor"
  - (Bottom) layer: system configs

In this way, we don't need a [sysdefault] and can just put things in /etc.
And that will solve other problems like:

   ryanmce's complaint to me yesterday was HGEDITOR=vim hg
--config ui.editor=true foo   would run vim, even though editor is
'specified on command line'...

Excerpts from Augie Fackler's message of 2017-03-08 18:48:55 -0500:
> # HG changeset patch
> # User Augie Fackler 
> # Date 1489016567 18000
> #  Wed Mar 08 18:42:47 2017 -0500
> # Node ID 71fc64c48cfff1b7a2120c60e2b958da3263c0dc
> # Parent  92f7d6585c185e85763b3bad81b1304b8cdb5937
> ui: introduce sysdefault section for pager and editor configuration
> 
> The debian package currently has to patch Mercurial to move the
> default editor from `vi` to `sensible-editor`. Now that we're growing
> another suboptimal-on-most-platforms default program (`more` as the
> pager), let's do packagers a small favor and give them a place where
> they can specify the default program for their platform, rather than
> having to rely on patching code during the build process. I'd expect
> the configuration on OS X to be something like:
> 
> [sysdefault]
> editor = nano
> pager = LESS=FRX less
> 
> and on debian to be:
> 
> [sysdefault]
> editor = sensible-editor
> pager = sensible-pager
> 
> diff --git a/mercurial/ui.py b/mercurial/ui.py
> --- a/mercurial/ui.py
> +++ b/mercurial/ui.py
> @@ -907,13 +907,11 @@ class ui(object):
>  # HGPLAINEXCEPT=pager, and the user didn't specify --debug.
>  return
>  
> -# TODO: add a "system defaults" config section so this default
> -# of more(1) can be easily replaced with a global
> -# configuration file. For example, on OS X the sane default is
> -# less(1), not more(1), and on debian it's
> -# sensible-pager(1). We should probably also give the system
> -# default editor command similar treatment.
> -envpager = encoding.environ.get('PAGER', 'more')
> +# sysdefault.pager is available for packagers or system
> +# administrators to specify a saner default pager for their
> +# environment.
> +defaultpager = self.config('sysdefault', 'pager', default='more')
> +envpager = encoding.environ.get('PAGER', defaultpager)
>  pagercmd = self.config('pager', 'pager', envpager)
>  if not pagercmd:
>  return
> @@ -1348,6 +1346,10 @@ class ui(object):
>  editor = 'E'
>  else:
>  editor = 'vi'
> +# sysdefault.editor is available for packagers or system
> +# administrators to specify a saner default editor for their
> +# environment.
> +editor = self.config("sysdefault", "editor", default=editor)
>  return (encoding.environ.get("HGEDITOR") or
>  self.config("ui", "editor") or
>  encoding.environ.get("VISUAL") or
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] py3: drop unused aliases to array.array which are replaced with bytearray

2017-03-12 Thread Augie Fackler
On Sun, Mar 12, 2017 at 12:08:43PM -0700, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1489344422 25200
> #  Sun Mar 12 11:47:02 2017 -0700
> # Node ID 78cce06ea6c3820626e57704eda821095677a23b
> # Parent  ff6dc91618236ef7a3d315921133b48bbc0d6f89
> py3: drop unused aliases to array.array which are replaced with bytearray

Queued, thanks.

>
> diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
> --- a/mercurial/branchmap.py
> +++ b/mercurial/branchmap.py
> @@ -7,7 +7,6 @@
>
>  from __future__ import absolute_import
>
> -import array
>  import struct
>
>  from .node import (
> @@ -23,7 +22,6 @@ from . import (
>  util,
>  )
>
> -array = array.array
>  calcsize = struct.calcsize
>  pack = struct.pack
>  unpack = struct.unpack
> diff --git a/mercurial/tags.py b/mercurial/tags.py
> --- a/mercurial/tags.py
> +++ b/mercurial/tags.py
> @@ -12,7 +12,6 @@
>
>  from __future__ import absolute_import
>
> -import array
>  import errno
>
>  from .node import (
> @@ -28,8 +27,6 @@ from . import (
>  util,
>  )
>
> -array = array.array
> -
>  # Tags computation can be expensive and caches exist to make it fast in
>  # the common case.
>  #
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2] rbc: empty (and invalid) rbc-names file should give an empty name list

2017-03-12 Thread Mads Kiilerich
# HG changeset patch
# User Mads Kiilerich 
# Date 1489346250 25200
#  Sun Mar 12 12:17:30 2017 -0700
# Node ID 1b5144a87e936fc8071463956816a89041478126
# Parent  023b6f7456b3622cc81332ae9d6e30b7ecc37415
rbc: empty (and invalid) rbc-names file should give an empty name list

An empty file (if it somehow should exist) used to give a list with an empty
name. That didn't do any harm, but it was "wrong". Fix that.

diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -362,7 +362,9 @@ class revbranchcache(object):
 try:
 bndata = repo.vfs.read(_rbcnames)
 self._rbcsnameslen = len(bndata) # for verification before writing
-self._names = [encoding.tolocal(bn) for bn in bndata.split('\0')]
+if bndata:
+self._names = [encoding.tolocal(bn)
+   for bn in bndata.split('\0')]
 except (IOError, OSError):
 if readonly:
 # don't try to use cache - fall back to the slow path
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH py3] pycompat: default to BytesIO instead of StringIO

2017-03-12 Thread Augie Fackler
On Mon, Mar 13, 2017 at 12:57:06AM +0530, Pulkit Goyal wrote:
> # HG changeset patch
> # User Pulkit Goyal <7895pul...@gmail.com>
> # Date 1489346714 -19800
> #  Mon Mar 13 00:55:14 2017 +0530
> # Node ID 047e7ee79f6a30b295bf02fa23171212848546f6
> # Parent  719e64bf9ec2d7b8e86b6550a5d193b3c67944d1
> pycompat: default to BytesIO instead of StringIO

Queued, thanks.

>
> diff -r 719e64bf9ec2 -r 047e7ee79f6a mercurial/pycompat.py
> --- a/mercurial/pycompat.py   Sun Mar 12 00:47:39 2017 -0500
> +++ b/mercurial/pycompat.py   Mon Mar 13 00:55:14 2017 +0530
> @@ -55,6 +55,7 @@
>  sysexecutable = sys.executable
>  if sysexecutable:
>  sysexecutable = os.fsencode(sysexecutable)
> +stringio = io.BytesIO
>
>  # TODO: .buffer might not exist if std streams were replaced; we'll need
>  # a silly wrapper to make a bytes stream backed by a unicode one.
> @@ -180,8 +181,8 @@
>  getcwd = os.getcwd
>  sysexecutable = sys.executable
>  shlexsplit = shlex.split
> +stringio = io.StringIO
>
> -stringio = io.StringIO
>  empty = _queue.Empty
>  queue = _queue.Queue
>
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 2] rbc: use struct unpack_from and pack_into instead of unpack and pack

2017-03-12 Thread Mads Kiilerich
# HG changeset patch
# User Mads Kiilerich 
# Date 1476837995 -7200
#  Wed Oct 19 02:46:35 2016 +0200
# Node ID 023b6f7456b3622cc81332ae9d6e30b7ecc37415
# Parent  1c3352d7eaf24533ad52d4b8a024211e9189fb0b
rbc: use struct unpack_from and pack_into instead of unpack and pack

These functions were introduced in Python 2.5 and are faster and simpler than
the old ones ...  mainly because we can avoid intermediate buffers:

  $ python -m timeit -s "_rbcrecfmt='>4sI'" -s 's = "x"*1' -s 'from struct 
import unpack' 'unpack(_rbcrecfmt, buffer(s, 16, 8))'
  100 loops, best of 3: 0.543 usec per loop
  $ python -m timeit -s "_rbcrecfmt='>4sI'" -s 's = "x"*1' -s 'from struct 
import unpack_from' 'unpack_from(_rbcrecfmt, s, 16)'
  100 loops, best of 3: 0.323 usec per loop

  $ python -m timeit -s "from array import array" -s "_rbcrecfmt='>4sI'" -s "s 
= array('c')" -s 's.fromstring("x"*1)' -s 'from struct import pack' -s "rec 
= array('c')" 'rec.fromstring(pack(_rbcrecfmt, "asdf", 7))'
  100 loops, best of 3: 0.364 usec per loop
  $ python -m timeit -s "from array import array" -s "_rbcrecfmt='>4sI'" -s "s 
= array('c')" -s 's.fromstring("x"*1)' -s 'from struct import pack_into' -s 
"rec = array('c')" -s 'rec.fromstring("x"*100)' 'pack_into(_rbcrecfmt, rec, 0, 
"asdf", 7)'
  100 loops, best of 3: 0.229 usec per loop

diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -25,8 +25,8 @@ from . import (
 
 array = array.array
 calcsize = struct.calcsize
-pack = struct.pack
-unpack = struct.unpack
+pack_into = struct.pack_into
+unpack_from = struct.unpack_from
 
 def _filename(repo):
 """name of a branchcache file for a given repo or repoview"""
@@ -409,8 +409,7 @@ class revbranchcache(object):
 
 # fast path: extract data from cache, use it if node is matching
 reponode = changelog.node(rev)[:_rbcnodelen]
-cachenode, branchidx = unpack(
-_rbcrecfmt, buffer(self._rbcrevs, rbcrevidx, _rbcrecsize))
+cachenode, branchidx = unpack_from(_rbcrecfmt, self._rbcrevs, 
rbcrevidx)
 close = bool(branchidx & _rbccloseflag)
 if close:
 branchidx &= _rbcbranchidxmask
@@ -454,13 +453,11 @@ class revbranchcache(object):
 def _setcachedata(self, rev, node, branchidx):
 """Writes the node's branch data to the in-memory cache data."""
 rbcrevidx = rev * _rbcrecsize
-rec = array('c')
-rec.fromstring(pack(_rbcrecfmt, node, branchidx))
 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
 self._rbcrevs.extend('\0' *
  (len(self._repo.changelog) * _rbcrecsize -
   len(self._rbcrevs)))
-self._rbcrevs[rbcrevidx:rbcrevidx + _rbcrecsize] = rec
+pack_into(_rbcrecfmt, self._rbcrevs, rbcrevidx, node, branchidx)
 self._rbcrevslen = min(self._rbcrevslen, rev)
 
 tr = self._repo.currenttransaction()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH py3] pycompat: default to BytesIO instead of StringIO

2017-03-12 Thread Pulkit Goyal
On Mon, Mar 13, 2017 at 12:59 AM, Gregory Szorc 
wrote:

> On Sun, Mar 12, 2017 at 12:27 PM, Pulkit Goyal <7895pul...@gmail.com>
> wrote:
>
>> # HG changeset patch
>> # User Pulkit Goyal <7895pul...@gmail.com>
>> # Date 1489346714 -19800
>> #  Mon Mar 13 00:55:14 2017 +0530
>> # Node ID 047e7ee79f6a30b295bf02fa23171212848546f6
>> # Parent  719e64bf9ec2d7b8e86b6550a5d193b3c67944d1
>> pycompat: default to BytesIO instead of StringIO
>>
>> diff -r 719e64bf9ec2 -r 047e7ee79f6a mercurial/pycompat.py
>> --- a/mercurial/pycompat.py Sun Mar 12 00:47:39 2017 -0500
>> +++ b/mercurial/pycompat.py Mon Mar 13 00:55:14 2017 +0530
>> @@ -55,6 +55,7 @@
>>  sysexecutable = sys.executable
>>  if sysexecutable:
>>  sysexecutable = os.fsencode(sysexecutable)
>> +stringio = io.BytesIO
>>
>>  # TODO: .buffer might not exist if std streams were replaced; we'll
>> need
>>  # a silly wrapper to make a bytes stream backed by a unicode one.
>> @@ -180,8 +181,8 @@
>>  getcwd = os.getcwd
>>  sysexecutable = sys.executable
>>  shlexsplit = shlex.split
>> +stringio = io.StringIO
>>
>
> Should this attempt to use cStringIO.StringIO?
>
>
​io here refers to cStringIO only.
https://www.mercurial-scm.org/repo/hg-committed/file/tip/mercurial/pycompat.py#l22
​
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 4 of 5 V2] util: add a getfstype method

2017-03-12 Thread Yuya Nishihara
On Sun, 12 Mar 2017 12:06:32 -0700, Jun Wu wrote:
> Excerpts from Yuya Nishihara's message of 2017-03-12 11:58:40 -0700:
> > > That's good to know. I actually had 3 patches to move it to vfs, but was
> > > concerned about the future "repostorage" layer holding vfs objects that
> > > won't get invalidated across chg workers.
> > 
> > If the filesystem at the cached repository location changed, cache should be
> > invalidated and repostorage would be recreated anyway.
> 
> Even if location does not change, the user can run "mount" to change the
> "mtab" that affects us.

My point is that the repository should be considered changed if he mounted
another filesystem onto that location. vfs caches cansymlink, execflag, etc.,
which are all invalid.

> Querying "mtab" confidently is expensive. And "mtab" can answer all vfs
> queries. So I think it's better to cache "mtab" per process, instead of
> caching "fstype" per vfs.

I won't object to it if it can be implemented cleanly.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH py3] pycompat: default to BytesIO instead of StringIO

2017-03-12 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1489346714 -19800
#  Mon Mar 13 00:55:14 2017 +0530
# Node ID 047e7ee79f6a30b295bf02fa23171212848546f6
# Parent  719e64bf9ec2d7b8e86b6550a5d193b3c67944d1
pycompat: default to BytesIO instead of StringIO

diff -r 719e64bf9ec2 -r 047e7ee79f6a mercurial/pycompat.py
--- a/mercurial/pycompat.py Sun Mar 12 00:47:39 2017 -0500
+++ b/mercurial/pycompat.py Mon Mar 13 00:55:14 2017 +0530
@@ -55,6 +55,7 @@
 sysexecutable = sys.executable
 if sysexecutable:
 sysexecutable = os.fsencode(sysexecutable)
+stringio = io.BytesIO
 
 # TODO: .buffer might not exist if std streams were replaced; we'll need
 # a silly wrapper to make a bytes stream backed by a unicode one.
@@ -180,8 +181,8 @@
 getcwd = os.getcwd
 sysexecutable = sys.executable
 shlexsplit = shlex.split
+stringio = io.StringIO
 
-stringio = io.StringIO
 empty = _queue.Empty
 queue = _queue.Queue
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] debugfsinfo: print fstype information

2017-03-12 Thread Jun Wu
Sorry. It's meant to be PATCH 8 of 8. Next time I'll use "--in-reply-to" to
attach it to an existing thread.

Excerpts from Augie Fackler's message of 2017-03-12 11:54:15 -0700:
> 
> > On Mar 12, 2017, at 11:53, Yuya Nishihara  wrote:
> > 
> > On Sun, 12 Mar 2017 14:12:03 -0400, Augie Fackler wrote:
> >> On Sun, Mar 12, 2017 at 01:34:53AM -0800, Jun Wu wrote:
> >>> # HG changeset patch
> >>> # User Jun Wu 
> >>> # Date 1489311257 28800
> >>> #  Sun Mar 12 01:34:17 2017 -0800
> >>> # Node ID ff9af50d033388f74cbaf1eeac1509b3e75da07b
> >>> # Parent  9da40a9e54c419490a2ff23b9dda7acc109f81cd
> >>> # Available At https://bitbucket.org/quark-zju/hg-draft 
> >>> #  hg pull https://bitbucket.org/quark-zju/hg-draft  -r 
> >>> ff9af50d0333
> >>> debugfsinfo: print fstype information
> >> 
> >> Queued, thanks.
> >> 
> >>> 
> >>> Since we have util.getfstype, it'll be handy to use "debugfsinfo" to test
> >>> it.
> >>> 
> >>> diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
> >>> --- a/mercurial/debugcommands.py
> >>> +++ b/mercurial/debugcommands.py
> >>> @@ -791,4 +791,5 @@ def debugfsinfo(ui, path="."):
> >>> util.writefile('.debugfsinfo', '')
> >>> ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
> >>> +ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
> > 
> > It appears debugfsinfo isn't covered by tests.
> > 
> >  $ hg debugfsinfo
> >  exec: yes
> >  ...
> >  ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
> >  AttributeError: 'module' object has no attribute 'getfstype'
> 
> Sigh. Pruning and we'll come back to this. Jun, you'll want to 'hg touch' 
> this patch locally.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[Bug 5499] New: on running command hg bzexport to create a patch

2017-03-12 Thread mercurial-bugs
https://bz.mercurial-scm.org/show_bug.cgi?id=5499

Bug ID: 5499
   Summary: on running command hg bzexport to create a patch
   Product: Mercurial
   Version: unspecified
  Hardware: PC
OS: Windows
Status: UNCONFIRMED
  Severity: feature
  Priority: wish
 Component: Mercurial
  Assignee: bugzi...@mercurial-scm.org
  Reporter: paavinina...@gmail.com
CC: mercurial-devel@mercurial-scm.org

** unknown exception encountered, please report by visiting
** https://mercurial-scm.org/wiki/BugTracker
** Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec  5 2015, 20:32:19) [MSC v.1500 32
bi
t (Intel)]
** Mercurial Distributed SCM (version 3.7.3)
** Extensions loaded: strip, mq, purge, share, transplant, color, pager,
histedi
t, rebase, blackbox, firefoxtree, reviewboard, bzexport, push-to-try
Traceback (most recent call last):
  File "c:/mozilla-build/python/Scripts/hg", line 43, in 
mercurial.dispatch.run()
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\dispatch.py", line
5
4, in run
sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\dispatch.py", line
1
20, in dispatch
ret = _runcatch(req)
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\dispatch.py", line
1
91, in _runcatch
return _dispatch(req)
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\dispatch.py", line
9
24, in _dispatch
cmdpats, cmdoptions)
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\dispatch.py", line
6
81, in runcommand
ret = _runcommand(ui, options, cmd, d)
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\extensions.py",
line
 195, in closure
return func(*(args + a), **kw)
  File "c:\mozilla-build\python\Lib\site-packages\hgext\pager.py", line 143, in
pagecmd
return orig(ui, options, cmd, cmdfunc)
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\extensions.py",
line
 195, in closure
return func(*(args + a), **kw)
  File "c:\mozilla-build\python\Lib\site-packages\hgext\color.py", line 518, in
colorcmd
return orig(ui_, opts, cmd, cmdfunc)
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\dispatch.py", line
1
055, in _runcommand
return checkargs()
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\dispatch.py", line
1
015, in checkargs
return cmdfunc()
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\dispatch.py", line
9
21, in 
d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\util.py", line 991,
in check
return func(*args, **kwargs)
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\extensions.py",
line
 195, in closure
return func(*(args + a), **kw)
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\util.py", line 991,
in check
return func(*args, **kwargs)
  File "c:\mozilla-build\python\Lib\site-packages\hgext\mq.py", line 3517, in
mq
command
return orig(ui, repo, *args, **kwargs)
  File "c:\mozilla-build\python\Lib\site-packages\mercurial\util.py", line 991,
in check
return func(*args, **kwargs)
  File
"c:/Users/hp/.mozbuild/version-control-tools/hgext\bzexport\__init__.py",
 line 915, in bzexport
if desc[0] in ['-', ':', '.']:
IndexError: string index out of range

-- 
You are receiving this mail because:
You are on the CC list for the bug.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 7 of 7 V3] util: enable hardlink for copyfile

2017-03-12 Thread Jun Wu
Excerpts from Mads Kiilerich's message of 2017-03-12 11:48:35 -0700:
> I only see mentioning of problems with Windows on the client side. 
> Matt's theory of the source of the cache coherency issue suggested that 
> it was interaction between client and server side caches. Non-windows 
> client side implementations may or may not have the same problem, but I 
> see nothing suggesting they have.
> 
> That might of course be because most users of repos on CIFS are Windows 
> users. The problem is serious when it happens, but considering the 
> non-Windows uncertainty, the small amount of non-Windows users using 
> CIFS repos, and the negative impact on all non-Windows users, it might 
> be justified to be less conservative for non-Windows.

Per discussion with Augie yesterday, I prefer the very conservative
approach. That's why I added the "_isprocgenuine" check which looks
expensive but will greatly increase our confidence, and spent 2 hours
checking kernel code, doing experiments, and writing the commit message.

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


[PATCH RFC] configoptions: introduce registrar for config options

2017-03-12 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1489346234 25200
#  Sun Mar 12 12:17:14 2017 -0700
# Node ID dd26bc2a3056879181851aaa3ff4accbfc42e1ad
# Parent  62939e0148f170b67ca8c7374f36c413b67fd387
configoptions: introduce registrar for config options

Various talks at the sprint have revolved around establishing more
formalization around config options. Specific problems we'd like
to solve or are thinking about solving include:

* Experimental config options not documented and are not discoverable
  to end-users.
* Config options aren't strongly typed (it depends how they are
  accessed).
* Config options for extensions don't appear in `hg help config`.
* There is no formal mechanism to map a config option to command
  argument behavior. e.g. have a config option imply a command
  argument. Instead, logic is done in the command implementation,
  which results in inconsistent behavior, error messages, weird
  `hg help ` output.
* Config option validation is done at the call site and not as part
  of config loading or command dispatching.
* Config options are declared by side-effect all over the repo. It
  might be nicer to have a single "registry" so the full context of
  all options is easily referenced.
* No mechanism to "alias" an old config option to a new one. e.g.
  carrying over "experimental.feature" to its final value.

This patch introduces a very eary proof of concept for improving
the situation. It adds config options to the "registrar" mechanism,
which allows their declaration to be formalized and recorded in
a central location. This is conceptually similar to populating a
central dict with the data. I chose to use decorators and (for now)
empty functions for declaring config options. This allows docstrings
to be used for writing the config help.

In the future, one could imagine actually calling the function
declaring the config option. It could receive a ui instance and
an object defining the command being invoked. The function could
then look for conflicting options, adjust command arguments, etc.
It could do so in a way that is consistent across commands. e.g.
a ConfigOptionConflict exception could be raised and the ui or
dispatcher could consistently format that error condition rather
than leaving it to individual command functions to raise on their
own.

It's worth noting that we need all the *core* options defined in
a central file because of lazy module loading. If a module isn't
loaded, the config option declarations wouldn't be called!

There are several things missing from this patch and open issues to
resolve:

* i18n of help text
* Actually using docstrings in `hg help`
* Hooking up strong typing or hinted typing
* Figuring out how to declare config options with sub-options
* Better solution for declaring config options that have both global
  options and per-item sub-options (like hostsecurity.ciphers)
* Actually hooking it up to config loading
* Mechanism for declaring config options in extensions

diff --git a/mercurial/configoptions.py b/mercurial/configoptions.py
new file mode 100644
--- /dev/null
+++ b/mercurial/configoptions.py
@@ -0,0 +1,102 @@
+# configoptions.py -- Declaration of configuration options
+#
+# Copyright 2017 Gregory Szorc 
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from . import (
+registrar,
+)
+
+configoption = registrar.configoption()
+
+@configoption('hostsecurity.ciphers')
+def optionciphers():
+"""Defines the cryptographic ciphers to use for connections.
+
+Value must be a valid OpenSSL Cipher List Format as documented at
+
https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
+
+This setting is for advanced users only. Setting to incorrect values
+can significantly lower connection security or decrease performance.
+You have been warned.
+
+This option requires Python 2.7.
+"""
+
+@configoption('hostsecurity.minimumprotocol')
+def optionminimumprotocol():
+"""Defines the minimum channel encryption protocol to use.
+
+By default, the highest version of TLS supported by both client and
+server is used.
+
+Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
+
+When running on an old Python version, only ``tls1.0`` is allowed since
+old versions of Python only support up to TLS 1.0.
+
+When running a Python that supports modern TLS versions, the default is
+``tls1.1``. ``tls1.0`` can still be used to allow TLS 1.0. However, this
+weakens security and should only be used as a feature of last resort if
+a server does not support TLS 1.1+.
+"""
+
+@configoption('hostsecurity.*:ciphers')
+def perhostciphers():
+"""Per host version of ``hostsecurity.ciphers``."""
+
+@configoption('hostsecurity.*:fingerprints')
+def perhostfingerprints():
+"""A list of hashes of the DER encoded peer/remote 

Re: [PATCH 06 of 10 py3] mpatch: use bytesio instead of stringio in pure-python mpatch code

2017-03-12 Thread Yuya Nishihara
On Sun, 12 Mar 2017 14:57:46 -0400, Augie Fackler wrote:
> # HG changeset patch
> # User Augie Fackler 
> # Date 1489297542 18000
> #  Sun Mar 12 00:45:42 2017 -0500
> # Node ID 30c4b444e0beaea64ab35b594bb976bafba9aa34
> # Parent  666d6b8778093c73611aa728f92c688a75994ed6
> mpatch: use bytesio instead of stringio in pure-python mpatch code
> 
> diff --git a/mercurial/pure/mpatch.py b/mercurial/pure/mpatch.py
> --- a/mercurial/pure/mpatch.py
> +++ b/mercurial/pure/mpatch.py
> @@ -7,10 +7,10 @@
>  
>  from __future__ import absolute_import
>  
> +import io
>  import struct
>  
> -from . import policy, pycompat
> -stringio = pycompat.stringio
> +from . import policy
>  modulepolicy = policy.policy
>  policynocffi = policy.policynocffi
>  
> @@ -68,7 +68,7 @@ def patches(a, bins):
>  if not tl:
>  return a
>  
> -m = stringio()
> +m = io.BytesIO()

Perhaps this is the bug of our pycompat layer, which should export BytesIO
as stringio on Python 3.

Queued the other patches, thanks.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 10 of 10 py3] repoview: specify setattr values as native strings

2017-03-12 Thread Pulkit Goyal
This series don't include any rocket science, so must be pushed. LGTM

On Mon, Mar 13, 2017 at 12:27 AM, Augie Fackler  wrote:

> # HG changeset patch
> # User Augie Fackler 
> # Date 1489297686 18000
> #  Sun Mar 12 00:48:06 2017 -0500
> # Node ID 2ca323667f43ebf95f29d671fd00f3ae7753fa09
> # Parent  e8cceea7006f5b63cc17444d2552b54c1b97f33a
> repoview: specify setattr values as native strings
>
> diff --git a/mercurial/repoview.py b/mercurial/repoview.py
> --- a/mercurial/repoview.py
> +++ b/mercurial/repoview.py
> @@ -331,8 +331,8 @@ class repoview(object):
>  if cl is None:
>  cl = copy.copy(unfichangelog)
>  cl.filteredrevs = revs
> -object.__setattr__(self, '_clcache', cl)
> -object.__setattr__(self, '_clcachekey', newkey)
> +object.__setattr__(self, r'_clcache', cl)
> +object.__setattr__(self, r'_clcachekey', newkey)
>  return cl
>
>  def unfiltered(self):
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH V2] py3: add "b" prefix to string literals related to module policy

2017-03-12 Thread FUJIWARA Katsunori
# HG changeset patch
# User FUJIWARA Katsunori 
# Date 1489345596 -32400
#  Mon Mar 13 04:06:36 2017 +0900
# Node ID 2526bffdc7f01acb4e0f77865fce0ffab675250f
# Parent  62939e0148f170b67ca8c7374f36c413b67fd387
py3: add "b" prefix to string literals related to module policy

String literals without explicit prefix in __init__.py and policy.py
are treated as unicode object on Python3, because these modules are
loaded before setup of our specific code transformation (the later
module is imported at the beginning of __init__.py).

BTW, "modulepolicy" in __init__.py is initialized by "policy.policy".

This causes issues below;

  - checking "policy" value in other modules causes unintentional result

For example, "b'py' not in (u'c', u'py')" returns True
unintentionally on Python3.

  - writing "policy" out fails at conversion from unicode to bytes

62939e0148f1 fixed this issue for default code path, but "policy"
can be overridden by HGMODULEPOLICY environment variable (it should
be rare case for developer using Python3, though).

This patch does:

  - add "b" prefix to all string literals, which are related to module
policy, in modules above.

  - check existence of HGMODULEPOLICY, and overwrite "policy" only if
it exists

For simplicity, this patch omits checking "supports_bytes_environ",
switching os.environ/os.environb, and so on (Yuya agreed this in
personal talking)

diff --git a/mercurial/__init__.py b/mercurial/__init__.py
--- a/mercurial/__init__.py
+++ b/mercurial/__init__.py
@@ -68,7 +68,7 @@ class hgimporter(object):
 # indicates the type of module. So just assume what we found
 # is OK (even though it could be a pure Python module).
 except ImportError:
-if modulepolicy == 'c':
+if modulepolicy == b'c':
 raise
 zl = ziploader('mercurial', 'pure')
 mod = zl.load_module(name)
@@ -106,7 +106,7 @@ class hgimporter(object):
   'version should exist' % name)
 
 except ImportError:
-if modulepolicy == 'c':
+if modulepolicy == b'c':
 raise
 
 # Could not load the C extension and pure Python is allowed. So
diff --git a/mercurial/policy.py b/mercurial/policy.py
--- a/mercurial/policy.py
+++ b/mercurial/policy.py
@@ -19,9 +19,9 @@ import sys
 #py - only load pure Python modules
 #
 # By default, require the C extensions for performance reasons.
-policy = 'c'
-policynoc = ('cffi', 'cffi-allow', 'py')
-policynocffi = ('c', 'py')
+policy = b'c'
+policynoc = (b'cffi', b'cffi-allow', b'py')
+policynocffi = (b'c', b'py')
 
 try:
 from . import __modulepolicy__
@@ -42,4 +42,8 @@ if sys.version_info[0] >= 3:
 policy = b'py'
 
 # Environment variable can always force settings.
-policy = os.environ.get('HGMODULEPOLICY', policy)
+if sys.version_info[0] >= 3:
+if 'HGMODULEPOLICY' in os.environ:
+policy = os.environ['HGMODULEPOLICY'].encode('utf-8')
+else:
+policy = os.environ.get('HGMODULEPOLICY', policy)
diff --git a/tests/test-check-code.t b/tests/test-check-code.t
--- a/tests/test-check-code.t
+++ b/tests/test-check-code.t
@@ -27,8 +27,14 @@ New errors are not allowed. Warnings are
use encoding.environ instead (py3)
   Skipping mercurial/httpclient/__init__.py it has no-che?k-code (glob)
   Skipping mercurial/httpclient/_readers.py it has no-che?k-code (glob)
-  mercurial/policy.py:45:
-   > policy = os.environ.get('HGMODULEPOLICY', policy)
+  mercurial/policy.py:46:
+   > if 'HGMODULEPOLICY' in os.environ:
+   use encoding.environ instead (py3)
+  mercurial/policy.py:47:
+   > policy = os.environ['HGMODULEPOLICY'].encode('utf-8')
+   use encoding.environ instead (py3)
+  mercurial/policy.py:49:
+   > policy = os.environ.get('HGMODULEPOLICY', policy)
use encoding.environ instead (py3)
   Skipping mercurial/statprof.py it has no-che?k-code (glob)
   [1]
diff --git a/tests/test-check-py3-commands.t b/tests/test-check-py3-commands.t
--- a/tests/test-check-py3-commands.t
+++ b/tests/test-check-py3-commands.t
@@ -23,3 +23,10 @@ The full traceback is hidden to have a s
   $ $PYTHON3 `which hg` version | tail -1
   *** failed to import extension babar from imaginary_elephant: *: 
'imaginary_elephant' (glob)
   warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Test bytes-ness of policy.policy with HGMODULEPOLICY
+
+  $ HGMODULEPOLICY=py
+  $ export HGMODULEPOLICY
+  $ $PYTHON3 `which hg` debuginstall 2>&1 2>&1 | tail -1
+  no problems detected
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] py3: drop unused aliases to array.array which are replaced with bytearray

2017-03-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1489344422 25200
#  Sun Mar 12 11:47:02 2017 -0700
# Node ID 78cce06ea6c3820626e57704eda821095677a23b
# Parent  ff6dc91618236ef7a3d315921133b48bbc0d6f89
py3: drop unused aliases to array.array which are replaced with bytearray

diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -7,7 +7,6 @@
 
 from __future__ import absolute_import
 
-import array
 import struct
 
 from .node import (
@@ -23,7 +22,6 @@ from . import (
 util,
 )
 
-array = array.array
 calcsize = struct.calcsize
 pack = struct.pack
 unpack = struct.unpack
diff --git a/mercurial/tags.py b/mercurial/tags.py
--- a/mercurial/tags.py
+++ b/mercurial/tags.py
@@ -12,7 +12,6 @@
 
 from __future__ import absolute_import
 
-import array
 import errno
 
 from .node import (
@@ -28,8 +27,6 @@ from . import (
 util,
 )
 
-array = array.array
-
 # Tags computation can be expensive and caches exist to make it fast in
 # the common case.
 #
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


  1   2   >