Re: [PATCH v2] template: provide a termwidth keyword (issue5395)

2016-10-08 Thread Yuya Nishihara
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

2016-10-08 Thread Yuya Nishihara
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

2016-10-08 Thread Yuya Nishihara
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

2016-10-08 Thread Yuya Nishihara
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

2016-10-08 Thread Pierre-Yves David



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)

2016-10-08 Thread Pierre-Yves David



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)

2016-10-08 Thread Jun Wu
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

2016-10-08 Thread Jun Wu
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

2016-10-08 Thread Pierre-Yves David



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

2016-10-08 Thread Pierre-Yves David



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

2016-10-08 Thread Jun Wu
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

2016-10-08 Thread Gregory Szorc
# 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*

2016-10-08 Thread Gregory Szorc
# 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

2016-10-08 Thread Gregory Szorc
# 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

2016-10-08 Thread Gregory Szorc
# 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*

2016-10-08 Thread Gregory Szorc
# 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*

2016-10-08 Thread Gregory Szorc
# 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*

2016-10-08 Thread Gregory Szorc
# 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

2016-10-08 Thread Pulkit Goyal
On Sat, Oct 8, 2016 at 7: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.
>
> 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

2016-10-08 Thread Martijn Pieters
# 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

2016-10-08 Thread Gregory Szorc
# 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)

2016-10-08 Thread Augie Fackler
# 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

2016-10-08 Thread Gregory Szorc
# 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

2016-10-08 Thread Gregory Szorc
# 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)

2016-10-08 Thread Mads Kiilerich

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)

2016-10-08 Thread Yuya Nishihara
# 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

2016-10-08 Thread Rodrigo Damazio Bovendorp via Mercurial-devel
# 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

2016-10-08 Thread Yuya Nishihara
On Sat, 8 Oct 2016 18:42:55 +0200, Martijn Pieters wrote:
> On 8 October 2016 at 18:37, Mateusz Kwapich  wrote:
> > # 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

2016-10-08 Thread Augie Fackler
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

2016-10-08 Thread Martijn Pieters
On 8 October 2016 at 18:37, Mateusz Kwapich  wrote:

> # 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

2016-10-08 Thread Augie Fackler
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

2016-10-08 Thread Pierre-Yves David

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)

2016-10-08 Thread Augie Fackler
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

2016-10-08 Thread Augie Fackler
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

2016-10-08 Thread Simon Farnsworth
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

2016-10-08 Thread Simon Farnsworth
# 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

2016-10-08 Thread FUJIWARA Katsunori
# 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

2016-10-08 Thread FUJIWARA Katsunori
# 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

2016-10-08 Thread FUJIWARA Katsunori
# 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

2016-10-08 Thread FUJIWARA Katsunori
# 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

2016-10-08 Thread FUJIWARA Katsunori
# 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)

2016-10-08 Thread Ryan McElroy
# 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

2016-10-08 Thread Martijn Pieters
On 8 October 2016 at 18:00, Pulkit Goyal <7895pul...@gmail.com> wrote:

> On Sat, Oct 8, 2016 at 5:55 PM, Mateusz Kwapich  wrote:
> > # 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

2016-10-08 Thread Gregory Szorc
# 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

2016-10-08 Thread Martijn Pieters
On 8 October 2016 at 17:55, 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.
>

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

2016-10-08 Thread Pulkit Goyal
On Sat, Oct 8, 2016 at 5:55 PM, Mateusz Kwapich  wrote:
> # 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

2016-10-08 Thread Mateusz Kwapich
# 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

2016-10-08 Thread Gregory Szorc
# 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

2016-10-08 Thread liscju
# 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

2016-10-08 Thread Martijn Pieters
On 8 October 2016 at 17:00, Gregory Szorc  wrote:

> # 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)

2016-10-08 Thread Simon Farnsworth
# 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)

2016-10-08 Thread Simon Farnsworth
# 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

2016-10-08 Thread Jun Wu
# 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

2016-10-08 Thread Martijn Pieters
On 8 October 2016 at 17:10, 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
>
> 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)

2016-10-08 Thread Augie Fackler

> On Oct 8, 2016, at 17:07, Tooru Fujisawa  wrote:
> 
> # 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

2016-10-08 Thread Augie Fackler
# 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

2016-10-08 Thread Augie Fackler
# 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

2016-10-08 Thread Augie Fackler
# 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

2016-10-08 Thread Martijn Pieters
On 8 October 2016 at 14:40, Augie Fackler  wrote:

> # 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)

2016-10-08 Thread Tooru Fujisawa
# 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

2016-10-08 Thread Martijn Pieters
On 8 October 2016 at 14:20, Augie Fackler  wrote:

> # 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

2016-10-08 Thread Gregory Szorc
# 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

2016-10-08 Thread Gregory Szorc
# 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

2016-10-08 Thread Gregory Szorc
# 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

2016-10-08 Thread Gregory Szorc
# 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)

2016-10-08 Thread Gregory Szorc
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 Fackler  wrote:

>
> > 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

2016-10-08 Thread Augie Fackler
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

2016-10-08 Thread Pulkit Goyal
# 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)

2016-10-08 Thread Augie Fackler

> 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;
> ___
> 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)

2016-10-08 Thread Pierre-Yves David



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)

2016-10-08 Thread Philippe Pepiot
# 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

2016-10-08 Thread Sean Farley
Kostia Balytskyi  writes:

> # 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

2016-10-08 Thread Sean Farley
Stanislau Hlebik  writes:

> # 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

2016-10-08 Thread Pulkit Goyal
Much needed series.

On Sat, Oct 8, 2016 at 2:40 PM, Augie Fackler  wrote:
> # 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

2016-10-08 Thread Augie Fackler
# 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)

2016-10-08 Thread Tooru Fujisawa
# 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

2016-10-08 Thread Mercurial Commits
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 Fackler 
date: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

2016-10-08 Thread Gábor Stefanik
# 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

2016-10-08 Thread Pulkit Goyal
# 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

2016-10-08 Thread bugzilla
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

2016-10-08 Thread Pulkit Goyal
On Sat, Oct 8, 2016 at 12:12 PM, Yuya Nishihara  wrote:
> 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

2016-10-08 Thread Yuya Nishihara
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

2016-10-08 Thread Augie Fackler
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

2016-10-08 Thread Pierre-Yves David



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

2016-10-08 Thread Augie Fackler
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

2016-10-08 Thread Gábor Stefanik
# 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

2016-10-08 Thread Augie Fackler
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)

2016-10-08 Thread Pierre-Yves David



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

2016-10-08 Thread Simon Farnsworth

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

2016-10-08 Thread Pierre-Yves David



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

2016-10-08 Thread Simon Farnsworth

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)

2016-10-08 Thread Simon Farnsworth
# 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

2016-10-08 Thread Pierre-Yves David

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

2016-10-08 Thread Pierre-Yves David



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

2016-10-08 Thread Augie Fackler
# 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

2016-10-08 Thread Yuya Nishihara
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

2016-10-08 Thread Pierre-Yves David



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

2016-10-08 Thread Pulkit Goyal
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

2016-10-08 Thread Pulkit Goyal
# 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

2016-10-08 Thread Pierre-Yves David



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


  1   2   >