Re: [PATCH v2] template: provide a termwidth keyword (issue5395)
On Sat, 8 Oct 2016 02:32:00 -0700, Simon Farnsworth wrote: > # HG changeset patch > # User Simon Farnsworth> # Date 1475918808 25200 > # Sat Oct 08 02:26:48 2016 -0700 > # Node ID 4c76c4023f440ee2fefe2b632a99869cd657ff90 > # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 > template: provide a termwidth keyword (issue5395) > > We want to provide terminal-sized output. As a starting point, expose the > terminal width to the templater for use in things like fill. Looks good. Queued, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 3 of 3 v3] util: ensure forwarded attrs are set in globals() as sysstr
On Sat, 08 Oct 2016 11:10:09 -0400, Augie Fackler wrote: > # HG changeset patch > # User Augie Fackler> # Date 1475930199 14400 > # Sat Oct 08 08:36:39 2016 -0400 > # Node ID fb12c11bfe23af38dfb55c721d28a7bfded8c2ed > # Parent 1c7199563d7d8f400f907c63c133d7414ae1f684 > util: ensure forwarded attrs are set in globals() as sysstr Queued the series, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH v3] mail: take --encoding and HGENCODING into account
On Sat, 08 Oct 2016 05:48:32 -0500, Gábor Stefanik wrote: > # HG changeset patch > # User Gábor Stefanik> # Date 1475667922 -7200 > # Wed Oct 05 13:45:22 2016 +0200 > # Node ID d7125caa00dcc6036d3d5aee3e4d524211b95e02 > # Parent dbcef8918bbdd8a64d9f79a37bcfa284a26f3a39 > mail: take --encoding and HGENCODING into account > > Fall back to our encoding strategy for sending MIME text > that's neither ASCII nor UTF-8. Queued this, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2] py3: make encodefun in store.py compatible with py3k
On Sat, 8 Oct 2016 08:55:46 -0700, Mateusz Kwapich wrote: > # HG changeset patch > # User Mateusz Kwapich> # Date 1475942045 25200 > # Sat Oct 08 08:54:05 2016 -0700 > # Node ID 086b25d1866e33fb7ebbe6c51522e6b573e281e2 > # Parent 225efa4bf7f497e55f0ba57f64a33dce39eaeb29 > py3: make encodefun in store.py compatible with py3k > > This ensures that the filename encoding functions always map bytestrings > to bytestrings regardless of python version. > > diff --git a/mercurial/store.py b/mercurial/store.py > --- a/mercurial/store.py > +++ b/mercurial/store.py > @@ -16,6 +16,7 @@ from .i18n import _ > from . import ( > error, > parsers, > +pycompat, > scmutil, > util, > ) > @@ -98,11 +99,20 @@ def _buildencodefun(): > 'the\\x07quick\\xadshot' > ''' > e = '_' > -cmap = dict([(chr(x), chr(x)) for x in xrange(127)]) > +if pycompat.ispy3: > +xchr = lambda x: bytes([x]) > +asciistr = bytes(xrange(127)) > +else: > +xchr = chr > +asciistr = map(chr, xrange(127)) > +capitals = list(range(ord("A"), ord("Z") + 1)) > + > +cmap = {x:x for x in asciistr} Dict comprehension isn't available in Python 2.6. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] contributing: add new file with a pointer to the wiki
On 10/08/2016 04:39 PM, Augie Fackler wrote: # HG changeset patch # User Augie Fackler# Date 1475937540 14400 # Sat Oct 08 10:39:00 2016 -0400 # Node ID 7765e2cea8a778ecafe31b48362f9978bfd961d3 # Parent 87b8e40eb8125d5ddc848d972b117989346057dd contributing: add new file with a pointer to the wiki This is great! Pushed, many thanks. -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] import: abort instead of crashing when copy source does not exist (issue5375)
On 10/08/2016 07:06 PM, Mads Kiilerich wrote: On 10/08/2016 06:11 PM, Ryan McElroy wrote: # HG changeset patch # User Ryan McElroy# Date 1475929618 25200 # Sat Oct 08 05:26:58 2016 -0700 # Node ID 961569a2cbeebfd54c9369c6e36d03d4938aef38 # Parent dbcef8918bbdd8a64d9f79a37bcfa284a26f3a39 import: abort instead of crashing when copy source does not exist (issue5375) Previously, when a patch contained a move or copy from a source that did not exist, `hg import` would crash. This patch changes import to raise a PatchError with an explanantion of what is wrong with the patch to avoid the stack trace and bad user experience. diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -1952,8 +1952,10 @@ def _applydiff(ui, fp, patcher, backend, data, mode = None, None if gp.op in ('RENAME', 'COPY'): data, mode = store.getfile(gp.oldpath)[:2] -# FIXME: failing getfile has never been handled here -assert data is not None +if data is None: +# This means that the old path does not exist +raise PatchError(_("source file '%s' does not exist") + % gp.oldpath) if gp.mode: mode = gp.mode if gp.op == 'ADD': diff --git a/tests/test-import.t b/tests/test-import.t --- a/tests/test-import.t +++ b/tests/test-import.t @@ -1793,3 +1793,13 @@ repository when file not found for patch 1 out of 1 hunks FAILED -- saving rejects to file file1.rej abort: patch failed to apply [255] + +test import crash (issue5375) + $ cd .. + $ hg init repo + $ cd repo + $ printf "diff --git a/a b/b\nrename from a\nrename to b" | hg import - + applying patch from stdin + a not tracked! + abort: source file 'a' does not exist + [255] Hmm. For a patch modifying a non-existing file we already get: unable to find 'f' for patching 1 out of 1 hunks FAILED -- saving rejects to file f.rej patch failed, unable to continue (try -v) patch failed, rejects left in working directory $ cat f.rej --- f +++ f @@ -1,1 +1,2 @@ +f In the tested case, I would thus also expect it to leave a .rej file with the failing rename "hunk" while applying the rest of the patch (even though a pure rename arguably *doesn't* have any hunks). BUT the logic around this check seems wrong. A rename or copy of a missing file should be handled exactly the same, no matter if it is a bare rename/copy or if it also modifies the file (= has a first hunk). I don't know if it is better to give a not-entirely-correct abort than to fail with an assertion error, but I think it still deserves a FIXME/TODO. +1 we should keep the same erro flow than for other patch error (especially because I'm not sure how --partial deal with this patch. (The iterhunks docstring seems wrong, for example regarding 'file' entries and firsthunk. Let's go find pmezard!) TGVs for Brest leave from Gare Montparnasse every hour. Cheers, -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] templater: add relpath() to convert repo path to relative path (issue5394)
This looks good to me. Excerpts from Yuya Nishihara's message of 2016-10-08 19:05:16 +0200: > # HG changeset patch > # User Yuya Nishihara> # Date 1475933066 -7200 > # Sat Oct 08 15:24:26 2016 +0200 > # Node ID 83e6528647265043ed30be784e0db8fd59133230 > # Parent 2def3d55b1b9ec2acd53f96ca755d778b5ec865b > templater: add relpath() to convert repo path to relative path (issue5394) > > File paths in template are repository-absolute paths. This function can be > used to convert them to filesystem paths relative to cwd. This also converts > '/' to '\\' on Windows. > > diff --git a/mercurial/templater.py b/mercurial/templater.py > --- a/mercurial/templater.py > +++ b/mercurial/templater.py > @@ -713,6 +713,18 @@ def localdate(context, mapping, args): > tzoffset = util.makedate()[1] > return (date[0], tzoffset) > > +@templatefunc('relpath(path)') > +def relpath(context, mapping, args): > +"""Convert a repository-absolute path into a filesystem path relative to > +the current working directory.""" > +if len(args) != 1: > +# i18n: "relpath" is a keyword > +raise error.ParseError(_("relpath expects one argument")) > + > +repo = mapping['ctx'].repo() > +path = evalstring(context, mapping, args[0]) > +return repo.pathto(path) > + > @templatefunc('revset(query[, formatargs...])') > def revset(context, mapping, args): > """Execute a revision set query. See > diff --git a/tests/test-command-template.t b/tests/test-command-template.t > --- a/tests/test-command-template.t > +++ b/tests/test-command-template.t > @@ -3521,6 +3521,15 @@ Test files function >0 > > > +Test relpath function > + > + $ hg log -r0 -T '{files % "{file|relpath}\n"}' > + a > + $ cd .. > + $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}' > + r/a (glob) > + $ cd r > + > Test active bookmark templating > >$ hg book foo ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] util: document we want Python type mapping to be temporary
It should be PATCH 3 of the [PATCH 1 of 2] parsers: return NULL from PyInit_parsers on Python 3 Note: hgpatch.lihdd.net supports getting a branch across email threads, based on "Parent" information: http://hgpatch.lihdd.net/d15d8ac73cfd2d1ddbd443262ccad9c68ee69406/branch Excerpts from Pierre-Yves David's message of 2016-10-08 23:38:46 +0200: > > On 10/08/2016 07:16 PM, Gregory Szorc wrote: > > # HG changeset patch > > # User Gregory Szorc> > # Date 1475947010 -7200 > > # Sat Oct 08 19:16:50 2016 +0200 > > # Node ID d15d8ac73cfd2d1ddbd443262ccad9c68ee69406 > > # Parent 266ad9c9faa524a8b3f473c924db409681cb205e > > util: document we want Python type mapping to be temporary > > > > I think remapping Python C API types and functions is not a great > > approach. I'd prefer this whole #ifdef disappeared. Add a comment > > so we don't forget about it. > > I cannot find anywhere to apply this. This code does not seems to exists > in our current public repository. Am I missing something? > ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] util: document we want Python type mapping to be temporary
On 10/08/2016 07:16 PM, Gregory Szorc wrote: # HG changeset patch # User Gregory Szorc# Date 1475947010 -7200 # Sat Oct 08 19:16:50 2016 +0200 # Node ID d15d8ac73cfd2d1ddbd443262ccad9c68ee69406 # Parent 266ad9c9faa524a8b3f473c924db409681cb205e util: document we want Python type mapping to be temporary I think remapping Python C API types and functions is not a great approach. I'd prefer this whole #ifdef disappeared. Add a comment so we don't forget about it. I cannot find anywhere to apply this. This code does not seems to exists in our current public repository. Am I missing something? -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] hgweb: fix the MRO in Python 3
On 10/08/2016 07:12 PM, Martijn Pieters wrote: # HG changeset patch # User Martijn Pieters# Date 1475946679 -7200 # Sat Oct 08 19:11:19 2016 +0200 # Node ID 8475a954a40385035b57abe05af31308597a0b3c # Parent 2c8ec8c2ddfeb2d229b81eb5b11e3639fb34b0a0 hgweb: fix the MRO in Python 3 object should appear at the end, otherwise it tries to pre-empt the other new-style classes in the MRO, resulting in an unresolvable MRO in Py3. We still need to include object because otherwise in 2.7 we end up with an old-style class if threading is not supported, new-style if it is. Pushed, thanks -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] util: document we want Python type mapping to be temporary
These look good to me. (Including related patches: util: define PyInt_Type on Python 3 parsers: return NULL from PyInit_parsers on Python 3) I think we can always iterate on Python 3 later. Excerpts from Gregory Szorc's message of 2016-10-08 19:16:54 +0200: > # HG changeset patch > # User Gregory Szorc> # Date 1475947010 -7200 > # Sat Oct 08 19:16:50 2016 +0200 > # Node ID d15d8ac73cfd2d1ddbd443262ccad9c68ee69406 > # Parent 266ad9c9faa524a8b3f473c924db409681cb205e > util: document we want Python type mapping to be temporary > > I think remapping Python C API types and functions is not a great > approach. I'd prefer this whole #ifdef disappeared. Add a comment > so we don't forget about it. > > diff --git a/mercurial/util.h b/mercurial/util.h > --- a/mercurial/util.h > +++ b/mercurial/util.h > @@ -12,8 +12,11 @@ > > #if PY_MAJOR_VERSION >= 3 > > #define IS_PY3K > +/* The mapping of Python types is meant to be temporary to get Python > + * 3 to compile. We should remove this once Python 3 support is fully > + * supported and proper types are used in the extensions themselves. */ > #define PyInt_Type PyLong_Type > #define PyInt_FromLong PyLong_FromLong > #define PyInt_AsLong PyLong_AsLong > ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 7 of 7] parsers: use PyVarObject_HEAD_INIT
# HG changeset patch # User Gregory Szorc# Date 1475959442 -7200 # Sat Oct 08 22:44:02 2016 +0200 # Node ID ad527a4c62ad35b84c4ad25d080ee427528966fa # Parent 40775aad0c78f6c1fd07e7160d50426efbe032ed parsers: use PyVarObject_HEAD_INIT The macro changed slightly in Python 3, introducing curly brackets that somehow confuse Clang into issuing a ton of compiler warnings. Using PyVarObject_HEAD_INIT makes these go away. It's worth noting that the code is identical: the 2nd argument to PyVarObject_HEAD_INIT is assigned to the ob_size field and is inserted immediately after "PyObject_HEAD_INIT(type)" is generated. Compilers are weird. diff --git a/mercurial/parsers.c b/mercurial/parsers.c --- a/mercurial/parsers.c +++ b/mercurial/parsers.c @@ -2515,10 +2515,9 @@ static PyGetSetDef index_getset[] = { {NULL} /* Sentinel */ }; static PyTypeObject indexType = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ + PyVarObject_HEAD_INIT(NULL, 0) "parsers.index", /* tp_name */ sizeof(indexObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)index_dealloc, /* tp_dealloc */ ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 7] manifest: convert PyString* to PyBytes*
# HG changeset patch # User Gregory Szorc# Date 1475956675 -7200 # Sat Oct 08 21:57:55 2016 +0200 # Node ID d9914b172e706be9b208e84977160cdc3b3d5266 # Parent d15d8ac73cfd2d1ddbd443262ccad9c68ee69406 manifest: convert PyString* to PyBytes* Python 2.6 introduced PyBytesObject and PyBytes* as aliases for PyStringObject and PyString*. So on Python 2.6+, PyBytes* and PyString* are identical and this patch should be a no-op. On Python 3, PyStringObject is effectively renamed to PyUnicodeObject and PyBytesObject becomes the main type for byte strings. This patch begins the process of mass converting PyString* to PyBytes* so the C extensions use the correct type on Python 3. diff --git a/mercurial/manifest.c b/mercurial/manifest.c --- a/mercurial/manifest.c +++ b/mercurial/manifest.c @@ -55,12 +55,12 @@ static PyObject *nodeof(line *l) { return NULL; } if (l->hash_suffix != '\0') { char newhash[21]; - memcpy(newhash, PyString_AsString(hash), 20); + memcpy(newhash, PyBytes_AsString(hash), 20); Py_DECREF(hash); newhash[20] = l->hash_suffix; - hash = PyString_FromStringAndSize(newhash, 21); + hash = PyBytes_FromStringAndSize(newhash, 21); } return hash; } @@ -78,9 +78,9 @@ static PyObject *hashflags(line *l) PyObject *tup; if (!hash) return NULL; - flags = PyString_FromStringAndSize(s + hplen - 1, flen); + flags = PyBytes_FromStringAndSize(s + hplen - 1, flen); if (!flags) { Py_DECREF(hash); return NULL; } @@ -143,9 +143,9 @@ static int lazymanifest_init(lazymanifes PyObject *pydata; if (!PyArg_ParseTuple(args, "S", )) { return -1; } - err = PyString_AsStringAndSize(pydata, , ); + err = PyBytes_AsStringAndSize(pydata, , ); self->dirty = false; if (err == -1) return -1; @@ -237,12 +237,12 @@ static PyObject *lmiter_iterentriesnext( if (!l) { goto done; } pl = pathlen(l); - path = PyString_FromStringAndSize(l->start, pl); + path = PyBytes_FromStringAndSize(l->start, pl); hash = nodeof(l); consumed = pl + 41; - flags = PyString_FromStringAndSize(l->start + consumed, + flags = PyBytes_FromStringAndSize(l->start + consumed, l->len - consumed - 1); if (!path || !hash || !flags) { goto done; } @@ -299,9 +299,9 @@ static PyObject *lmiter_iterkeysnext(PyO if (!l) { return NULL; } pl = pathlen(l); - return PyString_FromStringAndSize(l->start, pl); + return PyBytes_FromStringAndSize(l->start, pl); } #ifdef IS_PY3K #define LAZYMANIFESTKEYSITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT @@ -397,14 +397,14 @@ static int linecmp(const void *left, con static PyObject *lazymanifest_getitem(lazymanifest *self, PyObject *key) { line needle; line *hit; - if (!PyString_Check(key)) { + if (!PyBytes_Check(key)) { PyErr_Format(PyExc_TypeError, "getitem: manifest keys must be a string."); return NULL; } - needle.start = PyString_AsString(key); + needle.start = PyBytes_AsString(key); hit = bsearch(, self->lines, self->numlines, sizeof(line), ); if (!hit || hit->deleted) { PyErr_Format(PyExc_KeyError, "No such manifest entry."); @@ -416,14 +416,14 @@ static PyObject *lazymanifest_getitem(la static int lazymanifest_delitem(lazymanifest *self, PyObject *key) { line needle; line *hit; - if (!PyString_Check(key)) { + if (!PyBytes_Check(key)) { PyErr_Format(PyExc_TypeError, "delitem: manifest keys must be a string."); return -1; } - needle.start = PyString_AsString(key); + needle.start = PyBytes_AsString(key); hit = bsearch(, self->lines, self->numlines, sizeof(line), ); if (!hit || hit->deleted) { PyErr_Format(PyExc_KeyError, @@ -485,9 +485,9 @@ static int lazymanifest_setitem( size_t dlen; char *dest; int i; line new; - if (!PyString_Check(key)) { + if (!PyBytes_Check(key)) { PyErr_Format(PyExc_TypeError, "setitem: manifest keys must be a string."); return -1; } @@ -498,19 +498,19 @@ static int lazymanifest_setitem( PyErr_Format(PyExc_TypeError, "Manifest values must be a tuple of (node, flags)."); return -1; } - if (PyString_AsStringAndSize(key, , ) == -1) { + if
[PATCH 5 of 7] util: remove PyString* aliases on Python 3
# HG changeset patch # User Gregory Szorc# Date 1475957096 -7200 # Sat Oct 08 22:04:56 2016 +0200 # Node ID a33e93c20bc1290af106a0f077fece735ea05245 # Parent a91e68ef608ec814bd853f31920fe1f75993dd40 util: remove PyString* aliases on Python 3 We no longer have any users of the legacy PyString* functions. We no longer need these redefinitions. After this change, the only reference to "PyString" in the repo is in watchman's C extension. That isn't our code and porting Mercurial extensions to Python 3 is not a high priority at the moment. watchman's C extension will be dealt with later. diff --git a/mercurial/util.h b/mercurial/util.h --- a/mercurial/util.h +++ b/mercurial/util.h @@ -19,49 +19,8 @@ #define PyInt_Type PyLong_Type #define PyInt_FromLong PyLong_FromLong #define PyInt_AsLong PyLong_AsLong -/* - Mapping of some of the python < 2.x PyString* functions to py3k's PyUnicode. - - The commented names below represent those that are present in the PyBytes - definitions for python < 2.6 (below in this file) that don't have a direct - implementation. -*/ - -#define PyStringObject PyUnicodeObject -#define PyString_Type PyUnicode_Type - -#define PyString_Check PyUnicode_Check -#define PyString_CheckExact PyUnicode_CheckExact -#define PyString_CHECK_INTERNED PyUnicode_CHECK_INTERNED -#define PyString_AS_STRING PyUnicode_AsLatin1String -#define PyString_GET_SIZE PyUnicode_GET_SIZE - -#define PyString_FromStringAndSize PyUnicode_FromStringAndSize -#define PyString_FromString PyUnicode_FromString -#define PyString_FromFormatV PyUnicode_FromFormatV -#define PyString_FromFormat PyUnicode_FromFormat -/* #define PyString_Size PyUnicode_GET_SIZE */ -/* #define PyString_AsString */ -/* #define PyString_Repr */ -#define PyString_Concat PyUnicode_Concat -#define PyString_ConcatAndDel PyUnicode_AppendAndDel -#define _PyString_Resize PyUnicode_Resize -/* #define _PyString_Eq */ -#define PyString_Format PyUnicode_Format -/* #define _PyString_FormatLong */ -/* #define PyString_DecodeEscape */ -#define _PyString_Join PyUnicode_Join -#define PyString_Decode PyUnicode_Decode -#define PyString_Encode PyUnicode_Encode -#define PyString_AsEncodedObject PyUnicode_AsEncodedObject -#define PyString_AsEncodedString PyUnicode_AsEncodedString -#define PyString_AsDecodedObject PyUnicode_AsDecodedObject -#define PyString_AsDecodedString PyUnicode_AsDecodedUnicode -/* #define PyString_AsStringAndSize */ -#define _PyString_InsertThousandsGrouping _PyUnicode_InsertThousandsGrouping - #endif /* PY_MAJOR_VERSION */ typedef struct { PyObject_HEAD ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 6 of 7] pathencode: use Py_SIZE directly
# HG changeset patch # User Gregory Szorc# Date 1475958082 -7200 # Sat Oct 08 22:21:22 2016 +0200 # Node ID 40775aad0c78f6c1fd07e7160d50426efbe032ed # Parent a33e93c20bc1290af106a0f077fece735ea05245 pathencode: use Py_SIZE directly On Python 2, PyBytes_GET_SIZE is the same as PyString_GET_SIZE which is the same as Py_SIZE which resolves to a struct member. On Python 3, PyBytes_GET_SIZE is "(assert(PyBytes_Check(op)),Py_SIZE(op))". The compiler barfs when assigning to this version. This patch simply changes PyBytes_GET_SIZE to Py_SIZE. On Python 2, there is no effective change in behavior. On Python 3, we drop the PyBytes_Check(). However, in all cases we have explicitly created a PyBytesObject in the same function, so the PyBytes_Check() is guaranteed to be true. Despite this, code changes over time, so I've added added assert() in all callers so we can catch this in debug builds. With this patch, all mercurial.* C extensions now compile on Python 3 on my OS X machine. There are several compiler warnings and I'm sure there are incompatibilities with Python 3, including possibly segfaults. But it is a milestone. diff --git a/mercurial/pathencode.c b/mercurial/pathencode.c --- a/mercurial/pathencode.c +++ b/mercurial/pathencode.c @@ -170,9 +170,10 @@ PyObject *encodedir(PyObject *self, PyOb newobj = PyBytes_FromStringAndSize(NULL, newlen); if (newobj) { - PyBytes_GET_SIZE(newobj)--; + assert(PyBytes_Check(newobj)); + Py_SIZE(newobj)--; _encodedir(PyBytes_AS_STRING(newobj), newlen, path, len + 1); } @@ -637,9 +638,10 @@ static PyObject *hashmangle(const char * if (lastdot >= 0) memcopy(dest, , destsize, [lastdot], len - lastdot - 1); - PyBytes_GET_SIZE(ret) = destlen; + PyBytes_Check(ret); + Py_SIZE(ret) = destlen; return ret; } @@ -749,9 +751,10 @@ PyObject *pathencode(PyObject *self, PyO newobj = PyBytes_FromStringAndSize(NULL, newlen); if (newobj) { - PyBytes_GET_SIZE(newobj)--; + PyBytes_Check(newobj); + Py_SIZE(newobj)--; basicencode(PyBytes_AS_STRING(newobj), newlen, path, len + 1); } } ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 4 of 7] parsers: convert PyString* to PyBytes*
# HG changeset patch # User Gregory Szorc# Date 1475956949 -7200 # Sat Oct 08 22:02:29 2016 +0200 # Node ID a91e68ef608ec814bd853f31920fe1f75993dd40 # Parent 5ce286c00dcefb7c432265417eb3d5d1fe368296 parsers: convert PyString* to PyBytes* With this change, we no longer have any occurrences of "PyString" in our C extensions. diff --git a/mercurial/parsers.c b/mercurial/parsers.c --- a/mercurial/parsers.c +++ b/mercurial/parsers.c @@ -609,39 +609,39 @@ static PyObject *pack_dirstate(PyObject /* Figure out how much we need to allocate. */ for (nbytes = 40, pos = 0; PyDict_Next(map, , , );) { PyObject *c; - if (!PyString_Check(k)) { + if (!PyBytes_Check(k)) { PyErr_SetString(PyExc_TypeError, "expected string key"); goto bail; } - nbytes += PyString_GET_SIZE(k) + 17; + nbytes += PyBytes_GET_SIZE(k) + 17; c = PyDict_GetItem(copymap, k); if (c) { - if (!PyString_Check(c)) { + if (!PyBytes_Check(c)) { PyErr_SetString(PyExc_TypeError, "expected string key"); goto bail; } - nbytes += PyString_GET_SIZE(c) + 1; + nbytes += PyBytes_GET_SIZE(c) + 1; } } - packobj = PyString_FromStringAndSize(NULL, nbytes); + packobj = PyBytes_FromStringAndSize(NULL, nbytes); if (packobj == NULL) goto bail; - p = PyString_AS_STRING(packobj); + p = PyBytes_AS_STRING(packobj); pn = PySequence_ITEM(pl, 0); - if (PyString_AsStringAndSize(pn, , ) == -1 || l != 20) { + if (PyBytes_AsStringAndSize(pn, , ) == -1 || l != 20) { PyErr_SetString(PyExc_TypeError, "expected a 20-byte hash"); goto bail; } memcpy(p, s, l); p += 20; pn = PySequence_ITEM(pl, 1); - if (PyString_AsStringAndSize(pn, , ) == -1 || l != 20) { + if (PyBytes_AsStringAndSize(pn, , ) == -1 || l != 20) { PyErr_SetString(PyExc_TypeError, "expected a 20-byte hash"); goto bail; } memcpy(p, s, l); @@ -684,23 +684,23 @@ static PyObject *pack_dirstate(PyObject putbe32((uint32_t)size, p + 4); putbe32((uint32_t)mtime, p + 8); t = p + 12; p += 16; - len = PyString_GET_SIZE(k); - memcpy(p, PyString_AS_STRING(k), len); + len = PyBytes_GET_SIZE(k); + memcpy(p, PyBytes_AS_STRING(k), len); p += len; o = PyDict_GetItem(copymap, k); if (o) { *p++ = '\0'; - l = PyString_GET_SIZE(o); - memcpy(p, PyString_AS_STRING(o), l); + l = PyBytes_GET_SIZE(o); + memcpy(p, PyBytes_AS_STRING(o), l); p += l; len += l + 1; } putbe32((uint32_t)len, t); } - pos = p - PyString_AS_STRING(packobj); + pos = p - PyBytes_AS_STRING(packobj); if (pos != nbytes) { PyErr_Format(PyExc_SystemError, "bad dirstate size: %ld != %ld", (long)pos, (long)nbytes); goto bail; @@ -795,9 +795,9 @@ static const char *index_deref(indexObje } return self->offsets[pos]; } - return PyString_AS_STRING(self->data) + pos * v1_hdrsize; + return PyBytes_AS_STRING(self->data) + pos * v1_hdrsize; } static inline int index_get_parents(indexObject *self, Py_ssize_t rev, int *ps, int maxrev) @@ -925,9 +925,9 @@ static const char *index_node(indexObjec if (pos >= self->length - 1) { PyObject *tuple, *str; tuple = PyList_GET_ITEM(self->added, pos - self->length + 1); str = PyTuple_GetItem(tuple, 7); - return str ? PyString_AS_STRING(str) : NULL; + return str ? PyBytes_AS_STRING(str) : NULL; } data = index_deref(self, pos); return data ? data + 32 : NULL; @@ -936,9 +936,9 @@ static const char *index_node(indexObjec static int nt_insert(indexObject *self, const char *node, int rev); static int node_check(PyObject *obj, char **node, Py_ssize_t *nodelen) { - if (PyString_AsStringAndSize(obj, node, nodelen) == -1) + if (PyBytes_AsStringAndSize(obj, node, nodelen) == -1) return -1; if (*nodelen == 20) return 0; PyErr_SetString(PyExc_ValueError, "20-byte hash required"); @@ -1824,18 +1824,18 @@ static
[PATCH 2 of 7] osutil: convert PyString* to PyBytes*
# HG changeset patch # User Gregory Szorc# Date 1475956735 -7200 # Sat Oct 08 21:58:55 2016 +0200 # Node ID 921f070e83bcf78ffccac50c75ad6f8eebf2894b # Parent d9914b172e706be9b208e84977160cdc3b3d5266 osutil: convert PyString* to PyBytes* Continuing the conversion from PyString* to PyBytes*. diff --git a/mercurial/osutil.c b/mercurial/osutil.c --- a/mercurial/osutil.c +++ b/mercurial/osutil.c @@ -623,9 +623,9 @@ static PyObject *statfiles(PyObject *sel pypath = PySequence_GetItem(names, i); if (!pypath) goto bail; - path = PyString_AsString(pypath); + path = PyBytes_AsString(pypath); if (path == NULL) { Py_DECREF(pypath); PyErr_SetString(PyExc_TypeError, "not a string"); goto bail; ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 7] pathencode: convert PyString* to PyBytes*
# HG changeset patch # User Gregory Szorc# Date 1475956867 -7200 # Sat Oct 08 22:01:07 2016 +0200 # Node ID 5ce286c00dcefb7c432265417eb3d5d1fe368296 # Parent 921f070e83bcf78ffccac50c75ad6f8eebf2894b pathencode: convert PyString* to PyBytes* diff --git a/mercurial/pathencode.c b/mercurial/pathencode.c --- a/mercurial/pathencode.c +++ b/mercurial/pathencode.c @@ -155,9 +155,9 @@ PyObject *encodedir(PyObject *self, PyOb if (!PyArg_ParseTuple(args, "O:encodedir", )) return NULL; - if (PyString_AsStringAndSize(pathobj, , ) == -1) { + if (PyBytes_AsStringAndSize(pathobj, , ) == -1) { PyErr_SetString(PyExc_TypeError, "expected a string"); return NULL; } @@ -167,13 +167,13 @@ PyObject *encodedir(PyObject *self, PyOb Py_INCREF(pathobj); return pathobj; } - newobj = PyString_FromStringAndSize(NULL, newlen); + newobj = PyBytes_FromStringAndSize(NULL, newlen); if (newobj) { - PyString_GET_SIZE(newobj)--; - _encodedir(PyString_AS_STRING(newobj), newlen, path, + PyBytes_GET_SIZE(newobj)--; + _encodedir(PyBytes_AS_STRING(newobj), newlen, path, len + 1); } return newobj; @@ -514,11 +514,11 @@ PyObject *lowerencode(PyObject *self, Py if (!PyArg_ParseTuple(args, "s#:lowerencode", , )) return NULL; newlen = _lowerencode(NULL, 0, path, len); - ret = PyString_FromStringAndSize(NULL, newlen); + ret = PyBytes_FromStringAndSize(NULL, newlen); if (ret) - _lowerencode(PyString_AS_STRING(ret), newlen, path, len); + _lowerencode(PyBytes_AS_STRING(ret), newlen, path, len); return ret; } @@ -567,13 +567,13 @@ static PyObject *hashmangle(const char * destsize = 120; if (lastdot >= 0) destsize += len - lastdot - 1; - ret = PyString_FromStringAndSize(NULL, destsize); + ret = PyBytes_FromStringAndSize(NULL, destsize); if (ret == NULL) return NULL; - dest = PyString_AS_STRING(ret); + dest = PyBytes_AS_STRING(ret); memcopy(dest, , destsize, "dh/", 3); /* Copy up to dirprefixlen bytes of each path component, up to a limit of maxshortdirslen bytes. */ @@ -637,9 +637,9 @@ static PyObject *hashmangle(const char * if (lastdot >= 0) memcopy(dest, , destsize, [lastdot], len - lastdot - 1); - PyString_GET_SIZE(ret) = destlen; + PyBytes_GET_SIZE(ret) = destlen; return ret; } @@ -652,9 +652,9 @@ static int sha1hash(char hash[20], const static PyObject *shafunc; PyObject *shaobj, *hashobj; if (shafunc == NULL) { - PyObject *hashlib, *name = PyString_FromString("hashlib"); + PyObject *hashlib, *name = PyBytes_FromString("hashlib"); if (name == NULL) return -1; @@ -685,16 +685,16 @@ static int sha1hash(char hash[20], const Py_DECREF(shaobj); if (hashobj == NULL) return -1; - if (!PyString_Check(hashobj) || PyString_GET_SIZE(hashobj) != 20) { + if (!PyBytes_Check(hashobj) || PyBytes_GET_SIZE(hashobj) != 20) { PyErr_SetString(PyExc_TypeError, "result of digest is not a 20-byte hash"); Py_DECREF(hashobj); return -1; } - memcpy(hash, PyString_AS_STRING(hashobj), 20); + memcpy(hash, PyBytes_AS_STRING(hashobj), 20); Py_DECREF(hashobj); return 0; } @@ -730,9 +730,9 @@ PyObject *pathencode(PyObject *self, PyO if (!PyArg_ParseTuple(args, "O:pathencode", )) return NULL; - if (PyString_AsStringAndSize(pathobj, , ) == -1) { + if (PyBytes_AsStringAndSize(pathobj, , ) == -1) { PyErr_SetString(PyExc_TypeError, "expected a string"); return NULL; } @@ -746,13 +746,13 @@ PyObject *pathencode(PyObject *self, PyO Py_INCREF(pathobj); return pathobj; } - newobj = PyString_FromStringAndSize(NULL, newlen); + newobj = PyBytes_FromStringAndSize(NULL, newlen); if (newobj) { - PyString_GET_SIZE(newobj)--; - basicencode(PyString_AS_STRING(newobj), newlen, path, + PyBytes_GET_SIZE(newobj)--; + basicencode(PyBytes_AS_STRING(newobj), newlen, path, len + 1); } } else ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org
Re: [PATCH] hgweb: fix the MRO in Python 3
On Sat, Oct 8, 2016 at 7:12 PM, Martijn Pieterswrote: > # HG changeset patch > # User Martijn Pieters > # Date 1475946679 -7200 > # Sat Oct 08 19:11:19 2016 +0200 > # Node ID 8475a954a40385035b57abe05af31308597a0b3c > # Parent 2c8ec8c2ddfeb2d229b81eb5b11e3639fb34b0a0 > hgweb: fix the MRO in Python 3 > > object should appear at the end, otherwise it tries to pre-empt the other > new-style classes in the MRO, resulting in an unresolvable MRO in Py3. We > still > need to include object because otherwise in 2.7 we end up with an old-style > class if threading is not supported, new-style if it is. > > diff --git a/mercurial/hgweb/server.py b/mercurial/hgweb/server.py > --- a/mercurial/hgweb/server.py > +++ b/mercurial/hgweb/server.py > @@ -263,7 +263,7 @@ > return open(opt, 'a') > return default > > -class MercurialHTTPServer(object, _mixin, httpservermod.httpserver): > +class MercurialHTTPServer(_mixin, httpservermod.httpserver, object): It's an excellent one :D > > # SO_REUSEADDR has broken semantics on windows > if os.name == 'nt': > ___ > 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] hgweb: fix the MRO in Python 3
# HG changeset patch # User Martijn Pieters# Date 1475946679 -7200 # Sat Oct 08 19:11:19 2016 +0200 # Node ID 8475a954a40385035b57abe05af31308597a0b3c # Parent 2c8ec8c2ddfeb2d229b81eb5b11e3639fb34b0a0 hgweb: fix the MRO in Python 3 object should appear at the end, otherwise it tries to pre-empt the other new-style classes in the MRO, resulting in an unresolvable MRO in Py3. We still need to include object because otherwise in 2.7 we end up with an old-style class if threading is not supported, new-style if it is. diff --git a/mercurial/hgweb/server.py b/mercurial/hgweb/server.py --- a/mercurial/hgweb/server.py +++ b/mercurial/hgweb/server.py @@ -263,7 +263,7 @@ return open(opt, 'a') return default -class MercurialHTTPServer(object, _mixin, httpservermod.httpserver): +class MercurialHTTPServer(_mixin, httpservermod.httpserver, object): # SO_REUSEADDR has broken semantics on windows if os.name == 'nt': ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] util: document we want Python type mapping to be temporary
# HG changeset patch # User Gregory Szorc# Date 1475947010 -7200 # Sat Oct 08 19:16:50 2016 +0200 # Node ID d15d8ac73cfd2d1ddbd443262ccad9c68ee69406 # Parent 266ad9c9faa524a8b3f473c924db409681cb205e util: document we want Python type mapping to be temporary I think remapping Python C API types and functions is not a great approach. I'd prefer this whole #ifdef disappeared. Add a comment so we don't forget about it. diff --git a/mercurial/util.h b/mercurial/util.h --- a/mercurial/util.h +++ b/mercurial/util.h @@ -12,8 +12,11 @@ #if PY_MAJOR_VERSION >= 3 #define IS_PY3K +/* The mapping of Python types is meant to be temporary to get Python + * 3 to compile. We should remove this once Python 3 support is fully + * supported and proper types are used in the extensions themselves. */ #define PyInt_Type PyLong_Type #define PyInt_FromLong PyLong_FromLong #define PyInt_AsLong PyLong_AsLong ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH v5] copy: distinguish "file exists" cases and add a hint (BC)
# HG changeset patch # User Augie Fackler# Date 1474319739 14400 # Mon Sep 19 17:15:39 2016 -0400 # Node ID 3d6ce2e360155bcc7e5af21fd0fda3415aa03110 # Parent dd0ff715a82caa9afd0fa999dccca4d967a506a3 copy: distinguish "file exists" cases and add a hint (BC) Users that want to add a copy record to an existing commit with 'hg commit --amend' should be guided towards this workflow, rather than reaching for some sort of uncommit-recommit flow. As part of this, distinguish in the top-line error message whether the file merely already exists (untracked) on disk or the file already exists in history. The full list of copy and rename cases and how they interact with flags are listed below: target exists --after --force | action nn *| copy ny *| (1) untrackedn n| (4) NEWHINT untrackedn y| (3) untrackedy *| (2) yn n| (4) NEWHINT yn y| (3) yy n| (2) yy y| (3) deleted n n| copy deleted n y| (3) deleted y n| (1) deleted y y| (1) * = don't care (1) : not recording move - does not exist (2) preserve target contents (3) replace target contents (4) : not overwriting - file {exists,already committed} Credit to Kevin for wholly rewriting my table to cover more cases we discovered at the sprint. I think this change gets the hints correct in all cases, but I'd appreciate close inspection of the test cases to make sure I haven't gotten turned around in here. diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -640,8 +640,26 @@ def copy(ui, repo, pats, opts, rename=Fa if not after and exists or after and state in 'mn': if not opts['force']: -ui.warn(_('%s: not overwriting - file exists\n') % -reltarget) +if state in 'mn': +msg = _('%s: not overwriting - file already committed\n') +if after: +flags = '--after --force' +else: +flags = '--force' +if rename: +hint = _('(hg rename %s to replace the file by ' + 'recording a rename)\n') % flags +else: +hint = _('(hg copy %s to replace the file by ' + 'recording a copy)\n') % flags +else: +msg = _('%s: not overwriting - file exists\n') +if rename: +hint = _('(hg rename --after to record the rename)\n') +else: +hint = _('(hg copy --after to record the copy)\n') +ui.warn(msg % reltarget) +ui.warn(hint) return if after: diff --git a/tests/test-copy.t b/tests/test-copy.t --- a/tests/test-copy.t +++ b/tests/test-copy.t @@ -226,11 +226,23 @@ foo was clean: C foo Trying to copy on top of an existing file fails, $ hg copy -A bar foo - foo: not overwriting - file exists + foo: not overwriting - file already committed + (hg copy --after --force to replace the file by recording a copy) +same error without the --after, so the user doesn't have to go through +two hints: + $ hg copy bar foo + foo: not overwriting - file already committed + (hg copy --force to replace the file by recording a copy) but it's considered modified after a copy --after --force $ hg copy -Af bar foo $ hg st -AC foo M foo bar +The hint for a file that exists but is not in file history doesn't +mention --force: + $ touch xyzzy + $ hg cp bar xyzzy + xyzzy: not overwriting - file exists + (hg copy --after to record the copy) $ cd .. diff --git a/tests/test-rename.t b/tests/test-rename.t --- a/tests/test-rename.t +++ b/tests/test-rename.t @@ -265,7 +265,8 @@ move everything under directory d1 to ex overwrite existing files (d2/b) $ hg rename d1/* d2 - d2/b: not overwriting - file exists + d2/b: not overwriting - file already committed + (hg rename --force to replace the file by recording a rename) moving d1/d11/a1 to d2/d11/a1 (glob) $ hg status -C A d2/a @@ -370,6 +371,7 @@ attempt to overwrite an existing file $ echo "ca" > d1/ca $ hg rename d1/ba d1/ca d1/ca: not overwriting - file exists + (hg rename --after to record the rename) $ hg status -C ? d1/ca $ hg update -C @@ -393,6 +395,7 @@ attempt to overwrite an existing broken $ ln -s ba d1/ca $ hg rename --traceback d1/ba d1/ca d1/ca: not overwriting - file exists + (hg rename --after to record the rename) $ hg status -C ? d1/ca $ hg update -C
[PATCH 1 of 2] parsers: return NULL from PyInit_parsers on Python 3
# HG changeset patch # User Gregory Szorc# Date 1475941889 -7200 # Sat Oct 08 17:51:29 2016 +0200 # Node ID 66c3f600e684f2323ac56c16eba6a57930f8919e # Parent f98e32b5c44fafb85bee108abe2a24595e59ddbc parsers: return NULL from PyInit_parsers on Python 3 This function must return a PyObject* or the compiler complains. diff --git a/mercurial/parsers.c b/mercurial/parsers.c --- a/mercurial/parsers.c +++ b/mercurial/parsers.c @@ -2879,9 +2879,9 @@ PyMODINIT_FUNC PyInit_parsers(void) { PyObject *mod; if (check_python_version() == -1) - return; + return NULL; mod = PyModule_Create(_module); module_init(mod); return mod; } ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 2] util: define PyInt_Type on Python 3
# HG changeset patch # User Gregory Szorc# Date 1475946164 -7200 # Sat Oct 08 19:02:44 2016 +0200 # Node ID 266ad9c9faa524a8b3f473c924db409681cb205e # Parent 66c3f600e684f2323ac56c16eba6a57930f8919e util: define PyInt_Type on Python 3 util.h attempts to wallpaper over C API differences between Python 2 and 3. This is not the correct approach where performance is critical. But it is good enough for the current state of the Python 3 port. diff --git a/mercurial/util.h b/mercurial/util.h --- a/mercurial/util.h +++ b/mercurial/util.h @@ -12,8 +12,9 @@ #if PY_MAJOR_VERSION >= 3 #define IS_PY3K +#define PyInt_Type PyLong_Type #define PyInt_FromLong PyLong_FromLong #define PyInt_AsLong PyLong_AsLong /* ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] import: abort instead of crashing when copy source does not exist (issue5375)
On 10/08/2016 06:11 PM, Ryan McElroy wrote: # HG changeset patch # User Ryan McElroy# Date 1475929618 25200 # Sat Oct 08 05:26:58 2016 -0700 # Node ID 961569a2cbeebfd54c9369c6e36d03d4938aef38 # Parent dbcef8918bbdd8a64d9f79a37bcfa284a26f3a39 import: abort instead of crashing when copy source does not exist (issue5375) Previously, when a patch contained a move or copy from a source that did not exist, `hg import` would crash. This patch changes import to raise a PatchError with an explanantion of what is wrong with the patch to avoid the stack trace and bad user experience. diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -1952,8 +1952,10 @@ def _applydiff(ui, fp, patcher, backend, data, mode = None, None if gp.op in ('RENAME', 'COPY'): data, mode = store.getfile(gp.oldpath)[:2] -# FIXME: failing getfile has never been handled here -assert data is not None +if data is None: +# This means that the old path does not exist +raise PatchError(_("source file '%s' does not exist") + % gp.oldpath) if gp.mode: mode = gp.mode if gp.op == 'ADD': diff --git a/tests/test-import.t b/tests/test-import.t --- a/tests/test-import.t +++ b/tests/test-import.t @@ -1793,3 +1793,13 @@ repository when file not found for patch 1 out of 1 hunks FAILED -- saving rejects to file file1.rej abort: patch failed to apply [255] + +test import crash (issue5375) + $ cd .. + $ hg init repo + $ cd repo + $ printf "diff --git a/a b/b\nrename from a\nrename to b" | hg import - + applying patch from stdin + a not tracked! + abort: source file 'a' does not exist + [255] Hmm. For a patch modifying a non-existing file we already get: unable to find 'f' for patching 1 out of 1 hunks FAILED -- saving rejects to file f.rej patch failed, unable to continue (try -v) patch failed, rejects left in working directory $ cat f.rej --- f +++ f @@ -1,1 +1,2 @@ +f In the tested case, I would thus also expect it to leave a .rej file with the failing rename "hunk" while applying the rest of the patch (even though a pure rename arguably *doesn't* have any hunks). BUT the logic around this check seems wrong. A rename or copy of a missing file should be handled exactly the same, no matter if it is a bare rename/copy or if it also modifies the file (= has a first hunk). I don't know if it is better to give a not-entirely-correct abort than to fail with an assertion error, but I think it still deserves a FIXME/TODO. (The iterhunks docstring seems wrong, for example regarding 'file' entries and firsthunk. Let's go find pmezard!) /Mads ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] templater: add relpath() to convert repo path to relative path (issue5394)
# HG changeset patch # User Yuya Nishihara# Date 1475933066 -7200 # Sat Oct 08 15:24:26 2016 +0200 # Node ID 83e6528647265043ed30be784e0db8fd59133230 # Parent 2def3d55b1b9ec2acd53f96ca755d778b5ec865b templater: add relpath() to convert repo path to relative path (issue5394) File paths in template are repository-absolute paths. This function can be used to convert them to filesystem paths relative to cwd. This also converts '/' to '\\' on Windows. diff --git a/mercurial/templater.py b/mercurial/templater.py --- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -713,6 +713,18 @@ def localdate(context, mapping, args): tzoffset = util.makedate()[1] return (date[0], tzoffset) +@templatefunc('relpath(path)') +def relpath(context, mapping, args): +"""Convert a repository-absolute path into a filesystem path relative to +the current working directory.""" +if len(args) != 1: +# i18n: "relpath" is a keyword +raise error.ParseError(_("relpath expects one argument")) + +repo = mapping['ctx'].repo() +path = evalstring(context, mapping, args[0]) +return repo.pathto(path) + @templatefunc('revset(query[, formatargs...])') def revset(context, mapping, args): """Execute a revision set query. See diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -3521,6 +3521,15 @@ Test files function 0 +Test relpath function + + $ hg log -r0 -T '{files % "{file|relpath}\n"}' + a + $ cd .. + $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}' + r/a (glob) + $ cd r + Test active bookmark templating $ hg book foo ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] match: adding non-recursive directory matching
# HG changeset patch # User Rodrigo Damazio Bovendorp# Date 1475944120 25200 # Sat Oct 08 09:28:40 2016 -0700 # Node ID 545efe5a72efdce925a6a3fd3774b350c90b5c55 # Parent dbcef8918bbdd8a64d9f79a37bcfa284a26f3a39 match: adding non-recursive directory matching This allows one to match all files in a directory, without matching anything in subdirectories. It's implemented almost identically to path:, except for the regex termination, which doesn't allow more than one / after the directory name. diff --git a/mercurial/match.py b/mercurial/match.py --- a/mercurial/match.py +++ b/mercurial/match.py @@ -105,6 +105,9 @@ 'glob:' - a glob relative to cwd 're:' - a regular expression 'path:' - a path relative to repository root +'files:' - a path relative to repository root, which is matched + non-recursively (files inside the directory will match, + but subdirectories and files in them won't 'relglob:' - an unrooted glob (*.c matches C files in all dirs) 'relpath:' - a path relative to cwd 'relre:' - a regexp that needn't match the start of a name @@ -286,7 +289,7 @@ for kind, pat in [_patsplit(p, default) for p in patterns]: if kind in ('glob', 'relpath'): pat = pathutil.canonpath(root, cwd, pat, auditor) -elif kind in ('relglob', 'path'): +elif kind in ('relglob', 'path', 'files'): pat = util.normpath(pat) elif kind in ('listfile', 'listfile0'): try: @@ -447,7 +450,8 @@ if ':' in pattern: kind, pat = pattern.split(':', 1) if kind in ('re', 'glob', 'path', 'relglob', 'relpath', 'relre', -'listfile', 'listfile0', 'set', 'include', 'subinclude'): +'listfile', 'listfile0', 'set', 'include', 'subinclude', +'files'): return kind, pat return default, pattern @@ -540,6 +544,19 @@ if pat == '.': return '' return '^' + util.re.escape(pat) + '(?:/|$)' +if kind == 'files': +# Match one of: +# For pat = 'some/dir': +# some/dir +# some/dir/ +# some/dir/filename +# For pat = '' or pat = '.': +# filename +if pat == '.': +escaped = '' +else: +escaped = util.re.escape(pat) +return '^' + escaped + '(?:^|/|$)[^/]*$' if kind == 'relglob': return '(?:|.*/)' + _globre(pat) + globsuffix if kind == 'relpath': @@ -628,7 +645,7 @@ break root.append(p) r.append('/'.join(root) or '.') -elif kind in ('relpath', 'path'): +elif kind in ('relpath', 'path', 'files'): r.append(pat or '.') else: # relglob, re, relre r.append('.') diff --git a/tests/test-locate.t b/tests/test-locate.t --- a/tests/test-locate.t +++ b/tests/test-locate.t @@ -52,6 +52,12 @@ t/b t/e.h t/x + $ hg locate files: + b + t.h + $ hg locate files:. + b + t.h $ hg locate -r 0 a a $ hg locate -r 0 NONEXISTENT @@ -119,6 +125,13 @@ ../t/e.h (glob) ../t/x (glob) + $ hg files files: + ../b (glob) + ../t.h (glob) + $ hg files files:. + ../b (glob) + ../t.h (glob) + $ hg locate b ../b (glob) ../t/b (glob) diff --git a/tests/test-walk.t b/tests/test-walk.t --- a/tests/test-walk.t +++ b/tests/test-walk.t @@ -112,6 +112,8 @@ f beans/navy ../beans/navy f beans/pinto ../beans/pinto f beans/turtle../beans/turtle + $ hg debugwalk -I 'files:mammals' + f mammals/skunk skunk $ hg debugwalk . f mammals/Procyonidae/cacomistle Procyonidae/cacomistle f mammals/Procyonidae/coatimundi Procyonidae/coatimundi ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] py3: revset - change iteritems to items
On Sat, 8 Oct 2016 18:42:55 +0200, Martijn Pieters wrote: > On 8 October 2016 at 18:37, Mateusz Kwapichwrote: > > # HG changeset patch > > # User Mateusz Kwapich > > # Date 1475944606 25200 > > # Sat Oct 08 09:36:46 2016 -0700 > > # Node ID 18cee0bbfd402a5005b286b723a6a495bf86a165 > > # Parent 02795fabd7daf1b35b4d36de3dbca16e55a63451 > > py3: revset - change iteritems to items > > > > If we'll ever have so many revset predicated so that using "items" is > > creating > > pref problems we'll have bigger problem than just that. > > LGTM. We may still want to figure out why the importer hook doesn't catch > this one; This is a bug of check-py3-compat.py. It appears modules imported _only_ by imp.load_module() aren't transformed by our importer. I'm trying to fix this issue. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] hgweb: make fctx.annotate a separated function so it could be wrapped
On Sat, Oct 08, 2016 at 04:17:13PM +0100, Jun Wu wrote: > # HG changeset patch > # User Jun Wu> # Date 1475939434 -3600 > # Sat Oct 08 16:10:34 2016 +0100 > # Node ID 30141bc03ab8608b04aa717e4dee46046c00f5d6 > # Parent cd7276f7ea8308df2c5d8874d335d73247d0f357 > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > 30141bc03ab8 > hgweb: make fctx.annotate a separated function so it could be wrapped Queued with enthusiasm for our faster annotation overlords. > > This patch moves "fctx.annotate" used by the "annotate" webcommand, along > with the diffopts to a separated function which takes a ui and a fctx. > So it could be replaced by other implementations which don't want to replace > the core "fctx.annotate" directly. > > diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py > --- a/mercurial/hgweb/webcommands.py > +++ b/mercurial/hgweb/webcommands.py > @@ -32,5 +32,4 @@ from .. import ( > error, > graphmod, > -patch, > revset, > scmutil, > @@ -862,6 +861,4 @@ def annotate(web, req, tmpl): > f = fctx.path() > parity = paritygen(web.stripecount) > -diffopts = patch.difffeatureopts(web.repo.ui, untrusted=True, > - section='annotate', whitespace=True) > > def parents(f): > @@ -878,6 +875,6 @@ def annotate(web, req, tmpl): > lines = [((fctx.filectx(fctx.filerev()), 1), '(binary:%s)' % mt)] > else: > -lines = fctx.annotate(follow=True, linenumber=True, > - diffopts=diffopts) > +lines = webutil.annotate(fctx, web.repo.ui) > + > previousrev = None > blockparitygen = paritygen(1) > diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py > --- a/mercurial/hgweb/webutil.py > +++ b/mercurial/hgweb/webutil.py > @@ -165,4 +165,9 @@ class _siblings(object): > return len(self.siblings) > > +def annotate(fctx, ui): > +diffopts = patch.difffeatureopts(ui, untrusted=True, > + section='annotate', whitespace=True) > +return fctx.annotate(follow=True, linenumber=True, diffopts=diffopts) > + > def parents(ctx, hide=None): > if isinstance(ctx, context.basefilectx): > ___ > 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] py3: revset - change iteritems to items
On 8 October 2016 at 18:37, Mateusz Kwapichwrote: > # HG changeset patch > # User Mateusz Kwapich > # Date 1475944606 25200 > # Sat Oct 08 09:36:46 2016 -0700 > # Node ID 18cee0bbfd402a5005b286b723a6a495bf86a165 > # Parent 02795fabd7daf1b35b4d36de3dbca16e55a63451 > py3: revset - change iteritems to items > > If we'll ever have so many revset predicated so that using "items" is > creating > pref problems we'll have bigger problem than just that. > LGTM. We may still want to figure out why the importer hook doesn't catch this one; there may be other places (in external code) where it'll fail too. Low priority with this fix though. > diff --git a/mercurial/revset.py b/mercurial/revset.py > --- a/mercurial/revset.py > +++ b/mercurial/revset.py > @@ -3835,7 +3835,7 @@ def prettyformatset(revs): > def loadpredicate(ui, extname, registrarobj): > """Load revset predicates from specified registrarobj > """ > -for name, func in registrarobj._table.iteritems(): > +for name, func in registrarobj._table.items(): > symbols[name] = func > if func._safe: > safesymbols.add(name) > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel > -- Martijn Pieters ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH V2] manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
On Sat, Oct 08, 2016 at 06:05:12PM +0200, Gregory Szorc wrote: > # HG changeset patch > # User Gregory Szorc> # Date 1475942697 -7200 > # Sat Oct 08 18:04:57 2016 +0200 > # Node ID f98e32b5c44fafb85bee108abe2a24595e59ddbc > # Parent ece8e9fc1bf2effb388bbca7222d3c644996aa2b > manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3 queued, thanks > > This flag disappeared in Python 3. It is only necessary in Python 2, > apparently. > > diff --git a/mercurial/manifest.c b/mercurial/manifest.c > --- a/mercurial/manifest.c > +++ b/mercurial/manifest.c > @@ -253,8 +253,15 @@ done: > Py_XDECREF(flags); > return ret; > } > > +#ifdef IS_PY3K > +#define LAZYMANIFESTENTRIESITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT > +#else > +#define LAZYMANIFESTENTRIESITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT \ > + | Py_TPFLAGS_HAVE_ITER > +#endif > + > static PyTypeObject lazymanifestEntriesIterator = { > PyObject_HEAD_INIT(NULL) > 0, /*ob_size */ > "parsers.lazymanifest.entriesiterator", /*tp_name */ > @@ -274,11 +281,9 @@ static PyTypeObject lazymanifestEntriesI > 0, /*tp_str */ > 0, /*tp_getattro */ > 0, /*tp_setattro */ > 0, /*tp_as_buffer */ > - /* tp_flags: Py_TPFLAGS_HAVE_ITER tells python to > -use tp_iter and tp_iternext fields. */ > - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, > + LAZYMANIFESTENTRIESITERATOR_TPFLAGS, /* tp_flags */ > "Iterator for 3-tuples in a lazymanifest.", /* tp_doc */ > 0, /* tp_traverse */ > 0, /* tp_clear */ > 0, /* tp_richcompare */ > @@ -297,8 +302,15 @@ static PyObject *lmiter_iterkeysnext(PyO > pl = pathlen(l); > return PyString_FromStringAndSize(l->start, pl); > } > > +#ifdef IS_PY3K > +#define LAZYMANIFESTKEYSITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT > +#else > +#define LAZYMANIFESTKEYSITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT \ > + | Py_TPFLAGS_HAVE_ITER > +#endif > + > static PyTypeObject lazymanifestKeysIterator = { > PyObject_HEAD_INIT(NULL) > 0, /*ob_size */ > "parsers.lazymanifest.keysiterator", /*tp_name */ > @@ -318,11 +330,9 @@ static PyTypeObject lazymanifestKeysIter > 0, /*tp_str */ > 0, /*tp_getattro */ > 0, /*tp_setattro */ > 0, /*tp_as_buffer */ > - /* tp_flags: Py_TPFLAGS_HAVE_ITER tells python to > -use tp_iter and tp_iternext fields. */ > - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, > + LAZYMANIFESTKEYSITERATOR_TPFLAGS, /* tp_flags */ > "Keys iterator for a lazymanifest.", /* tp_doc */ > 0, /* tp_traverse */ > 0, /* tp_clear */ > 0, /* tp_richcompare */ > @@ -872,8 +882,14 @@ static PyMethodDef lazymanifest_methods[ >"Encode this manifest to text."}, > {NULL}, > }; > > +#ifdef IS_PY3K > +#define LAZYMANIFEST_TPFLAGS Py_TPFLAGS_DEFAULT > +#else > +#define LAZYMANIFEST_TPFLAGS Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_SEQUENCE_IN > +#endif > + > static PyTypeObject lazymanifestType = { > PyObject_HEAD_INIT(NULL) > 0,/* ob_size */ > "parsers.lazymanifest", /* tp_name */ > @@ -893,9 +909,9 @@ static PyTypeObject lazymanifestType = { > 0,/* tp_str */ > 0,/* tp_getattro */ > 0,/* tp_setattro */ > 0,/* tp_as_buffer */ > - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_SEQUENCE_IN, /* tp_flags */ > + LAZYMANIFEST_TPFLAGS, /* tp_flags */ > "TODO(augie)",/* tp_doc */ > 0,/* tp_traverse */ > 0,/* tp_clear */ > 0,/* tp_richcompare */ > ___ > 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 1 of 7] copies: don't record divergence for files needing no merge
On 10/07/2016 02:31 PM, Gábor Stefanik wrote: # HG changeset patch # User Gábor Stefanik# Date 1475494199 -7200 # Mon Oct 03 13:29:59 2016 +0200 # Node ID 5b7cd65a9be6c82b3ad14096b41db44c198a6769 # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 copies: don't record divergence for files needing no merge Patch 1 is pushed. -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] import: abort instead of crashing when copy source does not exist (issue5375)
On Sat, Oct 08, 2016 at 09:11:38AM -0700, Ryan McElroy wrote: > # HG changeset patch > # User Ryan McElroy> # Date 1475929618 25200 > # Sat Oct 08 05:26:58 2016 -0700 > # Node ID 961569a2cbeebfd54c9369c6e36d03d4938aef38 > # Parent dbcef8918bbdd8a64d9f79a37bcfa284a26f3a39 > import: abort instead of crashing when copy source does not exist (issue5375) Queued, thanks > > Previously, when a patch contained a move or copy from a source that did not > exist, `hg import` would crash. This patch changes import to raise a > PatchError > with an explanantion of what is wrong with the patch to avoid the stack trace > and bad user experience. > > diff --git a/mercurial/patch.py b/mercurial/patch.py > --- a/mercurial/patch.py > +++ b/mercurial/patch.py > @@ -1952,8 +1952,10 @@ def _applydiff(ui, fp, patcher, backend, > data, mode = None, None > if gp.op in ('RENAME', 'COPY'): > data, mode = store.getfile(gp.oldpath)[:2] > -# FIXME: failing getfile has never been handled here > -assert data is not None > +if data is None: > +# This means that the old path does not exist > +raise PatchError(_("source file '%s' does not exist") > + % gp.oldpath) > if gp.mode: > mode = gp.mode > if gp.op == 'ADD': > diff --git a/tests/test-import.t b/tests/test-import.t > --- a/tests/test-import.t > +++ b/tests/test-import.t > @@ -1793,3 +1793,13 @@ repository when file not found for patch >1 out of 1 hunks FAILED -- saving rejects to file file1.rej >abort: patch failed to apply >[255] > + > +test import crash (issue5375) > + $ cd .. > + $ hg init repo > + $ cd repo > + $ printf "diff --git a/a b/b\nrename from a\nrename to b" | hg import - > + applying patch from stdin > + a not tracked! > + abort: source file 'a' does not exist > + [255] > ___ > 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] py3: make encodefun in store.py compatible with py3k
On Sat, Oct 08, 2016 at 08:55:46AM -0700, Mateusz Kwapich wrote: > # HG changeset patch > # User Mateusz Kwapich> # Date 1475942045 25200 > # Sat Oct 08 08:54:05 2016 -0700 > # Node ID 086b25d1866e33fb7ebbe6c51522e6b573e281e2 > # Parent 225efa4bf7f497e55f0ba57f64a33dce39eaeb29 > py3: make encodefun in store.py compatible with py3k Queued thanks > > This ensures that the filename encoding functions always map bytestrings > to bytestrings regardless of python version. > > diff --git a/mercurial/store.py b/mercurial/store.py > --- a/mercurial/store.py > +++ b/mercurial/store.py > @@ -16,6 +16,7 @@ from .i18n import _ > from . import ( > error, > parsers, > +pycompat, > scmutil, > util, > ) > @@ -98,11 +99,20 @@ def _buildencodefun(): > 'the\\x07quick\\xadshot' > ''' > e = '_' > -cmap = dict([(chr(x), chr(x)) for x in xrange(127)]) > +if pycompat.ispy3: > +xchr = lambda x: bytes([x]) > +asciistr = bytes(xrange(127)) > +else: > +xchr = chr > +asciistr = map(chr, xrange(127)) > +capitals = list(range(ord("A"), ord("Z") + 1)) > + > +cmap = {x:x for x in asciistr} > for x in _reserved(): > -cmap[chr(x)] = "~%02x" % x > -for x in list(range(ord("A"), ord("Z") + 1)) + [ord(e)]: > -cmap[chr(x)] = e + chr(x).lower() > +cmap[xchr(x)] = "~%02x" % x > +for x in capitals + [ord(e)]: > +cmap[xchr(x)] = e + xchr(x).lower() > + > dmap = {} > for k, v in cmap.iteritems(): > dmap[v] = k > diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t > --- a/tests/test-check-py3-compat.t > +++ b/tests/test-check-py3-compat.t > @@ -134,7 +134,6 @@ >mercurial/sshserver.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) >mercurial/statichttprepo.py: error importing: module > 'mercurial.util' has no attribute 'urlerr' (error at byterange.py:*) >mercurial/store.py: error importing module: name 'xrange' is > not defined (line *) > - mercurial/streamclone.py: error importing: can't concat bytes > to str (error at store.py:*) >mercurial/subrepo.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) >mercurial/templatefilters.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) >mercurial/templatekw.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > ___ > 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 RFC] templater: provide ring operations on integers
This is RFC because I have no idea what I'm doing in the parser. If someone at the sprint has 5 minutes available to educate me, I can update this to a better version. On 08/10/2016 18:24, Simon Farnsworth wrote: # HG changeset patch # User Simon Farnsworth# Date 1475943860 25200 # Sat Oct 08 09:24:20 2016 -0700 # Node ID e89699ba5c9f0bf883bfae7c485e50219b90b2f9 # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 templater: provide ring operations on integers The termwidth template keyword is of limited use without some way to ensure that margins are respected. Provide the three core ring operations - addition, subtraction and multiplication. We can extend to division and modulus later if necessary. diff --git a/mercurial/templater.py b/mercurial/templater.py --- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -33,6 +33,9 @@ "|": (5, None, None, ("|", 5), None), "%": (6, None, None, ("%", 6), None), ")": (0, None, None, None, None), +"+": (10, None, None, ("+", 10), None), +"-": (10, None, ("negate", 10), ("-", 10), None), +"*": (12, None, None, ("*", 12), None), "integer": (0, "integer", None, None, None), "symbol": (0, "symbol", None, None, None), "string": (0, "string", None, None, None), @@ -48,7 +51,7 @@ c = program[pos] if c.isspace(): # skip inter-token whitespace pass -elif c in "(,)%|": # handle simple operators +elif c in "(,)%|+-*": # handle simple operators yield (c, None, pos) elif c in '"\'': # handle quoted templates s = pos + 1 @@ -70,7 +73,7 @@ pos += 1 else: raise error.ParseError(_("unterminated string"), s) -elif c.isdigit() or c == '-': +elif c.isdigit(): s = pos if c == '-': # simply take negate operator as part of integer pos += 1 @@ -420,6 +423,29 @@ # If so, return the expanded value. yield i +def buildnegate(exp, context): +arg = compileexp(exp[1], context, exprmethods) +return (runnegate, arg) + +def runnegate(context, mapping, data): +data = evalinteger(context, mapping, data, +_('negation needs an integer argument')) +return -data + + +def buildarithmetic(exp, context, func): +left = compileexp(exp[1], context, exprmethods) +right = compileexp(exp[2], context, exprmethods) +return (runarithmetic, (func, left, right)) + +def runarithmetic(context, mapping, data): +func, left, right = data +left = evalinteger(context, mapping, left, +_('arithmetic only defined on integers')) +right = evalinteger(context, mapping, right, +_('arithmetic only defined on integers')) +return func(left, right) + def buildfunc(exp, context): n = getsymbol(exp[1]) args = [compileexp(x, context, exprmethods) for x in getlist(exp[2])] @@ -906,6 +932,7 @@ # methods to interpret function arguments or inner expressions (e.g. {_(x)}) exprmethods = { "integer": lambda e, c: (runinteger, e[1]), +"negate": lambda e, c: (runinteger, e[1]), "string": lambda e, c: (runstring, e[1]), "symbol": lambda e, c: (runsymbol, e[1]), "template": buildtemplate, @@ -914,6 +941,10 @@ "|": buildfilter, "%": buildmap, "func": buildfunc, +"+": lambda e, c: buildarithmetic(e, c, lambda a, b: a + b), +"-": lambda e, c: buildarithmetic(e, c, lambda a, b: a - b), +"negate": buildnegate, +"*": lambda e, c: buildarithmetic(e, c, lambda a, b: a * b), } # methods to interpret top-level template (e.g. {x}, {x|_}, {x % "y"}) diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -5,6 +5,8 @@ $ echo line 1 > b $ echo line 2 >> b $ hg commit -l b -d '100 0' -u 'User Name ' + $ hg log -T '{date(date, "%s") + 1} {date(date, "%s") - 2 * 1}\n' + 101 98 $ hg add b $ echo other 1 > c @@ -2890,14 +2892,15 @@ $ hg debugtemplate -v '{(-4)}\n' (template (group - ('integer', '-4')) + (negate +('integer', '4'))) ('string', '\n')) -4 $ hg debugtemplate '{(-)}\n' - hg: parse error at 2: integer literal without digits + hg: parse error at 3: not a prefix: ) [255] $ hg debugtemplate '{(-a)}\n' - hg: parse error at 2: integer literal without digits + hg: parse error: negation needs an integer argument [255] top-level integer literal is interpreted as symbol (i.e. variable name): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org
[PATCH RFC] templater: provide ring operations on integers
# HG changeset patch # User Simon Farnsworth# Date 1475943860 25200 # Sat Oct 08 09:24:20 2016 -0700 # Node ID e89699ba5c9f0bf883bfae7c485e50219b90b2f9 # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 templater: provide ring operations on integers The termwidth template keyword is of limited use without some way to ensure that margins are respected. Provide the three core ring operations - addition, subtraction and multiplication. We can extend to division and modulus later if necessary. diff --git a/mercurial/templater.py b/mercurial/templater.py --- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -33,6 +33,9 @@ "|": (5, None, None, ("|", 5), None), "%": (6, None, None, ("%", 6), None), ")": (0, None, None, None, None), +"+": (10, None, None, ("+", 10), None), +"-": (10, None, ("negate", 10), ("-", 10), None), +"*": (12, None, None, ("*", 12), None), "integer": (0, "integer", None, None, None), "symbol": (0, "symbol", None, None, None), "string": (0, "string", None, None, None), @@ -48,7 +51,7 @@ c = program[pos] if c.isspace(): # skip inter-token whitespace pass -elif c in "(,)%|": # handle simple operators +elif c in "(,)%|+-*": # handle simple operators yield (c, None, pos) elif c in '"\'': # handle quoted templates s = pos + 1 @@ -70,7 +73,7 @@ pos += 1 else: raise error.ParseError(_("unterminated string"), s) -elif c.isdigit() or c == '-': +elif c.isdigit(): s = pos if c == '-': # simply take negate operator as part of integer pos += 1 @@ -420,6 +423,29 @@ # If so, return the expanded value. yield i +def buildnegate(exp, context): +arg = compileexp(exp[1], context, exprmethods) +return (runnegate, arg) + +def runnegate(context, mapping, data): +data = evalinteger(context, mapping, data, +_('negation needs an integer argument')) +return -data + + +def buildarithmetic(exp, context, func): +left = compileexp(exp[1], context, exprmethods) +right = compileexp(exp[2], context, exprmethods) +return (runarithmetic, (func, left, right)) + +def runarithmetic(context, mapping, data): +func, left, right = data +left = evalinteger(context, mapping, left, +_('arithmetic only defined on integers')) +right = evalinteger(context, mapping, right, +_('arithmetic only defined on integers')) +return func(left, right) + def buildfunc(exp, context): n = getsymbol(exp[1]) args = [compileexp(x, context, exprmethods) for x in getlist(exp[2])] @@ -906,6 +932,7 @@ # methods to interpret function arguments or inner expressions (e.g. {_(x)}) exprmethods = { "integer": lambda e, c: (runinteger, e[1]), +"negate": lambda e, c: (runinteger, e[1]), "string": lambda e, c: (runstring, e[1]), "symbol": lambda e, c: (runsymbol, e[1]), "template": buildtemplate, @@ -914,6 +941,10 @@ "|": buildfilter, "%": buildmap, "func": buildfunc, +"+": lambda e, c: buildarithmetic(e, c, lambda a, b: a + b), +"-": lambda e, c: buildarithmetic(e, c, lambda a, b: a - b), +"negate": buildnegate, +"*": lambda e, c: buildarithmetic(e, c, lambda a, b: a * b), } # methods to interpret top-level template (e.g. {x}, {x|_}, {x % "y"}) diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -5,6 +5,8 @@ $ echo line 1 > b $ echo line 2 >> b $ hg commit -l b -d '100 0' -u 'User Name ' + $ hg log -T '{date(date, "%s") + 1} {date(date, "%s") - 2 * 1}\n' + 101 98 $ hg add b $ echo other 1 > c @@ -2890,14 +2892,15 @@ $ hg debugtemplate -v '{(-4)}\n' (template (group - ('integer', '-4')) + (negate +('integer', '4'))) ('string', '\n')) -4 $ hg debugtemplate '{(-)}\n' - hg: parse error at 2: integer literal without digits + hg: parse error at 3: not a prefix: ) [255] $ hg debugtemplate '{(-a)}\n' - hg: parse error at 2: integer literal without digits + hg: parse error: negation needs an integer argument [255] top-level integer literal is interpreted as symbol (i.e. variable name): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 6 of 8 V2] perf: omit copying from ui.ferr to ui.fout for Mercurial earlier than 1.9
# HG changeset patch # User FUJIWARA Katsunori# Date 1475942599 -32400 # Sun Oct 09 01:03:19 2016 +0900 # Node ID 9478ced7cf3ce3665ce06daba820f3eb2b959f61 # Parent 1fb97069cef8454d4658592e44edbaab11d5e34d perf: omit copying from ui.ferr to ui.fout for Mercurial earlier than 1.9 Before this patch, referring ui.ferr prevents perf.py from measuring performance with Mercurial earlier than 1.9 (or 4e1ccd4c2b6d), because ui.ferr isn't available in such Mercurial, even though there are some code paths for Mercurial earlier than 1.9 in perf.py. For example, setting "_prereadsize" attribute in perfindex() and perfnodelookup() is effective only with hg earlier than 1.8 (or 61c9bc3da402). diff --git a/contrib/perf.py b/contrib/perf.py --- a/contrib/perf.py +++ b/contrib/perf.py @@ -137,7 +137,11 @@ def gettimer(ui, opts=None): opts = {} # redirect all to stderr ui = ui.copy() -ui.fout = ui.ferr +uifout = safeattrsetter(ui, 'fout', ignoremissing=True) +if uifout: +# for "historical portability": +# ui.fout/ferr have been available since 1.9 (or 4e1ccd4c2b6d) +uifout.set(ui.ferr) # get a formatter uiformatter = getattr(ui, 'formatter', None) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 7 of 8 V2] perf: replace ui.configint() by getint() for Mercurial earlier than 1.9
# HG changeset patch # User FUJIWARA Katsunori# Date 1475942599 -32400 # Sun Oct 09 01:03:19 2016 +0900 # Node ID 27633d2fb3282c3ba3e7eb9e2232d1c55cab4406 # Parent 9478ced7cf3ce3665ce06daba820f3eb2b959f61 perf: replace ui.configint() by getint() for Mercurial earlier than 1.9 Before this patch, using ui.configint() prevents perf.py from measuring performance with Mercurial earlier than 1.9 (or fa2b596db182), because ui.configint() isn't available in such Mercurial, even though there are some code paths for Mercurial earlier than 1.9 in perf.py. For example, setting "_prereadsize" attribute in perfindex() and perfnodelookup() is effective only with hg earlier than 1.8 (or 61c9bc3da402). This patch replaces ui.configint() invocations by newly introduced getint(). This patch also adds check-perf-code.py an extra check entry to detect direct usage of ui.configint() in perf.py. BTW, this patch doesn't choose adding configint() method at runtime by replacing ui.__class__ like below, even though this is the recommended way to modern Mercurial extensions. def uisetup(ui): if not util.safehasattr(ui, 'configint'): class uiwrap(ui.__class__): def configint(self, section, name, ): ui.__class__ = uiwrap Because changes to ui.__class__ by uisetup() of loaded extension have been propagated since 1.6.1 (or d8d0fc3988ca), the recommended way above doesn't work as expected with Mercurial earlier than it. diff --git a/contrib/perf.py b/contrib/perf.py --- a/contrib/perf.py +++ b/contrib/perf.py @@ -131,7 +131,7 @@ def gettimer(ui, opts=None): # enforce an idle period before execution to counteract power management # experimental config: perf.presleep -time.sleep(ui.configint("perf", "presleep", 1)) +time.sleep(getint(ui, "perf", "presleep", 1)) if opts is None: opts = {} @@ -222,6 +222,18 @@ def _timer(fm, func, title=None): # utilities for historical portability +def getint(ui, section, name, default): +# for "historical portability": +# ui.configint has been available since 1.9 (or fa2b596db182) +v = ui.config(section, name, None) +if v is None: +return default +try: +return int(v) +except ValueError: +raise error.ConfigError(("%s.%s is not an integer ('%s')") +% (section, name, v)) + def safeattrsetter(obj, name, ignoremissing=False): """Ensure that 'obj' has 'name' attribute before subsequent setattr @@ -569,7 +581,7 @@ def perfparents(ui, repo, **opts): timer, fm = gettimer(ui, opts) # control the number of commits perfparents iterates over # experimental config: perf.parentscount -count = ui.configint("perf", "parentscount", 1000) +count = getint(ui, "perf", "parentscount", 1000) if len(repo.changelog) < count: raise error.Abort("repo needs %d commits for this test" % count) repo = repo.unfiltered() diff --git a/tests/check-perf-code.py b/tests/check-perf-code.py --- a/tests/check-perf-code.py +++ b/tests/check-perf-code.py @@ -14,6 +14,8 @@ perfpypats = [ "use getbranchmapsubsettable() for early Mercurial"), (r'\.(vfs|svfs|opener|sopener)', "use getvfs()/getsvfs() for early Mercurial"), +(r'ui\.configint', + "use getint() instead of ui.configint() for early Mercurial"), ], # warnings [ ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 8 V2] perf: get subsettable from appropriate module for Mercurial earlier than 2.9
# HG changeset patch # User FUJIWARA Katsunori# Date 1475942597 -32400 # Sun Oct 09 01:03:17 2016 +0900 # Node ID ab2d4d5e7821c321017cdbdae7743824c0da76ff # Parent a03b967913dd881f750a5848f567d1e0a1d0e7ea perf: get subsettable from appropriate module for Mercurial earlier than 2.9 Before this patch, using branchmap.subsettable prevents perfbranchmap from measuring performance of Mercurial earlier than 2.9 (or 175c6fd8cacc), because 175c6fd8cacc moved subsettable from repoview.py to branchmap.py, even though there are some code paths for Mercurial earlier than 2.9 in perf.py. For example, setting "_prereadsize" attribute in perfindex() and perfnodelookup() is effective only with hg earlier than 1.8 (or 61c9bc3da402). To get subsettable from appropriate module, this patch examines existence of subsettable in branchmap and repoview. This patch also adds check-perf-code.py an extra check entry to detect direct usage of subsettable attribute in perf.py. diff --git a/contrib/perf.py b/contrib/perf.py --- a/contrib/perf.py +++ b/contrib/perf.py @@ -214,6 +214,24 @@ def safeattrsetter(obj, name, ignoremiss return attrutil() +# utilities to examine each internal API changes + +def getbranchmapsubsettable(): +# for "historical portability": +# subsettable is defined in: +# - branchmap since 2.9 (or 175c6fd8cacc) +# - repoview since 2.5 (or 59a9f18d4587) +for mod in (branchmap, repoview): +subsettable = getattr(mod, 'subsettable', None) +if subsettable: +return subsettable + +# bisecting in bcee63733aad::59a9f18d4587 can reach here (both +# branchmap and repoview modules exist, but subsettable attribute +# doesn't) +raise error.Abort(("perfbranchmap not available with this Mercurial"), + hint="use 2.5 or later") + # perf commands @command('perfwalk', formatteropts) @@ -848,10 +866,11 @@ def perfbranchmap(ui, repo, full=False, return d # add filter in smaller subset to bigger subset possiblefilters = set(repoview.filtertable) +subsettable = getbranchmapsubsettable() allfilters = [] while possiblefilters: for name in possiblefilters: -subset = branchmap.subsettable.get(name) +subset = subsettable.get(name) if subset not in possiblefilters: break else: diff --git a/tests/check-perf-code.py b/tests/check-perf-code.py --- a/tests/check-perf-code.py +++ b/tests/check-perf-code.py @@ -10,6 +10,8 @@ import sys # write static check patterns here perfpypats = [ [ +(r'(branchmap|repoview)\.subsettable', + "use getbranchmapsubsettable() for early Mercurial"), ], # warnings [ ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 8 V2] perf: avoid actual writing branch cache out correctly
# HG changeset patch # User FUJIWARA Katsunori# Date 1475942597 -32400 # Sun Oct 09 01:03:17 2016 +0900 # Node ID 33038811b6e57e0fb743223db4c0c99a7c69c652 # Parent ab2d4d5e7821c321017cdbdae7743824c0da76ff perf: avoid actual writing branch cache out correctly Mercurial 2.5 (or 9b6ae29d4801) introduced "perfbranchmap" command, and tried to avoid actual writing branch cache out by replacing write() of branchcache class in branchmap.py with no-op function (probably, for elimination of noisy and heavy file I/O factor). But its implementation isn't correct, because 9b6ae29d4801 replaced not branchmap.branchcache.write() but branchmap.write(). The latter doesn't exist, even at that change. To avoid actual writing branch cache out correctly, this patch replaces branchmap.branchcache.write() with no-op function. To detect mistake of replacement or change of API in the future quickly, this patch uses safeattrsetter() instead of direct attribute assignment. For similarity between replacements, this patch also changes replacement of branchmap.read(). In this patch, replacement of read()/write() can run safely outside "try" block, because two safeattrsetter() invocations ensure that replacement doesn't cause exception. FYI, the table below compares "base" filter wall time of perfbranchmap on recent mozilla-central repo with each Mercurial version between before and after this patch. = = ver beforeafter = = 2.5 18.492334 18.232455 2.6 18.733858 18.156702 2.7 18.245598 18.349210 2.8 18.289070 18.528422 2.9 17.572742 16.989655 3.0 17.406953 17.615012 3.1 17.228419 17.689805 3.2 17.862961 17.718367 3.3 2.632110 2.707960 3.4 3.285683 3.272060 3.5 3.370141 3.352176 3.6 3.366939 3.242455 3.7 3.300778 3.367328 3.8 3.300132 3.267298 3.9 3.418996 3.370265 = = IMHO, there is no serious overlooking performance regression. diff --git a/contrib/perf.py b/contrib/perf.py --- a/contrib/perf.py +++ b/contrib/perf.py @@ -884,16 +884,17 @@ def perfbranchmap(ui, repo, full=False, repo.filtered(name).branchmap() # add unfiltered allfilters.append(None) -oldread = branchmap.read -oldwrite = branchmap.branchcache.write + +branchcacheread = safeattrsetter(branchmap, 'read') +branchcachewrite = safeattrsetter(branchmap.branchcache, 'write') +branchcacheread.set(lambda repo: None) +branchcachewrite.set(lambda bc, repo: None) try: -branchmap.read = lambda repo: None -branchmap.write = lambda repo: None for name in allfilters: timer(getbranchmap(name), title=str(name)) finally: -branchmap.read = oldread -branchmap.branchcache.write = oldwrite +branchcacheread.restore() +branchcachewrite.restore() fm.end() @command('perfloadmarkers') ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 8 V2] perf: introduce safeattrsetter to replace direct attribute assignment
# HG changeset patch # User FUJIWARA Katsunori# Date 1475942596 -32400 # Sun Oct 09 01:03:16 2016 +0900 # Node ID a03b967913dd881f750a5848f567d1e0a1d0e7ea # Parent 87b8e40eb8125d5ddc848d972b117989346057dd perf: introduce safeattrsetter to replace direct attribute assignment Referring not-existing attribute immediately causes failure, but assigning a value to such attribute doesn't. For example, perf.py has code paths below, which assign a value to not-existing attribute. This causes incorrect performance measurement, but these code paths are executed successfully. - "repo._tags = None" in perftags() recent Mercurial has tags cache information in repo._tagscache - "branchmap.write = lambda repo: None" in perfbranchmap() branchmap cache is written out by branchcache.write() in branchmap.py "util.safehasattr() before assignment" can avoid this issue, but might increase mistake at "copy & paste" attribute name or so. To centralize (1) examining existence of, (2) assigning a value to, and (3) restoring an old value to the attribute, this patch introduces safeattrsetter(). This is used to replace direct attribute assignment in subsequent patches. Encapsulation of restoring is needed to completely remove direct attribute assignment from perf.py, even though restoring isn't needed so often. diff --git a/contrib/perf.py b/contrib/perf.py --- a/contrib/perf.py +++ b/contrib/perf.py @@ -182,6 +182,40 @@ def _timer(fm, func, title=None): fm.write('count', ' (best of %d)', count) fm.plain('\n') +# utilities for historical portability + +def safeattrsetter(obj, name, ignoremissing=False): +"""Ensure that 'obj' has 'name' attribute before subsequent setattr + +This function is aborted, if 'obj' doesn't have 'name' attribute +at runtime. This avoids overlooking removal of an attribute, which +breaks assumption of performance measurement, in the future. + +This function returns the object to (1) assign a new value, and +(2) restore an original value to the attribute. + +If 'ignoremissing' is true, missing 'name' attribute doesn't cause +abortion, and this function returns None. This is useful to +examine an attribute, which isn't ensured in all Mercurial +versions. +""" +if not util.safehasattr(obj, name): +if ignoremissing: +return None +raise error.Abort(("missing attribute %s of %s might break assumption" + " of performance measurement") % (name, obj)) + +origvalue = getattr(obj, name) +class attrutil(object): +def set(self, newvalue): +setattr(obj, name, newvalue) +def restore(self): +setattr(obj, name, origvalue) + +return attrutil() + +# perf commands + @command('perfwalk', formatteropts) def perfwalk(ui, repo, *pats, **opts): timer, fm = gettimer(ui, opts) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] import: abort instead of crashing when copy source does not exist (issue5375)
# HG changeset patch # User Ryan McElroy# Date 1475929618 25200 # Sat Oct 08 05:26:58 2016 -0700 # Node ID 961569a2cbeebfd54c9369c6e36d03d4938aef38 # Parent dbcef8918bbdd8a64d9f79a37bcfa284a26f3a39 import: abort instead of crashing when copy source does not exist (issue5375) Previously, when a patch contained a move or copy from a source that did not exist, `hg import` would crash. This patch changes import to raise a PatchError with an explanantion of what is wrong with the patch to avoid the stack trace and bad user experience. diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -1952,8 +1952,10 @@ def _applydiff(ui, fp, patcher, backend, data, mode = None, None if gp.op in ('RENAME', 'COPY'): data, mode = store.getfile(gp.oldpath)[:2] -# FIXME: failing getfile has never been handled here -assert data is not None +if data is None: +# This means that the old path does not exist +raise PatchError(_("source file '%s' does not exist") + % gp.oldpath) if gp.mode: mode = gp.mode if gp.op == 'ADD': diff --git a/tests/test-import.t b/tests/test-import.t --- a/tests/test-import.t +++ b/tests/test-import.t @@ -1793,3 +1793,13 @@ repository when file not found for patch 1 out of 1 hunks FAILED -- saving rejects to file file1.rej abort: patch failed to apply [255] + +test import crash (issue5375) + $ cd .. + $ hg init repo + $ cd repo + $ printf "diff --git a/a b/b\nrename from a\nrename to b" | hg import - + applying patch from stdin + a not tracked! + abort: source file 'a' does not exist + [255] ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 2] py3: make the string unicode so its iterable in py3k
On 8 October 2016 at 18:00, Pulkit Goyal <7895pul...@gmail.com> wrote: > On Sat, Oct 8, 2016 at 5:55 PM, Mateusz Kwapichwrote: > > # HG changeset patch > > # User Mateusz Kwapich > > # Date 1475941528 25200 > > # Sat Oct 08 08:45:28 2016 -0700 > > # Node ID 225efa4bf7f497e55f0ba57f64a33dce39eaeb29 > > # Parent 8f34e217338be6a1b997807521e95f9f7409d722 > > py3: make the string unicode so its iterable in py3k > > > > diff --git a/mercurial/store.py b/mercurial/store.py > > --- a/mercurial/store.py > > +++ b/mercurial/store.py > > @@ -65,7 +65,7 @@ def _reserved(): > > > > these characters will be escaped by encodefunctions > > ''' > > -winreserved = [ord(x) for x in '\\:*?"<>|'] > > +winreserved = [ord(x) for x in u'\\:*?"<>|'] > > ord() accepts both unicode and bytes in Python 2 world. So its better > to prevent using pycompat.sysstr() here. This comment is slightly confusing; you make it sound as if iteration over a bytestring in Py3 would be okay too (it isn't). With the above change we avoid iterating over a `bytes` object in Py3 which would be bad. In Py2 this is an iteration over unicode and then indeed ord() is fine (as it was when iterating over str). > > for x in range(32): > > yield x > > for x in range(126, 256): > > ___ > > 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 > -- Martijn Pieters ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH V2] manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
# HG changeset patch # User Gregory Szorc# Date 1475942697 -7200 # Sat Oct 08 18:04:57 2016 +0200 # Node ID f98e32b5c44fafb85bee108abe2a24595e59ddbc # Parent ece8e9fc1bf2effb388bbca7222d3c644996aa2b manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3 This flag disappeared in Python 3. It is only necessary in Python 2, apparently. diff --git a/mercurial/manifest.c b/mercurial/manifest.c --- a/mercurial/manifest.c +++ b/mercurial/manifest.c @@ -253,8 +253,15 @@ done: Py_XDECREF(flags); return ret; } +#ifdef IS_PY3K +#define LAZYMANIFESTENTRIESITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT +#else +#define LAZYMANIFESTENTRIESITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT \ + | Py_TPFLAGS_HAVE_ITER +#endif + static PyTypeObject lazymanifestEntriesIterator = { PyObject_HEAD_INIT(NULL) 0, /*ob_size */ "parsers.lazymanifest.entriesiterator", /*tp_name */ @@ -274,11 +281,9 @@ static PyTypeObject lazymanifestEntriesI 0, /*tp_str */ 0, /*tp_getattro */ 0, /*tp_setattro */ 0, /*tp_as_buffer */ - /* tp_flags: Py_TPFLAGS_HAVE_ITER tells python to - use tp_iter and tp_iternext fields. */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, + LAZYMANIFESTENTRIESITERATOR_TPFLAGS, /* tp_flags */ "Iterator for 3-tuples in a lazymanifest.", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -297,8 +302,15 @@ static PyObject *lmiter_iterkeysnext(PyO pl = pathlen(l); return PyString_FromStringAndSize(l->start, pl); } +#ifdef IS_PY3K +#define LAZYMANIFESTKEYSITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT +#else +#define LAZYMANIFESTKEYSITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT \ + | Py_TPFLAGS_HAVE_ITER +#endif + static PyTypeObject lazymanifestKeysIterator = { PyObject_HEAD_INIT(NULL) 0, /*ob_size */ "parsers.lazymanifest.keysiterator", /*tp_name */ @@ -318,11 +330,9 @@ static PyTypeObject lazymanifestKeysIter 0, /*tp_str */ 0, /*tp_getattro */ 0, /*tp_setattro */ 0, /*tp_as_buffer */ - /* tp_flags: Py_TPFLAGS_HAVE_ITER tells python to - use tp_iter and tp_iternext fields. */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, + LAZYMANIFESTKEYSITERATOR_TPFLAGS, /* tp_flags */ "Keys iterator for a lazymanifest.", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -872,8 +882,14 @@ static PyMethodDef lazymanifest_methods[ "Encode this manifest to text."}, {NULL}, }; +#ifdef IS_PY3K +#define LAZYMANIFEST_TPFLAGS Py_TPFLAGS_DEFAULT +#else +#define LAZYMANIFEST_TPFLAGS Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_SEQUENCE_IN +#endif + static PyTypeObject lazymanifestType = { PyObject_HEAD_INIT(NULL) 0,/* ob_size */ "parsers.lazymanifest", /* tp_name */ @@ -893,9 +909,9 @@ static PyTypeObject lazymanifestType = { 0,/* tp_str */ 0,/* tp_getattro */ 0,/* tp_setattro */ 0,/* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_SEQUENCE_IN, /* tp_flags */ + LAZYMANIFEST_TPFLAGS, /* tp_flags */ "TODO(augie)",/* tp_doc */ 0,/* tp_traverse */ 0,/* tp_clear */ 0,/* tp_richcompare */ ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2] py3: make encodefun in store.py compatible with py3k
On 8 October 2016 at 17:55, Mateusz Kwapichwrote: > # HG changeset patch > # User Mateusz Kwapich > # Date 1475942045 25200 > # Sat Oct 08 08:54:05 2016 -0700 > # Node ID 086b25d1866e33fb7ebbe6c51522e6b573e281e2 > # Parent 225efa4bf7f497e55f0ba57f64a33dce39eaeb29 > py3: make encodefun in store.py compatible with py3k > > This ensures that the filename encoding functions always map bytestrings > to bytestrings regardless of python version. > These two look good. > diff --git a/mercurial/store.py b/mercurial/store.py > --- a/mercurial/store.py > +++ b/mercurial/store.py > @@ -16,6 +16,7 @@ from .i18n import _ > from . import ( > error, > parsers, > +pycompat, > scmutil, > util, > ) > @@ -98,11 +99,20 @@ def _buildencodefun(): > 'the\\x07quick\\xadshot' > ''' > e = '_' > -cmap = dict([(chr(x), chr(x)) for x in xrange(127)]) > +if pycompat.ispy3: > +xchr = lambda x: bytes([x]) > +asciistr = bytes(xrange(127)) > +else: > +xchr = chr > +asciistr = map(chr, xrange(127)) > +capitals = list(range(ord("A"), ord("Z") + 1)) > + > +cmap = {x:x for x in asciistr} > for x in _reserved(): > -cmap[chr(x)] = "~%02x" % x > -for x in list(range(ord("A"), ord("Z") + 1)) + [ord(e)]: > -cmap[chr(x)] = e + chr(x).lower() > +cmap[xchr(x)] = "~%02x" % x > +for x in capitals + [ord(e)]: > +cmap[xchr(x)] = e + xchr(x).lower() > + > dmap = {} > for k, v in cmap.iteritems(): > dmap[v] = k > diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t > --- a/tests/test-check-py3-compat.t > +++ b/tests/test-check-py3-compat.t > @@ -134,7 +134,6 @@ >mercurial/sshserver.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) >mercurial/statichttprepo.py: error importing: module > 'mercurial.util' has no attribute 'urlerr' (error at byterange.py:*) >mercurial/store.py: error importing module: name 'xrange' > is not defined (line *) > - mercurial/streamclone.py: error importing: can't concat > bytes to str (error at store.py:*) >mercurial/subrepo.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) >mercurial/templatefilters.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) >mercurial/templatekw.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel > -- Martijn Pieters ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 2] py3: make the string unicode so its iterable in py3k
On Sat, Oct 8, 2016 at 5:55 PM, Mateusz Kwapichwrote: > # HG changeset patch > # User Mateusz Kwapich > # Date 1475941528 25200 > # Sat Oct 08 08:45:28 2016 -0700 > # Node ID 225efa4bf7f497e55f0ba57f64a33dce39eaeb29 > # Parent 8f34e217338be6a1b997807521e95f9f7409d722 > py3: make the string unicode so its iterable in py3k > > diff --git a/mercurial/store.py b/mercurial/store.py > --- a/mercurial/store.py > +++ b/mercurial/store.py > @@ -65,7 +65,7 @@ def _reserved(): > > these characters will be escaped by encodefunctions > ''' > -winreserved = [ord(x) for x in '\\:*?"<>|'] > +winreserved = [ord(x) for x in u'\\:*?"<>|'] ord() accepts both unicode and bytes in Python 2 world. So its better to prevent using pycompat.sysstr() here. > for x in range(32): > yield x > for x in range(126, 256): > ___ > 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] py3: make encodefun in store.py compatible with py3k
# HG changeset patch # User Mateusz Kwapich# Date 1475942045 25200 # Sat Oct 08 08:54:05 2016 -0700 # Node ID 086b25d1866e33fb7ebbe6c51522e6b573e281e2 # Parent 225efa4bf7f497e55f0ba57f64a33dce39eaeb29 py3: make encodefun in store.py compatible with py3k This ensures that the filename encoding functions always map bytestrings to bytestrings regardless of python version. diff --git a/mercurial/store.py b/mercurial/store.py --- a/mercurial/store.py +++ b/mercurial/store.py @@ -16,6 +16,7 @@ from .i18n import _ from . import ( error, parsers, +pycompat, scmutil, util, ) @@ -98,11 +99,20 @@ def _buildencodefun(): 'the\\x07quick\\xadshot' ''' e = '_' -cmap = dict([(chr(x), chr(x)) for x in xrange(127)]) +if pycompat.ispy3: +xchr = lambda x: bytes([x]) +asciistr = bytes(xrange(127)) +else: +xchr = chr +asciistr = map(chr, xrange(127)) +capitals = list(range(ord("A"), ord("Z") + 1)) + +cmap = {x:x for x in asciistr} for x in _reserved(): -cmap[chr(x)] = "~%02x" % x -for x in list(range(ord("A"), ord("Z") + 1)) + [ord(e)]: -cmap[chr(x)] = e + chr(x).lower() +cmap[xchr(x)] = "~%02x" % x +for x in capitals + [ord(e)]: +cmap[xchr(x)] = e + xchr(x).lower() + dmap = {} for k, v in cmap.iteritems(): dmap[v] = k diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t --- a/tests/test-check-py3-compat.t +++ b/tests/test-check-py3-compat.t @@ -134,7 +134,6 @@ mercurial/sshserver.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) mercurial/statichttprepo.py: error importing: module 'mercurial.util' has no attribute 'urlerr' (error at byterange.py:*) mercurial/store.py: error importing module: name 'xrange' is not defined (line *) - mercurial/streamclone.py: error importing: can't concat bytes to str (error at store.py:*) mercurial/subrepo.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) mercurial/templatefilters.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) mercurial/templatekw.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3
# HG changeset patch # User Gregory Szorc# Date 1475940865 -7200 # Sat Oct 08 17:34:25 2016 +0200 # Node ID 33f1118c90814a8e06f390940829255a01f4e4a1 # Parent ece8e9fc1bf2effb388bbca7222d3c644996aa2b manifest: drop Py_TPFLAGS_HAVE_SEQUENCE_IN from tp_flags in Python 3 This flag disappeared in Python 3. It is only necessary in Python 2, apparently. diff --git a/mercurial/manifest.c b/mercurial/manifest.c --- a/mercurial/manifest.c +++ b/mercurial/manifest.c @@ -13,8 +13,12 @@ #include #include "util.h" +#if PY_MAJOR_VERSION >= 3 +#define IS_PY3K +#endif + #define DEFAULT_LINES 10 typedef struct { char *start; @@ -253,8 +257,15 @@ done: Py_XDECREF(flags); return ret; } +#ifdef IS_PY3K +#define LAZYMANIFESTENTRIESITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT +#else +#define LAZYMANIFESTENTRIESITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT \ + | Py_TPFLAGS_HAVE_ITER +#endif + static PyTypeObject lazymanifestEntriesIterator = { PyObject_HEAD_INIT(NULL) 0, /*ob_size */ "parsers.lazymanifest.entriesiterator", /*tp_name */ @@ -274,11 +285,9 @@ static PyTypeObject lazymanifestEntriesI 0, /*tp_str */ 0, /*tp_getattro */ 0, /*tp_setattro */ 0, /*tp_as_buffer */ - /* tp_flags: Py_TPFLAGS_HAVE_ITER tells python to - use tp_iter and tp_iternext fields. */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, + LAZYMANIFESTENTRIESITERATOR_TPFLAGS, /* tp_flags */ "Iterator for 3-tuples in a lazymanifest.", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -297,8 +306,15 @@ static PyObject *lmiter_iterkeysnext(PyO pl = pathlen(l); return PyString_FromStringAndSize(l->start, pl); } +#ifdef IS_PY3K +#define LAZYMANIFESTKEYSITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT +#else +#define LAZYMANIFESTKEYSITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT \ + | Py_TPFLAGS_HAVE_ITER +#endif + static PyTypeObject lazymanifestKeysIterator = { PyObject_HEAD_INIT(NULL) 0, /*ob_size */ "parsers.lazymanifest.keysiterator", /*tp_name */ @@ -318,11 +334,9 @@ static PyTypeObject lazymanifestKeysIter 0, /*tp_str */ 0, /*tp_getattro */ 0, /*tp_setattro */ 0, /*tp_as_buffer */ - /* tp_flags: Py_TPFLAGS_HAVE_ITER tells python to - use tp_iter and tp_iternext fields. */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, + LAZYMANIFESTKEYSITERATOR_TPFLAGS, /* tp_flags */ "Keys iterator for a lazymanifest.", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -872,8 +886,14 @@ static PyMethodDef lazymanifest_methods[ "Encode this manifest to text."}, {NULL}, }; +#ifdef IS_PY3K +#define LAZYMANIFEST_TPFLAGS Py_TPFLAGS_DEFAULT +#else +#define LAZYMANIFEST_TPFLAGS Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_SEQUENCE_IN +#endif + static PyTypeObject lazymanifestType = { PyObject_HEAD_INIT(NULL) 0,/* ob_size */ "parsers.lazymanifest", /* tp_name */ @@ -893,9 +913,9 @@ static PyTypeObject lazymanifestType = { 0,/* tp_str */ 0,/* tp_getattro */ 0,/* tp_setattro */ 0,/* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_SEQUENCE_IN, /* tp_flags */ + LAZYMANIFEST_TPFLAGS, /* tp_flags */ "TODO(augie)",/* tp_doc */ 0,/* tp_traverse */ 0,/* tp_clear */ 0,/* tp_richcompare */ ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH WIP] help: show help content for disabled extension
# HG changeset patch # User liscju# Date 1475926049 -7200 # Sat Oct 08 13:27:29 2016 +0200 # Node ID 5497a92be82db414f6913f869d5acd18b205cb2b # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 help: show help content for disabled extension So far for disabled extension help showed only extension summary. This commit makes help read content of the help comments in extension module without actually loading the module. diff --git a/mercurial/help.py b/mercurial/help.py --- a/mercurial/help.py +++ b/mercurial/help.py @@ -7,6 +7,7 @@ from __future__ import absolute_import +import ast import itertools import os import textwrap @@ -300,6 +301,38 @@ addtopicsymbols('templates', '.. functio addtopicsymbols('hgweb', '.. webcommandsmarker', webcommands.commands, dedent=True) +def parsedisabledext(modname): +# return list of (command_name, command_module, command_doc) +def finddisabledext(name): +paths = extensions._disabledpaths() +if name in paths: +return paths[name] +return None + +def iscmd(funast): +for decorator in funast.decorator_list: +if isinstance(decorator, ast.Call) and decorator.func.id == 'command': +return True +return False + +def extractcmds(extast): +return [funast.name for funast in extast.body if isinstance(funast, ast.FunctionDef) and iscmd(funast)] + +def extractcmddoc(extast, cmd): +funasts = [funast for funast in extast.body + if isinstance(funast, ast.FunctionDef) and iscmd(funast) and funast.name == cmd] +if len(funasts) > 0: +return ast.get_docstring(funasts[0]) +else: +return None + +extfile = open(finddisabledext(modname), 'r') +try: +extast = ast.parse(extfile.read()) +return [(cmdname, modname, extractcmddoc(extast, cmdname)) for cmdname in extractcmds(extast)] +except SyntaxError: +return [] + def help_(ui, name, unknowncmd=False, full=True, subtopic=None, **opts): ''' Generate the help for 'name' as unformatted restructured text. If @@ -395,7 +428,7 @@ def help_(ui, name, unknowncmd=False, fu return rst -def helplist(select=None, **opts): +def helplist(select=None, disabledext=None, **opts): # list of commands if name == "shortlist": header = _('basic commands:\n\n') @@ -406,17 +439,24 @@ def help_(ui, name, unknowncmd=False, fu h = {} cmds = {} -for c, e in commands.table.iteritems(): + +if not disabledext: +commandinfos = [(c, e[0].__module__, e[0].__doc__) for c, e in commands.table.iteritems()] +else: +commandinfos = parsedisabledext(disabledext) + +for cmdname, cmdmod, cmddoc in commandinfos: +c = cmdname f = c.partition("|")[0] if select and not select(f): continue if (not select and name != 'shortlist' and -e[0].__module__ != commands.__name__): +cmdmod != commands.__name__): continue if name == "shortlist" and not f.startswith("^"): continue f = f.lstrip("^") -doc = e[0].__doc__ +doc = cmddoc if filtercmd(ui, f, name, doc): continue doc = gettext(doc) @@ -548,7 +588,8 @@ def help_(ui, name, unknowncmd=False, fu modcmds = set([c.partition('|')[0] for c in ct]) rst.extend(helplist(modcmds.__contains__)) else: -rst.append(_("(use 'hg help extensions' for information on enabling" +rst.extend(helplist(lambda w: True, disabledext=name)) +rst.append(_("\n(use 'hg help extensions' for information on enabling" " extensions)\n")) return rst diff --git a/tests/test-extension.t b/tests/test-extension.t --- a/tests/test-extension.t +++ b/tests/test-extension.t @@ -1040,11 +1040,23 @@ Disabled extensions: $ hg help churn churn extension - command to display statistics about repository history + list of commands: + + churn histogram of changes to the repository + + (use 'hg help -v -e churn' to show built-in aliases and global options) + (use 'hg help extensions' for information on enabling extensions) $ hg help patchbomb patchbomb extension - command to send changesets as (a series of) patch emails + list of commands: + + email send changesets by email + + (use 'hg help -v patchbomb' to show built-in aliases and global options) + (use 'hg help extensions' for information on enabling extensions) @@ -1065,6 +1077,8 @@ Broken disabled extension and command: $ hg --config extensions.path=./path.py help broken broken extension - (no help text available) + no commands defined
Re: [PATCH 4 of 4] dirs: document performance reasons for bypassing Python C API
On 8 October 2016 at 17:00, Gregory Szorcwrote: > # HG changeset patch > # User Gregory Szorc > # Date 1475938278 -7200 > # Sat Oct 08 16:51:18 2016 +0200 > # Node ID 136b1a54213542f535f155de5ce01049b3577b4a > # Parent da39a5835ea2d1aae1a51995b6d7e593f598be4b > dirs: document performance reasons for bypassing Python C API > > So someone isn't tempted to change it. > +100 for the comment. Hacking in the internals of immutable Python types outside of the C-API would otherwise increase the WTF-frequency to intolerable levels, as the old code already did. The only thing that could *perhaps* be added (in the commit message or in the comment) is a pointer to https://docs.python.org/2/c-api/string.html#c._PyString_Resize / https://docs.python.org/3/c-api/bytes.html#c._PyBytes_Resize, where the string length hacking originates from, so that future maintainers can at least follow *that* implementation as a reference guide if this were to break against future CPython changes. > > diff --git a/mercurial/dirs.c b/mercurial/dirs.c > --- a/mercurial/dirs.c > +++ b/mercurial/dirs.c > @@ -55,8 +55,16 @@ static int _addpath(PyObject *dirs, PyOb > Py_ssize_t pos = PyBytes_GET_SIZE(path); > PyObject *key = NULL; > int ret = -1; > > + /* This loop is super critical for performance. That's why we > inline > + * access to Python structs instead of going through a supported > API. > + * The implementation, therefore, is heavily dependent on CPython > + * implementation details. We also commit violations of the Python > + * "protocol" such as mutating immutable objects. But since we only > + * mutate objects created in this function or in other well-defined > + * locations, the references are known so these violations should go > + * unnoticed. */ > while ((pos = _finddir(cpath, pos - 1)) != -1) { > PyObject *val; > > /* It's likely that every prefix already has an entry > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel > -- Martijn Pieters ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 2] evolve: indent cmdnext and cmdprev ready for locking change (issue5244)
# HG changeset patch # User Simon Farnsworth# Date 1475939661 25200 # Sat Oct 08 08:14:21 2016 -0700 # Node ID ee284d7c5faa5d9f17853f51c17883844b985c58 # Parent 5383671ef612a1764bbbed13a7ef2d339d0a9c2d evolve: indent cmdnext and cmdprev ready for locking change (issue5244) The locking change I'm about to introduce forces an indentation shift. Do the indentation change with no code change now, to make the next change easier to review diff --git a/hgext/evolve.py b/hgext/evolve.py --- a/hgext/evolve.py +++ b/hgext/evolve.py @@ -2213,57 +2213,58 @@ """update to parent revision Displays the summary line of the destination for clarity.""" -wkctx = repo[None] -wparents = wkctx.parents() -dryrunopt = opts['dry_run'] -if len(wparents) != 1: -raise error.Abort('merge in progress') -if not opts['merge']: -try: -cmdutil.bailifchanged(repo) -except error.Abort as exc: -exc.hint = _('do you want --merge?') -raise - -parents = wparents[0].parents() -topic = getattr(repo, 'currenttopic', '') -if topic and not opts.get("no_topic", False): -parents = [ctx for ctx in parents if ctx.topic() == topic] -displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate}) -if not parents: -ui.warn(_('no parent in topic "%s"\n') % topic) -ui.warn(_('(do you want --no-topic)\n')) -elif len(parents) == 1: -p = parents[0] -bm = bmactive(repo) -shouldmove = opts.get('move_bookmark') and bm is not None -if dryrunopt: -ui.write(('hg update %s;\n' % p.rev())) -if shouldmove: -ui.write(('hg bookmark %s -r %s;\n' % (bm, p.rev( +if True: +wkctx = repo[None] +wparents = wkctx.parents() +dryrunopt = opts['dry_run'] +if len(wparents) != 1: +raise error.Abort('merge in progress') +if not opts['merge']: +try: +cmdutil.bailifchanged(repo) +except error.Abort as exc: +exc.hint = _('do you want --merge?') +raise + +parents = wparents[0].parents() +topic = getattr(repo, 'currenttopic', '') +if topic and not opts.get("no_topic", False): +parents = [ctx for ctx in parents if ctx.topic() == topic] +displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate}) +if not parents: +ui.warn(_('no parent in topic "%s"\n') % topic) +ui.warn(_('(do you want --no-topic)\n')) +elif len(parents) == 1: +p = parents[0] +bm = bmactive(repo) +shouldmove = opts.get('move_bookmark') and bm is not None +if dryrunopt: +ui.write(('hg update %s;\n' % p.rev())) +if shouldmove: +ui.write(('hg bookmark %s -r %s;\n' % (bm, p.rev( +else: +ret = hg.update(repo, p.rev()) +if not ret: +tr = lock = None +wlock = repo.wlock() +try: +lock = repo.lock() +tr = repo.transaction('previous') +if shouldmove: +repo._bookmarks[bm] = p.node() +repo._bookmarks.recordchange(tr) +else: +bmdeactivate(repo) +tr.close() +finally: +lockmod.release(tr, lock, wlock) +displayer.show(p) +return 0 else: -ret = hg.update(repo, p.rev()) -if not ret: -tr = lock = None -wlock = repo.wlock() -try: -lock = repo.lock() -tr = repo.transaction('previous') -if shouldmove: -repo._bookmarks[bm] = p.node() -repo._bookmarks.recordchange(tr) -else: -bmdeactivate(repo) -tr.close() -finally: -lockmod.release(tr, lock, wlock) -displayer.show(p) -return 0 -else: -for p in parents: -displayer.show(p) -ui.warn(_('multiple parents, explicitly update to one\n')) -return 1 +for p in parents: +displayer.show(p) +ui.warn(_('multiple parents, explicitly update to one\n')) +return 1 @command('^next', [('B', 'move-bookmark', False, @@ -2281,91 +2282,92 @@ Displays the summary line of the destination for clarity. """ -wkctx = repo[None] -wparents = wkctx.parents() -dryrunopt = opts['dry_run'] -if len(wparents) != 1: -raise error.Abort('merge in progress') -
[PATCH 2 of 2] evolve: lock the working copy early in next and prev (issue5244)
# HG changeset patch # User Simon Farnsworth# Date 1475939634 25200 # Sat Oct 08 08:13:54 2016 -0700 # Node ID 8a0c9c0158b3e9574a4571af3dce9978844b825d # Parent ee284d7c5faa5d9f17853f51c17883844b985c58 evolve: lock the working copy early in next and prev (issue5244) Both next and prev depend on a consistent working copy, but were waiting to take the lock until they were ready to alter the working copy. Take the lock before reading the working copy state, and do not release it until we're definitely not going to change the working copy. diff --git a/hgext/evolve.py b/hgext/evolve.py --- a/hgext/evolve.py +++ b/hgext/evolve.py @@ -2213,10 +2213,13 @@ """update to parent revision Displays the summary line of the destination for clarity.""" -if True: +wlock = None +dryrunopt = opts['dry_run'] +if not dryrunopt: +wlock = repo.wlock() +try: wkctx = repo[None] wparents = wkctx.parents() -dryrunopt = opts['dry_run'] if len(wparents) != 1: raise error.Abort('merge in progress') if not opts['merge']: @@ -2246,7 +2249,6 @@ ret = hg.update(repo, p.rev()) if not ret: tr = lock = None -wlock = repo.wlock() try: lock = repo.lock() tr = repo.transaction('previous') @@ -2258,13 +2260,22 @@ tr.close() finally: lockmod.release(tr, lock, wlock) +wlock = None +else: +lockmod.release(wlock) +wlock = None + displayer.show(p) return 0 else: +lockmod.release(wlock) +wlock = None for p in parents: displayer.show(p) ui.warn(_('multiple parents, explicitly update to one\n')) return 1 +finally: +lockmod.release(wlock) @command('^next', [('B', 'move-bookmark', False, @@ -2282,10 +2293,13 @@ Displays the summary line of the destination for clarity. """ -if True: +wlock = None +dryrunopt = opts['dry_run'] +if not dryrunopt: +wlock = repo.wlock() +try: wkctx = repo[None] wparents = wkctx.parents() -dryrunopt = opts['dry_run'] if len(wparents) != 1: raise error.Abort('merge in progress') if not opts['merge']: @@ -2315,7 +2329,6 @@ ret = hg.update(repo, c.rev()) if not ret: lock = tr = None -wlock = repo.wlock() try: lock = repo.lock() tr = repo.transaction('next') @@ -2327,15 +2340,23 @@ tr.close() finally: lockmod.release(tr, lock, wlock) +wlock = None +else: +lockmod.release(wlock) +wlock = None displayer.show(c) result = 0 elif children: +lockmod.release(wlock) +wlock = None ui.warn(_("ambigious next changeset:\n")) for c in children: displayer.show(c) ui.warn(_('explicitly update to one of them\n')) result = 1 else: +lockmod.release(wlock) +wlock = None aspchildren = _aspiringchildren(repo, [repo['.'].rev()]) if topic: filtered.extend(repo[c] for c in children @@ -2368,6 +2389,8 @@ return result return 1 return result +finally: +lockmod.release(wlock) def _reachablefrombookmark(repo, revs, bookmarks): """filter revisions and bookmarks reachable from the given bookmark diff --git a/tests/fake-editor.sh b/tests/fake-editor.sh new file mode 100755 --- /dev/null +++ b/tests/fake-editor.sh @@ -0,0 +1,3 @@ +#!/bin/sh +sleep 5 +echo "new desc" >> $1 diff --git a/tests/test-prev-next.t b/tests/test-prev-next.t --- a/tests/test-prev-next.t +++ b/tests/test-prev-next.t @@ -206,3 +206,34 @@ move:[5] added d atop:[6] added b (3) working directory is now at 47ea25be8aea + +prev and next should lock properly against other commands + + $ hg init repo + $ cd repo + $ HGEDITOR=${TESTDIR}/fake-editor.sh + $ echo hi > foo + $ hg ci -Am 'one' + adding foo + $ echo bye > foo + $ hg ci -Am 'two' + + $ hg amend --edit & + $ sleep 1 + $ hg prev + waiting for lock on working directory of $TESTTMP/repo held by process '*' on host '*' (glob) + got lock after [4-6] seconds (re) + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + [0] one + $ wait + + $ hg amend --edit & + $ sleep 1 + $ hg next --evolve + waiting for
[PATCH] hgweb: make fctx.annotate a separated function so it could be wrapped
# HG changeset patch # User Jun Wu# Date 1475939434 -3600 # Sat Oct 08 16:10:34 2016 +0100 # Node ID 30141bc03ab8608b04aa717e4dee46046c00f5d6 # Parent cd7276f7ea8308df2c5d8874d335d73247d0f357 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 30141bc03ab8 hgweb: make fctx.annotate a separated function so it could be wrapped This patch moves "fctx.annotate" used by the "annotate" webcommand, along with the diffopts to a separated function which takes a ui and a fctx. So it could be replaced by other implementations which don't want to replace the core "fctx.annotate" directly. diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -32,5 +32,4 @@ from .. import ( error, graphmod, -patch, revset, scmutil, @@ -862,6 +861,4 @@ def annotate(web, req, tmpl): f = fctx.path() parity = paritygen(web.stripecount) -diffopts = patch.difffeatureopts(web.repo.ui, untrusted=True, - section='annotate', whitespace=True) def parents(f): @@ -878,6 +875,6 @@ def annotate(web, req, tmpl): lines = [((fctx.filectx(fctx.filerev()), 1), '(binary:%s)' % mt)] else: -lines = fctx.annotate(follow=True, linenumber=True, - diffopts=diffopts) +lines = webutil.annotate(fctx, web.repo.ui) + previousrev = None blockparitygen = paritygen(1) diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py --- a/mercurial/hgweb/webutil.py +++ b/mercurial/hgweb/webutil.py @@ -165,4 +165,9 @@ class _siblings(object): return len(self.siblings) +def annotate(fctx, ui): +diffopts = patch.difffeatureopts(ui, untrusted=True, + section='annotate', whitespace=True) +return fctx.annotate(follow=True, linenumber=True, diffopts=diffopts) + def parents(ctx, hide=None): if isinstance(ctx, context.basefilectx): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 3 of 3 v3] util: ensure forwarded attrs are set in globals() as sysstr
On 8 October 2016 at 17:10, Augie Facklerwrote: > # HG changeset patch > # User Augie Fackler > # Date 1475930199 14400 > # Sat Oct 08 08:36:39 2016 -0400 > # Node ID fb12c11bfe23af38dfb55c721d28a7bfded8c2ed > # Parent 1c7199563d7d8f400f907c63c133d7414ae1f684 > util: ensure forwarded attrs are set in globals() as sysstr > > Custom module importer strikes again. > Series LGTM. > > diff --git a/mercurial/util.py b/mercurial/util.py > --- a/mercurial/util.py > +++ b/mercurial/util.py > @@ -60,7 +60,8 @@ for attr in ( > 'socketserver', > 'xmlrpclib', > ): > -globals()[attr] = getattr(pycompat, attr) > +a = pycompat.sysstr(attr) > +globals()[a] = getattr(pycompat, a) > > # This line is to make pyflakes happy: > urlreq = pycompat.urlreq > diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t > --- a/tests/test-check-py3-compat.t > +++ b/tests/test-check-py3-compat.t > @@ -16,83 +16,73 @@ >$ hg files 'set:(**.py) - grep(pygments)' | sed 's|\\|/|g' \ >> | xargs $PYTHON3 contrib/check-py3-compat.py \ >> | sed 's/[0-9][0-9]*)$/*)/' > - hgext/automv.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > - hgext/blackbox.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > - hgext/bugzilla.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > - hgext/censor.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > - hgext/chgserver.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > - hgext/children.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > - hgext/churn.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > - hgext/clonebundles.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > - hgext/color.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/automv.py: error importing: ord() expected string of > length 1, but int found (error at store.py:*) > + hgext/blackbox.py: error importing: ord() expected string > of length 1, but int found (error at store.py:*) > + hgext/bugzilla.py: error importing: ord() expected string > of length 1, but int found (error at store.py:*) > + hgext/censor.py: error importing: ord() expected string of > length 1, but int found (error at store.py:*) > + hgext/chgserver.py: error importing: ord() expected string > of length 1, but int found (error at store.py:*) > + hgext/children.py: error importing: ord() expected string > of length 1, but int found (error at store.py:*) > + hgext/churn.py: error importing: ord() expected string of > length 1, but int found (error at store.py:*) > + hgext/clonebundles.py: error importing: ord() expected > string of length 1, but int found (error at store.py:*) > + hgext/color.py: error importing: ord() expected string of > length 1, but int found (error at store.py:*) >hgext/convert/bzr.py: error importing module: Parent > module 'hgext.convert' not loaded, cannot perform relative import (line *) > - hgext/convert/common.py: error importing module: > module 'mercurial.util' has no attribute 'pickle' (line *) > - hgext/convert/convcmd.py: error importing: module > 'mercurial.util' has no attribute 'urlerr' (error at httpconnection.py:*) > + hgext/convert/convcmd.py: error importing: ord() expected > string of length 1, but int found (error at store.py:*) >hgext/convert/cvs.py: error importing module: Parent > module 'hgext.convert' not loaded, cannot perform relative import (line *) > - hgext/convert/cvsps.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/convert/cvsps.py: error importing: ord() expected > string of length 1, but int found (error at store.py:*) >hgext/convert/darcs.py: error importing module: Parent > module 'hgext.convert' not loaded, cannot perform relative import (line *) >hgext/convert/filemap.py: error importing module: Parent > module 'hgext.convert' not loaded, cannot perform relative import (line *) >hgext/convert/git.py: error importing module: Parent > module 'hgext.convert' not loaded, cannot perform relative import (line *) >hgext/convert/gnuarch.py: error importing module: Parent > module 'hgext.convert' not loaded, cannot perform relative import (line *) > - hgext/convert/hg.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/convert/hg.py: error importing: ord() expected string > of length 1, but int found (error at store.py:*) >hgext/convert/monotone.py: error importing module: Parent > module 'hgext.convert'
Re: [PATCH v2] hgweb: avoid line wrap between revision and annotate-info (issue5398)
> On Oct 8, 2016, at 17:07, Tooru Fujisawawrote: > > # HG changeset patch > # User Tooru Fujisawa > # Date 1475922774 -32400 > # Sat Oct 08 19:32:54 2016 +0900 > # Node ID 1e4ffe788b13fe6af5862bdc87b588fffd49a4a5 > # Parent f18cc848b48e2de5536fc861007d78d7d5bae42b > hgweb: avoid line wrap between revision and annotate-info (issue5398) Queued, many thanks. Congrats on your first patch to Mercurial. > > Add white-space: nowrap to td.annotate to avoid wrapping div.annotate-info > into next line if there is revision number in the same cell, as it is hard to > mouse over div.annotate-info if it's wrapped into next line. > > diff --git a/mercurial/templates/static/style-gitweb.css > b/mercurial/templates/static/style-gitweb.css > --- a/mercurial/templates/static/style-gitweb.css > +++ b/mercurial/templates/static/style-gitweb.css > @@ -50,16 +50,19 @@ td.indexlinks a { > } > td.indexlinks a:hover { background-color: #aa; } > div.pre { font-family:monospace; font-size:12px; white-space:pre; } > div.diff_info { font-family:monospace; color:#99; > background-color:#edece6; font-style:italic; } > div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; > padding:12px 8px; } > div.search { margin:4px 8px; position:absolute; top:56px; right:12px } > tr.thisrev a { color:#99; text-decoration: none; } > tr.thisrev pre { color:#009900; } > +td.annotate { > + white-space: nowrap; > +} > div.annotate-info { > display: none; > position: absolute; > background-color: #FF; > border: 1px solid #d9d8d1; > text-align: left; > color: #00; > padding: 5px; > diff --git a/mercurial/templates/static/style-monoblue.css > b/mercurial/templates/static/style-monoblue.css > --- a/mercurial/templates/static/style-monoblue.css > +++ b/mercurial/templates/static/style-monoblue.css > @@ -330,16 +330,19 @@ td.source { > .lineno a { > color: #999; > } > td.linenr { > width: 60px; > } > tr.thisrev a { color:#99; text-decoration: none; } > tr.thisrev td.source { color:#009900; } > +td.annotate { > + white-space: nowrap; > +} > div.annotate-info { > display: none; > position: absolute; > background-color: #FF; > border: solid 1px #CCC; > text-align: left; > color: #666; > padding: 5px; > diff --git a/mercurial/templates/static/style-paper.css > b/mercurial/templates/static/style-paper.css > --- a/mercurial/templates/static/style-paper.css > +++ b/mercurial/templates/static/style-paper.css > @@ -205,16 +205,19 @@ h3 { > .bigtable .node { width: 5em; font-family: monospace;} > .bigtable .permissions { width: 8em; text-align: left;} > .bigtable .size { width: 5em; text-align: right; } > .bigtable .annotate { text-align: right; } > .bigtable td.annotate { font-size: smaller; } > .bigtable td.source { font-size: inherit; } > tr.thisrev a { color:#99; text-decoration: none; } > tr.thisrev td.source { color:#009900; } > +td.annotate { > + white-space: nowrap; > +} > div.annotate-info { > display: none; > position: absolute; > background-color: #FF; > border: 1px solid #999; > text-align: left; > color: #00; > padding: 5px; > diff --git a/mercurial/templates/static/style.css > b/mercurial/templates/static/style.css > --- a/mercurial/templates/static/style.css > +++ b/mercurial/templates/static/style.css > @@ -7,16 +7,19 @@ a { text-decoration:none; } > .lineno { width: 60px; color: #aaa; font-size: smaller; > text-align: right; } > .plusline { color: green; } > .minusline { color: red; } > .atline { color: purple; } > .annotate { font-size: smaller; text-align: right; padding-right: 1em; } > tr.thisrev a { color:#99; text-decoration: none; } > tr.thisrev pre { color:#009900; } > +td.annotate { > + white-space: nowrap; > +} > div.annotate-info { > display: none; > position: absolute; > background-color: #FF; > border: 1px solid #888; > text-align: left; > color: #00; > padding: 5px; > diff --git a/tests/test-hgweb-commands.t b/tests/test-hgweb-commands.t > --- a/tests/test-hgweb-commands.t > +++ b/tests/test-hgweb-commands.t > @@ -1960,16 +1960,19 @@ Static files > .lineno { width: 60px; color: #aaa; font-size: smaller; > text-align: right; } > .plusline { color: green; } > .minusline { color: red; } > .atline { color: purple; } > .annotate { font-size: smaller; text-align: right; padding-right: 1em; } > tr.thisrev a { color:#99; text-decoration: none; } > tr.thisrev pre { color:#009900; } > + td.annotate { > +white-space: nowrap; > + } > div.annotate-info { > display: none; > position: absolute; > background-color: #FF; > border: 1px solid #888; > text-align: left; > color: #00; > padding: 5px; > diff --git a/tests/test-hgweb.t b/tests/test-hgweb.t > --- a/tests/test-hgweb.t > +++ b/tests/test-hgweb.t > @@ -335,17 +335,17 @@ Test the access/error files are opened i > > $ $PYTHON
[PATCH 2 of 3 v3] pycompat: when setting attrs, ensure we use sysstr
# HG changeset patch # User Augie Fackler# Date 1475930143 14400 # Sat Oct 08 08:35:43 2016 -0400 # Node ID 1c7199563d7d8f400f907c63c133d7414ae1f684 # Parent f8683a413385590d3083caba116034170bffd02e pycompat: when setting attrs, ensure we use sysstr The custom module importer was making these bytes, so when we poked values into self.__dict__ we had bytes instead of unicode on py3 and it didn't work. diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py --- a/mercurial/pycompat.py +++ b/mercurial/pycompat.py @@ -74,8 +74,10 @@ class _pycompatstub(object): def _registeraliases(self, origin, items): """Add items that will be populated at the first access""" -self._aliases.update((item.replace('_', '').lower(), (origin, item)) - for item in items) +items = map(sysstr, items) +self._aliases.update( +(item.replace(sysstr('_'), sysstr('')).lower(), (origin, item)) +for item in items) def __getattr__(self, name): try: ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 3 v3] i18n: make the locale directory name the same string type as the datapath
# HG changeset patch # User Augie Fackler# Date 1475918778 14400 # Sat Oct 08 05:26:18 2016 -0400 # Node ID f8683a413385590d3083caba116034170bffd02e # Parent aa23c93e636d1045b932588cdb742cce6fd62313 i18n: make the locale directory name the same string type as the datapath diff --git a/mercurial/i18n.py b/mercurial/i18n.py --- a/mercurial/i18n.py +++ b/mercurial/i18n.py @@ -49,7 +49,7 @@ if (os.name == 'nt' _ugettext = None def setdatapath(datapath): -localedir = os.path.join(datapath, 'locale') +localedir = os.path.join(datapath, pycompat.sysstr('locale')) t = gettextmod.translation('hg', localedir, _languages, fallback=True) global _ugettext try: diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t --- a/tests/test-check-py3-compat.t +++ b/tests/test-check-py3-compat.t @@ -16,96 +16,83 @@ $ hg files 'set:(**.py) - grep(pygments)' | sed 's|\\|/|g' \ > | xargs $PYTHON3 contrib/check-py3-compat.py \ > | sed 's/[0-9][0-9]*)$/*)/' - hgext/acl.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/automv.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/blackbox.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/bugzilla.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/censor.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/chgserver.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/children.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/churn.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/clonebundles.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/color.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) + hgext/automv.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/blackbox.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/bugzilla.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/censor.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/chgserver.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/children.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/churn.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/clonebundles.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/color.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) hgext/convert/bzr.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) - hgext/convert/common.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/convert/convcmd.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/convert/cvs.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/convert/cvsps.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/convert/darcs.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) + hgext/convert/common.py: error importing module: module 'mercurial.util' has no attribute 'pickle' (line *) + hgext/convert/convcmd.py: error importing: module 'mercurial.util' has no attribute 'urlerr' (error at httpconnection.py:*) + hgext/convert/cvs.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) + hgext/convert/cvsps.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/convert/darcs.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) hgext/convert/filemap.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) - hgext/convert/git.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/convert/gnuarch.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/convert/hg.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/convert/monotone.py: error importing:
[PATCH 3 of 3 v3] util: ensure forwarded attrs are set in globals() as sysstr
# HG changeset patch # User Augie Fackler# Date 1475930199 14400 # Sat Oct 08 08:36:39 2016 -0400 # Node ID fb12c11bfe23af38dfb55c721d28a7bfded8c2ed # Parent 1c7199563d7d8f400f907c63c133d7414ae1f684 util: ensure forwarded attrs are set in globals() as sysstr Custom module importer strikes again. diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -60,7 +60,8 @@ for attr in ( 'socketserver', 'xmlrpclib', ): -globals()[attr] = getattr(pycompat, attr) +a = pycompat.sysstr(attr) +globals()[a] = getattr(pycompat, a) # This line is to make pyflakes happy: urlreq = pycompat.urlreq diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t --- a/tests/test-check-py3-compat.t +++ b/tests/test-check-py3-compat.t @@ -16,83 +16,73 @@ $ hg files 'set:(**.py) - grep(pygments)' | sed 's|\\|/|g' \ > | xargs $PYTHON3 contrib/check-py3-compat.py \ > | sed 's/[0-9][0-9]*)$/*)/' - hgext/automv.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) - hgext/blackbox.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) - hgext/bugzilla.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) - hgext/censor.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) - hgext/chgserver.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) - hgext/children.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) - hgext/churn.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) - hgext/clonebundles.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) - hgext/color.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/automv.py: error importing: ord() expected string of length 1, but int found (error at store.py:*) + hgext/blackbox.py: error importing: ord() expected string of length 1, but int found (error at store.py:*) + hgext/bugzilla.py: error importing: ord() expected string of length 1, but int found (error at store.py:*) + hgext/censor.py: error importing: ord() expected string of length 1, but int found (error at store.py:*) + hgext/chgserver.py: error importing: ord() expected string of length 1, but int found (error at store.py:*) + hgext/children.py: error importing: ord() expected string of length 1, but int found (error at store.py:*) + hgext/churn.py: error importing: ord() expected string of length 1, but int found (error at store.py:*) + hgext/clonebundles.py: error importing: ord() expected string of length 1, but int found (error at store.py:*) + hgext/color.py: error importing: ord() expected string of length 1, but int found (error at store.py:*) hgext/convert/bzr.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) - hgext/convert/common.py: error importing module: module 'mercurial.util' has no attribute 'pickle' (line *) - hgext/convert/convcmd.py: error importing: module 'mercurial.util' has no attribute 'urlerr' (error at httpconnection.py:*) + hgext/convert/convcmd.py: error importing: ord() expected string of length 1, but int found (error at store.py:*) hgext/convert/cvs.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) - hgext/convert/cvsps.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/convert/cvsps.py: error importing: ord() expected string of length 1, but int found (error at store.py:*) hgext/convert/darcs.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) hgext/convert/filemap.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) hgext/convert/git.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) hgext/convert/gnuarch.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) - hgext/convert/hg.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/convert/hg.py: error importing: ord() expected string of length 1, but int found (error at store.py:*) hgext/convert/monotone.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) hgext/convert/p4.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) hgext/convert/subversion.py: error importing module:
Re: [PATCH 1 of 2] pycompat: when setting attrs, ensure we use sysstr
On 8 October 2016 at 14:40, Augie Facklerwrote: > # HG changeset patch > # User Augie Fackler > # Date 1475930143 14400 > # Sat Oct 08 08:35:43 2016 -0400 > # Node ID 53708ce020c58f25079ef7b3802c71308843c0b4 > # Parent 392dc40e200e6fdc3ee5172c949b81cc56163e62 > pycompat: when setting attrs, ensure we use sysstr > > The custom module importer was making these bytes, so when we poked > values into self.__dict__ we had bytes instead of unicode on py3 and > it didn't work. > Looks great. > > diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py > --- a/mercurial/pycompat.py > +++ b/mercurial/pycompat.py > @@ -74,8 +74,10 @@ class _pycompatstub(object): > > def _registeraliases(self, origin, items): > """Add items that will be populated at the first access""" > -self._aliases.update((item.replace('_', '').lower(), (origin, > item)) > - for item in items) > +items = map(sysstr, items) > +self._aliases.update( > +(item.replace(sysstr('_'), sysstr('')).lower(), (origin, > item)) > +for item in items) > > def __getattr__(self, name): > try: > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel > -- Martijn Pieters ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH v2] hgweb: avoid line wrap between revision and annotate-info (issue5398)
# HG changeset patch # User Tooru Fujisawa# Date 1475922774 -32400 # Sat Oct 08 19:32:54 2016 +0900 # Node ID 1e4ffe788b13fe6af5862bdc87b588fffd49a4a5 # Parent f18cc848b48e2de5536fc861007d78d7d5bae42b hgweb: avoid line wrap between revision and annotate-info (issue5398) Add white-space: nowrap to td.annotate to avoid wrapping div.annotate-info into next line if there is revision number in the same cell, as it is hard to mouse over div.annotate-info if it's wrapped into next line. diff --git a/mercurial/templates/static/style-gitweb.css b/mercurial/templates/static/style-gitweb.css --- a/mercurial/templates/static/style-gitweb.css +++ b/mercurial/templates/static/style-gitweb.css @@ -50,16 +50,19 @@ td.indexlinks a { } td.indexlinks a:hover { background-color: #aa; } div.pre { font-family:monospace; font-size:12px; white-space:pre; } div.diff_info { font-family:monospace; color:#99; background-color:#edece6; font-style:italic; } div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; padding:12px 8px; } div.search { margin:4px 8px; position:absolute; top:56px; right:12px } tr.thisrev a { color:#99; text-decoration: none; } tr.thisrev pre { color:#009900; } +td.annotate { + white-space: nowrap; +} div.annotate-info { display: none; position: absolute; background-color: #FF; border: 1px solid #d9d8d1; text-align: left; color: #00; padding: 5px; diff --git a/mercurial/templates/static/style-monoblue.css b/mercurial/templates/static/style-monoblue.css --- a/mercurial/templates/static/style-monoblue.css +++ b/mercurial/templates/static/style-monoblue.css @@ -330,16 +330,19 @@ td.source { .lineno a { color: #999; } td.linenr { width: 60px; } tr.thisrev a { color:#99; text-decoration: none; } tr.thisrev td.source { color:#009900; } +td.annotate { + white-space: nowrap; +} div.annotate-info { display: none; position: absolute; background-color: #FF; border: solid 1px #CCC; text-align: left; color: #666; padding: 5px; diff --git a/mercurial/templates/static/style-paper.css b/mercurial/templates/static/style-paper.css --- a/mercurial/templates/static/style-paper.css +++ b/mercurial/templates/static/style-paper.css @@ -205,16 +205,19 @@ h3 { .bigtable .node { width: 5em; font-family: monospace;} .bigtable .permissions { width: 8em; text-align: left;} .bigtable .size { width: 5em; text-align: right; } .bigtable .annotate { text-align: right; } .bigtable td.annotate { font-size: smaller; } .bigtable td.source { font-size: inherit; } tr.thisrev a { color:#99; text-decoration: none; } tr.thisrev td.source { color:#009900; } +td.annotate { + white-space: nowrap; +} div.annotate-info { display: none; position: absolute; background-color: #FF; border: 1px solid #999; text-align: left; color: #00; padding: 5px; diff --git a/mercurial/templates/static/style.css b/mercurial/templates/static/style.css --- a/mercurial/templates/static/style.css +++ b/mercurial/templates/static/style.css @@ -7,16 +7,19 @@ a { text-decoration:none; } .lineno { width: 60px; color: #aaa; font-size: smaller; text-align: right; } .plusline { color: green; } .minusline { color: red; } .atline { color: purple; } .annotate { font-size: smaller; text-align: right; padding-right: 1em; } tr.thisrev a { color:#99; text-decoration: none; } tr.thisrev pre { color:#009900; } +td.annotate { + white-space: nowrap; +} div.annotate-info { display: none; position: absolute; background-color: #FF; border: 1px solid #888; text-align: left; color: #00; padding: 5px; diff --git a/tests/test-hgweb-commands.t b/tests/test-hgweb-commands.t --- a/tests/test-hgweb-commands.t +++ b/tests/test-hgweb-commands.t @@ -1960,16 +1960,19 @@ Static files .lineno { width: 60px; color: #aaa; font-size: smaller; text-align: right; } .plusline { color: green; } .minusline { color: red; } .atline { color: purple; } .annotate { font-size: smaller; text-align: right; padding-right: 1em; } tr.thisrev a { color:#99; text-decoration: none; } tr.thisrev pre { color:#009900; } + td.annotate { +white-space: nowrap; + } div.annotate-info { display: none; position: absolute; background-color: #FF; border: 1px solid #888; text-align: left; color: #00; padding: 5px; diff --git a/tests/test-hgweb.t b/tests/test-hgweb.t --- a/tests/test-hgweb.t +++ b/tests/test-hgweb.t @@ -335,17 +335,17 @@ Test the access/error files are opened i $ $PYTHON -c "print len(file('access.log').readlines()), 'log lines written'" 14 log lines written static file $ get-with-headers.py --twice localhost:$HGPORT 'static/style-gitweb.css' - date etag server 200 Script output follows - content-length: 6947 + content-length: 6986 content-type: text/css body { font-family:
Re: [PATCH v2] i18n: make the locale directory name the same string type as the datapath
On 8 October 2016 at 14:20, Augie Facklerwrote: > # HG changeset patch > # User Augie Fackler > # Date 1475918778 14400 > # Sat Oct 08 05:26:18 2016 -0400 > # Node ID 392dc40e200e6fdc3ee5172c949b81cc56163e62 > # Parent 87b8e40eb8125d5ddc848d972b117989346057dd > i18n: make the locale directory name the same string type as the datapath > > diff --git a/mercurial/i18n.py b/mercurial/i18n.py > --- a/mercurial/i18n.py > +++ b/mercurial/i18n.py > @@ -49,7 +49,11 @@ if (os.name == 'nt' > _ugettext = None > > def setdatapath(datapath): > -localedir = os.path.join(datapath, 'locale') > +if isinstance(datapath, unicode): > +locpart = u'locale' > +else: > +locpart = 'locale' > +localedir = os.path.join(datapath, locpart) > Since datapath is basically always sysstr (either __file__ or sys.executable), just use sysstr('locale') here. > t = gettextmod.translation('hg', localedir, _languages, fallback=True) > global _ugettext > try: > diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t > --- a/tests/test-check-py3-compat.t > +++ b/tests/test-check-py3-compat.t > @@ -16,96 +16,83 @@ >$ hg files 'set:(**.py) - grep(pygments)' | sed 's|\\|/|g' \ >> | xargs $PYTHON3 contrib/check-py3-compat.py \ >> | sed 's/[0-9][0-9]*)$/*)/' > - hgext/acl.py: error importing: Can't mix strings and bytes > in path components (error at i18n.py:*) > - hgext/automv.py: error importing: Can't mix strings and > bytes in path components (error at i18n.py:*) > - hgext/blackbox.py: error importing: Can't mix strings and > bytes in path components (error at i18n.py:*) > - hgext/bugzilla.py: error importing: Can't mix strings and > bytes in path components (error at i18n.py:*) > - hgext/censor.py: error importing: Can't mix strings and > bytes in path components (error at i18n.py:*) > - hgext/chgserver.py: error importing: Can't mix strings and > bytes in path components (error at i18n.py:*) > - hgext/children.py: error importing: Can't mix strings and > bytes in path components (error at i18n.py:*) > - hgext/churn.py: error importing: Can't mix strings and > bytes in path components (error at i18n.py:*) > - hgext/clonebundles.py: error importing: Can't mix strings > and bytes in path components (error at i18n.py:*) > - hgext/color.py: error importing: Can't mix strings and > bytes in path components (error at i18n.py:*) > + hgext/automv.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/blackbox.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/bugzilla.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/censor.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/chgserver.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/children.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/churn.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/clonebundles.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/color.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) >hgext/convert/bzr.py: error importing module: Parent > module 'hgext.convert' not loaded, cannot perform relative import (line *) > - hgext/convert/common.py: error importing: Can't mix strings > and bytes in path components (error at i18n.py:*) > - hgext/convert/convcmd.py: error importing: Can't mix > strings and bytes in path components (error at i18n.py:*) > - hgext/convert/cvs.py: error importing: Can't mix strings > and bytes in path components (error at i18n.py:*) > - hgext/convert/cvsps.py: error importing: Can't mix strings > and bytes in path components (error at i18n.py:*) > - hgext/convert/darcs.py: error importing: Can't mix strings > and bytes in path components (error at i18n.py:*) > + hgext/convert/common.py: error importing module: > module 'mercurial.util' has no attribute 'pickle' (line *) > + hgext/convert/convcmd.py: error importing: module > 'mercurial.util' has no attribute 'urlerr' (error at httpconnection.py:*) > + hgext/convert/cvs.py: error importing module: Parent > module 'hgext.convert' not loaded, cannot perform relative import (line *) > + hgext/convert/cvsps.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/convert/darcs.py: error importing module: Parent > module 'hgext.convert' not loaded, cannot perform relative import (line *) >hgext/convert/filemap.py: error importing module: Parent > module 'hgext.convert' not loaded,
[PATCH 2 of 4] dirs: convert PyString to PyBytes
# HG changeset patch # User Gregory Szorc# Date 1475929919 -7200 # Sat Oct 08 14:31:59 2016 +0200 # Node ID 3904cbad91663a7ae74c117a21879220b3e851b6 # Parent 33589809a2a64ceeb2828bbfe6e9126d6997bf94 dirs: convert PyString to PyBytes PyStringObject was renamed to PyBytes in Python 3 along with the corresponding PyString* functions and macros. PyString* doesn't exist in Python 3. But PyBytes* is an alias to PyString in Python 2. So rewrite PyString* to PyBytes* for Python 2/3 dual compatibility. diff --git a/mercurial/dirs.c b/mercurial/dirs.c --- a/mercurial/dirs.c +++ b/mercurial/dirs.c @@ -40,10 +40,10 @@ static inline Py_ssize_t _finddir(const } static int _addpath(PyObject *dirs, PyObject *path) { - const char *cpath = PyString_AS_STRING(path); - Py_ssize_t pos = PyString_GET_SIZE(path); + const char *cpath = PyBytes_AS_STRING(path); + Py_ssize_t pos = PyBytes_GET_SIZE(path); PyObject *key = NULL; int ret = -1; while ((pos = _finddir(cpath, pos - 1)) != -1) { @@ -52,18 +52,18 @@ static int _addpath(PyObject *dirs, PyOb /* It's likely that every prefix already has an entry in our dict. Try to avoid allocating and deallocating a string for each prefix we check. */ if (key != NULL) - ((PyStringObject *)key)->ob_shash = -1; + ((PyBytesObject *)key)->ob_shash = -1; else { /* Force Python to not reuse a small shared string. */ - key = PyString_FromStringAndSize(cpath, + key = PyBytes_FromStringAndSize(cpath, pos < 2 ? 2 : pos); if (key == NULL) goto bail; } Py_SIZE(key) = pos; - ((PyStringObject *)key)->ob_sval[pos] = '\0'; + ((PyBytesObject *)key)->ob_sval[pos] = '\0'; val = PyDict_GetItem(dirs, key); if (val != NULL) { PyInt_AS_LONG(val) += 1; @@ -92,17 +92,17 @@ bail: } static int _delpath(PyObject *dirs, PyObject *path) { - char *cpath = PyString_AS_STRING(path); - Py_ssize_t pos = PyString_GET_SIZE(path); + char *cpath = PyBytes_AS_STRING(path); + Py_ssize_t pos = PyBytes_GET_SIZE(path); PyObject *key = NULL; int ret = -1; while ((pos = _finddir(cpath, pos - 1)) != -1) { PyObject *val; - key = PyString_FromStringAndSize(cpath, pos); + key = PyBytes_FromStringAndSize(cpath, pos); if (key == NULL) goto bail; @@ -133,9 +133,9 @@ static int dirs_fromdict(PyObject *dirs, PyObject *key, *value; Py_ssize_t pos = 0; while (PyDict_Next(source, , , )) { - if (!PyString_Check(key)) { + if (!PyBytes_Check(key)) { PyErr_SetString(PyExc_TypeError, "expected string key"); return -1; } if (skipchar) { @@ -164,9 +164,9 @@ static int dirs_fromiter(PyObject *dirs, if (iter == NULL) return -1; while ((item = PyIter_Next(iter)) != NULL) { - if (!PyString_Check(item)) { + if (!PyBytes_Check(item)) { PyErr_SetString(PyExc_TypeError, "expected string"); break; } @@ -223,9 +223,9 @@ static int dirs_init(dirsObject *self, P PyObject *dirs_addpath(dirsObject *self, PyObject *args) { PyObject *path; - if (!PyArg_ParseTuple(args, "O!:addpath", _Type, )) + if (!PyArg_ParseTuple(args, "O!:addpath", _Type, )) return NULL; if (_addpath(self->dict, path) == -1) return NULL; @@ -236,9 +236,9 @@ PyObject *dirs_addpath(dirsObject *self, static PyObject *dirs_delpath(dirsObject *self, PyObject *args) { PyObject *path; - if (!PyArg_ParseTuple(args, "O!:delpath", _Type, )) + if (!PyArg_ParseTuple(args, "O!:delpath", _Type, )) return NULL; if (_delpath(self->dict, path) == -1) return NULL; @@ -247,9 +247,9 @@ static PyObject *dirs_delpath(dirsObject } static int dirs_contains(dirsObject *self, PyObject *value) { - return PyString_Check(value) ? PyDict_Contains(self->dict, value) : 0; + return PyBytes_Check(value) ? PyDict_Contains(self->dict, value) : 0; } static void dirs_dealloc(dirsObject *self) { ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 4 of 4] dirs: document performance reasons for bypassing Python C API
# HG changeset patch # User Gregory Szorc# Date 1475938278 -7200 # Sat Oct 08 16:51:18 2016 +0200 # Node ID 136b1a54213542f535f155de5ce01049b3577b4a # Parent da39a5835ea2d1aae1a51995b6d7e593f598be4b dirs: document performance reasons for bypassing Python C API So someone isn't tempted to change it. diff --git a/mercurial/dirs.c b/mercurial/dirs.c --- a/mercurial/dirs.c +++ b/mercurial/dirs.c @@ -55,8 +55,16 @@ static int _addpath(PyObject *dirs, PyOb Py_ssize_t pos = PyBytes_GET_SIZE(path); PyObject *key = NULL; int ret = -1; + /* This loop is super critical for performance. That's why we inline + * access to Python structs instead of going through a supported API. + * The implementation, therefore, is heavily dependent on CPython + * implementation details. We also commit violations of the Python + * "protocol" such as mutating immutable objects. But since we only + * mutate objects created in this function or in other well-defined + * locations, the references are known so these violations should go + * unnoticed. */ while ((pos = _finddir(cpath, pos - 1)) != -1) { PyObject *val; /* It's likely that every prefix already has an entry ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 4] dirs: port PyInt code to work on Python 3
# HG changeset patch # User Gregory Szorc# Date 1475936421 -7200 # Sat Oct 08 16:20:21 2016 +0200 # Node ID da39a5835ea2d1aae1a51995b6d7e593f598be4b # Parent 3904cbad91663a7ae74c117a21879220b3e851b6 dirs: port PyInt code to work on Python 3 PyIntObject no longer exists in Python 3. Instead, there is PyLongObject. Furthermore, PyInt_AS_LONG is a macro referencing a struct member. PyInt_AS_LONG doesn't exist in Python 3 and PyLong_AS_LONG is a #define for PyLong_AsLong, which is a function. So assigning to the return value of PyLong_AS_LONG doesn't work. This patch introduces a macro for obtaining the value of an integer-like type that works on Python 2 and Python 3. On Python 3, we access the struct field of the underlying PyLongObjet directly, without overflow checking. This is essentially the same as what Python 2 was doing except using a PyLong instead of a PyInt. diff --git a/mercurial/dirs.c b/mercurial/dirs.c --- a/mercurial/dirs.c +++ b/mercurial/dirs.c @@ -10,8 +10,18 @@ #define PY_SSIZE_T_CLEAN #include #include "util.h" +#if PY_MAJOR_VERSION >= 3 +#define IS_PY3K +#endif + +#ifdef IS_PY3K +#define PYLONG_VALUE(o) ((PyLongObject *)o)->ob_digit[1] +#else +#define PYLONG_VALUE(o) PyInt_AS_LONG(o) +#endif + /* * This is a multiset of directory names, built from the files that * appear in a dirstate or manifest. * @@ -65,19 +75,23 @@ static int _addpath(PyObject *dirs, PyOb ((PyBytesObject *)key)->ob_sval[pos] = '\0'; val = PyDict_GetItem(dirs, key); if (val != NULL) { - PyInt_AS_LONG(val) += 1; + PYLONG_VALUE(val) += 1; break; } /* Force Python to not reuse a small shared int. */ +#ifdef IS_PY3K + val = PyLong_FromLong(0x1eadbeef); +#else val = PyInt_FromLong(0x1eadbeef); +#endif if (val == NULL) goto bail; - PyInt_AS_LONG(val) = 1; + PYLONG_VALUE(val) = 1; ret = PyDict_SetItem(dirs, key, val); Py_DECREF(val); if (ret == -1) goto bail; @@ -112,9 +126,9 @@ static int _delpath(PyObject *dirs, PyOb "expected a value, found none"); goto bail; } - if (--PyInt_AS_LONG(val) <= 0) { + if (--PYLONG_VALUE(val) <= 0) { if (PyDict_DelItem(dirs, key) == -1) goto bail; } else break; ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 4] dirs: inline string macros
# HG changeset patch # User Gregory Szorc# Date 1475935371 -7200 # Sat Oct 08 16:02:51 2016 +0200 # Node ID 33589809a2a64ceeb2828bbfe6e9126d6997bf94 # Parent 2def3d55b1b9ec2acd53f96ca755d778b5ec865b dirs: inline string macros The old code happened to work because of how the macro was defined. This no longer works in Python 3. Furthermore, assigning to a macro just feels weird. So just inline the macro. diff --git a/mercurial/dirs.c b/mercurial/dirs.c --- a/mercurial/dirs.c +++ b/mercurial/dirs.c @@ -60,10 +60,10 @@ static int _addpath(PyObject *dirs, PyOb pos < 2 ? 2 : pos); if (key == NULL) goto bail; } - PyString_GET_SIZE(key) = pos; - PyString_AS_STRING(key)[pos] = '\0'; + Py_SIZE(key) = pos; + ((PyStringObject *)key)->ob_sval[pos] = '\0'; val = PyDict_GetItem(dirs, key); if (val != NULL) { PyInt_AS_LONG(val) += 1; ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] hgweb: avoid line wrapping between revision and annotate-info box in annotate cell (issue5398)
Tooru: if you send a version with a correct commit message, I can update the test expectations for you and make sure this gets committed. Or if you want to try to run the tests: $ cd tests $ ./run-tests.py -j4 --interactive test-hgweb* Then accept the changes, amend the commit, and resend. On Sat, Oct 8, 2016 at 4:28 PM, Augie Facklerwrote: > > > On Oct 8, 2016, at 12:56, Tooru Fujisawa wrote: > > > > # HG changeset patch > > # User Tooru Fujisawa > > # Date 1475922774 -32400 > > # Sat Oct 08 19:32:54 2016 +0900 > > # Node ID a0f1fe5c0bd88ea2ebb2756e20669747e61f5c35 > > # Parent f18cc848b48e2de5536fc861007d78d7d5bae42b > > hgweb: avoid line wrapping between revision and annotate-info box in > annotate cell (issue5398) > > Looks pretty good, however: > > 1) this summary line is too long: > 6: summary line too long (limit is 78) >hgweb: avoid line wrapping between revision and annotate-info box in > annotate cell (issue5398) > (test-check-commit.t) > > 2) test-hgweb{,-commands}.t have some minor expectation updates that need > to be done. > > Can you correct those two issues and mail a v2? > > Thanks! > > > > > Add white-space: nowrap to td.annotate to avoid wrapping > div.annotate-info > > into next line if there is revision number in the same cell, as it is > hard to > > mouse over div.annotate-info if it's wrapped into next line. > > > > diff --git a/mercurial/templates/static/style-gitweb.css > b/mercurial/templates/static/style-gitweb.css > > --- a/mercurial/templates/static/style-gitweb.css > > +++ b/mercurial/templates/static/style-gitweb.css > > @@ -50,16 +50,19 @@ td.indexlinks a { > > } > > td.indexlinks a:hover { background-color: #aa; } > > div.pre { font-family:monospace; font-size:12px; white-space:pre; } > > div.diff_info { font-family:monospace; color:#99; > background-color:#edece6; font-style:italic; } > > div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; > padding:12px 8px; } > > div.search { margin:4px 8px; position:absolute; top:56px; right:12px } > > tr.thisrev a { color:#99; text-decoration: none; } > > tr.thisrev pre { color:#009900; } > > +td.annotate { > > + white-space: nowrap; > > +} > > div.annotate-info { > > display: none; > > position: absolute; > > background-color: #FF; > > border: 1px solid #d9d8d1; > > text-align: left; > > color: #00; > > padding: 5px; > > diff --git a/mercurial/templates/static/style-monoblue.css > b/mercurial/templates/static/style-monoblue.css > > --- a/mercurial/templates/static/style-monoblue.css > > +++ b/mercurial/templates/static/style-monoblue.css > > @@ -330,16 +330,19 @@ td.source { > > .lineno a { > > color: #999; > > } > > td.linenr { > > width: 60px; > > } > > tr.thisrev a { color:#99; text-decoration: none; } > > tr.thisrev td.source { color:#009900; } > > +td.annotate { > > + white-space: nowrap; > > +} > > div.annotate-info { > > display: none; > > position: absolute; > > background-color: #FF; > > border: solid 1px #CCC; > > text-align: left; > > color: #666; > > padding: 5px; > > diff --git a/mercurial/templates/static/style-paper.css > b/mercurial/templates/static/style-paper.css > > --- a/mercurial/templates/static/style-paper.css > > +++ b/mercurial/templates/static/style-paper.css > > @@ -205,16 +205,19 @@ h3 { > > .bigtable .node { width: 5em; font-family: monospace;} > > .bigtable .permissions { width: 8em; text-align: left;} > > .bigtable .size { width: 5em; text-align: right; } > > .bigtable .annotate { text-align: right; } > > .bigtable td.annotate { font-size: smaller; } > > .bigtable td.source { font-size: inherit; } > > tr.thisrev a { color:#99; text-decoration: none; } > > tr.thisrev td.source { color:#009900; } > > +td.annotate { > > + white-space: nowrap; > > +} > > div.annotate-info { > > display: none; > > position: absolute; > > background-color: #FF; > > border: 1px solid #999; > > text-align: left; > > color: #00; > > padding: 5px; > > diff --git a/mercurial/templates/static/style.css > b/mercurial/templates/static/style.css > > --- a/mercurial/templates/static/style.css > > +++ b/mercurial/templates/static/style.css > > @@ -7,16 +7,19 @@ a { text-decoration:none; } > > .lineno { width: 60px; color: #aaa; font-size: smaller; > > text-align: right; } > > .plusline { color: green; } > > .minusline { color: red; } > > .atline { color: purple; } > > .annotate { font-size: smaller; text-align: right; padding-right: 1em; } > > tr.thisrev a { color:#99; text-decoration: none; } > > tr.thisrev pre { color:#009900; } > > +td.annotate { > > + white-space: nowrap; > > +} > > div.annotate-info { > > display: none; > > position: absolute; > > background-color: #FF; > > border: 1px solid #888; > > text-align: left; > > color: #00; > > padding: 5px; > > ___ >
Re: [PATCH V2] py3: make format strings unicodes and not bytes
On Sat, Oct 08, 2016 at 04:39:19PM +0200, Pulkit Goyal wrote: > # HG changeset patch > # User Pulkit Goyal <7895pul...@gmail.com> > # Date 1475935858 -7200 > # Sat Oct 08 16:10:58 2016 +0200 > # Node ID 6847725111006f427e2c460948aa07acb36364a6 > # Parent 14da91b1ac26cac422b04a5e41b451e381c75e08 > py3: make format strings unicodes and not bytes Queued, thanks > Fixes issues on Python 3, wherein docstrings are unicodes. > Shouldn't break anything on Python 2. > > diff -r 14da91b1ac26 -r 684772511100 mercurial/filemerge.py > --- a/mercurial/filemerge.py Sat Oct 08 08:36:39 2016 -0400 > +++ b/mercurial/filemerge.py Sat Oct 08 16:10:58 2016 +0200 > @@ -19,6 +19,7 @@ > error, > formatter, > match, > +pycompat, > scmutil, > simplemerge, > tagmerge, > @@ -93,7 +94,8 @@ > '''return a decorator for populating internal merge tool table''' > def decorator(func): > fullname = ':' + name > -func.__doc__ = "``%s``\n" % fullname + func.__doc__.strip() > +func.__doc__ = pycompat.sysstr("``%s``\n" % fullname) > ++ func.__doc__.strip() > internals[fullname] = func > internals['internal:' + name] = func > internalsdoc[fullname] = func > ___ > 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: make format strings unicodes and not bytes
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1475935858 -7200 # Sat Oct 08 16:10:58 2016 +0200 # Node ID 6847725111006f427e2c460948aa07acb36364a6 # Parent 14da91b1ac26cac422b04a5e41b451e381c75e08 py3: make format strings unicodes and not bytes Fixes issues on Python 3, wherein docstrings are unicodes. Shouldn't break anything on Python 2. diff -r 14da91b1ac26 -r 684772511100 mercurial/filemerge.py --- a/mercurial/filemerge.pySat Oct 08 08:36:39 2016 -0400 +++ b/mercurial/filemerge.pySat Oct 08 16:10:58 2016 +0200 @@ -19,6 +19,7 @@ error, formatter, match, +pycompat, scmutil, simplemerge, tagmerge, @@ -93,7 +94,8 @@ '''return a decorator for populating internal merge tool table''' def decorator(func): fullname = ':' + name -func.__doc__ = "``%s``\n" % fullname + func.__doc__.strip() +func.__doc__ = pycompat.sysstr("``%s``\n" % fullname) ++ func.__doc__.strip() internals[fullname] = func internals['internal:' + name] = func internalsdoc[fullname] = func ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] hgweb: avoid line wrapping between revision and annotate-info box in annotate cell (issue5398)
> On Oct 8, 2016, at 12:56, Tooru Fujisawawrote: > > # HG changeset patch > # User Tooru Fujisawa > # Date 1475922774 -32400 > # Sat Oct 08 19:32:54 2016 +0900 > # Node ID a0f1fe5c0bd88ea2ebb2756e20669747e61f5c35 > # Parent f18cc848b48e2de5536fc861007d78d7d5bae42b > hgweb: avoid line wrapping between revision and annotate-info box in annotate > cell (issue5398) Looks pretty good, however: 1) this summary line is too long: 6: summary line too long (limit is 78) hgweb: avoid line wrapping between revision and annotate-info box in annotate cell (issue5398) (test-check-commit.t) 2) test-hgweb{,-commands}.t have some minor expectation updates that need to be done. Can you correct those two issues and mail a v2? Thanks! > > Add white-space: nowrap to td.annotate to avoid wrapping div.annotate-info > into next line if there is revision number in the same cell, as it is hard to > mouse over div.annotate-info if it's wrapped into next line. > > diff --git a/mercurial/templates/static/style-gitweb.css > b/mercurial/templates/static/style-gitweb.css > --- a/mercurial/templates/static/style-gitweb.css > +++ b/mercurial/templates/static/style-gitweb.css > @@ -50,16 +50,19 @@ td.indexlinks a { > } > td.indexlinks a:hover { background-color: #aa; } > div.pre { font-family:monospace; font-size:12px; white-space:pre; } > div.diff_info { font-family:monospace; color:#99; > background-color:#edece6; font-style:italic; } > div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; > padding:12px 8px; } > div.search { margin:4px 8px; position:absolute; top:56px; right:12px } > tr.thisrev a { color:#99; text-decoration: none; } > tr.thisrev pre { color:#009900; } > +td.annotate { > + white-space: nowrap; > +} > div.annotate-info { > display: none; > position: absolute; > background-color: #FF; > border: 1px solid #d9d8d1; > text-align: left; > color: #00; > padding: 5px; > diff --git a/mercurial/templates/static/style-monoblue.css > b/mercurial/templates/static/style-monoblue.css > --- a/mercurial/templates/static/style-monoblue.css > +++ b/mercurial/templates/static/style-monoblue.css > @@ -330,16 +330,19 @@ td.source { > .lineno a { > color: #999; > } > td.linenr { > width: 60px; > } > tr.thisrev a { color:#99; text-decoration: none; } > tr.thisrev td.source { color:#009900; } > +td.annotate { > + white-space: nowrap; > +} > div.annotate-info { > display: none; > position: absolute; > background-color: #FF; > border: solid 1px #CCC; > text-align: left; > color: #666; > padding: 5px; > diff --git a/mercurial/templates/static/style-paper.css > b/mercurial/templates/static/style-paper.css > --- a/mercurial/templates/static/style-paper.css > +++ b/mercurial/templates/static/style-paper.css > @@ -205,16 +205,19 @@ h3 { > .bigtable .node { width: 5em; font-family: monospace;} > .bigtable .permissions { width: 8em; text-align: left;} > .bigtable .size { width: 5em; text-align: right; } > .bigtable .annotate { text-align: right; } > .bigtable td.annotate { font-size: smaller; } > .bigtable td.source { font-size: inherit; } > tr.thisrev a { color:#99; text-decoration: none; } > tr.thisrev td.source { color:#009900; } > +td.annotate { > + white-space: nowrap; > +} > div.annotate-info { > display: none; > position: absolute; > background-color: #FF; > border: 1px solid #999; > text-align: left; > color: #00; > padding: 5px; > diff --git a/mercurial/templates/static/style.css > b/mercurial/templates/static/style.css > --- a/mercurial/templates/static/style.css > +++ b/mercurial/templates/static/style.css > @@ -7,16 +7,19 @@ a { text-decoration:none; } > .lineno { width: 60px; color: #aaa; font-size: smaller; > text-align: right; } > .plusline { color: green; } > .minusline { color: red; } > .atline { color: purple; } > .annotate { font-size: smaller; text-align: right; padding-right: 1em; } > tr.thisrev a { color:#99; text-decoration: none; } > tr.thisrev pre { color:#009900; } > +td.annotate { > + white-space: nowrap; > +} > div.annotate-info { > display: none; > position: absolute; > background-color: #FF; > border: 1px solid #888; > text-align: left; > color: #00; > padding: 5px; > ___ > 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 evolve-ext] split: avoid trying to split an empty commit (issue5191)
On 10/08/2016 03:50 PM, Philippe Pepiot wrote: # HG changeset patch # User Philippe Pepiot# Date 1475934552 -7200 # Sat Oct 08 15:49:12 2016 +0200 # Node ID 1ef723b6fdfb8f940e0e1a82f2936917e7d4e23f # Parent 5383671ef612a1764bbbed13a7ef2d339d0a9c2d split: avoid trying to split an empty commit (issue5191) Pushed, thanks a lot. -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH evolve-ext] split: avoid trying to split an empty commit (issue5191)
# HG changeset patch # User Philippe Pepiot# Date 1475934552 -7200 # Sat Oct 08 15:49:12 2016 +0200 # Node ID 1ef723b6fdfb8f940e0e1a82f2936917e7d4e23f # Parent 5383671ef612a1764bbbed13a7ef2d339d0a9c2d split: avoid trying to split an empty commit (issue5191) diff --git a/hgext/evolve.py b/hgext/evolve.py --- a/hgext/evolve.py +++ b/hgext/evolve.py @@ -2932,11 +2932,12 @@ def cmdsplit(ui, repo, *revs, **opts): else: ui.status(_("no more change to split\n")) -tip = repo[newcommits[-1]] -bmupdate(tip.node()) -if bookactive is not None: -bmactivate(repo, bookactive) -obsolete.createmarkers(repo, [(repo[r], newcommits)]) +if newcommits: +tip = repo[newcommits[-1]] +bmupdate(tip.node()) +if bookactive is not None: +bmactivate(repo, bookactive) +obsolete.createmarkers(repo, [(repo[r], newcommits)]) tr.close() finally: lockmod.release(tr, lock, wlock) diff --git a/tests/test-split.t b/tests/test-split.t --- a/tests/test-split.t +++ b/tests/test-split.t @@ -378,3 +378,10 @@ Running split with both unnamed and name (use either `hg split ` or `hg split --rev `, not both) [255] +Split empty commit (issue5191) + $ hg branch new-branch + marked working directory as branch new-branch + (branches are permanent and global, did you want a bookmark?) + $ hg commit -m "empty" + $ hg split + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH remotenames-ext] tests: fix failures related to double->single quote changes
Kostia Balytskyiwrites: > # HG changeset patch > # User Kostia Balytskyi > # Date 1474562531 25200 > # Thu Sep 22 09:42:11 2016 -0700 > # Node ID 3aa5c4dbf5086615dbbe42b0d2d9fd5ca0488cf1 > # Parent 7a6c5ff76f225c8ebe9baef9d5ef753da915aa8b > tests: fix failures related to double->single quote changes I thought I replied to this before but it seems to have already been pushed. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2 V3 remotenames-ext] remotenames: selectivepull, update to the unknown bookmark tries to pull it
Stanislau Hlebikwrites: > # HG changeset patch > # User Stanislau Hlebik > # Date 1471860690 25200 > # Mon Aug 22 03:11:30 2016 -0700 > # Node ID 7dae93347fd658a558284e55d27060e980f324f0 > # Parent 866049ffa049dc598af834a035f27a06684d264d > remotenames: selectivepull, update to the unknown bookmark tries to pull it > > Part of Selective Pull project (see > https://www.mercurial-scm.org/wiki/SelectivePullPlan for details). > If Selective Pull is enabled, then we want to be able to check out > revision even if it's not present locally, but present on remote server. > If rev or node is not present locally, new request is issued to find > it remotely. If it is present remotely then it's pulled. After sitting down together at the sprint, I was able to review these and fix up the tests. Finally queued and pushed, thanks! ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2] util: ensure forwarded attrs are set in globals() as sysstr
Much needed series. On Sat, Oct 8, 2016 at 2:40 PM, Augie Facklerwrote: > # HG changeset patch > # User Augie Fackler > # Date 1475930199 14400 > # Sat Oct 08 08:36:39 2016 -0400 > # Node ID 6034bb7c1e0cb80cae6f3f7d3058a456f9b49c5b > # Parent 53708ce020c58f25079ef7b3802c71308843c0b4 > util: ensure forwarded attrs are set in globals() as sysstr > > Custom module importer strikes again. > > diff --git a/mercurial/util.py b/mercurial/util.py > --- a/mercurial/util.py > +++ b/mercurial/util.py > @@ -60,7 +60,8 @@ for attr in ( > 'socketserver', > 'xmlrpclib', > ): > -globals()[attr] = getattr(pycompat, attr) > +a = pycompat.sysstr(attr) > +globals()[a] = getattr(pycompat, a) > > # This line is to make pyflakes happy: > urlreq = pycompat.urlreq > diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t > --- a/tests/test-check-py3-compat.t > +++ b/tests/test-check-py3-compat.t > @@ -16,83 +16,73 @@ >$ hg files 'set:(**.py) - grep(pygments)' | sed 's|\\|/|g' \ >> | xargs $PYTHON3 contrib/check-py3-compat.py \ >> | sed 's/[0-9][0-9]*)$/*)/' > - hgext/automv.py: error importing: module 'mercurial.util' > has no attribute 'stringio' (error at patch.py:*) > - hgext/blackbox.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > - hgext/bugzilla.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > - hgext/censor.py: error importing: module 'mercurial.util' > has no attribute 'stringio' (error at patch.py:*) > - hgext/chgserver.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > - hgext/children.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > - hgext/churn.py: error importing: module 'mercurial.util' > has no attribute 'stringio' (error at patch.py:*) > - hgext/clonebundles.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > - hgext/color.py: error importing: module 'mercurial.util' > has no attribute 'stringio' (error at patch.py:*) > + hgext/automv.py: error importing: ord() expected string of > length 1, but int found (error at store.py:*) > + hgext/blackbox.py: error importing: ord() expected string of > length 1, but int found (error at store.py:*) > + hgext/bugzilla.py: error importing: ord() expected string of > length 1, but int found (error at store.py:*) > + hgext/censor.py: error importing: ord() expected string of > length 1, but int found (error at store.py:*) > + hgext/chgserver.py: error importing: ord() expected string of > length 1, but int found (error at store.py:*) > + hgext/children.py: error importing: ord() expected string of > length 1, but int found (error at store.py:*) > + hgext/churn.py: error importing: ord() expected string of > length 1, but int found (error at store.py:*) > + hgext/clonebundles.py: error importing: ord() expected string > of length 1, but int found (error at store.py:*) > + hgext/color.py: error importing: ord() expected string of > length 1, but int found (error at store.py:*) >hgext/convert/bzr.py: error importing module: Parent module > 'hgext.convert' not loaded, cannot perform relative import (line *) > - hgext/convert/common.py: error importing module: module > 'mercurial.util' has no attribute 'pickle' (line *) > - hgext/convert/convcmd.py: error importing: module > 'mercurial.util' has no attribute 'urlerr' (error at httpconnection.py:*) > + hgext/convert/convcmd.py: error importing: ord() expected > string of length 1, but int found (error at store.py:*) >hgext/convert/cvs.py: error importing module: Parent module > 'hgext.convert' not loaded, cannot perform relative import (line *) > - hgext/convert/cvsps.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/convert/cvsps.py: error importing: ord() expected string > of length 1, but int found (error at store.py:*) >hgext/convert/darcs.py: error importing module: Parent > module 'hgext.convert' not loaded, cannot perform relative import (line *) >hgext/convert/filemap.py: error importing module: Parent > module 'hgext.convert' not loaded, cannot perform relative import (line *) >hgext/convert/git.py: error importing module: Parent module > 'hgext.convert' not loaded, cannot perform relative import (line *) >hgext/convert/gnuarch.py: error importing module: Parent > module 'hgext.convert' not loaded, cannot perform relative import (line *) > - hgext/convert/hg.py: error importing: module > 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) > + hgext/convert/hg.py: error importing: can't concat bytes to > str (error at filemerge.py:*) >hgext/convert/monotone.py: error importing module: Parent >
[PATCH v2] i18n: make the locale directory name the same string type as the datapath
# HG changeset patch # User Augie Fackler# Date 1475918778 14400 # Sat Oct 08 05:26:18 2016 -0400 # Node ID 392dc40e200e6fdc3ee5172c949b81cc56163e62 # Parent 87b8e40eb8125d5ddc848d972b117989346057dd i18n: make the locale directory name the same string type as the datapath diff --git a/mercurial/i18n.py b/mercurial/i18n.py --- a/mercurial/i18n.py +++ b/mercurial/i18n.py @@ -49,7 +49,11 @@ if (os.name == 'nt' _ugettext = None def setdatapath(datapath): -localedir = os.path.join(datapath, 'locale') +if isinstance(datapath, unicode): +locpart = u'locale' +else: +locpart = 'locale' +localedir = os.path.join(datapath, locpart) t = gettextmod.translation('hg', localedir, _languages, fallback=True) global _ugettext try: diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t --- a/tests/test-check-py3-compat.t +++ b/tests/test-check-py3-compat.t @@ -16,96 +16,83 @@ $ hg files 'set:(**.py) - grep(pygments)' | sed 's|\\|/|g' \ > | xargs $PYTHON3 contrib/check-py3-compat.py \ > | sed 's/[0-9][0-9]*)$/*)/' - hgext/acl.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/automv.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/blackbox.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/bugzilla.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/censor.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/chgserver.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/children.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/churn.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/clonebundles.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/color.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) + hgext/automv.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/blackbox.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/bugzilla.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/censor.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/chgserver.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/children.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/churn.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/clonebundles.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/color.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) hgext/convert/bzr.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) - hgext/convert/common.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/convert/convcmd.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/convert/cvs.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/convert/cvsps.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/convert/darcs.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) + hgext/convert/common.py: error importing module: module 'mercurial.util' has no attribute 'pickle' (line *) + hgext/convert/convcmd.py: error importing: module 'mercurial.util' has no attribute 'urlerr' (error at httpconnection.py:*) + hgext/convert/cvs.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) + hgext/convert/cvsps.py: error importing: module 'mercurial.util' has no attribute 'stringio' (error at patch.py:*) + hgext/convert/darcs.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) hgext/convert/filemap.py: error importing module: Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) - hgext/convert/git.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/convert/gnuarch.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) - hgext/convert/hg.py: error importing: Can't mix strings and bytes in
[PATCH] hgweb: avoid line wrapping between revision and annotate-info box in annotate cell (issue5398)
# HG changeset patch # User Tooru Fujisawa# Date 1475922774 -32400 # Sat Oct 08 19:32:54 2016 +0900 # Node ID a0f1fe5c0bd88ea2ebb2756e20669747e61f5c35 # Parent f18cc848b48e2de5536fc861007d78d7d5bae42b hgweb: avoid line wrapping between revision and annotate-info box in annotate cell (issue5398) Add white-space: nowrap to td.annotate to avoid wrapping div.annotate-info into next line if there is revision number in the same cell, as it is hard to mouse over div.annotate-info if it's wrapped into next line. diff --git a/mercurial/templates/static/style-gitweb.css b/mercurial/templates/static/style-gitweb.css --- a/mercurial/templates/static/style-gitweb.css +++ b/mercurial/templates/static/style-gitweb.css @@ -50,16 +50,19 @@ td.indexlinks a { } td.indexlinks a:hover { background-color: #aa; } div.pre { font-family:monospace; font-size:12px; white-space:pre; } div.diff_info { font-family:monospace; color:#99; background-color:#edece6; font-style:italic; } div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; padding:12px 8px; } div.search { margin:4px 8px; position:absolute; top:56px; right:12px } tr.thisrev a { color:#99; text-decoration: none; } tr.thisrev pre { color:#009900; } +td.annotate { + white-space: nowrap; +} div.annotate-info { display: none; position: absolute; background-color: #FF; border: 1px solid #d9d8d1; text-align: left; color: #00; padding: 5px; diff --git a/mercurial/templates/static/style-monoblue.css b/mercurial/templates/static/style-monoblue.css --- a/mercurial/templates/static/style-monoblue.css +++ b/mercurial/templates/static/style-monoblue.css @@ -330,16 +330,19 @@ td.source { .lineno a { color: #999; } td.linenr { width: 60px; } tr.thisrev a { color:#99; text-decoration: none; } tr.thisrev td.source { color:#009900; } +td.annotate { + white-space: nowrap; +} div.annotate-info { display: none; position: absolute; background-color: #FF; border: solid 1px #CCC; text-align: left; color: #666; padding: 5px; diff --git a/mercurial/templates/static/style-paper.css b/mercurial/templates/static/style-paper.css --- a/mercurial/templates/static/style-paper.css +++ b/mercurial/templates/static/style-paper.css @@ -205,16 +205,19 @@ h3 { .bigtable .node { width: 5em; font-family: monospace;} .bigtable .permissions { width: 8em; text-align: left;} .bigtable .size { width: 5em; text-align: right; } .bigtable .annotate { text-align: right; } .bigtable td.annotate { font-size: smaller; } .bigtable td.source { font-size: inherit; } tr.thisrev a { color:#99; text-decoration: none; } tr.thisrev td.source { color:#009900; } +td.annotate { + white-space: nowrap; +} div.annotate-info { display: none; position: absolute; background-color: #FF; border: 1px solid #999; text-align: left; color: #00; padding: 5px; diff --git a/mercurial/templates/static/style.css b/mercurial/templates/static/style.css --- a/mercurial/templates/static/style.css +++ b/mercurial/templates/static/style.css @@ -7,16 +7,19 @@ a { text-decoration:none; } .lineno { width: 60px; color: #aaa; font-size: smaller; text-align: right; } .plusline { color: green; } .minusline { color: red; } .atline { color: purple; } .annotate { font-size: smaller; text-align: right; padding-right: 1em; } tr.thisrev a { color:#99; text-decoration: none; } tr.thisrev pre { color:#009900; } +td.annotate { + white-space: nowrap; +} div.annotate-info { display: none; position: absolute; background-color: #FF; border: 1px solid #888; text-align: left; color: #00; padding: 5px; ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@30053: 4 new changesets
4 new changesets in mercurial: http://selenic.com/repo/hg//rev/d229be12e256 changeset: 30050:d229be12e256 user:Pulkit Goyal <7895pul...@gmail.com> date:Fri Oct 07 12:13:28 2016 +0200 summary: py3: convert to unicode to pass into encode() http://selenic.com/repo/hg//rev/3139ec39b505 changeset: 30051:3139ec39b505 user:Pulkit Goyal <7895pul...@gmail.com> date:Fri Oct 07 14:04:49 2016 +0200 summary: py3: handle multiple arguments in .encode() and .decode() http://selenic.com/repo/hg//rev/eaaedad68011 changeset: 30052:eaaedad68011 user:Pulkit Goyal <7895pul...@gmail.com> date:Fri Oct 07 15:29:57 2016 +0200 summary: py3: switch to .items() using transformer http://selenic.com/repo/hg//rev/dbcef8918bbd changeset: 30053:dbcef8918bbd bookmark:@ tag: tip user:Augie Facklerdate:Fri Oct 07 08:01:16 2016 -0400 summary: util: correct check of sys.version_info -- Repository URL: http://selenic.com/repo/hg/ ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH v3] mail: take --encoding and HGENCODING into account
# HG changeset patch # User Gábor Stefanik# Date 1475667922 -7200 # Wed Oct 05 13:45:22 2016 +0200 # Node ID d7125caa00dcc6036d3d5aee3e4d524211b95e02 # Parent dbcef8918bbdd8a64d9f79a37bcfa284a26f3a39 mail: take --encoding and HGENCODING into account Fall back to our encoding strategy for sending MIME text that's neither ASCII nor UTF-8. diff --git a/mercurial/mail.py b/mercurial/mail.py --- a/mercurial/mail.py +++ b/mercurial/mail.py @@ -8,6 +8,7 @@ from __future__ import absolute_import, print_function import email +import email.charset import os import quopri import smtplib @@ -203,24 +204,33 @@ raise error.Abort(_('%r specified as email transport, ' 'but not in PATH') % method) +def codec2iana(cs): +'' +cs = email.charset.Charset(cs).input_charset.lower() + +# "latin1" normalizes to "iso8859-1", standard calls for "iso-8859-1" +if cs.startswith("iso") and not cs.startswith("iso-"): +return "iso-" + cs[3:] +return cs + def mimetextpatch(s, subtype='plain', display=False): '''Return MIME message suitable for a patch. -Charset will be detected as utf-8 or (possibly fake) us-ascii. +Charset will be detected by first trying to decode as us-ascii, then utf-8, +and finally the global encodings. If all those fail, fall back to +ISO-8859-1, an encoding with that allows all byte sequences. Transfer encodings will be used if necessary.''' -cs = 'us-ascii' -if not display: +cs = ['us-ascii', 'utf-8', encoding.encoding, encoding.fallbackencoding] +if display: +return mimetextqp(s, subtype, 'us-ascii') +for charset in cs: try: -s.decode('us-ascii') +s.decode(charset) +return mimetextqp(s, subtype, codec2iana(charset)) except UnicodeDecodeError: -try: -s.decode('utf-8') -cs = 'utf-8' -except UnicodeDecodeError: -# We'll go with us-ascii as a fallback. -pass +pass -return mimetextqp(s, subtype, cs) +return mimetextqp(s, subtype, "iso-8859-1") def mimetextqp(body, subtype, charset): '''Return MIME message. diff --git a/tests/test-patchbomb.t b/tests/test-patchbomb.t --- a/tests/test-patchbomb.t +++ b/tests/test-patchbomb.t @@ -632,7 +632,7 @@ $ hg commit -A -d '5 0' -m 'isolatin 8-bit encoding' adding isolatin -fake ascii mbox: +iso-8859-1 mbox: $ hg email --date '1970-1-1 0:5' -f quux -t foo -c bar -r tip -m mbox this patch series consists of 1 patches. @@ -640,9 +640,9 @@ sending [PATCH] isolatin 8-bit encoding ... $ cat mbox From quux ... ... .. ..:..:.. (re) - Content-Type: text/plain; charset="us-ascii" + Content-Type: text/plain; charset="iso-8859-1" MIME-Version: 1.0 - Content-Transfer-Encoding: 8bit + Content-Transfer-Encoding: quoted-printable Subject: [PATCH] isolatin 8-bit encoding X-Mercurial-Node: 240fb913fc1b7ff15ddb9f33e73d82bf5277c720 X-Mercurial-Series-Index: 1 @@ -667,7 +667,7 @@ --- /dev/nullThu Jan 01 00:00:00 1970 + +++ b/isolatin Thu Jan 01 00:00:05 1970 + @@ -0,0 +1,1 @@ - +h\xf6mma! (esc) + +h=F6mma! ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH V3] mail: handle renamed email.Header
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1475854211 -7200 # Fri Oct 07 17:30:11 2016 +0200 # Node ID 00d9aeada4447cb5f155b9c455c537e499ace4ee # Parent 6ffb7e0249f44ab120b4437ae7d65020d03927ba mail: handle renamed email.Header We are still using email.Header which was renamed to email.header back in Python 2.5. References: https://hg.python.org/cpython/file/2.4/Lib/email and https://hg.python.org/cpython/file/2.5/Lib/email diff -r 6ffb7e0249f4 -r 00d9aeada444 mercurial/mail.py --- a/mercurial/mail.py Fri Oct 07 08:32:18 2016 -0400 +++ b/mercurial/mail.py Fri Oct 07 17:30:11 2016 +0200 @@ -8,6 +8,7 @@ from __future__ import absolute_import, print_function import email +import email.header import os import quopri import smtplib @@ -23,7 +24,7 @@ util, ) -_oldheaderinit = email.Header.Header.__init__ +_oldheaderinit = email.header.Header.__init__ def _unifiedheaderinit(self, *args, **kw): """ Python 2.7 introduces a backwards incompatible change @@ -279,7 +280,7 @@ if not display: # split into words? s, cs = _encode(ui, s, charsets) -return str(email.Header.Header(s, cs)) +return str(email.header.Header(s, cs)) return s def _addressencode(ui, name, addr, charsets=None): @@ -330,7 +331,7 @@ def headdecode(s): '''Decodes RFC-2047 header''' uparts = [] -for part, charset in email.Header.decode_header(s): +for part, charset in email.header.decode_header(s): if charset is not None: try: uparts.append(part.decode(charset)) diff -r 6ffb7e0249f4 -r 00d9aeada444 tests/test-check-py3-compat.t --- a/tests/test-check-py3-compat.t Fri Oct 07 08:32:18 2016 -0400 +++ b/tests/test-check-py3-compat.t Fri Oct 07 17:30:11 2016 +0200 @@ -121,7 +121,6 @@ mercurial/i18n.py: error importing module: bytes expected, not str (line *) mercurial/keepalive.py: error importing module: module 'mercurial.util' has no attribute 'httplib' (line *) mercurial/localrepo.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) - mercurial/mail.py: error importing module: module 'email' has no attribute 'Header' (line *) mercurial/manifest.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) mercurial/merge.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) mercurial/namespaces.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[Bug 5398] New: annotate-info popup in annotate page is hard to mouse over
https://bz.mercurial-scm.org/show_bug.cgi?id=5398 Bug ID: 5398 Summary: annotate-info popup in annotate page is hard to mouse over Product: Mercurial Version: unspecified Hardware: PC OS: Mac OS Status: UNCONFIRMED Severity: feature Priority: wish Component: hgweb Assignee: bugzi...@selenic.com Reporter: arai.un...@gmail.com CC: mercurial-de...@selenic.com Initially filed as https://bugzilla.mozilla.org/show_bug.cgi?id=1308152 annotate-info box added by the following change is wrapped into next line if there is revision number in the same cell: https://selenic.com/hg/rev/9c37df347485 it makes hard to move mouse to annotate-info box, after hovering revision number: https://bug1308152.bmoattachments.org/attachment.cgi?id=8798356 (the screenshot is for hg.mozilla.org, it uses different template, but the issue is same) adding "white-space: nowrap" to td.annotate will fix this issue. patch is ready, will post it to mailing list. -- 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] mail: handle renamed email.Header
On Sat, Oct 8, 2016 at 12:12 PM, Yuya Nishiharawrote: > On Sat, 8 Oct 2016 12:01:00 +0200, Augie Fackler wrote: >> >> > On Oct 8, 2016, at 11:53, Augie Fackler wrote: >> > >> > Queued this, thanks. >> > >> >> On Oct 8, 2016, at 10:24, Pulkit Goyal <7895pul...@gmail.com> wrote: >> >> >> >> # HG changeset patch >> >> # User Pulkit Goyal <7895pul...@gmail.com> >> >> # Date 1475854211 -7200 >> >> # Fri Oct 07 17:30:11 2016 +0200 >> >> # Node ID 2a61396608bcbba3d3f4e50002b19563741d2fb5 >> >> # Parent 6ffb7e0249f44ab120b4437ae7d65020d03927ba >> >> mail: handle renamed email.Header >> >> >> >> We are still using email.Header which was renamed to email.header back in >> >> Python 2.5. References: https://hg.python.org/cpython/file/2.4/Lib/email >> >> and https://hg.python.org/cpython/file/2.5/Lib/email >> >> >> >> diff -r 6ffb7e0249f4 -r 2a61396608bc mercurial/mail.py >> >> --- a/mercurial/mail.pyFri Oct 07 08:32:18 2016 -0400 >> >> +++ b/mercurial/mail.pyFri Oct 07 17:30:11 2016 +0200 >> >> @@ -23,7 +23,7 @@ >> >>util, >> >> ) >> >> >> >> -_oldheaderinit = email.Header.Header.__init__ >> >> +_oldheaderinit = email.header.Header.__init__ >> >> Hm. Can you look at this? Yeah same as mentioned by Yuya, need to import email.header. >>> import email >>> email.header Traceback (most recent call last): File "", line 1, in AttributeError: 'module' object has no attribute 'header' >>> email.header.Header Traceback (most recent call last): File "", line 1, in AttributeError: 'module' object has no attribute 'header' >>> import email.header >>> email.header.Header >>> email.header Sending a fixed patch. >> >> --- /home/augie/hg/tests/test-hgwebdir-paths.py.out >> +++ /home/augie/hg/tests/test-hgwebdir-paths.py.err >> @@ -0,0 +1,20 @@ >> +Traceback (most recent call last): >> + File "/home/augie/hg/tests/test-hgwebdir-paths.py", line 4, in >> +from mercurial import ( >> + File "/tmp/hgtests.z8vTiR/install/lib/python/mercurial/hg.py", line 19, >> in >> +from . import ( >> + File "/tmp/hgtests.z8vTiR/install/lib/python/mercurial/bundlerepo.py", >> line 23, in >> +from . import ( >> + File "/tmp/hgtests.z8vTiR/install/lib/python/mercurial/changelog.py", >> line 19, in >> +from . import ( >> + File "/tmp/hgtests.z8vTiR/install/lib/python/mercurial/revlog.py", line >> 31, in >> +from . import ( >> + File >> "/tmp/hgtests.z8vTiR/install/lib/python/mercurial/templatefilters.py", line >> 15, in >> +from . import ( >> + File "/tmp/hgtests.z8vTiR/install/lib/python/mercurial/templatekw.py", >> line 11, in >> +from . import ( >> + File "/tmp/hgtests.z8vTiR/install/lib/python/mercurial/patch.py", line >> 28, in >> +from . import ( >> + File "/tmp/hgtests.z8vTiR/install/lib/python/mercurial/mail.py", line 26, >> in >> +_oldheaderinit = email.header.Header.__init__ >> +AttributeError: 'module' object has no attribute 'header' >> >> ERROR: test-hgwebdir-paths.py output changed > > Perhaps we'll need "import email.header". ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH v2] revset: build _syminitletters from a saner source: the string module
On Sat, 08 Oct 2016 05:22:09 -0400, Augie Fackler wrote: > # HG changeset patch > # User Augie Fackler> # Date 1475843560 14400 > # Fri Oct 07 08:32:40 2016 -0400 > # Node ID 51453143c4378705f5592c8fc91222f3101bb393 > # Parent 6ffb7e0249f44ab120b4437ae7d65020d03927ba > revset: build _syminitletters from a saner source: the string module > > For now, these sets will be unicode characters in Python 3, which is > probably wrong, but it un-blocks importing the module so we can get > further along. In the future we'll have to come up with a reasonable > encoding strategy for revsets in Python 3. Sure. Queued, thanks. For future reference, we'll have to - convert symletters back to bytes - handle divergence of bytes[n] -> int|str ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 3 of 3] mq: release lock after transaction in qrefresh
On Mon, Oct 03, 2016 at 06:05:36PM +0200, Pierre-Yves David wrote: > # HG changeset patch > # User Pierre-Yves David> # Date 1470920717 -7200 > # Thu Aug 11 15:05:17 2016 +0200 > # Node ID 870b39c306bef0889f738d292006a1a322757e22 > # Parent 901855444329e0a4ad7ad0e41cf0a1b6fd3ed5bc > # EXP-Topic vfs.ward > mq: release lock after transaction in qrefresh Queued these, thanks > > The transaction should be closed within the lock. > > diff --git a/hgext/mq.py b/hgext/mq.py > --- a/hgext/mq.py > +++ b/hgext/mq.py > @@ -1840,7 +1840,7 @@ class queue(object): > > self.applied.append(statusentry(n, patchfn)) > finally: > -lockmod.release(lock, tr) > +lockmod.release(tr, lock) > except: # re-raises > ctx = repo[cparents[0]] > repo.dirstate.rebuild(ctx.node(), ctx.manifest()) > ___ > 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 4] bisect: extract the 'reset' logic into its own function
On 10/05/2016 05:56 PM, Ryan McElroy wrote: On 10/3/2016 3:37 PM, Pierre-Yves David wrote: # HG changeset patch # User Pierre-Yves David# Date 1472004833 -7200 # Wed Aug 24 04:13:53 2016 +0200 # Node ID efd8013b1521399d07ca956c1cba7bd9f7dfc6e0 # Parent ec6cb977f8e62bf13f86c3a7ebbee182ae50422e # EXP-Topic bisect bisect: extract the 'reset' logic into its own function This is part of small clean up movement. The bisect module seem more appropriate to host the bisect logic. The cleanup itself is motivated by some higher level cleanup around vfs and locking. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -902,8 +902,7 @@ def bisect(ui, repo, rev=None, extra=Non cmdutil.checkunfinished(repo) if reset: -if repo.vfs.exists("bisect.state"): -repo.vfs.unlink("bisect.state") +hbisect.resetstate(repo) return state = hbisect.load_state(repo) diff --git a/mercurial/hbisect.py b/mercurial/hbisect.py --- a/mercurial/hbisect.py +++ b/mercurial/hbisect.py @@ -159,6 +159,11 @@ def save_state(repo, state): f.write("%s %s\n" % (kind, hex(node))) f.close() +def resetstate(repo): +"""remove any bisect state from the repository""" +if repo.vfs.exists("bisect.state"): +repo.vfs.unlink("bisect.state") Generally, do we care about the race condition here? Would it be better to do something like the below (In another patch)? Generally it does, however, we are supposed to have locking before touching this things (which we actually do not, but that will get fixed soon). We could add that double security in another patches. Cheers, -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 4 of 4] bisect: move 'printresult' in the 'hbisect' module
On Wed, Oct 05, 2016 at 04:59:13PM +0100, Ryan McElroy wrote: > On 10/3/2016 3:37 PM, Pierre-Yves David wrote: > > # HG changeset patch > > # User Pierre-Yves David> > # Date 1472005151 -7200 > > # Wed Aug 24 04:19:11 2016 +0200 > > # Node ID 0aea0bb1821e36d03049dee5d6aaf8d6bfa87eeb > > # Parent 2c643f89b68448619f6cf4326c58ef8cc686e51a > > # EXP-Topic bisect > > bisect: move 'printresult' in the 'hbisect' module > > > > The logic is already extracted into a closure. We move it into the module > > dedicated to bisect. > > This series looks good to me as-is. Queued, thanks for the review. > ___ > 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] mail: take --encoding and HGENCODING into account
# HG changeset patch # User Gábor Stefanik# Date 1475667922 -7200 # Wed Oct 05 13:45:22 2016 +0200 # Node ID c03ad1ac8772ffe8cd626c70ea0f544298fdcf9c # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 mail: take --encoding and HGENCODING into account Fall back to our encoding strategy for sending MIME text that's neither ASCII nor UTF-8. diff --git a/mercurial/mail.py b/mercurial/mail.py --- a/mercurial/mail.py +++ b/mercurial/mail.py @@ -8,6 +8,7 @@ from __future__ import absolute_import, print_function import email +import email.charset import os import quopri import smtplib @@ -203,24 +204,33 @@ raise error.Abort(_('%r specified as email transport, ' 'but not in PATH') % method) +def codec2iana(cs): +'' +cs = email.charset.Charset(cs).input_charset.lower() + +# "latin1" normalizes to "iso8859-1", standard calls for "iso-8859-1" +if cs.startswith("iso") and not cs.startswith("iso-"): +return "iso-" + cs[3:] +return cs + def mimetextpatch(s, subtype='plain', display=False): '''Return MIME message suitable for a patch. -Charset will be detected as utf-8 or (possibly fake) us-ascii. +Charset will be detected by first trying to decode as us-ascii, then utf-8, +and finally the global encodings. If all those fail, fall back to +ISO-8859-1, an encoding with that allows all byte sequences. Transfer encodings will be used if necessary.''' - -cs = 'us-ascii' -if not display: + +cs = ['us-ascii', 'utf-8', encoding.encoding, encoding.fallbackencoding] +if display: +return mimetextqp(s, subtype, None) +for charset in cs: try: -s.decode('us-ascii') +s.decode(charset) +return mimetextqp(s, subtype, codec2iana(charset)) except UnicodeDecodeError: -try: -s.decode('utf-8') -cs = 'utf-8' -except UnicodeDecodeError: -# We'll go with us-ascii as a fallback. -pass +pass -return mimetextqp(s, subtype, cs) +return mimetextqp(s, subtype, "iso-8859-1") def mimetextqp(body, subtype, charset): '''Return MIME message. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] mail: handle renamed email.Header
Queued this, thanks. > On Oct 8, 2016, at 10:24, Pulkit Goyal <7895pul...@gmail.com> wrote: > > # HG changeset patch > # User Pulkit Goyal <7895pul...@gmail.com> > # Date 1475854211 -7200 > # Fri Oct 07 17:30:11 2016 +0200 > # Node ID 2a61396608bcbba3d3f4e50002b19563741d2fb5 > # Parent 6ffb7e0249f44ab120b4437ae7d65020d03927ba > mail: handle renamed email.Header > > We are still using email.Header which was renamed to email.header back in > Python 2.5. References: https://hg.python.org/cpython/file/2.4/Lib/email > and https://hg.python.org/cpython/file/2.5/Lib/email > > diff -r 6ffb7e0249f4 -r 2a61396608bc mercurial/mail.py > --- a/mercurial/mail.py Fri Oct 07 08:32:18 2016 -0400 > +++ b/mercurial/mail.py Fri Oct 07 17:30:11 2016 +0200 > @@ -23,7 +23,7 @@ > util, > ) > > -_oldheaderinit = email.Header.Header.__init__ > +_oldheaderinit = email.header.Header.__init__ > def _unifiedheaderinit(self, *args, **kw): > """ > Python 2.7 introduces a backwards incompatible change > @@ -279,7 +279,7 @@ > if not display: > # split into words? > s, cs = _encode(ui, s, charsets) > -return str(email.Header.Header(s, cs)) > +return str(email.header.Header(s, cs)) > return s > > def _addressencode(ui, name, addr, charsets=None): > @@ -330,7 +330,7 @@ > def headdecode(s): > '''Decodes RFC-2047 header''' > uparts = [] > -for part, charset in email.Header.decode_header(s): > +for part, charset in email.header.decode_header(s): > if charset is not None: > try: > uparts.append(part.decode(charset)) > diff -r 6ffb7e0249f4 -r 2a61396608bc tests/test-check-py3-compat.t > --- a/tests/test-check-py3-compat.t Fri Oct 07 08:32:18 2016 -0400 > +++ b/tests/test-check-py3-compat.t Fri Oct 07 17:30:11 2016 +0200 > @@ -121,7 +121,6 @@ > mercurial/i18n.py: error importing module: bytes expected, not > str (line *) > mercurial/keepalive.py: error importing module: module > 'mercurial.util' has no attribute 'httplib' (line *) > mercurial/localrepo.py: error importing: a bytes-like object is > required, not 'str' (error at revset.py:*) > - mercurial/mail.py: error importing module: module 'email' > has no attribute 'Header' (line *) > mercurial/manifest.py: error importing: a bytes-like object is > required, not 'str' (error at revset.py:*) > mercurial/merge.py: error importing: a bytes-like object is > required, not 'str' (error at revset.py:*) > mercurial/namespaces.py: error importing: a bytes-like object > is required, not 'str' (error at revset.py:*) > ___ > 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] revert: do not reverse hunks in interactive when REV is not parent (issue5096)
On 09/30/2016 06:39 PM, Martin von Zweigbergk via Mercurial-devel wrote: This looks great to me. I think Pierre-Yves wanted to discuss this in person at the sprint, and since the sprint is only a week away, I can wait. I won't be at the sprint, but Augie/durin42 will be and I saw that he also was confused about the current behavior. I still haven't heard from anyone who has used the feature who prefers the way it currently works. I'm still not very enthusiastic about this, but lets discuss it today or tomorrow. -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] merge: add conflict labels to merge command
On 08/10/2016 11:37, Pierre-Yves David wrote: On 10/08/2016 11:35 AM, Simon Farnsworth wrote: On 08/10/2016 11:31, Pierre-Yves David wrote: On 10/08/2016 10:26 AM, Simon Farnsworth wrote: # HG changeset patch # User Simon Farnsworth# Date 1475855510 25200 # Fri Oct 07 08:51:50 2016 -0700 # Node ID 9293c425580b06b3ab10f9648b35e4a982cc5c67 # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 merge: add conflict labels to merge command Pushed, thanks, test-subrepo-git.t and test-subrepo.t says hi. Cheers, They pass for me without fixups - I'm running git v2.9.3 and running the test suite with ./run-tests.py -l -j24. I see a failure in test-paths.t, because zeroconf assumes I have IPv4 locally (I don't). Even if I run those two tests individually, I don't see issues. I'm running 2.9.3. Can you check the changesets I pushed on hg-committed? They look OK - I can't work out what's triggering the discrepancy between tests on my system and tests on yours. -- Simon Farnsworth ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] merge: add conflict labels to merge command
On 10/08/2016 11:35 AM, Simon Farnsworth wrote: On 08/10/2016 11:31, Pierre-Yves David wrote: On 10/08/2016 10:26 AM, Simon Farnsworth wrote: # HG changeset patch # User Simon Farnsworth# Date 1475855510 25200 # Fri Oct 07 08:51:50 2016 -0700 # Node ID 9293c425580b06b3ab10f9648b35e4a982cc5c67 # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 merge: add conflict labels to merge command Pushed, thanks, test-subrepo-git.t and test-subrepo.t says hi. Cheers, They pass for me without fixups - I'm running git v2.9.3 and running the test suite with ./run-tests.py -l -j24. I see a failure in test-paths.t, because zeroconf assumes I have IPv4 locally (I don't). Even if I run those two tests individually, I don't see issues. I'm running 2.9.3. Can you check the changesets I pushed on hg-committed? Cheers, -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] merge: add conflict labels to merge command
On 08/10/2016 11:31, Pierre-Yves David wrote: On 10/08/2016 10:26 AM, Simon Farnsworth wrote: # HG changeset patch # User Simon Farnsworth# Date 1475855510 25200 # Fri Oct 07 08:51:50 2016 -0700 # Node ID 9293c425580b06b3ab10f9648b35e4a982cc5c67 # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 merge: add conflict labels to merge command Pushed, thanks, test-subrepo-git.t and test-subrepo.t says hi. Cheers, They pass for me without fixups - I'm running git v2.9.3 and running the test suite with ./run-tests.py -l -j24. I see a failure in test-paths.t, because zeroconf assumes I have IPv4 locally (I don't). Even if I run those two tests individually, I don't see issues. -- Simon Farnsworth ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH v2] template: provide a termwidth keyword (issue5395)
# HG changeset patch # User Simon Farnsworth# Date 1475918808 25200 # Sat Oct 08 02:26:48 2016 -0700 # Node ID 4c76c4023f440ee2fefe2b632a99869cd657ff90 # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 template: provide a termwidth keyword (issue5395) We want to provide terminal-sized output. As a starting point, expose the terminal width to the templater for use in things like fill. diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py --- a/mercurial/templatekw.py +++ b/mercurial/templatekw.py @@ -589,5 +589,10 @@ for name, func in registrarobj._table.iteritems(): keywords[name] = func +@templatekeyword('termwidth') +def termwidth(repo, ctx, templ, **args): +"""Integer. The width of the current terminal.""" +return repo.ui.termwidth() + # tell hggettext to extract docstrings from these functions: i18nfunctions = keywords.values() diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -3214,6 +3214,11 @@ hg: parse error: fill expects an integer width [255] + $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}' + bcc7ff960b8e:desc to be + termwidth.1:wrapped desc + termwidth.1:to be wrapped (no-eol) + $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}' {node|short} (no-eol) $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}' ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] merge: add conflict labels to merge command
On 10/08/2016 10:26 AM, Simon Farnsworth wrote: # HG changeset patch # User Simon Farnsworth# Date 1475855510 25200 # Fri Oct 07 08:51:50 2016 -0700 # Node ID 9293c425580b06b3ab10f9648b35e4a982cc5c67 # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 merge: add conflict labels to merge command Pushed, thanks, test-subrepo-git.t and test-subrepo.t says hi. Cheers, -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] check-commit: allow underscore as commit topic
On 10/05/2016 04:02 PM, Mathias De Maré wrote: # HG changeset patch # User Mathias De Maré# Date 1475674114 -7200 # Wed Oct 05 15:28:34 2016 +0200 # Node ID 88b22f2c1aee03d452e8b125442c69cd8bb62703 # Parent 1779dde4c9ef97cb242f8d501655f236f66e5439 check-commit: allow underscore as commit topic It's currently not possible to commit with a changeset topic like 'bash_completion'. This change fixes that. Pushed, thanks, cheers. -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH v2] revset: build _syminitletters from a saner source: the string module
# HG changeset patch # User Augie Fackler# Date 1475843560 14400 # Fri Oct 07 08:32:40 2016 -0400 # Node ID 51453143c4378705f5592c8fc91222f3101bb393 # Parent 6ffb7e0249f44ab120b4437ae7d65020d03927ba revset: build _syminitletters from a saner source: the string module For now, these sets will be unicode characters in Python 3, which is probably wrong, but it un-blocks importing the module so we can get further along. In the future we'll have to come up with a reasonable encoding strategy for revsets in Python 3. This patch was originally pair-programmed with Martijn. diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -9,6 +9,7 @@ from __future__ import absolute_import import heapq import re +import string from .i18n import _ from . import ( @@ -22,6 +23,7 @@ from . import ( parser, pathutil, phases, +pycompat, registrar, repoview, util, @@ -173,11 +175,12 @@ elements = { keywords = set(['and', 'or', 'not']) # default set of valid characters for the initial letter of symbols -_syminitletters = set(c for c in [chr(i) for i in xrange(256)] - if c.isalnum() or c in '._@' or ord(c) > 127) +_syminitletters = set( +string.ascii_letters + +string.digits + pycompat.sysstr('._@')) | set(map(chr, xrange(128, 256))) # default set of valid characters for non-initial letters of symbols -_symletters = _syminitletters | set('-/') +_symletters = _syminitletters | set(pycompat.sysstr('-/')) def tokenize(program, lookup=None, syminitletters=None, symletters=None): ''' @@ -2619,8 +2622,7 @@ def optimize(tree): # the set of valid characters for the initial letter of symbols in # alias declarations and definitions -_aliassyminitletters = set(c for c in [chr(i) for i in xrange(256)] - if c.isalnum() or c in '._@$' or ord(c) > 127) +_aliassyminitletters = _syminitletters | set(pycompat.sysstr('$')) def _parsewith(spec, lookup=None, syminitletters=None): """Generate a parse tree of given spec with given tokenizing options diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t --- a/tests/test-check-py3-compat.t +++ b/tests/test-check-py3-compat.t @@ -120,35 +120,33 @@ mercurial/httppeer.py: error importing: Can't mix strings and bytes in path components (error at i18n.py:*) mercurial/i18n.py: error importing module: bytes expected, not str (line *) mercurial/keepalive.py: error importing module: module 'mercurial.util' has no attribute 'httplib' (line *) - mercurial/localrepo.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) + mercurial/localrepo.py: error importing: module 'mercurial.util' has no attribute 'urlerr' (error at httpconnection.py:*) mercurial/mail.py: error importing module: module 'email' has no attribute 'Header' (line *) - mercurial/manifest.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) - mercurial/merge.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) - mercurial/namespaces.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) - mercurial/patch.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) + mercurial/manifest.py: error importing: module 'email' has no attribute 'Header' (error at mail.py:*) + mercurial/merge.py: error importing: module 'email' has no attribute 'Header' (error at mail.py:*) + mercurial/namespaces.py: error importing: module 'email' has no attribute 'Header' (error at mail.py:*) + mercurial/patch.py: error importing: module 'email' has no attribute 'Header' (error at mail.py:*) mercurial/pvec.py: error importing module: name 'xrange' is not defined (line *) - mercurial/repair.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) - mercurial/revlog.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) - mercurial/revset.py: error importing module: name 'xrange' is not defined (line *) - mercurial/scmutil.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) + mercurial/repair.py: error importing: module 'mercurial.util' has no attribute 'urlerr' (error at httpconnection.py:*) + mercurial/revlog.py: error importing: module 'email' has no attribute 'Header' (error at mail.py:*) + mercurial/revset.py: error importing module: 'dict' object has no attribute 'iteritems' (line *) mercurial/scmwindows.py: error importing module: No module named 'winreg' (line *) - mercurial/simplemerge.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) - mercurial/sshpeer.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) - mercurial/sshserver.py: error
Re: [PATCH] mail: take --encoding and HGENCODING into account
On Fri, 07 Oct 2016 09:56:10 -0500, Gábor Stefanik wrote: > # HG changeset patch > # User Gábor Stefanik> # Date 1475667922 -7200 > # Wed Oct 05 13:45:22 2016 +0200 > # Node ID 31350841be0c6af1c335fb02b28b8fd1f79089b9 > # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 > mail: take --encoding and HGENCODING into account New encoding strategy looks good. Can you update tests and resend? Also, I found a couple of nits. Please see the inline comments. > --- a/mercurial/mail.py > +++ b/mercurial/mail.py > @@ -205,22 +205,40 @@ > > def mimetextpatch(s, subtype='plain', display=False): > '''Return MIME message suitable for a patch. > -Charset will be detected as utf-8 or (possibly fake) us-ascii. > +Charset will be detected by first trying to decode as us-ascii, then > utf-8, > +and finally the global encodings. If all those fail, fall back to > +ISO-8859-1, an encoding with that allows all byte sequences. > Transfer encodings will be used if necessary.''' > > -cs = 'us-ascii' > +def codec2iana(encoding): > +encoding = email.charset.Charset(encoding).input_charset.lower() > + > +if encoding.startswith("iso") and not encoding.startswith("iso-"): > +return "iso-" + encoding[3:] > +return encoding - encoding.charset is a module. we need "import encoding.charset" in case it isn't imported yet. - we generally define this kind of functions in module scope, which has to capture no local variables. - better to not shadow the global "encoding" module. - can you add a comment why we have to fix 'iso' aliases? > +cs = "iso-8859-1" # a "safe" encoding with no invalid byte sequences > if not display: This change is mostly the source of the test failure. Maybe we can move it to "not display" block. > try: > s.decode('us-ascii') > +cs = 'us-ascii' > except UnicodeDecodeError: > try: > s.decode('utf-8') > cs = 'utf-8' > except UnicodeDecodeError: > -# We'll go with us-ascii as a fallback. > -pass > +try: > +s.decode(encoding.encoding) > +cs = encoding.encoding > +except UnicodeDecodeError: > +try: > +s.decode(encoding.fallbackencoding) > +cs = encoding.fallbackencoding > +except UnicodeDecodeError SyntaxError > +# fall back to ISO-8859-1 > +pass It's time to rewrite them as a for loop? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] merge: use labels in subrepo merge
On 10/08/2016 10:26 AM, Simon Farnsworth wrote: # HG changeset patch # User Simon Farnsworth# Date 1475915128 25200 # Sat Oct 08 01:25:28 2016 -0700 # Node ID 6b8becb59babb6ac9770d41551c2e533673b694c # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 merge: use labels in subrepo merge I've pushed this, I had to update test-subrepo-git.t, test-subrepo.t. Thanks. -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] mail: handle renamed email.Header
Don't take this one, I send an updated version with test output updated based on current tip of hg-committed. On Fri, Oct 7, 2016 at 5:30 PM, Pulkit Goyal <7895pul...@gmail.com> wrote: > # HG changeset patch > # User Pulkit Goyal <7895pul...@gmail.com> > # Date 1475854211 -7200 > # Fri Oct 07 17:30:11 2016 +0200 > # Node ID 96f956b15caca4b754bbdee542173d9acef24561 > # Parent afce80b816e2baf6ed2b828feee00115f71936b6 > mail: handle renamed email.Header > > We are still using email.Header which was renamed to email.header back in > Python 2.5. References: https://hg.python.org/cpython/file/2.4/Lib/email > and https://hg.python.org/cpython/file/2.5/Lib/email > > diff -r afce80b816e2 -r 96f956b15cac mercurial/mail.py > --- a/mercurial/mail.py Fri Oct 07 15:29:57 2016 +0200 > +++ b/mercurial/mail.py Fri Oct 07 17:30:11 2016 +0200 > @@ -23,7 +23,7 @@ > util, > ) > > -_oldheaderinit = email.Header.Header.__init__ > +_oldheaderinit = email.header.Header.__init__ > def _unifiedheaderinit(self, *args, **kw): > """ > Python 2.7 introduces a backwards incompatible change > @@ -279,7 +279,7 @@ > if not display: > # split into words? > s, cs = _encode(ui, s, charsets) > -return str(email.Header.Header(s, cs)) > +return str(email.header.Header(s, cs)) > return s > > def _addressencode(ui, name, addr, charsets=None): > @@ -330,7 +330,7 @@ > def headdecode(s): > '''Decodes RFC-2047 header''' > uparts = [] > -for part, charset in email.Header.decode_header(s): > +for part, charset in email.header.decode_header(s): > if charset is not None: > try: > uparts.append(part.decode(charset)) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] mail: handle renamed email.Header
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1475854211 -7200 # Fri Oct 07 17:30:11 2016 +0200 # Node ID 2a61396608bcbba3d3f4e50002b19563741d2fb5 # Parent 6ffb7e0249f44ab120b4437ae7d65020d03927ba mail: handle renamed email.Header We are still using email.Header which was renamed to email.header back in Python 2.5. References: https://hg.python.org/cpython/file/2.4/Lib/email and https://hg.python.org/cpython/file/2.5/Lib/email diff -r 6ffb7e0249f4 -r 2a61396608bc mercurial/mail.py --- a/mercurial/mail.py Fri Oct 07 08:32:18 2016 -0400 +++ b/mercurial/mail.py Fri Oct 07 17:30:11 2016 +0200 @@ -23,7 +23,7 @@ util, ) -_oldheaderinit = email.Header.Header.__init__ +_oldheaderinit = email.header.Header.__init__ def _unifiedheaderinit(self, *args, **kw): """ Python 2.7 introduces a backwards incompatible change @@ -279,7 +279,7 @@ if not display: # split into words? s, cs = _encode(ui, s, charsets) -return str(email.Header.Header(s, cs)) +return str(email.header.Header(s, cs)) return s def _addressencode(ui, name, addr, charsets=None): @@ -330,7 +330,7 @@ def headdecode(s): '''Decodes RFC-2047 header''' uparts = [] -for part, charset in email.Header.decode_header(s): +for part, charset in email.header.decode_header(s): if charset is not None: try: uparts.append(part.decode(charset)) diff -r 6ffb7e0249f4 -r 2a61396608bc tests/test-check-py3-compat.t --- a/tests/test-check-py3-compat.t Fri Oct 07 08:32:18 2016 -0400 +++ b/tests/test-check-py3-compat.t Fri Oct 07 17:30:11 2016 +0200 @@ -121,7 +121,6 @@ mercurial/i18n.py: error importing module: bytes expected, not str (line *) mercurial/keepalive.py: error importing module: module 'mercurial.util' has no attribute 'httplib' (line *) mercurial/localrepo.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) - mercurial/mail.py: error importing module: module 'email' has no attribute 'Header' (line *) mercurial/manifest.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) mercurial/merge.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) mercurial/namespaces.py: error importing: a bytes-like object is required, not 'str' (error at revset.py:*) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 3 of 3 RFC] chgserve: preimport enabled extensions
On 10/07/2016 08:16 AM, Yuya Nishihara wrote: On Mon, 3 Oct 2016 07:32:47 +0100, Jun Wu wrote: - "chgserve" as an executable, will couple with "hgext/chgserver.py". With the current direction, "chgserver" will make less sense as an extension. I'm not sure if moving it out is a good idea or not. Anyway I want to move chgserver.py to the core. Only reason I kept it as an extension is I couldn't address circular imports between chgserver.py an commandserver.py. +1 for moving it into core now the chg integration is close to completion. Cheers, -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel