Re: [PATCH 1 of 5] rust-cpython: put leaked reference in PyLeakedRef

2019-10-13 Thread Martin von Zweigbergk via Mercurial-devel
On Sun, Oct 13, 2019 at 8:52 PM Yuya Nishihara  wrote:

> On Sun, 13 Oct 2019 07:46:14 -0700, Martin von Zweigbergk wrote:
> > On Sat, Oct 12, 2019, 01:06 Yuya Nishihara  wrote:
> > > # HG changeset patch
> > > # User Yuya Nishihara 
> > > # Date 1568552779 -32400
> > > #  Sun Sep 15 22:06:19 2019 +0900
> > > # Node ID 458c6598a13caee640294d88af4e93783fc36476
> > > # Parent  ce20b870041fc4d6ba6989acbb9373797ce9b3d6
> > > rust-cpython: put leaked reference in PyLeakedRef
>
> > > -/// Returns a leaked reference and its management object.
> > > +/// Returns a leaked reference.
> > >  ///
> > >  /// # Safety
> > >  ///
> > >  /// It's up to you to make sure that the management object lives
> > >  /// longer than the leaked reference. Otherwise, you'll get a
> > >  /// dangling reference.
> > >
> >
> > This seems inaccurate, or at least unclear, now.
>
> Yeah, it could be rephrased as "Returns a leaked reference temporarily
> held by its management object." I don't care much about the document
> accuracy of intermediate patches.
>

Sorry, I had not realized the comment was changed in a later patch.


>
> > > @@ -318,12 +319,13 @@ macro_rules! py_shared_ref {
> > >  ///
> > >  /// In truth, this does not represent leaked references themselves;
> > >  /// it is instead useful alongside them to manage them.
> >
> > So does this.
>
> This one is still true in this patch. PyLeakedRef doesn't provide any
> smart-pointer-like functions yet.
>

Oh, I guess I misunderstood what this comment was about. I had thought that
storing the reference in the management object (as we do after this patch)
would count as "represent".

I'll queue this mostly based on Georges' review, thanks.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 8] eol: test-eol-update.t coverage around update --clean using filters ... badly

2019-10-13 Thread Yuya Nishihara
On Mon, 14 Oct 2019 02:13:35 +0200, Mads Kiilerich wrote:
> # HG changeset patch
> # User Mads Kiilerich 
> # Date 1571004565 -7200
> #  Mon Oct 14 00:09:25 2019 +0200
> # Node ID 57f88532f7005eeb13cb06418ae3a3b156085adf
> # Parent  52781d57313d512efb7150603104bea3ca11d0eb
> eol: test-eol-update.t coverage around update --clean using filters ... badly

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


Re: [PATCH 2 of 8] localrepo: debug log of filter name when filtering through a function

2019-10-13 Thread Yuya Nishihara
On Mon, 14 Oct 2019 02:13:36 +0200, Mads Kiilerich wrote:
> # HG changeset patch
> # User Mads Kiilerich 
> # Date 1570970400 -7200
> #  Sun Oct 13 14:40:00 2019 +0200
> # Node ID 2b91375a812ce3c694efa35a98a109387962
> # Parent  57f88532f7005eeb13cb06418ae3a3b156085adf
> localrepo: debug log of filter name when filtering through a function

> @@ -1907,7 +1909,8 @@ class localrepository(object):
>  def _filter(self, filterpats, filename, data):
>  for mf, fn, cmd in filterpats:
>  if mf(filename):
> -self.ui.debug(b"filtering %s through %s\n" % (filename, cmd))
> +self.ui.debug(b"filtering %s through %s\n" %
> +  (filename, cmd or 
> pycompat.bytestr(fn.__name__)))

Nit: changed pycompat.bytestr() to pycompat.sysbytes() in flight.
Function names should be ascii in general, but that isn't guaranteed.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 2] patchcopies: give up any optimization based on `introrev`

2019-10-13 Thread Yuya Nishihara
On Sun, 13 Oct 2019 23:02:25 +0200, Pierre-Yves David wrote:
> On 10/13/19 12:08 PM, Yuya Nishihara wrote:
> > On Fri, 11 Oct 2019 20:00:58 +0200, Pierre-Yves David wrote:
> >> On 10/11/19 2:02 PM, Yuya Nishihara wrote:
> >>> On Fri, 11 Oct 2019 01:04:12 +0200, Pierre-Yves David wrote:
>  # HG changeset patch
>  # User Pierre-Yves David 
>  # Date 1570672173 -7200
>  #  Thu Oct 10 03:49:33 2019 +0200
>  # Node ID 2477ba483c04067900d1e9f6523b03df68a4d545
>  # Parent  8ff1ecfadcd110849c47c77e31c92809eea466ab
>  # EXP-Topic patchcopies-regression
>  # Available At https://bitbucket.org/octobus/mercurial-devel/
>  #  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
>  2477ba483c04
>  patchcopies: give up any optimization based on `introrev`
> 
>  Between 8a0136f69027 and d98fb3f42f33, we sped up the search for the
>  introduction revision during path copies. However, further checking show 
>  that
>  finding the introduction revision is still expensive and that we are 
>  better off
>  without it. So we simply drop it and only rely on the linkrev 
>  optimisation.
> 
>  I ran `perfpathcopies` on 6989 pair of revision in the pypy
>  repository (`hg perfhelper-pathcopies`. The result is massively in favor 
>  of
>  dropping this condition. The result of the copy tracing are unchanged.
> 
>  Attempt to use a smaller changes preserving linkrev usage were 
>  unsuccessful, it
>  can return wrong result. The following changesets broke 
>  test-mv-cp-st-diff.t
> 
>    -if not f.isintroducedafter(limit):
>    +if limit >= 0 and f.linkrev() < limit:
> return None
> >>>
> >>> Sure. I meant comparing linkrevs, not linkrev vs (changelog) rev. If both
> >>> arms were linkrevs, and if the limit pointed to the revision where the
> >>> linkrevs of its files are guaranteed to be the lowest, the comparison
> >>> (e.g. f.linkrev() < repo[limit][path].linkrev()) would work.
> >>>
> >>> My question was whether it would make things fast or not.
> >>
> >> Ha, I understand your proposal better now.
> >>
> >> My testing of the version in this patch versus the "wrong" version using
> >> linkrev too agressively did not show a significant difference (-1%).
> > 
> > Do you mean only 1% speedup or measurable speedup on 1% cases? I don't think
> > the former is significant, but the latter could be depending on use cases.
> 
> only ±1% speedup for all (many) cases I looked at.
> 
> >> So
> >> I don't it to raise anything better. Can we move forward with this
> >> series and maybe try a different approach later ?
> > 
> > Better to leave the _findlimit() function? Or won't it be any useful in
> > your future work?
> 
> That seems easy enough t reintroduce later if needed. My current 
> optimization work focus on the changeset based copies tracing algorithm. 
> I don't think I'll spend much time on the filelog based one.

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


[PATCH V2] dirs: remove mutable string optimization at all

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570964769 -32400
#  Sun Oct 13 20:06:09 2019 +0900
# Node ID dd9f93e8af83be1bfd7082026d28f774917f0593
# Parent  feaea7fe888383bcb1d28e69df325e41ef68ece9
dirs: remove mutable string optimization at all

As far as I can see, the optimization trick has been dead since 42e89b87ca79
"dirs: speed up by storing number of direct children per dir". After
42e89b87ca79, the key variable is cleared to NULL at each iteration.

diff --git a/mercurial/cext/dirs.c b/mercurial/cext/dirs.c
--- a/mercurial/cext/dirs.c
+++ b/mercurial/cext/dirs.c
@@ -26,9 +26,6 @@
  *
  * We modify Python integers for refcounting, but those integers are
  * never visible to Python code.
- *
- * We mutate strings in-place, but leave them immutable once they can
- * be seen by Python code.
  */
 typedef struct {
PyObject_HEAD
@@ -63,46 +60,18 @@ static int _addpath(PyObject *dirs, PyOb
* "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. The code for adjusting the length of a PyBytesObject is
-   * essentially a minimal version of _PyBytes_Resize. */
+   * unnoticed. */
while ((pos = _finddir(cpath, pos - 1)) != -1) {
PyObject *val;
 
-   if (pos < 2) {
-   key = PyBytes_FromStringAndSize(cpath, pos);
-   if (key == NULL)
-   goto bail;
-   } else {
-   /* 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)
-   ((PyBytesObject *)key)->ob_shash = -1;
-   else {
-   /* We know pos >= 2, so we won't get a small
-* shared string. */
-   key = PyBytes_FromStringAndSize(cpath, pos);
-   if (key == NULL)
-   goto bail;
-   }
-   /* Py_SIZE(o) refers to the ob_size member of
-* the struct. Yes, assigning to what looks
-* like a function seems wrong. */
-   Py_SIZE(key) = pos;
-   ((PyBytesObject *)key)->ob_sval[pos] = '\0';
-   }
+   key = PyBytes_FromStringAndSize(cpath, pos);
+   if (key == NULL)
+   goto bail;
 
val = PyDict_GetItem(dirs, key);
if (val != NULL) {
PYLONG_VALUE(val) += 1;
-   if (pos < 2) {
-   /* This was a short string, so we
-* probably got a small shared string
-* we can't mutate on the next loop
-* iteration. Clear it.
-*/
-   Py_CLEAR(key);
-   }
+   Py_CLEAR(key);
break;
}
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 5] rust-cpython: put leaked reference in PyLeakedRef

2019-10-13 Thread Yuya Nishihara
On Sun, 13 Oct 2019 07:46:14 -0700, Martin von Zweigbergk wrote:
> On Sat, Oct 12, 2019, 01:06 Yuya Nishihara  wrote:
> > # HG changeset patch
> > # User Yuya Nishihara 
> > # Date 1568552779 -32400
> > #  Sun Sep 15 22:06:19 2019 +0900
> > # Node ID 458c6598a13caee640294d88af4e93783fc36476
> > # Parent  ce20b870041fc4d6ba6989acbb9373797ce9b3d6
> > rust-cpython: put leaked reference in PyLeakedRef

> > -/// Returns a leaked reference and its management object.
> > +/// Returns a leaked reference.
> >  ///
> >  /// # Safety
> >  ///
> >  /// It's up to you to make sure that the management object lives
> >  /// longer than the leaked reference. Otherwise, you'll get a
> >  /// dangling reference.
> >
> 
> This seems inaccurate, or at least unclear, now.

Yeah, it could be rephrased as "Returns a leaked reference temporarily
held by its management object." I don't care much about the document
accuracy of intermediate patches.

> > @@ -318,12 +319,13 @@ macro_rules! py_shared_ref {
> >  ///
> >  /// In truth, this does not represent leaked references themselves;
> >  /// it is instead useful alongside them to manage them.
> 
> So does this.

This one is still true in this patch. PyLeakedRef doesn't provide any
smart-pointer-like functions yet.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] dirs: remove mutable string optimization at all

2019-10-13 Thread Yuya Nishihara
On Sun, 13 Oct 2019 15:33:28 -0400, Matt Harbison wrote:
> On Sun, 13 Oct 2019 07:27:32 -0400, Yuya Nishihara  wrote:
> 
> > # HG changeset patch
> > # User Yuya Nishihara 
> > # Date 1570964769 -32400
> > #  Sun Oct 13 20:06:09 2019 +0900
> > # Node ID 87dfcdb8394e377049b5a337585309ae4c652c7d
> > # Parent  ce20b870041fc4d6ba6989acbb9373797ce9b3d6
> > dirs: remove mutable string optimization at all
> 
> Should this original comment go away too?
> 
> https://www.mercurial-scm.org/repo/hg/file/52781d57313d/mercurial/cext/dirs.c#l30

Good catch. I'll send V2.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 8 of 8] eol: don't fallback to use .hgeol from tip (BC)

2019-10-13 Thread Mads Kiilerich
# HG changeset patch
# User Mads Kiilerich 
# Date 1570925426 -7200
#  Sun Oct 13 02:10:26 2019 +0200
# Node ID 74c8ac8124723f06a612ff560403d4bd288ec5f4
# Parent  68dde01bb05c782d484d96e424512b89e0673bec
eol: don't fallback to use .hgeol from tip (BC)

If no .hgeol were found in the current working directory, eol would fallback to
use the one in tip. That could in some cases give very confusing or wrong
behaviour when it applied wrong filters.

It might be convenient to have plain 'clone' immediately apply 'native'
encoding patterns in the cloned repo. But it is wrong to assume that this
revision is tip, and even more wrong to also apply it when not cloning - for
example when updating between history revisions. The encoding should always
match the content of the current .hgeol . It should never use anything else.

diff --git a/hgext/eol.py b/hgext/eol.py
--- a/hgext/eol.py
+++ b/hgext/eol.py
@@ -387,7 +387,7 @@ def reposetup(ui, repo):
 return eol.match
 
 def _hgcleardirstate(self):
-self._eolmatch = self.loadeol([None, b'tip'])
+self._eolmatch = self.loadeol([None])
 if not self._eolmatch:
 self._eolmatch = util.never
 return
diff --git a/tests/test-eol-clone.t b/tests/test-eol-clone.t
--- a/tests/test-eol-clone.t
+++ b/tests/test-eol-clone.t
@@ -21,9 +21,8 @@ setup repository
   adding .hgeol
   adding a.txt
 
-Test commit of removed .hgeol - currently it seems to live on as zombie
-(causing "filtering a.txt through tolf") after being removed ... but actually
-it is just confusing use of tip revision.
+Test commit of removed .hgeol and how it immediately makes the automatic
+changes explicit and committable.
 
   $ cd ..
   $ hg clone repo repo-2
@@ -41,7 +40,7 @@ it is just confusing use of tip revision
   $ hg remove .hgeol
   $ touch a.txt *  # ensure consistent st dirtyness checks, ignoring dirstate 
timing
   $ hg st -v --debug
-  filtering a.txt through tolf
+  M a.txt
   R .hgeol
   $ hg commit -m 'remove eol'
   $ hg exp
@@ -49,16 +48,26 @@ it is just confusing use of tip revision
   # User test
   # Date 0 0
   #  Thu Jan 01 00:00:00 1970 +
-  # Node ID c60b96c20c7de8c821127b548c34e5b170bcf9fe
+  # Node ID 3c20c2d90333b6ecdc8f7aa8f9b73223c7c7a608
   # Parent  90f94e2cf4e24628afddd641688dfe4cd476d6e4
   remove eol
   
-  diff -r 90f94e2cf4e2 -r c60b96c20c7d .hgeol
+  diff -r 90f94e2cf4e2 -r 3c20c2d90333 .hgeol
   --- a/.hgeol Thu Jan 01 00:00:00 1970 +
   +++ /dev/nullThu Jan 01 00:00:00 1970 +
   @@ -1,2 +0,0 @@
   -[patterns]
   -**.txt = native
+  diff -r 90f94e2cf4e2 -r 3c20c2d90333 a.txt
+  --- a/a.txt  Thu Jan 01 00:00:00 1970 +
+  +++ b/a.txt  Thu Jan 01 00:00:00 1970 +
+  @@ -1,3 +1,3 @@
+  -first
+  -second
+  -third
+  +first\r (esc)
+  +second\r (esc)
+  +third\r (esc)
   $ hg push --quiet
   $ cd ..
 
@@ -75,7 +84,7 @@ the source repo:
   updating to branch default
   resolving manifests
branchmerge: False, force: False, partial: False
-   ancestor: , local: +, remote: c60b96c20c7d
+   ancestor: , local: +, remote: 3c20c2d90333
   calling hook preupdate.eol: hgext.eol.preupdate
a.txt: remote created -> g
   getting a.txt
@@ -83,9 +92,9 @@ the source repo:
   $ cd repo-3
 
   $ cat a.txt
-  first
-  second
-  third
+  first\r (esc)
+  second\r (esc)
+  third\r (esc)
 
 Test clone of revision with .hgeol
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 8] eol: tweak test-eol-clone.t with better descriptions and logging

2019-10-13 Thread Mads Kiilerich
# HG changeset patch
# User Mads Kiilerich 
# Date 1571010144 -7200
#  Mon Oct 14 01:42:24 2019 +0200
# Node ID 68dde01bb05c782d484d96e424512b89e0673bec
# Parent  950c89a71e9837dc81da80ed34eee9b602a808d9
eol: tweak test-eol-clone.t with better descriptions and logging

Expose impact of changes coming next ...

diff --git a/tests/test-eol-clone.t b/tests/test-eol-clone.t
--- a/tests/test-eol-clone.t
+++ b/tests/test-eol-clone.t
@@ -21,7 +21,9 @@ setup repository
   adding .hgeol
   adding a.txt
 
-Clone
+Test commit of removed .hgeol - currently it seems to live on as zombie
+(causing "filtering a.txt through tolf") after being removed ... but actually
+it is just confusing use of tip revision.
 
   $ cd ..
   $ hg clone repo repo-2
@@ -37,14 +39,46 @@ Clone
   second
   third
   $ hg remove .hgeol
+  $ touch a.txt *  # ensure consistent st dirtyness checks, ignoring dirstate 
timing
+  $ hg st -v --debug
+  filtering a.txt through tolf
+  R .hgeol
   $ hg commit -m 'remove eol'
+  $ hg exp
+  # HG changeset patch
+  # User test
+  # Date 0 0
+  #  Thu Jan 01 00:00:00 1970 +
+  # Node ID c60b96c20c7de8c821127b548c34e5b170bcf9fe
+  # Parent  90f94e2cf4e24628afddd641688dfe4cd476d6e4
+  remove eol
+  
+  diff -r 90f94e2cf4e2 -r c60b96c20c7d .hgeol
+  --- a/.hgeol Thu Jan 01 00:00:00 1970 +
+  +++ /dev/nullThu Jan 01 00:00:00 1970 +
+  @@ -1,2 +0,0 @@
+  -[patterns]
+  -**.txt = native
   $ hg push --quiet
   $ cd ..
 
-Test clone of repo with .hgeol in working dir, but no .hgeol in tip
+Test clone of repo with .hgeol in working dir, but no .hgeol in default
+checkout revision tip. The repo is correctly updated to be consistent and have
+the exact content checked out without filtering, ignoring the current .hgeol in
+the source repo:
 
-  $ hg clone repo repo-3
+  $ cat repo/.hgeol
+  [patterns]
+  **.txt = native
+  $ hg clone repo repo-3 -v --debug
+  linked 7 files
   updating to branch default
+  resolving manifests
+   branchmerge: False, force: False, partial: False
+   ancestor: , local: +, remote: c60b96c20c7d
+  calling hook preupdate.eol: hgext.eol.preupdate
+   a.txt: remote created -> g
+  getting a.txt
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd repo-3
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 8] eol: fix update - don't use and apply removed .hgeol patterns

2019-10-13 Thread Mads Kiilerich
# HG changeset patch
# User Mads Kiilerich 
# Date 1570925707 -7200
#  Sun Oct 13 02:15:07 2019 +0200
# Node ID 950c89a71e9837dc81da80ed34eee9b602a808d9
# Parent  844fa54a1ffbc052fbcd76f103b3db6b02a84690
eol: fix update - don't use and apply removed .hgeol patterns

'hg up -C' to revisions with different .hgeol patterns could leave dirty
changes in the working directory. That could make deployment of new .hgeol
filters tricky: they would "occasionally" apply also in branches where they
shouldn't.

Fixed by dropping all old patterns before applying new ones.

diff --git a/hgext/eol.py b/hgext/eol.py
--- a/hgext/eol.py
+++ b/hgext/eol.py
@@ -221,6 +221,12 @@ class eolfile(object):
 self.match = match.match(root, b'', [], include, exclude)
 
 def copytoui(self, ui):
+newpatterns = set(pattern for pattern, key, m in self.patterns)
+for section in (b'decode', b'encode'):
+for oldpattern, _filter in ui.configitems(section):
+if oldpattern not in newpatterns:
+if ui.configsource(section, oldpattern) == b'eol':
+ui.setconfig(section, oldpattern, b'!', b'eol')
 for pattern, key, m in self.patterns:
 try:
 ui.setconfig(b'decode', pattern, self._decode[key], b'eol')
diff --git a/tests/test-eol-update.t b/tests/test-eol-update.t
--- a/tests/test-eol-update.t
+++ b/tests/test-eol-update.t
@@ -120,12 +120,6 @@ Test EOL update
first
   -second
third
-  diff --git a/f b/f
-  --- a/f
-  +++ b/f
-  @@ -1,1 +1,1 @@
-  -f\r (esc)
-  +f
   $ dotest CRLF
   
   % hg clone repo repo-CRLF
@@ -159,12 +153,6 @@ Test EOL update
first
   -second
third
-  diff --git a/f b/f
-  --- a/f
-  +++ b/f
-  @@ -1,1 +1,1 @@
-  -f\r (esc)
-  +f
 
 Test in repo using eol extension, while keeping an eye on how filters are
 applied:
@@ -177,8 +165,8 @@ applied:
   > eol =
   > EOF
 
-Update to revision 0 which has no .hgeol . Unfortunately, it uses the filter
-from tip ... which evidently is wrong:
+Update to revision 0 which has no .hgeol, shouldn't use any filters, and
+obviously should leave things as tidy as they were before the clean update.
 
   $ hg up -c -r 0 -v --debug
   resolving manifests
@@ -193,22 +181,8 @@ from tip ... which evidently is wrong:
   filtering a.txt through tolf
f: remote created -> g
   getting f
-  filtering f through tolf
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg st
-  M f
-  $ touch .hgeol *  # ensure consistent dirtyness checks ignoring dirstate
-  $ hg up -C -r 0 -v --debug
-  eol: detected change in .hgeol
-  filtering .hgeol through isbinary
-  filtering a.txt through tolf
-  resolving manifests
-   branchmerge: False, force: True, partial: False
-   ancestor: 15cbdf8ca3db+, local: 15cbdf8ca3db+, remote: 15cbdf8ca3db
-  calling hook preupdate.eol: hgext.eol.preupdate
-   f: remote is newer -> g
-  getting f
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ hg branch b
   marked working directory as branch b
@@ -250,9 +224,9 @@ Merge changes that apply a filter to f:
   -f\r (esc)
   +f
 
-Abort the merge with up -C to revision 0 ... but notice how .hgeol changes are
-not detected correctly: f is filtered with tolf even though there is no filter
-for f in revision 0, and it thus ends up with working directory changes.
+Abort the merge with up -C to revision 0.
+Note that files are filtered correctly for revision 0: f is not filtered, a.txt
+is filtered with tolf, and everything is left tidy.
 
   $ touch .hgeol *  # ensure consistent dirtyness checks ignoring dirstate
   $ hg up -C -r 0 -v --debug
@@ -269,7 +243,6 @@ for f in revision 0, and it thus ends up
   filtering a.txt through tolf
f: remote is newer -> g
   getting f
-  filtering f through tolf
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ touch .hgeol *
@@ -277,16 +250,9 @@ for f in revision 0, and it thus ends up
   eol: detected change in .hgeol
   filtering .hgeol through isbinary
   filtering a.txt through tolf
-  M f
   $ hg diff
-  diff --git a/f b/f
-  --- a/f
-  +++ b/f
-  @@ -1,1 +1,1 @@
-  -f\r (esc)
-  +f
 
-Workaround: Update again - this will read the right .hgeol:
+Things were clean, and updating again will not change anything:
 
   $ touch .hgeol *
   $ hg up -C -r 0 -v --debug
@@ -297,9 +263,7 @@ Workaround: Update again - this will rea
branchmerge: False, force: True, partial: False
ancestor: 15cbdf8ca3db+, local: 15cbdf8ca3db+, remote: 15cbdf8ca3db
   calling hook preupdate.eol: hgext.eol.preupdate
-   f: remote is newer -> g
-  getting f
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ touch .hgeol *
   $ hg st --debug
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org

[PATCH 4 of 8] eol: update isbinary filter to work without compat wrapper

2019-10-13 Thread Mads Kiilerich
# HG changeset patch
# User Mads Kiilerich 
# Date 1571009598 -7200
#  Mon Oct 14 01:33:18 2019 +0200
# Node ID 5670699747c92d725927e25754817d5aa498d728
# Parent  1e663f4a658dbf6669c9bfd53918bf1daa734dc6
eol: update isbinary filter to work without compat wrapper

diff --git a/hgext/eol.py b/hgext/eol.py
--- a/hgext/eol.py
+++ b/hgext/eol.py
@@ -165,7 +165,7 @@ def tocrlf(s, params, ui, **kwargs):
 return util.tocrlf(s)
 
 
-def isbinary(s, params):
+def isbinary(s, params, ui, **kwargs):
 """Filter to do nothing with the file."""
 return s
 
diff --git a/tests/test-eol-update.t b/tests/test-eol-update.t
--- a/tests/test-eol-update.t
+++ b/tests/test-eol-update.t
@@ -187,7 +187,7 @@ from tip ... which evidently is wrong:
   calling hook preupdate.eol: hgext.eol.preupdate
.hgeol: remote created -> g
   getting .hgeol
-  filtering .hgeol through compat-isbinary
+  filtering .hgeol through isbinary
a.txt: remote created -> g
   getting a.txt
   filtering a.txt through tolf
@@ -200,7 +200,7 @@ from tip ... which evidently is wrong:
   $ touch .hgeol *  # ensure consistent dirtyness checks ignoring dirstate
   $ hg up -C -r 0 -v --debug
   eol: detected change in .hgeol
-  filtering .hgeol through compat-isbinary
+  filtering .hgeol through isbinary
   filtering a.txt through tolf
   resolving manifests
branchmerge: False, force: True, partial: False
@@ -263,7 +263,7 @@ for f in revision 0, and it thus ends up
   calling hook preupdate.eol: hgext.eol.preupdate
.hgeol: remote is newer -> g
   getting .hgeol
-  filtering .hgeol through compat-isbinary
+  filtering .hgeol through isbinary
a.txt: remote is newer -> g
   getting a.txt
   filtering a.txt through tolf
@@ -275,7 +275,7 @@ for f in revision 0, and it thus ends up
   $ touch .hgeol *
   $ hg st --debug
   eol: detected change in .hgeol
-  filtering .hgeol through compat-isbinary
+  filtering .hgeol through isbinary
   filtering a.txt through tolf
   M f
   $ hg diff
@@ -291,7 +291,7 @@ Workaround: Update again - this will rea
   $ touch .hgeol *
   $ hg up -C -r 0 -v --debug
   eol: detected change in .hgeol
-  filtering .hgeol through compat-isbinary
+  filtering .hgeol through isbinary
   filtering a.txt through tolf
   resolving manifests
branchmerge: False, force: True, partial: False
@@ -304,7 +304,7 @@ Workaround: Update again - this will rea
   $ touch .hgeol *
   $ hg st --debug
   eol: detected change in .hgeol
-  filtering .hgeol through compat-isbinary
+  filtering .hgeol through isbinary
   filtering a.txt through tolf
 
   $ cd ..
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 8] localrepo: fix variable binding in handling of old filters

2019-10-13 Thread Mads Kiilerich
# HG changeset patch
# User Mads Kiilerich 
# Date 1570925119 -7200
#  Sun Oct 13 02:05:19 2019 +0200
# Node ID 1e663f4a658dbf6669c9bfd53918bf1daa734dc6
# Parent  2b91375a812ce3c694efa35a98a109387962
localrepo: fix variable binding in handling of old filters

The lambda was referencing oldfn in outer scope without binding the current
value. If oldfn function were reassigned before use, wrong filters could be
used.

Fixed by having oldfn as named parameter default value of the lambda.

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1900,7 +1900,7 @@ class localrepository(object):
 # Wrap old filters not supporting keyword arguments
 if not pycompat.getargspec(fn)[2]:
 oldfn = fn
-fn = lambda s, c, **kwargs: oldfn(s, c)
+fn = lambda s, c, oldfn=oldfn, **kwargs: oldfn(s, c)
 fn.__name__ = 'compat-' + oldfn.__name__
 l.append((mf, fn, params))
 self._filterpats[filter] = l
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 8] eol: cache needs update, also if it has same timestamp as the source

2019-10-13 Thread Mads Kiilerich
# HG changeset patch
# User Mads Kiilerich 
# Date 1570925493 -7200
#  Sun Oct 13 02:11:33 2019 +0200
# Node ID 844fa54a1ffbc052fbcd76f103b3db6b02a84690
# Parent  5670699747c92d725927e25754817d5aa498d728
eol: cache needs update, also if it has same timestamp as the source

Ignoring same timestamp could (in theory?) cause changes to not be detected.

It might happen quite often that the cache is populated right after .hgeol has
been updated and they thus have the same time stamp second. But we want
correctness, and if it populates the cache so fast, then it can also not be a
big problem to run it again next time when the timestamp has moved on.

diff --git a/hgext/eol.py b/hgext/eol.py
--- a/hgext/eol.py
+++ b/hgext/eol.py
@@ -401,7 +401,7 @@ def reposetup(ui, repo):
 except OSError:
 eolmtime = 0
 
-if eolmtime > cachemtime:
+if eolmtime >= cachemtime and eolmtime > 0:
 self.ui.debug(b"eol: detected change in .hgeol\n")
 
 hgeoldata = self.wvfs.read(b'.hgeol')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 8] localrepo: debug log of filter name when filtering through a function

2019-10-13 Thread Mads Kiilerich
# HG changeset patch
# User Mads Kiilerich 
# Date 1570970400 -7200
#  Sun Oct 13 14:40:00 2019 +0200
# Node ID 2b91375a812ce3c694efa35a98a109387962
# Parent  57f88532f7005eeb13cb06418ae3a3b156085adf
localrepo: debug log of filter name when filtering through a function

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1896,10 +1896,12 @@ class localrepository(object):
 break
 if not fn:
 fn = lambda s, c, **kwargs: procutil.filter(s, c)
+fn.__name__ = 'commandfilter'
 # Wrap old filters not supporting keyword arguments
 if not pycompat.getargspec(fn)[2]:
 oldfn = fn
 fn = lambda s, c, **kwargs: oldfn(s, c)
+fn.__name__ = 'compat-' + oldfn.__name__
 l.append((mf, fn, params))
 self._filterpats[filter] = l
 return self._filterpats[filter]
@@ -1907,7 +1909,8 @@ class localrepository(object):
 def _filter(self, filterpats, filename, data):
 for mf, fn, cmd in filterpats:
 if mf(filename):
-self.ui.debug(b"filtering %s through %s\n" % (filename, cmd))
+self.ui.debug(b"filtering %s through %s\n" %
+  (filename, cmd or pycompat.bytestr(fn.__name__)))
 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
 break
 
diff --git a/tests/test-eol-update.t b/tests/test-eol-update.t
--- a/tests/test-eol-update.t
+++ b/tests/test-eol-update.t
@@ -187,21 +187,21 @@ from tip ... which evidently is wrong:
   calling hook preupdate.eol: hgext.eol.preupdate
.hgeol: remote created -> g
   getting .hgeol
-  filtering .hgeol through 
+  filtering .hgeol through compat-isbinary
a.txt: remote created -> g
   getting a.txt
-  filtering a.txt through 
+  filtering a.txt through tolf
f: remote created -> g
   getting f
-  filtering f through 
+  filtering f through tolf
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg st
   M f
   $ touch .hgeol *  # ensure consistent dirtyness checks ignoring dirstate
   $ hg up -C -r 0 -v --debug
   eol: detected change in .hgeol
-  filtering .hgeol through 
-  filtering a.txt through 
+  filtering .hgeol through compat-isbinary
+  filtering a.txt through tolf
   resolving manifests
branchmerge: False, force: True, partial: False
ancestor: 15cbdf8ca3db+, local: 15cbdf8ca3db+, remote: 15cbdf8ca3db
@@ -263,20 +263,20 @@ for f in revision 0, and it thus ends up
   calling hook preupdate.eol: hgext.eol.preupdate
.hgeol: remote is newer -> g
   getting .hgeol
-  filtering .hgeol through 
+  filtering .hgeol through compat-isbinary
a.txt: remote is newer -> g
   getting a.txt
-  filtering a.txt through 
+  filtering a.txt through tolf
f: remote is newer -> g
   getting f
-  filtering f through 
+  filtering f through tolf
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ touch .hgeol *
   $ hg st --debug
   eol: detected change in .hgeol
-  filtering .hgeol through 
-  filtering a.txt through 
+  filtering .hgeol through compat-isbinary
+  filtering a.txt through tolf
   M f
   $ hg diff
   diff --git a/f b/f
@@ -291,8 +291,8 @@ Workaround: Update again - this will rea
   $ touch .hgeol *
   $ hg up -C -r 0 -v --debug
   eol: detected change in .hgeol
-  filtering .hgeol through 
-  filtering a.txt through 
+  filtering .hgeol through compat-isbinary
+  filtering a.txt through tolf
   resolving manifests
branchmerge: False, force: True, partial: False
ancestor: 15cbdf8ca3db+, local: 15cbdf8ca3db+, remote: 15cbdf8ca3db
@@ -304,8 +304,8 @@ Workaround: Update again - this will rea
   $ touch .hgeol *
   $ hg st --debug
   eol: detected change in .hgeol
-  filtering .hgeol through 
-  filtering a.txt through 
+  filtering .hgeol through compat-isbinary
+  filtering a.txt through tolf
 
   $ cd ..
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 8] eol: test-eol-update.t coverage around update --clean using filters ... badly

2019-10-13 Thread Mads Kiilerich
# HG changeset patch
# User Mads Kiilerich 
# Date 1571004565 -7200
#  Mon Oct 14 00:09:25 2019 +0200
# Node ID 57f88532f7005eeb13cb06418ae3a3b156085adf
# Parent  52781d57313d512efb7150603104bea3ca11d0eb
eol: test-eol-update.t coverage around update --clean using filters ... badly

This will reveal problems and track their fixes.

diff --git a/tests/test-eol-update.t b/tests/test-eol-update.t
--- a/tests/test-eol-update.t
+++ b/tests/test-eol-update.t
@@ -26,14 +26,17 @@ Test EOL update
   > EOF
   > 
   > printf "first\nsecond\nthird\n" > a.txt
+  > printf "f\r\n" > f
   > hg commit --addremove -m 'LF commit'
   > 
   > cat > .hgeol < [patterns]
   > **.txt = CRLF
+  > f = LF
   > EOF
   > 
   > printf "first\r\nsecond\r\nthird\r\n" > a.txt
+  > printf "f\n" > f
   > hg commit -m 'CRLF commit'
   > 
   > cd ..
@@ -83,10 +86,11 @@ Test EOL update
   % hg init
   adding .hgeol
   adding a.txt
+  adding f
   $ dotest LF
   
   % hg clone repo repo-LF
-  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   % a.txt (before)
   first\r (esc)
   second\r (esc)
@@ -104,7 +108,7 @@ Test EOL update
third\r (esc)
   % hg update 0
   merging a.txt
-  1 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  2 files updated, 1 files merged, 0 files removed, 0 files unresolved
   % a.txt
   first
   third
@@ -116,10 +120,16 @@ Test EOL update
first
   -second
third
+  diff --git a/f b/f
+  --- a/f
+  +++ b/f
+  @@ -1,1 +1,1 @@
+  -f\r (esc)
+  +f
   $ dotest CRLF
   
   % hg clone repo repo-CRLF
-  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   % a.txt (before)
   first\r (esc)
   second\r (esc)
@@ -137,7 +147,7 @@ Test EOL update
third\r (esc)
   % hg update 0
   merging a.txt
-  1 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  2 files updated, 1 files merged, 0 files removed, 0 files unresolved
   % a.txt
   first
   third
@@ -149,4 +159,154 @@ Test EOL update
first
   -second
third
+  diff --git a/f b/f
+  --- a/f
+  +++ b/f
+  @@ -1,1 +1,1 @@
+  -f\r (esc)
+  +f
+
+Test in repo using eol extension, while keeping an eye on how filters are
+applied:
+
+  $ cd repo
+
+  $ hg up -q -c -r null
+  $ cat > .hg/hgrc < [extensions]
+  > eol =
+  > EOF
+
+Update to revision 0 which has no .hgeol . Unfortunately, it uses the filter
+from tip ... which evidently is wrong:
+
+  $ hg up -c -r 0 -v --debug
+  resolving manifests
+   branchmerge: False, force: False, partial: False
+   ancestor: , local: +, remote: 15cbdf8ca3db
+  calling hook preupdate.eol: hgext.eol.preupdate
+   .hgeol: remote created -> g
+  getting .hgeol
+  filtering .hgeol through 
+   a.txt: remote created -> g
+  getting a.txt
+  filtering a.txt through 
+   f: remote created -> g
+  getting f
+  filtering f through 
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg st
+  M f
+  $ touch .hgeol *  # ensure consistent dirtyness checks ignoring dirstate
+  $ hg up -C -r 0 -v --debug
+  eol: detected change in .hgeol
+  filtering .hgeol through 
+  filtering a.txt through 
+  resolving manifests
+   branchmerge: False, force: True, partial: False
+   ancestor: 15cbdf8ca3db+, local: 15cbdf8ca3db+, remote: 15cbdf8ca3db
+  calling hook preupdate.eol: hgext.eol.preupdate
+   f: remote is newer -> g
+  getting f
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+  $ hg branch b
+  marked working directory as branch b
+  (branches are permanent and global, did you want a bookmark?)
+  $ hg ci -m b
+
+Merge changes that apply a filter to f:
+
+  $ hg merge 1
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg st
+  M .hgeol
+  M a.txt
+  M f
+  $ hg diff
+  diff --git a/.hgeol b/.hgeol
+  --- a/.hgeol
+  +++ b/.hgeol
+  @@ -1,2 +1,3 @@
+   [patterns]
+  -**.txt = LF
+  +**.txt = CRLF
+  +f = LF
+  diff --git a/a.txt b/a.txt
+  --- a/a.txt
+  +++ b/a.txt
+  @@ -1,3 +1,3 @@
+  -first
+  -second
+  -third
+  +first\r (esc)
+  +second\r (esc)
+  +third\r (esc)
+  diff --git a/f b/f
+  --- a/f
+  +++ b/f
+  @@ -1,1 +1,1 @@
+  -f\r (esc)
+  +f
+
+Abort the merge with up -C to revision 0 ... but notice how .hgeol changes are
+not detected correctly: f is filtered with tolf even though there is no filter
+for f in revision 0, and it thus ends up with working directory changes.
+
+  $ touch .hgeol *  # ensure consistent dirtyness checks ignoring dirstate
+  $ hg up -C -r 0 -v --debug
+  eol: detected change in .hgeol
+  resolving manifests
+   branchmerge: False, force: True, partial: False
+   ancestor: 1db78bdd3bd6+, local: 1db78bdd3bd6+, remote: 15cbdf8ca3db
+  calling hook preupdate.eol: hgext.eol.preupdate
+   .hgeol: remote is newer -> g
+  

Re: [PATCH 1 of 2] patchcopies: give up any optimization based on `introrev`

2019-10-13 Thread Pierre-Yves David



On 10/13/19 12:08 PM, Yuya Nishihara wrote:

On Fri, 11 Oct 2019 20:00:58 +0200, Pierre-Yves David wrote:

On 10/11/19 2:02 PM, Yuya Nishihara wrote:

On Fri, 11 Oct 2019 01:04:12 +0200, Pierre-Yves David wrote:

# HG changeset patch
# User Pierre-Yves David 
# Date 1570672173 -7200
#  Thu Oct 10 03:49:33 2019 +0200
# Node ID 2477ba483c04067900d1e9f6523b03df68a4d545
# Parent  8ff1ecfadcd110849c47c77e31c92809eea466ab
# EXP-Topic patchcopies-regression
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
2477ba483c04
patchcopies: give up any optimization based on `introrev`

