Re: [PATCH 1 of 8 V2] context: don't use mutable default argument value
On Sun, Mar 12, 2017 at 9:57 PM, Gregory Szorcwrote: > # 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
On Sun, Mar 12, 2017 at 7:59 PM, Bryan O'Sullivanwrote: > 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
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
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
Excerpts from Gregory Szorc's message of 2017-03-12 19:48:35 -0700: > > > On Mar 12, 2017, at 19:28, Jun Wuwrote: > > > > 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
> On Mar 12, 2017, at 19:28, Jun Wuwrote: > > 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
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()
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
On Sun, Mar 12, 2017 at 12:06 PM, Augie Facklerwrote: > 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
# 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
# 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()
# 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
# 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
# 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
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
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
# 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
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
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
# 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
# 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
On Sun, 12 Mar 2017 15:42:06 -0700, Augie Fackler wrote: > > On Mar 12, 2017, at 15:10, Augie Facklerwrote: > >> 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
# 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
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
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
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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
> On Mar 12, 2017, at 15:08, Yuya Nishiharawrote: > > 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
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'
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
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
> On Mar 12, 2017, at 12:26, Jun Wuwrote: > > 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
# 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
# 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
# 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
# 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
On Sun, 12 Mar 2017 13:17:54 -0700, Gregory Szorc wrote: > On Sun, Mar 12, 2017 at 12:49 PM, Augie Facklerwrote: > > > # 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'
# 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
On Sun, Mar 12, 2017 at 12:49 PM, Augie Facklerwrote: > # 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
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
# 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
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
# 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
# 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
# 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
# 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
# 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
# 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
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
# 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
# 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
# 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')
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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__
# 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
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
# 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
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
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
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
# 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
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
# 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
On Mon, Mar 13, 2017 at 12:59 AM, Gregory Szorcwrote: > 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
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
# 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
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 Nishiharawrote: > > > > 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
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
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
# 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
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
This series don't include any rocket science, so must be pushed. LGTM On Mon, Mar 13, 2017 at 12:27 AM, Augie Facklerwrote: > # 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
# 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
# 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