Between 8a0136f69027 and d98fb3f42f33, we sped up the search for the
introduction revision during path copies. However, further checking show that
finding the introduction revision is still expensive and that we are better off
without it. So we simply drop it and only rely on the linkrev optimisation.

I ran `perfpathcopies` on 6989 pair of revision in the pypy
repository (`hg perfhelper-pathcopies`. The result is massively in favor of
dropping this condition. The result of the copy tracing are unchanged.

Attempt to use a smaller changes preserving linkrev usage were unsuccessful, it
can return wrong result. The following changesets broke test-mv-cp-st-diff.t

  -if not f.isintroducedafter(limit):
  +if limit >= 0 and f.linkrev() < limit:
   return None


Sure. I meant comparing linkrevs, not linkrev vs (changelog) rev. If both
arms were linkrevs, and if the limit pointed to the revision where the
linkrevs of its files are guaranteed to be the lowest, the comparison
(e.g. f.linkrev() < repo[limit][path].linkrev()) would work.

My question was whether it would make things fast or not.


Ha, I understand your proposal better now.

My testing of the version in this patch versus the "wrong" version using
linkrev too agressively did not show a significant difference (-1%).


Do you mean only 1% speedup or measurable speedup on 1% cases? I don't think
the former is significant, but the latter could be depending on use cases.


only ±1% speedup for all (many) cases I looked at.


So
I don't it to raise anything better. Can we move forward with this
series and maybe try a different approach later ?


Better to leave the _findlimit() function? Or won't it be any useful in
your future work?


That seems easy enough t reintroduce later if needed. My current 
optimization work focus on the changeset based copies tracing algorithm. 
I don't think I'll spend much time on the filelog based one.


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


Re: [PATCH 1 of 5] rust-cpython: put leaked reference in PyLeakedRef

2019-10-13 Thread Martin von Zweigbergk via Mercurial-devel
On Sat, Oct 12, 2019, 01:06 Yuya Nishihara  wrote:

> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1568552779 -32400
> #  Sun Sep 15 22:06:19 2019 +0900
> # Node ID 458c6598a13caee640294d88af4e93783fc36476
> # Parent  ce20b870041fc4d6ba6989acbb9373797ce9b3d6
> rust-cpython: put leaked reference in PyLeakedRef
>
> The next patch will make PyLeakedRef manage the lifetime of the underlying
> object. leak_handle.data.take() will be removed soon.
>
> diff --git a/rust/hg-cpython/src/dirstate/copymap.rs
> b/rust/hg-cpython/src/dirstate/copymap.rs
> --- a/rust/hg-cpython/src/dirstate/copymap.rs
> +++ b/rust/hg-cpython/src/dirstate/copymap.rs
> @@ -13,6 +13,7 @@ use std::cell::RefCell;
>
>  use crate::dirstate::dirstate_map::DirstateMap;
>  use crate::ref_sharing::PyLeakedRef;
> +use hg::DirstateMap as RustDirstateMap;
>  use hg::{utils::hg_path::HgPathBuf, CopyMapIter};
>
>  py_class!(pub class CopyMap |py| {
> @@ -104,7 +105,7 @@ impl CopyMap {
>
>  py_shared_iterator!(
>  CopyMapKeysIterator,
> -PyLeakedRef,
> +PyLeakedRef<&'static RustDirstateMap>,
>  CopyMapIter<'static>,
>  CopyMap::translate_key,
>  Option
> @@ -112,7 +113,7 @@ py_shared_iterator!(
>
>  py_shared_iterator!(
>  CopyMapItemsIterator,
> -PyLeakedRef,
> +PyLeakedRef<&'static RustDirstateMap>,
>  CopyMapIter<'static>,
>  CopyMap::translate_key_value,
>  Option<(PyBytes, PyBytes)>
> diff --git a/rust/hg-cpython/src/dirstate/dirs_multiset.rs
> b/rust/hg-cpython/src/dirstate/dirs_multiset.rs
> --- a/rust/hg-cpython/src/dirstate/dirs_multiset.rs
> +++ b/rust/hg-cpython/src/dirstate/dirs_multiset.rs
> @@ -92,8 +92,9 @@ py_class!(pub class Dirs |py| {
>  })
>  }
>  def __iter__() -> PyResult {
> -let (leak_handle, leaked_ref) =
> +let mut leak_handle =
>  unsafe { self.inner_shared(py).leak_immutable()? };
> +let leaked_ref = leak_handle.data.take().unwrap();
>  DirsMultisetKeysIterator::from_inner(
>  py,
>  leak_handle,
> @@ -125,7 +126,7 @@ impl Dirs {
>
>  py_shared_iterator!(
>  DirsMultisetKeysIterator,
> -PyLeakedRef,
> +PyLeakedRef<&'static DirsMultiset>,
>  DirsMultisetIter<'static>,
>  Dirs::translate_key,
>  Option
> diff --git a/rust/hg-cpython/src/dirstate/dirstate_map.rs
> b/rust/hg-cpython/src/dirstate/dirstate_map.rs
> --- a/rust/hg-cpython/src/dirstate/dirstate_map.rs
> +++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs
> @@ -321,8 +321,9 @@ py_class!(pub class DirstateMap |py| {
>  }
>
>  def keys() -> PyResult {
> -let (leak_handle, leaked_ref) =
> +let mut leak_handle =
>  unsafe { self.inner_shared(py).leak_immutable()? };
> +let leaked_ref = leak_handle.data.take().unwrap();
>  DirstateMapKeysIterator::from_inner(
>  py,
>  leak_handle,
> @@ -331,8 +332,9 @@ py_class!(pub class DirstateMap |py| {
>  }
>
>  def items() -> PyResult {
> -let (leak_handle, leaked_ref) =
> +let mut leak_handle =
>  unsafe { self.inner_shared(py).leak_immutable()? };
> +let leaked_ref = leak_handle.data.take().unwrap();
>  DirstateMapItemsIterator::from_inner(
>  py,
>  leak_handle,
> @@ -341,8 +343,9 @@ py_class!(pub class DirstateMap |py| {
>  }
>
>  def __iter__() -> PyResult {
> -let (leak_handle, leaked_ref) =
> +let mut leak_handle =
>  unsafe { self.inner_shared(py).leak_immutable()? };
> +let leaked_ref = leak_handle.data.take().unwrap();
>  DirstateMapKeysIterator::from_inner(
>  py,
>  leak_handle,
> @@ -460,8 +463,9 @@ py_class!(pub class DirstateMap |py| {
>  }
>
>  def copymapiter() -> PyResult {
> -let (leak_handle, leaked_ref) =
> +let mut leak_handle =
>  unsafe { self.inner_shared(py).leak_immutable()? };
> +let leaked_ref = leak_handle.data.take().unwrap();
>  CopyMapKeysIterator::from_inner(
>  py,
>  leak_handle,
> @@ -470,8 +474,9 @@ py_class!(pub class DirstateMap |py| {
>  }
>
>  def copymapitemsiter() -> PyResult {
> -let (leak_handle, leaked_ref) =
> +let mut leak_handle =
>  unsafe { self.inner_shared(py).leak_immutable()? };
> +let leaked_ref = leak_handle.data.take().unwrap();
>  CopyMapItemsIterator::from_inner(
>  py,
>  leak_handle,
> @@ -513,7 +518,7 @@ py_shared_ref!(DirstateMap, RustDirstate
>
>  py_shared_iterator!(
>  DirstateMapKeysIterator,
> -PyLeakedRef,
> +PyLeakedRef<&'static RustDirstateMap>,
>  StateMapIter<'static>,
>  DirstateMap::translate_key,
>  Option
> @@ -521,7 +526,7 @@ py_shared_iterator!(
>
>  py_shared_iterator!(
>  DirstateMapItemsIterator,
> -PyLeakedRef,
> +PyLeakedRef<&'static RustDirstateMap>,
>  

Re: [PATCH 1 of 7] rust-cpython: add wrapper around decapsule_make_dirstate_tuple()

2019-10-13 Thread Yuya Nishihara
On Sun, 13 Oct 2019 22:41:37 +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1570953317 -32400
> #  Sun Oct 13 16:55:17 2019 +0900
> # Node ID 083f70b7b5899755bb28ce16d6fc45eee46e84e4
> # Parent  dbe969ca04b9711aa3b244b2dcea9b9925bab960
> rust-cpython: add wrapper around decapsule_make_dirstate_tuple()

This is actually V2. I forgot to add --flag V2, sorry.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 7] rust-cpython: drop direct dependency on python(27|3)_sys

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570970825 -32400
#  Sun Oct 13 21:47:05 2019 +0900
# Node ID f04203256726d2172b0aa42311263f56dd12d3ac
# Parent  7ac435844d990e027d8b589909ca42d17a89b6b4
rust-cpython: drop direct dependency on python(27|3)_sys

We no longer use it.

diff --git a/rust/Cargo.lock b/rust/Cargo.lock
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -66,8 +66,6 @@ dependencies = [
  "cpython 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "hg-core 0.1.0",
  "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
- "python27-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "python3-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
diff --git a/rust/hg-cpython/Cargo.toml b/rust/hg-cpython/Cargo.toml
--- a/rust/hg-cpython/Cargo.toml
+++ b/rust/hg-cpython/Cargo.toml
@@ -11,12 +11,9 @@ crate-type = ["cdylib"]
 [features]
 default = ["python27"]
 
-python27 = ["cpython/python27-sys",
-"cpython/extension-module-2-7",
-"python27-sys",
-]
+python27 = ["cpython/python27-sys", "cpython/extension-module-2-7"]
 
-python3 = ["python3-sys", "cpython/python3-sys", "cpython/extension-module"]
+python3 = ["cpython/python3-sys", "cpython/extension-module"]
 
 [dependencies]
 hg-core = { path = "../hg-core" }
@@ -25,11 +22,3 @@ libc = '*'
 [dependencies.cpython]
 version = "0.3"
 default-features = false
-
-[dependencies.python27-sys]
-version = "0.3"
-optional = true
-
-[dependencies.python3-sys]
-version = "0.3"
-optional = true
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 7] rust-cpython: leverage upstreamed py_capsule_fn!() macro

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570954064 -32400
#  Sun Oct 13 17:07:44 2019 +0900
# Node ID 7ac435844d990e027d8b589909ca42d17a89b6b4
# Parent  7073183d7ec824b6b3686b41b6c0a98d089a6447
rust-cpython: leverage upstreamed py_capsule_fn!() macro

diff --git a/rust/hg-cpython/src/cindex.rs b/rust/hg-cpython/src/cindex.rs
--- a/rust/hg-cpython/src/cindex.rs
+++ b/rust/hg-cpython/src/cindex.rs
@@ -9,23 +9,20 @@
 //!
 //! Ideally, we should use an Index entirely implemented in Rust,
 //! but this will take some time to get there.
-#[cfg(feature = "python27")]
-use python27_sys as python_sys;
-#[cfg(feature = "python3")]
-use python3_sys as python_sys;
 
-use cpython::{PyClone, PyErr, PyObject, PyResult, Python};
+use cpython::{PyClone, PyObject, PyResult, Python};
 use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION};
 use libc::c_int;
-use python_sys::PyCapsule_Import;
-use std::ffi::CStr;
-use std::mem::transmute;
 
-type IndexParentsFn = unsafe extern "C" fn(
-index: *mut python_sys::PyObject,
-rev: c_int,
-ps: *mut [c_int; 2],
-) -> c_int;
+py_capsule_fn!(
+from mercurial.cext.parsers import index_get_parents_CAPI
+as get_parents_capi
+signature (
+index: *mut RawPyObject,
+rev: c_int,
+ps: *mut [c_int; 2],
+) -> c_int
+);
 
 /// A `Graph` backed up by objects and functions from revlog.c
 ///
@@ -61,14 +58,14 @@ type IndexParentsFn = unsafe extern "C" 
 /// mechanisms in other contexts.
 pub struct Index {
 index: PyObject,
-parents: IndexParentsFn,
+parents: get_parents_capi::CapsuleFn,
 }
 
 impl Index {
 pub fn new(py: Python, index: PyObject) -> PyResult {
 Ok(Index {
 index: index,
-parents: decapsule_parents_fn(py)?,
+parents: get_parents_capi::retrieve(py)?,
 })
 }
 }
@@ -103,31 +100,3 @@ impl Graph for Index {
 }
 }
 }
-
-/// Return the `index_get_parents` function of the parsers C Extension module.
-///
-/// A pointer to the function is stored in the `parsers` module as a
-/// standard [Python capsule](https://docs.python.org/2/c-api/capsule.html).
-///
-/// This function retrieves the capsule and casts the function pointer
-///
-/// Casting function pointers is one of the rare cases of
-/// legitimate use cases of `mem::transmute()` (see
-/// https://doc.rust-lang.org/std/mem/fn.transmute.html of
-/// `mem::transmute()`.
-/// It is inappropriate for architectures where
-/// function and data pointer sizes differ (so-called "Harvard
-/// architectures"), but these are nowadays mostly DSPs
-/// and microcontrollers, hence out of our scope.
-fn decapsule_parents_fn(py: Python) -> PyResult {
-unsafe {
-let caps_name = CStr::from_bytes_with_nul_unchecked(
-b"mercurial.cext.parsers.index_get_parents_CAPI\0",
-);
-let from_caps = PyCapsule_Import(caps_name.as_ptr(), 0);
-if from_caps.is_null() {
-return Err(PyErr::fetch(py));
-}
-Ok(transmute(from_caps))
-}
-}
diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
--- a/rust/hg-cpython/src/dirstate.rs
+++ b/rust/hg-cpython/src/dirstate.rs
@@ -22,14 +22,7 @@ use hg::{
 StateMap,
 };
 use libc::{c_char, c_int};
-#[cfg(feature = "python27")]
-use python27_sys as python_sys;
-#[cfg(feature = "python3")]
-use python3_sys as python_sys;
-use python_sys::PyCapsule_Import;
 use std::convert::TryFrom;
-use std::ffi::CStr;
-use std::mem::transmute;
 
 // C code uses a custom `dirstate_tuple` type, checks in multiple instances
 // for this type, and raises a Python `Exception` if the check does not pass.
@@ -37,34 +30,23 @@ use std::mem::transmute;
 // would be a good idea in the near future to remove it entirely to allow
 // for a pure Python tuple of the same effective structure to be used,
 // rendering this type and the capsule below useless.
-type MakeDirstateTupleFn = unsafe extern "C" fn(
-state: c_char,
-mode: c_int,
-size: c_int,
-mtime: c_int,
-) -> *mut python_sys::PyObject;
-
-// This is largely a copy/paste from cindex.rs, pending the merge of a
-// `py_capsule_fn!` macro in the rust-cpython project:
-// https://github.com/dgrunwald/rust-cpython/pull/169
-fn decapsule_make_dirstate_tuple(py: Python) -> PyResult {
-unsafe {
-let caps_name = CStr::from_bytes_with_nul_unchecked(
-b"mercurial.cext.parsers.make_dirstate_tuple_CAPI\0",
-);
-let from_caps = PyCapsule_Import(caps_name.as_ptr(), 0);
-if from_caps.is_null() {
-return Err(PyErr::fetch(py));
-}
-Ok(transmute(from_caps))
-}
-}
+py_capsule_fn!(
+from mercurial.cext.parsers import make_dirstate_tuple_CAPI
+as make_dirstate_tuple_capi
+signature (
+state: c_char,
+mode: c_int,
+size: c_int,
+mtime: c_int,
+) -> *mut RawPyObject
+);
 
 

[PATCH 5 of 7] rust-cpython: bump cpython crates to 0.3

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570953909 -32400
#  Sun Oct 13 17:05:09 2019 +0900
# Node ID 7073183d7ec824b6b3686b41b6c0a98d089a6447
# Parent  d7823e47559d0b0aec701c9f6cc8f66ae59ecaa1
rust-cpython: bump cpython crates to 0.3

Unblocks py_capsule_fn!().

diff --git a/rust/Cargo.lock b/rust/Cargo.lock
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -33,13 +33,13 @@ dependencies = [
 
 [[package]]
 name = "cpython"
-version = "0.2.1"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 dependencies = [
  "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "python27-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "python3-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "python27-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "python3-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -63,11 +63,11 @@ dependencies = [
 name = "hg-cpython"
 version = "0.1.0"
 dependencies = [
- "cpython 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cpython 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "hg-core 0.1.0",
  "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
- "python27-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "python3-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "python27-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "python3-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -100,7 +100,7 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "python27-sys"
-version = "0.2.1"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 dependencies = [
  "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -109,7 +109,7 @@ dependencies = [
 
 [[package]]
 name = "python3-sys"
-version = "0.2.1"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 dependencies = [
  "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -304,14 +304,14 @@ source = "registry+https://github.com/ru
 "checksum bitflags 1.0.4 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
 "checksum byteorder 1.3.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
 "checksum cloudabi 0.0.3 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
-"checksum cpython 0.2.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"b489034e723e7f5109fecd19b719e664f89ef925be785885252469e9822fa940"
+"checksum cpython 0.3.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"85532c648315aeb0829ad216a6a29aa3212cf9319bc7f6daf1404aa0bdd1485f"
 "checksum fuchsia-cprng 0.1.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"81f7f8eb465745ea9b02e2704612a9946a59fa40572086c6fd49d6ddcf30bf31"
 "checksum lazy_static 1.3.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
 "checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" 
= "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74"
 "checksum memchr 2.2.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
 "checksum num-traits 0.2.6 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
-"checksum python27-sys 0.2.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"56114c37d4dca82526d74009df7782a28c871ac9d36b19d4cb9e67672258527e"
-"checksum python3-sys 0.2.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"61e4aac43f833fd637e429506cb2ac9d7df672c4b68f2eaaa163649b7fdc0444"
+"checksum python27-sys 0.3.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"372555e88a6bc8109eb641380240dc8d25a128fc48363ec9075664daadffdd5b"
+"checksum python3-sys 0.3.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"f3a8ebed3f1201fda179f3960609dbbc10cd8c75e9f2afcb03788278f367d8ea"
 "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" 
= "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
 "checksum rand_chacha 0.1.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
 "checksum rand_core 0.3.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"7a6fdeb83b075e8266dcc8762c22776f6877a6321f5f8c7411e5be7eed4b"
diff --git 

[PATCH 4 of 7] rust-cpython: turn inline comments into non-doc comments

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570953746 -32400
#  Sun Oct 13 17:02:26 2019 +0900
# Node ID d7823e47559d0b0aec701c9f6cc8f66ae59ecaa1
# Parent  1c18f9652cda28e7d8d0ffc2e7a01d16622bc98f
rust-cpython: turn inline comments into non-doc comments

diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
--- a/rust/hg-cpython/src/dirstate.rs
+++ b/rust/hg-cpython/src/dirstate.rs
@@ -31,12 +31,12 @@ use std::convert::TryFrom;
 use std::ffi::CStr;
 use std::mem::transmute;
 
-/// C code uses a custom `dirstate_tuple` type, checks in multiple instances
-/// for this type, and raises a Python `Exception` if the check does not pass.
-/// Because this type differs only in name from the regular Python tuple, it
-/// would be a good idea in the near future to remove it entirely to allow
-/// for a pure Python tuple of the same effective structure to be used,
-/// rendering this type and the capsule below useless.
+// C code uses a custom `dirstate_tuple` type, checks in multiple instances
+// for this type, and raises a Python `Exception` if the check does not pass.
+// Because this type differs only in name from the regular Python tuple, it
+// would be a good idea in the near future to remove it entirely to allow
+// for a pure Python tuple of the same effective structure to be used,
+// rendering this type and the capsule below useless.
 type MakeDirstateTupleFn = unsafe extern "C" fn(
 state: c_char,
 mode: c_int,
@@ -44,9 +44,9 @@ type MakeDirstateTupleFn = unsafe extern
 mtime: c_int,
 ) -> *mut python_sys::PyObject;
 
-/// This is largely a copy/paste from cindex.rs, pending the merge of a
-/// `py_capsule_fn!` macro in the rust-cpython project:
-/// https://github.com/dgrunwald/rust-cpython/pull/169
+// This is largely a copy/paste from cindex.rs, pending the merge of a
+// `py_capsule_fn!` macro in the rust-cpython project:
+// https://github.com/dgrunwald/rust-cpython/pull/169
 fn decapsule_make_dirstate_tuple(py: Python) -> PyResult {
 unsafe {
 let caps_name = CStr::from_bytes_with_nul_unchecked(
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 7] rust-cpython: fix signature of make_dirstate_tuple()

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570953670 -32400
#  Sun Oct 13 17:01:10 2019 +0900
# Node ID 1c18f9652cda28e7d8d0ffc2e7a01d16622bc98f
# Parent  46a5d47e23a43c12115de6707fe727e52a8a5f74
rust-cpython: fix signature of make_dirstate_tuple()

Fortunately, the layout of PyObject {} is compatible with a C pointer, but
we shouldn't rely on that. This also fixes the handling of NULL pointer.

diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
--- a/rust/hg-cpython/src/dirstate.rs
+++ b/rust/hg-cpython/src/dirstate.rs
@@ -23,9 +23,10 @@ use hg::{
 };
 use libc::{c_char, c_int};
 #[cfg(feature = "python27")]
-use python27_sys::PyCapsule_Import;
+use python27_sys as python_sys;
 #[cfg(feature = "python3")]
-use python3_sys::PyCapsule_Import;
+use python3_sys as python_sys;
+use python_sys::PyCapsule_Import;
 use std::convert::TryFrom;
 use std::ffi::CStr;
 use std::mem::transmute;
@@ -41,7 +42,7 @@ type MakeDirstateTupleFn = unsafe extern
 mode: c_int,
 size: c_int,
 mtime: c_int,
-) -> PyObject;
+) -> *mut python_sys::PyObject;
 
 /// This is largely a copy/paste from cindex.rs, pending the merge of a
 /// `py_capsule_fn!` macro in the rust-cpython project:
@@ -76,10 +77,11 @@ pub fn make_dirstate_tuple(
 // just do a naive enum cast.
 let state_code: u8 = state.into();
 
-unsafe {
+let maybe_obj = unsafe {
 let ptr = make(state_code as c_char, mode, size, mtime);
-Ok(ptr)
-}
+PyObject::from_owned_ptr_opt(py, ptr)
+};
+maybe_obj.ok_or_else(|| PyErr::fetch(py))
 }
 
 pub fn extract_dirstate(py: Python, dmap: ) -> Result {
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 7] rust-cpython: mark capsule function as unsafe

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570953495 -32400
#  Sun Oct 13 16:58:15 2019 +0900
# Node ID 46a5d47e23a43c12115de6707fe727e52a8a5f74
# Parent  083f70b7b5899755bb28ce16d6fc45eee46e84e4
rust-cpython: mark capsule function as unsafe

diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
--- a/rust/hg-cpython/src/dirstate.rs
+++ b/rust/hg-cpython/src/dirstate.rs
@@ -36,7 +36,7 @@ use std::mem::transmute;
 /// would be a good idea in the near future to remove it entirely to allow
 /// for a pure Python tuple of the same effective structure to be used,
 /// rendering this type and the capsule below useless.
-type MakeDirstateTupleFn = extern "C" fn(
+type MakeDirstateTupleFn = unsafe extern "C" fn(
 state: c_char,
 mode: c_int,
 size: c_int,
@@ -75,7 +75,11 @@ pub fn make_dirstate_tuple(
 // because Into has a specific implementation while `as c_char` would
 // just do a naive enum cast.
 let state_code: u8 = state.into();
-Ok(make(state_code as c_char, mode, size, mtime))
+
+unsafe {
+let ptr = make(state_code as c_char, mode, size, mtime);
+Ok(ptr)
+}
 }
 
 pub fn extract_dirstate(py: Python, dmap: ) -> Result {
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 7] rust-cpython: add wrapper around decapsule_make_dirstate_tuple()

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570953317 -32400
#  Sun Oct 13 16:55:17 2019 +0900
# Node ID 083f70b7b5899755bb28ce16d6fc45eee46e84e4
# Parent  dbe969ca04b9711aa3b244b2dcea9b9925bab960
rust-cpython: add wrapper around decapsule_make_dirstate_tuple()

There are a couple of safety issues. First, the returned function pointer
must be unsafe. Second, its return value must be a raw pointer (i.e.
python27_sys::PyObject), not a cpython::PyObject. The wrapper function will
address these issues.

diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
--- a/rust/hg-cpython/src/dirstate.rs
+++ b/rust/hg-cpython/src/dirstate.rs
@@ -46,9 +46,7 @@ type MakeDirstateTupleFn = extern "C" fn
 /// This is largely a copy/paste from cindex.rs, pending the merge of a
 /// `py_capsule_fn!` macro in the rust-cpython project:
 /// https://github.com/dgrunwald/rust-cpython/pull/169
-pub fn decapsule_make_dirstate_tuple(
-py: Python,
-) -> PyResult {
+fn decapsule_make_dirstate_tuple(py: Python) -> PyResult {
 unsafe {
 let caps_name = CStr::from_bytes_with_nul_unchecked(
 b"mercurial.cext.parsers.make_dirstate_tuple_CAPI\0",
@@ -61,6 +59,25 @@ pub fn decapsule_make_dirstate_tuple(
 }
 }
 
+pub fn make_dirstate_tuple(
+py: Python,
+entry: ,
+) -> PyResult {
+let make = decapsule_make_dirstate_tuple(py)?;
+
+let  {
+state,
+mode,
+size,
+mtime,
+} = entry;
+// Explicitly go through u8 first, then cast to platform-specific `c_char`
+// because Into has a specific implementation while `as c_char` would
+// just do a naive enum cast.
+let state_code: u8 = state.into();
+Ok(make(state_code as c_char, mode, size, mtime))
+}
+
 pub fn extract_dirstate(py: Python, dmap: ) -> Result {
 dmap.items(py)
 .iter()
diff --git a/rust/hg-cpython/src/dirstate/dirstate_map.rs 
b/rust/hg-cpython/src/dirstate/dirstate_map.rs
--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs
+++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs
@@ -16,11 +16,10 @@ use cpython::{
 exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyObject,
 PyResult, PyTuple, Python, PythonObject, ToPyObject,
 };
-use libc::c_char;
 
 use crate::{
 dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator},
-dirstate::{decapsule_make_dirstate_tuple, dirs_multiset::Dirs},
+dirstate::{dirs_multiset::Dirs, make_dirstate_tuple},
 ref_sharing::{PyLeakedRef, PySharedRefCell},
 };
 use hg::{
@@ -66,15 +65,7 @@ py_class!(pub class DirstateMap |py| {
 let key = key.extract::(py)?;
 match self.inner_shared(py).borrow().get(HgPath::new(key.data(py))) {
 Some(entry) => {
-// Explicitly go through u8 first, then cast to
-// platform-specific `c_char`.
-let state: u8 = entry.state.into();
-Ok(Some(decapsule_make_dirstate_tuple(py)?(
-state as c_char,
-entry.mode,
-entry.size,
-entry.mtime,
-)))
+Ok(Some(make_dirstate_tuple(py, entry)?))
 },
 None => Ok(default)
 }
@@ -303,15 +294,7 @@ py_class!(pub class DirstateMap |py| {
 let key = HgPath::new(key.data(py));
 match self.inner_shared(py).borrow().get(key) {
 Some(entry) => {
-// Explicitly go through u8 first, then cast to
-// platform-specific `c_char`.
-let state: u8 = entry.state.into();
-Ok(decapsule_make_dirstate_tuple(py)?(
-state as c_char,
-entry.mode,
-entry.size,
-entry.mtime,
-))
+Ok(make_dirstate_tuple(py, entry)?)
 },
 None => Err(PyErr::new::(
 py,
@@ -483,18 +466,9 @@ impl DirstateMap {
 res: (, ),
 ) -> PyResult> {
 let (f, entry) = res;
-
-// Explicitly go through u8 first, then cast to
-// platform-specific `c_char`.
-let state: u8 = entry.state.into();
 Ok(Some((
 PyBytes::new(py, f.as_ref()),
-decapsule_make_dirstate_tuple(py)?(
-state as c_char,
-entry.mode,
-entry.size,
-entry.mtime,
-),
+make_dirstate_tuple(py, entry)?,
 )))
 }
 }
diff --git a/rust/hg-cpython/src/parsers.rs b/rust/hg-cpython/src/parsers.rs
--- a/rust/hg-cpython/src/parsers.rs
+++ b/rust/hg-cpython/src/parsers.rs
@@ -15,15 +15,13 @@ use cpython::{
 PythonObject, ToPyObject,
 };
 use hg::{
-pack_dirstate, parse_dirstate, utils::hg_path::HgPathBuf, DirstateEntry,
+pack_dirstate, parse_dirstate, utils::hg_path::HgPathBuf,
 DirstatePackError, DirstateParents, 

Re: [PATCH 7 of 7] rust-cpython: leverage upstreamed py_capsule_fn!() macro

2019-10-13 Thread Georges Racinet
On 10/13/19 2:37 PM, Yuya Nishihara wrote:
> On Sun, 13 Oct 2019 14:08:24 +0200, Georges Racinet wrote:
>>> +py_capsule_fn!(
>>> +from mercurial.cext.parsers import index_get_parents_CAPI
>>> +as get_parents_capi
>>> +signature (
>>> +index: *mut python_sys::PyObject,
>> Here you can directly use RawPyObject:
>>
>>    index: *mut RawPyObject,
>>
>> see
>> https://github.com/dgrunwald/rust-cpython/commit/c5cfd32cf05005e3ad515063c9ca14100362eb93
> Oh, there is. I was looking for cpython::RawPyObject and failed.
That's actually how my first attempt looked like IIRC, but Mark
preferred it to be enclosed in the capsule submodule to limit that
abstraction leak to cases where it's really needed.
>
> I'll send V2 shortly.

Cool, once it's landed, I'll send the remainders of my own series:
removal of `py_set()` in favour of `cpython::objects::PySet`.

Regards,

-- 
Georges Racinet
https://octobus.net
GPG: BF5456F4DC625443849B6E58EE20CA44EF691D39, sur serveurs publics




signature.asc
Description: OpenPGP digital signature
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 7 of 7] rust-cpython: leverage upstreamed py_capsule_fn!() macro

2019-10-13 Thread Yuya Nishihara
On Sun, 13 Oct 2019 14:08:24 +0200, Georges Racinet wrote:
> > +py_capsule_fn!(
> > +from mercurial.cext.parsers import index_get_parents_CAPI
> > +as get_parents_capi
> > +signature (
> > +index: *mut python_sys::PyObject,
> 
> Here you can directly use RawPyObject:
> 
>    index: *mut RawPyObject,
> 
> see
> https://github.com/dgrunwald/rust-cpython/commit/c5cfd32cf05005e3ad515063c9ca14100362eb93

Oh, there is. I was looking for cpython::RawPyObject and failed.

I'll send V2 shortly.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 7 of 7] rust-cpython: leverage upstreamed py_capsule_fn!() macro

2019-10-13 Thread Georges Racinet
Hi,

I don't have time for a formal review right now, but I did skim over the
series, and I think it can be simplified and pushed further, removing
the whole sys_python dependency (see the inline comment below)

Actually I have a series of my own in the works to the same effect,
i.e., leveraging the rust-cpython 0.3.0 and its more integrated) capsule
integration. Here it is for reference:
https://dev.heptapod.net/octobus/mercurial-devel/merge_requests/1 (it
also makes use of the new high-level `PySet`, which I can submit
independently).

I did not submit it yet, because I've been slow on rebasing / testing
against Py2 and Py3 with consistent results. You shot first :-) Note
that I don't care much which version lands at the end of the day.

Regards,

On 10/13/19 11:47 AM, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1570954064 -32400
> #  Sun Oct 13 17:07:44 2019 +0900
> # Node ID 6c8410bd4ce786ceca53986514a1fbda5f097f2d
> # Parent  2d7671cc1d717f3ed3890e47324e4ed479529466
> rust-cpython: leverage upstreamed py_capsule_fn!() macro
Side remark: at some point I'd like to switch the Index capsule to the
array-of-functions-and-constants style, as in
https://dgrunwald.github.io/rust-cpython/doc/cpython/struct.PyCapsule.html#using-a-capsule-defined-in-another-extension-module

This is how all capsules defined in the Python standard library actually
work.
>
> diff --git a/rust/hg-cpython/src/cindex.rs b/rust/hg-cpython/src/cindex.rs
> --- a/rust/hg-cpython/src/cindex.rs
> +++ b/rust/hg-cpython/src/cindex.rs
> @@ -10,18 +10,20 @@
>  //! Ideally, we should use an Index entirely implemented in Rust,
>  //! but this will take some time to get there.
>  
> -use crate::python_sys::{self, PyCapsule_Import};
> -use cpython::{PyClone, PyErr, PyObject, PyResult, Python};
> +use crate::python_sys;
> +use cpython::{PyClone, PyObject, PyResult, Python};
>  use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION};
>  use libc::c_int;
> -use std::ffi::CStr;
> -use std::mem::transmute;
>  
> -type IndexParentsFn = unsafe extern "C" fn(
> -index: *mut python_sys::PyObject,
> -rev: c_int,
> -ps: *mut [c_int; 2],
> -) -> c_int;
> +py_capsule_fn!(
> +from mercurial.cext.parsers import index_get_parents_CAPI
> +as get_parents_capi
> +signature (
> +index: *mut python_sys::PyObject,

Here you can directly use RawPyObject:

   index: *mut RawPyObject,

see
https://github.com/dgrunwald/rust-cpython/commit/c5cfd32cf05005e3ad515063c9ca14100362eb93

the same would apply for other capsules, and that means we can
completely get rid of the dependency to sys_python

> +rev: c_int,
> +ps: *mut [c_int; 2],
> +) -> c_int
> +);
>  
>  /// A `Graph` backed up by objects and functions from revlog.c
>  ///
> @@ -57,14 +59,14 @@ type IndexParentsFn = unsafe extern "C" 
>  /// mechanisms in other contexts.
>  pub struct Index {
>  index: PyObject,
> -parents: IndexParentsFn,
> +parents: get_parents_capi::CapsuleFn,
>  }
>  
>  impl Index {
>  pub fn new(py: Python, index: PyObject) -> PyResult {
>  Ok(Index {
>  index: index,
> -parents: decapsule_parents_fn(py)?,
> +parents: get_parents_capi::retrieve(py)?,
>  })
>  }
>  }
> @@ -99,31 +101,3 @@ impl Graph for Index {
>  }
>  }
>  }
> -
> -/// Return the `index_get_parents` function of the parsers C Extension 
> module.
> -///
> -/// A pointer to the function is stored in the `parsers` module as a
> -/// standard [Python capsule](https://docs.python.org/2/c-api/capsule.html).
> -///
> -/// This function retrieves the capsule and casts the function pointer
> -///
> -/// Casting function pointers is one of the rare cases of
> -/// legitimate use cases of `mem::transmute()` (see
> -/// https://doc.rust-lang.org/std/mem/fn.transmute.html of
> -/// `mem::transmute()`.
> -/// It is inappropriate for architectures where
> -/// function and data pointer sizes differ (so-called "Harvard
> -/// architectures"), but these are nowadays mostly DSPs
> -/// and microcontrollers, hence out of our scope.
> -fn decapsule_parents_fn(py: Python) -> PyResult {
> -unsafe {
> -let caps_name = CStr::from_bytes_with_nul_unchecked(
> -b"mercurial.cext.parsers.index_get_parents_CAPI\0",
> -);
> -let from_caps = PyCapsule_Import(caps_name.as_ptr(), 0);
> -if from_caps.is_null() {
> -return Err(PyErr::fetch(py));
> -}
> -Ok(transmute(from_caps))
> -}
> -}
> diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
> --- a/rust/hg-cpython/src/dirstate.rs
> +++ b/rust/hg-cpython/src/dirstate.rs
> @@ -15,7 +15,7 @@ mod dirs_multiset;
>  mod dirstate_map;
>  
>  use crate::dirstate::{dirs_multiset::Dirs, dirstate_map::DirstateMap};
> -use crate::python_sys::{self, PyCapsule_Import};
> +use crate::python_sys;
>  use cpython::{
>  

[PATCH] dirs: remove mutable string optimization at all

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570964769 -32400
#  Sun Oct 13 20:06:09 2019 +0900
# Node ID 87dfcdb8394e377049b5a337585309ae4c652c7d
# Parent  ce20b870041fc4d6ba6989acbb9373797ce9b3d6
dirs: remove mutable string optimization at all

As far as I can see, the optimization trick has been dead since 42e89b87ca79
"dirs: speed up by storing number of direct children per dir". After
42e89b87ca79, the key variable is cleared to NULL at every iteration.

diff --git a/mercurial/cext/dirs.c b/mercurial/cext/dirs.c
--- a/mercurial/cext/dirs.c
+++ b/mercurial/cext/dirs.c
@@ -63,46 +63,18 @@ static int _addpath(PyObject *dirs, PyOb
* "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. The code for adjusting the length of a PyBytesObject is
-   * essentially a minimal version of _PyBytes_Resize. */
+   * unnoticed. */
while ((pos = _finddir(cpath, pos - 1)) != -1) {
PyObject *val;
 
-   if (pos < 2) {
-   key = PyBytes_FromStringAndSize(cpath, pos);
-   if (key == NULL)
-   goto bail;
-   } else {
-   /* 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)
-   ((PyBytesObject *)key)->ob_shash = -1;
-   else {
-   /* We know pos >= 2, so we won't get a small
-* shared string. */
-   key = PyBytes_FromStringAndSize(cpath, pos);
-   if (key == NULL)
-   goto bail;
-   }
-   /* Py_SIZE(o) refers to the ob_size member of
-* the struct. Yes, assigning to what looks
-* like a function seems wrong. */
-   Py_SIZE(key) = pos;
-   ((PyBytesObject *)key)->ob_sval[pos] = '\0';
-   }
+   key = PyBytes_FromStringAndSize(cpath, pos);
+   if (key == NULL)
+   goto bail;
 
val = PyDict_GetItem(dirs, key);
if (val != NULL) {
PYLONG_VALUE(val) += 1;
-   if (pos < 2) {
-   /* This was a short string, so we
-* probably got a small shared string
-* we can't mutate on the next loop
-* iteration. Clear it.
-*/
-   Py_CLEAR(key);
-   }
+   Py_CLEAR(key);
break;
}
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 2] perf: introduce a `--iteration` to `perfdirstate`

2019-10-13 Thread Yuya Nishihara
On Sat, 12 Oct 2019 04:20:42 +0200, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David 
> # Date 1570522984 14400
> #  Tue Oct 08 04:23:04 2019 -0400
> # Node ID 992c09636ae9d0543ea621305a71d6f9f77dc7dc
> # Parent  c88075eb28e3281a4470fde929fbf5a13bda5f8a
> # EXP-Topic perf-dirstate
> # Available At https://bitbucket.org/octobus/mercurial-devel/
> #  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
> 992c09636ae9
> perf: introduce a `--iteration` to `perfdirstate`

Fixed some missing b''s and queued, thanks.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 2] patchcopies: give up any optimization based on `introrev`

2019-10-13 Thread Yuya Nishihara
On Fri, 11 Oct 2019 20:00:58 +0200, Pierre-Yves David wrote:
> On 10/11/19 2:02 PM, Yuya Nishihara wrote:
> > On Fri, 11 Oct 2019 01:04:12 +0200, Pierre-Yves David wrote:
> >> # HG changeset patch
> >> # User Pierre-Yves David 
> >> # Date 1570672173 -7200
> >> #  Thu Oct 10 03:49:33 2019 +0200
> >> # Node ID 2477ba483c04067900d1e9f6523b03df68a4d545
> >> # Parent  8ff1ecfadcd110849c47c77e31c92809eea466ab
> >> # EXP-Topic patchcopies-regression
> >> # Available At https://bitbucket.org/octobus/mercurial-devel/
> >> #  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
> >> 2477ba483c04
> >> patchcopies: give up any optimization based on `introrev`
> >>
> >> Between 8a0136f69027 and d98fb3f42f33, we sped up the search for the
> >> introduction revision during path copies. However, further checking show 
> >> that
> >> finding the introduction revision is still expensive and that we are 
> >> better off
> >> without it. So we simply drop it and only rely on the linkrev optimisation.
> >>
> >> I ran `perfpathcopies` on 6989 pair of revision in the pypy
> >> repository (`hg perfhelper-pathcopies`. The result is massively in favor of
> >> dropping this condition. The result of the copy tracing are unchanged.
> >>
> >> Attempt to use a smaller changes preserving linkrev usage were 
> >> unsuccessful, it
> >> can return wrong result. The following changesets broke 
> >> test-mv-cp-st-diff.t
> >>
> >>  -if not f.isintroducedafter(limit):
> >>  +if limit >= 0 and f.linkrev() < limit:
> >>   return None
> > 
> > Sure. I meant comparing linkrevs, not linkrev vs (changelog) rev. If both
> > arms were linkrevs, and if the limit pointed to the revision where the
> > linkrevs of its files are guaranteed to be the lowest, the comparison
> > (e.g. f.linkrev() < repo[limit][path].linkrev()) would work.
> > 
> > My question was whether it would make things fast or not.
> 
> Ha, I understand your proposal better now.
> 
> My testing of the version in this patch versus the "wrong" version using 
> linkrev too agressively did not show a significant difference (-1%).

Do you mean only 1% speedup or measurable speedup on 1% cases? I don't think
the former is significant, but the latter could be depending on use cases.

> So
> I don't it to raise anything better. Can we move forward with this
> series and maybe try a different approach later ?

Better to leave the _findlimit() function? Or won't it be any useful in
your future work?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 7] rust-cpython: leverage upstreamed py_capsule_fn!() macro

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570954064 -32400
#  Sun Oct 13 17:07:44 2019 +0900
# Node ID 6c8410bd4ce786ceca53986514a1fbda5f097f2d
# Parent  2d7671cc1d717f3ed3890e47324e4ed479529466
rust-cpython: leverage upstreamed py_capsule_fn!() macro

diff --git a/rust/hg-cpython/src/cindex.rs b/rust/hg-cpython/src/cindex.rs
--- a/rust/hg-cpython/src/cindex.rs
+++ b/rust/hg-cpython/src/cindex.rs
@@ -10,18 +10,20 @@
 //! Ideally, we should use an Index entirely implemented in Rust,
 //! but this will take some time to get there.
 
-use crate::python_sys::{self, PyCapsule_Import};
-use cpython::{PyClone, PyErr, PyObject, PyResult, Python};
+use crate::python_sys;
+use cpython::{PyClone, PyObject, PyResult, Python};
 use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION};
 use libc::c_int;
-use std::ffi::CStr;
-use std::mem::transmute;
 
-type IndexParentsFn = unsafe extern "C" fn(
-index: *mut python_sys::PyObject,
-rev: c_int,
-ps: *mut [c_int; 2],
-) -> c_int;
+py_capsule_fn!(
+from mercurial.cext.parsers import index_get_parents_CAPI
+as get_parents_capi
+signature (
+index: *mut python_sys::PyObject,
+rev: c_int,
+ps: *mut [c_int; 2],
+) -> c_int
+);
 
 /// A `Graph` backed up by objects and functions from revlog.c
 ///
@@ -57,14 +59,14 @@ type IndexParentsFn = unsafe extern "C" 
 /// mechanisms in other contexts.
 pub struct Index {
 index: PyObject,
-parents: IndexParentsFn,
+parents: get_parents_capi::CapsuleFn,
 }
 
 impl Index {
 pub fn new(py: Python, index: PyObject) -> PyResult {
 Ok(Index {
 index: index,
-parents: decapsule_parents_fn(py)?,
+parents: get_parents_capi::retrieve(py)?,
 })
 }
 }
@@ -99,31 +101,3 @@ impl Graph for Index {
 }
 }
 }
-
-/// Return the `index_get_parents` function of the parsers C Extension module.
-///
-/// A pointer to the function is stored in the `parsers` module as a
-/// standard [Python capsule](https://docs.python.org/2/c-api/capsule.html).
-///
-/// This function retrieves the capsule and casts the function pointer
-///
-/// Casting function pointers is one of the rare cases of
-/// legitimate use cases of `mem::transmute()` (see
-/// https://doc.rust-lang.org/std/mem/fn.transmute.html of
-/// `mem::transmute()`.
-/// It is inappropriate for architectures where
-/// function and data pointer sizes differ (so-called "Harvard
-/// architectures"), but these are nowadays mostly DSPs
-/// and microcontrollers, hence out of our scope.
-fn decapsule_parents_fn(py: Python) -> PyResult {
-unsafe {
-let caps_name = CStr::from_bytes_with_nul_unchecked(
-b"mercurial.cext.parsers.index_get_parents_CAPI\0",
-);
-let from_caps = PyCapsule_Import(caps_name.as_ptr(), 0);
-if from_caps.is_null() {
-return Err(PyErr::fetch(py));
-}
-Ok(transmute(from_caps))
-}
-}
diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
--- a/rust/hg-cpython/src/dirstate.rs
+++ b/rust/hg-cpython/src/dirstate.rs
@@ -15,7 +15,7 @@ mod dirs_multiset;
 mod dirstate_map;
 
 use crate::dirstate::{dirs_multiset::Dirs, dirstate_map::DirstateMap};
-use crate::python_sys::{self, PyCapsule_Import};
+use crate::python_sys;
 use cpython::{
 exc, PyBytes, PyDict, PyErr, PyModule, PyObject, PyResult, PySequence,
 Python,
@@ -26,8 +26,6 @@ use hg::{
 };
 use libc::{c_char, c_int};
 use std::convert::TryFrom;
-use std::ffi::CStr;
-use std::mem::transmute;
 
 // C code uses a custom `dirstate_tuple` type, checks in multiple instances
 // for this type, and raises a Python `Exception` if the check does not pass.
@@ -35,34 +33,23 @@ use std::mem::transmute;
 // would be a good idea in the near future to remove it entirely to allow
 // for a pure Python tuple of the same effective structure to be used,
 // rendering this type and the capsule below useless.
-type MakeDirstateTupleFn = unsafe extern "C" fn(
-state: c_char,
-mode: c_int,
-size: c_int,
-mtime: c_int,
-) -> *mut python_sys::PyObject;
-
-// This is largely a copy/paste from cindex.rs, pending the merge of a
-// `py_capsule_fn!` macro in the rust-cpython project:
-// https://github.com/dgrunwald/rust-cpython/pull/169
-fn decapsule_make_dirstate_tuple(py: Python) -> PyResult {
-unsafe {
-let caps_name = CStr::from_bytes_with_nul_unchecked(
-b"mercurial.cext.parsers.make_dirstate_tuple_CAPI\0",
-);
-let from_caps = PyCapsule_Import(caps_name.as_ptr(), 0);
-if from_caps.is_null() {
-return Err(PyErr::fetch(py));
-}
-Ok(transmute(from_caps))
-}
-}
+py_capsule_fn!(
+from mercurial.cext.parsers import make_dirstate_tuple_CAPI
+as make_dirstate_tuple_capi
+signature (
+state: c_char,
+mode: c_int,
+size: c_int,
+   

[PATCH 6 of 7] rust-cpython: bump cpython crates to 0.3

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570953909 -32400
#  Sun Oct 13 17:05:09 2019 +0900
# Node ID 2d7671cc1d717f3ed3890e47324e4ed479529466
# Parent  88cde8b3df606c060c32de2002a2008f030a10c5
rust-cpython: bump cpython crates to 0.3

Unblocks py_capsule_fn!().

diff --git a/rust/Cargo.lock b/rust/Cargo.lock
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -33,13 +33,13 @@ dependencies = [
 
 [[package]]
 name = "cpython"
-version = "0.2.1"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 dependencies = [
  "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "python27-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "python3-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "python27-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "python3-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -63,11 +63,11 @@ dependencies = [
 name = "hg-cpython"
 version = "0.1.0"
 dependencies = [
- "cpython 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cpython 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "hg-core 0.1.0",
  "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
- "python27-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "python3-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "python27-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "python3-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -100,7 +100,7 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "python27-sys"
-version = "0.2.1"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 dependencies = [
  "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -109,7 +109,7 @@ dependencies = [
 
 [[package]]
 name = "python3-sys"
-version = "0.2.1"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 dependencies = [
  "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -304,14 +304,14 @@ source = "registry+https://github.com/ru
 "checksum bitflags 1.0.4 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
 "checksum byteorder 1.3.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
 "checksum cloudabi 0.0.3 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
-"checksum cpython 0.2.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"b489034e723e7f5109fecd19b719e664f89ef925be785885252469e9822fa940"
+"checksum cpython 0.3.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"85532c648315aeb0829ad216a6a29aa3212cf9319bc7f6daf1404aa0bdd1485f"
 "checksum fuchsia-cprng 0.1.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"81f7f8eb465745ea9b02e2704612a9946a59fa40572086c6fd49d6ddcf30bf31"
 "checksum lazy_static 1.3.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
 "checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" 
= "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74"
 "checksum memchr 2.2.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
 "checksum num-traits 0.2.6 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
-"checksum python27-sys 0.2.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"56114c37d4dca82526d74009df7782a28c871ac9d36b19d4cb9e67672258527e"
-"checksum python3-sys 0.2.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"61e4aac43f833fd637e429506cb2ac9d7df672c4b68f2eaaa163649b7fdc0444"
+"checksum python27-sys 0.3.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"372555e88a6bc8109eb641380240dc8d25a128fc48363ec9075664daadffdd5b"
+"checksum python3-sys 0.3.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"f3a8ebed3f1201fda179f3960609dbbc10cd8c75e9f2afcb03788278f367d8ea"
 "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" 
= "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
 "checksum rand_chacha 0.1.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
 "checksum rand_core 0.3.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"7a6fdeb83b075e8266dcc8762c22776f6877a6321f5f8c7411e5be7eed4b"
diff --git 

[PATCH 5 of 7] rust-cpython: turn inline comments into non-doc comments

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570953746 -32400
#  Sun Oct 13 17:02:26 2019 +0900
# Node ID 88cde8b3df606c060c32de2002a2008f030a10c5
# Parent  8ba14080af7216e711666457c2c068661ae3a97e
rust-cpython: turn inline comments into non-doc comments

diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
--- a/rust/hg-cpython/src/dirstate.rs
+++ b/rust/hg-cpython/src/dirstate.rs
@@ -29,12 +29,12 @@ use std::convert::TryFrom;
 use std::ffi::CStr;
 use std::mem::transmute;
 
-/// C code uses a custom `dirstate_tuple` type, checks in multiple instances
-/// for this type, and raises a Python `Exception` if the check does not pass.
-/// Because this type differs only in name from the regular Python tuple, it
-/// would be a good idea in the near future to remove it entirely to allow
-/// for a pure Python tuple of the same effective structure to be used,
-/// rendering this type and the capsule below useless.
+// C code uses a custom `dirstate_tuple` type, checks in multiple instances
+// for this type, and raises a Python `Exception` if the check does not pass.
+// Because this type differs only in name from the regular Python tuple, it
+// would be a good idea in the near future to remove it entirely to allow
+// for a pure Python tuple of the same effective structure to be used,
+// rendering this type and the capsule below useless.
 type MakeDirstateTupleFn = unsafe extern "C" fn(
 state: c_char,
 mode: c_int,
@@ -42,9 +42,9 @@ type MakeDirstateTupleFn = unsafe extern
 mtime: c_int,
 ) -> *mut python_sys::PyObject;
 
-/// This is largely a copy/paste from cindex.rs, pending the merge of a
-/// `py_capsule_fn!` macro in the rust-cpython project:
-/// https://github.com/dgrunwald/rust-cpython/pull/169
+// This is largely a copy/paste from cindex.rs, pending the merge of a
+// `py_capsule_fn!` macro in the rust-cpython project:
+// https://github.com/dgrunwald/rust-cpython/pull/169
 fn decapsule_make_dirstate_tuple(py: Python) -> PyResult {
 unsafe {
 let caps_name = CStr::from_bytes_with_nul_unchecked(
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 7] rust-cpython: fix signature of make_dirstate_tuple()

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570953670 -32400
#  Sun Oct 13 17:01:10 2019 +0900
# Node ID 8ba14080af7216e711666457c2c068661ae3a97e
# Parent  63a1df3aac72e67667eb7210f364f4b2d892b06f
rust-cpython: fix signature of make_dirstate_tuple()

Fortunately, the layout of PyObject {} is compatible with a C pointer, but
we shouldn't rely on that. This also fixes the handling of NULL pointer.

diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
--- a/rust/hg-cpython/src/dirstate.rs
+++ b/rust/hg-cpython/src/dirstate.rs
@@ -15,7 +15,7 @@ mod dirs_multiset;
 mod dirstate_map;
 
 use crate::dirstate::{dirs_multiset::Dirs, dirstate_map::DirstateMap};
-use crate::python_sys::PyCapsule_Import;
+use crate::python_sys::{self, PyCapsule_Import};
 use cpython::{
 exc, PyBytes, PyDict, PyErr, PyModule, PyObject, PyResult, PySequence,
 Python,
@@ -40,7 +40,7 @@ type MakeDirstateTupleFn = unsafe extern
 mode: c_int,
 size: c_int,
 mtime: c_int,
-) -> PyObject;
+) -> *mut python_sys::PyObject;
 
 /// This is largely a copy/paste from cindex.rs, pending the merge of a
 /// `py_capsule_fn!` macro in the rust-cpython project:
@@ -75,10 +75,11 @@ pub fn make_dirstate_tuple(
 // just do a naive enum cast.
 let state_code: u8 = state.into();
 
-unsafe {
+let maybe_obj = unsafe {
 let ptr = make(state_code as c_char, mode, size, mtime);
-Ok(ptr)
-}
+PyObject::from_owned_ptr_opt(py, ptr)
+};
+maybe_obj.ok_or_else(|| PyErr::fetch(py))
 }
 
 pub fn extract_dirstate(py: Python, dmap: ) -> Result {
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 7] rust-cpython: mark capsule function as unsafe

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570953495 -32400
#  Sun Oct 13 16:58:15 2019 +0900
# Node ID 63a1df3aac72e67667eb7210f364f4b2d892b06f
# Parent  00cd8123f876e03a3af2660c6cf4ba1a77b2bee3
rust-cpython: mark capsule function as unsafe

diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
--- a/rust/hg-cpython/src/dirstate.rs
+++ b/rust/hg-cpython/src/dirstate.rs
@@ -35,7 +35,7 @@ use std::mem::transmute;
 /// would be a good idea in the near future to remove it entirely to allow
 /// for a pure Python tuple of the same effective structure to be used,
 /// rendering this type and the capsule below useless.
-type MakeDirstateTupleFn = extern "C" fn(
+type MakeDirstateTupleFn = unsafe extern "C" fn(
 state: c_char,
 mode: c_int,
 size: c_int,
@@ -74,7 +74,11 @@ pub fn make_dirstate_tuple(
 // because Into has a specific implementation while `as c_char` would
 // just do a naive enum cast.
 let state_code: u8 = state.into();
-Ok(make(state_code as c_char, mode, size, mtime))
+
+unsafe {
+let ptr = make(state_code as c_char, mode, size, mtime);
+Ok(ptr)
+}
 }
 
 pub fn extract_dirstate(py: Python, dmap: ) -> Result {
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 7] rust-cpython: add wrapper around decapsule_make_dirstate_tuple()

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570953317 -32400
#  Sun Oct 13 16:55:17 2019 +0900
# Node ID 00cd8123f876e03a3af2660c6cf4ba1a77b2bee3
# Parent  6ecc771edbad738c634b50846de1943ea7d34d9e
rust-cpython: add wrapper around decapsule_make_dirstate_tuple()

There are a couple of safety issues. First, the returned function pointer
must be unsafe. Second, its return value must be a raw pointer (i.e.
python27_sys::PyObject), not a cpython::PyObject. The wrapper function will
address these issues.

diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
--- a/rust/hg-cpython/src/dirstate.rs
+++ b/rust/hg-cpython/src/dirstate.rs
@@ -45,9 +45,7 @@ type MakeDirstateTupleFn = extern "C" fn
 /// This is largely a copy/paste from cindex.rs, pending the merge of a
 /// `py_capsule_fn!` macro in the rust-cpython project:
 /// https://github.com/dgrunwald/rust-cpython/pull/169
-pub fn decapsule_make_dirstate_tuple(
-py: Python,
-) -> PyResult {
+fn decapsule_make_dirstate_tuple(py: Python) -> PyResult {
 unsafe {
 let caps_name = CStr::from_bytes_with_nul_unchecked(
 b"mercurial.cext.parsers.make_dirstate_tuple_CAPI\0",
@@ -60,6 +58,25 @@ pub fn decapsule_make_dirstate_tuple(
 }
 }
 
+pub fn make_dirstate_tuple(
+py: Python,
+entry: ,
+) -> PyResult {
+let make = decapsule_make_dirstate_tuple(py)?;
+
+let  {
+state,
+mode,
+size,
+mtime,
+} = entry;
+// Explicitly go through u8 first, then cast to platform-specific `c_char`
+// because Into has a specific implementation while `as c_char` would
+// just do a naive enum cast.
+let state_code: u8 = state.into();
+Ok(make(state_code as c_char, mode, size, mtime))
+}
+
 pub fn extract_dirstate(py: Python, dmap: ) -> Result {
 dmap.items(py)
 .iter()
diff --git a/rust/hg-cpython/src/dirstate/dirstate_map.rs 
b/rust/hg-cpython/src/dirstate/dirstate_map.rs
--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs
+++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs
@@ -16,11 +16,10 @@ use cpython::{
 exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyObject,
 PyResult, PyTuple, Python, PythonObject, ToPyObject,
 };
-use libc::c_char;
 
 use crate::{
 dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator},
-dirstate::{decapsule_make_dirstate_tuple, dirs_multiset::Dirs},
+dirstate::{dirs_multiset::Dirs, make_dirstate_tuple},
 ref_sharing::{PyLeakedRef, PySharedRefCell},
 };
 use hg::{
@@ -66,15 +65,7 @@ py_class!(pub class DirstateMap |py| {
 let key = key.extract::(py)?;
 match self.inner_shared(py).borrow().get(HgPath::new(key.data(py))) {
 Some(entry) => {
-// Explicitly go through u8 first, then cast to
-// platform-specific `c_char`.
-let state: u8 = entry.state.into();
-Ok(Some(decapsule_make_dirstate_tuple(py)?(
-state as c_char,
-entry.mode,
-entry.size,
-entry.mtime,
-)))
+Ok(Some(make_dirstate_tuple(py, entry)?))
 },
 None => Ok(default)
 }
@@ -303,15 +294,7 @@ py_class!(pub class DirstateMap |py| {
 let key = HgPath::new(key.data(py));
 match self.inner_shared(py).borrow().get(key) {
 Some(entry) => {
-// Explicitly go through u8 first, then cast to
-// platform-specific `c_char`.
-let state: u8 = entry.state.into();
-Ok(decapsule_make_dirstate_tuple(py)?(
-state as c_char,
-entry.mode,
-entry.size,
-entry.mtime,
-))
+Ok(make_dirstate_tuple(py, entry)?)
 },
 None => Err(PyErr::new::(
 py,
@@ -483,18 +466,9 @@ impl DirstateMap {
 res: (, ),
 ) -> PyResult> {
 let (f, entry) = res;
-
-// Explicitly go through u8 first, then cast to
-// platform-specific `c_char`.
-let state: u8 = entry.state.into();
 Ok(Some((
 PyBytes::new(py, f.as_ref()),
-decapsule_make_dirstate_tuple(py)?(
-state as c_char,
-entry.mode,
-entry.size,
-entry.mtime,
-),
+make_dirstate_tuple(py, entry)?,
 )))
 }
 }
diff --git a/rust/hg-cpython/src/parsers.rs b/rust/hg-cpython/src/parsers.rs
--- a/rust/hg-cpython/src/parsers.rs
+++ b/rust/hg-cpython/src/parsers.rs
@@ -15,15 +15,13 @@ use cpython::{
 PythonObject, ToPyObject,
 };
 use hg::{
-pack_dirstate, parse_dirstate, utils::hg_path::HgPathBuf, DirstateEntry,
+pack_dirstate, parse_dirstate, utils::hg_path::HgPathBuf,
 DirstatePackError, DirstateParents, 

[PATCH 1 of 7] rust-cpython: alias python(27|3)_sys globally

2019-10-13 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1570952770 -32400
#  Sun Oct 13 16:46:10 2019 +0900
# Node ID 6ecc771edbad738c634b50846de1943ea7d34d9e
# Parent  dbe969ca04b9711aa3b244b2dcea9b9925bab960
rust-cpython: alias python(27|3)_sys globally

diff --git a/rust/hg-cpython/src/cindex.rs b/rust/hg-cpython/src/cindex.rs
--- a/rust/hg-cpython/src/cindex.rs
+++ b/rust/hg-cpython/src/cindex.rs
@@ -9,15 +9,11 @@
 //!
 //! Ideally, we should use an Index entirely implemented in Rust,
 //! but this will take some time to get there.
-#[cfg(feature = "python27")]
-use python27_sys as python_sys;
-#[cfg(feature = "python3")]
-use python3_sys as python_sys;
 
+use crate::python_sys::{self, PyCapsule_Import};
 use cpython::{PyClone, PyErr, PyObject, PyResult, Python};
 use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION};
 use libc::c_int;
-use python_sys::PyCapsule_Import;
 use std::ffi::CStr;
 use std::mem::transmute;
 
diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
--- a/rust/hg-cpython/src/dirstate.rs
+++ b/rust/hg-cpython/src/dirstate.rs
@@ -9,10 +9,13 @@
 //! `hg-core` package.
 //!
 //! From Python, this will be seen as `mercurial.rustext.dirstate`
+
 mod copymap;
 mod dirs_multiset;
 mod dirstate_map;
+
 use crate::dirstate::{dirs_multiset::Dirs, dirstate_map::DirstateMap};
+use crate::python_sys::PyCapsule_Import;
 use cpython::{
 exc, PyBytes, PyDict, PyErr, PyModule, PyObject, PyResult, PySequence,
 Python,
@@ -22,10 +25,6 @@ use hg::{
 StateMap,
 };
 use libc::{c_char, c_int};
-#[cfg(feature = "python27")]
-use python27_sys::PyCapsule_Import;
-#[cfg(feature = "python3")]
-use python3_sys::PyCapsule_Import;
 use std::convert::TryFrom;
 use std::ffi::CStr;
 use std::mem::transmute;
diff --git a/rust/hg-cpython/src/lib.rs b/rust/hg-cpython/src/lib.rs
--- a/rust/hg-cpython/src/lib.rs
+++ b/rust/hg-cpython/src/lib.rs
@@ -24,6 +24,11 @@
 #[macro_use]
 extern crate cpython;
 
+#[cfg(feature = "python27")]
+use python27_sys as python_sys;
+#[cfg(feature = "python3")]
+use python3_sys as python_sys;
+
 pub mod ancestors;
 mod cindex;
 mod conversion;
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D7081: tests: open file in binary mode in test-upgrade-repo.t

2019-10-13 Thread mharbison72 (Matt Harbison)
Closed by commit rHG86b26f20146d: tests: open file in binary mode in 
test-upgrade-repo.t (authored by mharbison72).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7081?vs=17123=17126

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

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

AFFECTED FILES
  tests/test-upgrade-repo.t

CHANGE DETAILS

diff --git a/tests/test-upgrade-repo.t b/tests/test-upgrade-repo.t
--- a/tests/test-upgrade-repo.t
+++ b/tests/test-upgrade-repo.t
@@ -452,9 +452,9 @@
   >>> from __future__ import absolute_import, print_function
   >>> import random
   >>> random.seed(0) # have a reproducible content
-  >>> with open("f2", "w") as f:
+  >>> with open("f2", "wb") as f:
   ... for i in range(10):
-  ... f.write("%d\n" % random.randint(10, 99)) and None
+  ... f.write(b"%d\n" % random.randint(10, 99)) and 
None
   $ hg -q commit -A -m 'add f2'
 
 make sure we have a .d file



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


D7080: hghave: use a native string to invoke the `black` command

2019-10-13 Thread mharbison72 (Matt Harbison)
Closed by commit rHG138ac8cbce60: hghave: use a native string to invoke the 
`black` command (authored by mharbison72).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7080?vs=17122=17125

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

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

AFFECTED FILES
  tests/hghave.py

CHANGE DETAILS

diff --git a/tests/hghave.py b/tests/hghave.py
--- a/tests/hghave.py
+++ b/tests/hghave.py
@@ -984,8 +984,8 @@
 @check('grey', 'grey, the fork of the black formatter for python')
 def has_black():
 # use that to actual black as soon as possible
-# blackcmd = b'black --version'
-blackcmd = b'python3 $RUNTESTDIR/../contrib/grey.py --version'
+# blackcmd = 'black --version'
+blackcmd = 'python3 $RUNTESTDIR/../contrib/grey.py --version'
 # version_regex = b'black, version \d'
 version_regex = b'grey.py, version \d'
 return matchoutput(blackcmd, version_regex)



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


D7079: py3: convert cwd to native string when running `fix`

2019-10-13 Thread mharbison72 (Matt Harbison)
Closed by commit rHG2d1f9880af1b: py3: convert cwd to native string when 
running `fix` (authored by mharbison72).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7079?vs=17121=17124

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

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

AFFECTED FILES
  hgext/fix.py

CHANGE DETAILS

diff --git a/hgext/fix.py b/hgext/fix.py
--- a/hgext/fix.py
+++ b/hgext/fix.py
@@ -631,7 +631,7 @@
 proc = subprocess.Popen(
 procutil.tonativestr(command),
 shell=True,
-cwd=repo.root,
+cwd=procutil.tonativestr(repo.root),
 stdin=subprocess.PIPE,
 stdout=subprocess.PIPE,
 stderr=subprocess.PIPE,



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