D2727: bookmarks: test for exchanging long bookmark names (issue5165)
This revision was automatically updated to reflect the committed changes. Closed by commit rHG09b58af83d44: bookmarks: test for exchanging long bookmark names (issue5165) (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D2727?vs=6733&id=6762 REVISION DETAIL https://phab.mercurial-scm.org/D2727 AFFECTED FILES tests/test-bookmarks-pushpull.t CHANGE DETAILS diff --git a/tests/test-bookmarks-pushpull.t b/tests/test-bookmarks-pushpull.t --- a/tests/test-bookmarks-pushpull.t +++ b/tests/test-bookmarks-pushpull.t @@ -1030,6 +1030,34 @@ no changes found [1] +Pushing a really long bookmark should work fine (issue5165) +=== + +#if b2-binary + >>> open('longname', 'w').write('wat' * 100) + $ hg book `cat longname` + $ hg push -B `cat longname` ../unchanged-b + pushing to ../unchanged-b + searching for changes + no changes found + exporting bookmark (wat){100} (re) + [1] + $ hg -R ../unchanged-b book --delete `cat longname` + +Test again but forcing bundle2 exchange to make sure that doesn't regress. + + $ hg push -B `cat longname` ../unchanged-b --config devel.legacy.exchange=bundle1 + pushing to ../unchanged-b + searching for changes + no changes found + exporting bookmark (wat){100} (re) + [1] + $ hg -R ../unchanged-b book --delete `cat longname` + $ hg book --delete `cat longname` + $ hg co @ + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + (activating bookmark @) +#endif Check hook preventing push (issue4455) == To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@36766: new changeset
New changeset in mercurial: https://www.mercurial-scm.org/repo/hg/rev/d382344c69aa changeset: 36766:d382344c69aa tag: tip user:Gregory Szorc date:Sat Mar 03 18:55:43 2018 -0500 summary: perf: teach perfbdiff to call blocks() and to use xdiff -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 5 of 5] templater: split template functions to new module
# HG changeset patch # User Yuya Nishihara # Date 1520515382 -32400 # Thu Mar 08 22:23:02 2018 +0900 # Node ID b3f764c8098d6de1dca102f8b5b5d05721a6341f # Parent c22e2d75938bc761554c8da98a49b85aa6bff0de templater: split template functions to new module It has grown enough to be a dedicated module. diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -132,8 +132,9 @@ i18n/hg.pot: $(PYFILES) $(DOCFILES) i18n $(PYTHON) i18n/hggettext mercurial/commands.py \ hgext/*.py hgext/*/__init__.py \ mercurial/fileset.py mercurial/revset.py \ - mercurial/templatefilters.py mercurial/templatekw.py \ - mercurial/templater.py \ + mercurial/templatefilters.py \ + mercurial/templatefuncs.py \ + mercurial/templatekw.py \ mercurial/filemerge.py \ mercurial/hgweb/webcommands.py \ mercurial/util.py \ diff --git a/mercurial/extensions.py b/mercurial/extensions.py --- a/mercurial/extensions.py +++ b/mercurial/extensions.py @@ -290,8 +290,8 @@ def loadall(ui, whitelist=None): fileset, revset, templatefilters, +templatefuncs, templatekw, -templater, ) # list of (objname, loadermod, loadername) tuple: @@ -307,7 +307,7 @@ def loadall(ui, whitelist=None): ('internalmerge', filemerge, 'loadinternalmerge'), ('revsetpredicate', revset, 'loadpredicate'), ('templatefilter', templatefilters, 'loadfilter'), -('templatefunc', templater, 'loadfunction'), +('templatefunc', templatefuncs, 'loadfunction'), ('templatekeyword', templatekw, 'loadkeyword'), ] _loadextra(ui, newindex, extraloaders) diff --git a/mercurial/help.py b/mercurial/help.py --- a/mercurial/help.py +++ b/mercurial/help.py @@ -26,8 +26,8 @@ from . import ( pycompat, revset, templatefilters, +templatefuncs, templatekw, -templater, util, ) from .hgweb import ( @@ -309,7 +309,7 @@ addtopicsymbols('merge-tools', '.. inter addtopicsymbols('revisions', '.. predicatesmarker', revset.symbols) addtopicsymbols('templates', '.. keywordsmarker', templatekw.keywords) addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters) -addtopicsymbols('templates', '.. functionsmarker', templater.funcs) +addtopicsymbols('templates', '.. functionsmarker', templatefuncs.funcs) addtopicsymbols('hgweb', '.. webcommandsmarker', webcommands.commands, dedent=True) diff --git a/mercurial/registrar.py b/mercurial/registrar.py --- a/mercurial/registrar.py +++ b/mercurial/registrar.py @@ -368,7 +368,7 @@ class templatefunc(_templateregistrarbas extension, if an instance named as 'templatefunc' is used for decorating in extension. -Otherwise, explicit 'templater.loadfunction()' is needed. +Otherwise, explicit 'templatefuncs.loadfunction()' is needed. """ _getname = _funcregistrarbase._parsefuncdecl diff --git a/mercurial/templater.py b/mercurial/templatefuncs.py copy from mercurial/templater.py copy to mercurial/templatefuncs.py --- a/mercurial/templater.py +++ b/mercurial/templatefuncs.py @@ -1,24 +1,21 @@ -# templater.py - template expansion for output +# templatefuncs.py - common template functions # # Copyright 2005, 2006 Matt Mackall # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -from __future__ import absolute_import, print_function +from __future__ import absolute_import -import os import re from .i18n import _ from . import ( color, -config, encoding, error, minirst, obsutil, -parser, pycompat, registrar, revset as revsetmod, @@ -39,425 +36,8 @@ evalstring = templateutil.evalstring evalstringliteral = templateutil.evalstringliteral evalastype = templateutil.evalastype -# template parsing - -elements = { -# token-type: binding-strength, primary, prefix, infix, suffix -"(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None), -".": (18, None, None, (".", 18), None), -"%": (15, None, None, ("%", 15), None), -"|": (15, None, None, ("|", 15), None), -"*": (5, None, None, ("*", 5), None), -"/": (5, None, None, ("/", 5), None), -"+": (4, None, None, ("+", 4), None), -"-": (4, None, ("negate", 19), ("-", 4), None), -"=": (3, None, None, ("keyvalue", 3), None), -",": (2, None, None, ("list", 2), None), -")": (0, None, None, None, None), -"integer": (0, "integer", None, None, None), -"symbol": (0, "symbol", None, None, None), -"string": (0, "string", None, None, None), -"template": (0, "template", None, None, None), -"end": (0, None, None, None, None), -} - -def tokenize(program, start, end, term=None): -"""Parse a template expression into a stream of tokens, which must end -with term if specified""" -pos = start -program = pycompat.b
[PATCH 4 of 5] templater: move hybrid class and functions to templateutil module
# HG changeset patch # User Yuya Nishihara # Date 1520518509 -32400 # Thu Mar 08 23:15:09 2018 +0900 # Node ID c22e2d75938bc761554c8da98a49b85aa6bff0de # Parent dc412296cebd7c33cbae3b7ed5b0974186105387 templater: move hybrid class and functions to templateutil module And make _hybrid and _mappable classes public. _showlist() is still marked as private since it's weird and third-party codes shouldn't depend on it. diff --git a/hgext/lfs/__init__.py b/hgext/lfs/__init__.py --- a/hgext/lfs/__init__.py +++ b/hgext/lfs/__init__.py @@ -143,7 +143,7 @@ from mercurial import ( registrar, revlog, scmutil, -templatekw, +templateutil, upgrade, util, vfs as vfsmod, @@ -375,12 +375,12 @@ def lfsfiles(context, mapping): makemap = lambda v: { 'file': v, 'lfsoid': pointers[v].oid() if pointers[v] else None, -'lfspointer': templatekw.hybriddict(pointer(v)), +'lfspointer': templateutil.hybriddict(pointer(v)), } # TODO: make the separator ', '? -f = templatekw._showlist('lfs_file', files, templ, mapping) -return templatekw._hybrid(f, files, makemap, pycompat.identity) +f = templateutil._showlist('lfs_file', files, templ, mapping) +return templateutil.hybrid(f, files, makemap, pycompat.identity) @command('debuglfsupload', [('r', 'rev', [], _('upload large files introduced by REV'))]) diff --git a/hgext/remotenames.py b/hgext/remotenames.py --- a/hgext/remotenames.py +++ b/hgext/remotenames.py @@ -35,7 +35,7 @@ from mercurial import ( registrar, revsetlang, smartset, -templatekw, +templateutil, ) # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for @@ -237,8 +237,8 @@ def remotenameskw(context, mapping): if 'remotebranches' in repo.names: remotenames += repo.names['remotebranches'].names(repo, ctx.node()) -return templatekw.compatlist(context, mapping, 'remotename', remotenames, - plural='remotenames') +return templateutil.compatlist(context, mapping, 'remotename', remotenames, + plural='remotenames') @templatekeyword('remotebookmarks', requires={'repo', 'ctx', 'templ'}) def remotebookmarkskw(context, mapping): @@ -250,8 +250,8 @@ def remotebookmarkskw(context, mapping): if 'remotebookmarks' in repo.names: remotebmarks = repo.names['remotebookmarks'].names(repo, ctx.node()) -return templatekw.compatlist(context, mapping, 'remotebookmark', - remotebmarks, plural='remotebookmarks') +return templateutil.compatlist(context, mapping, 'remotebookmark', + remotebmarks, plural='remotebookmarks') @templatekeyword('remotebranches', requires={'repo', 'ctx', 'templ'}) def remotebrancheskw(context, mapping): @@ -263,8 +263,8 @@ def remotebrancheskw(context, mapping): if 'remotebranches' in repo.names: remotebranches = repo.names['remotebranches'].names(repo, ctx.node()) -return templatekw.compatlist(context, mapping, 'remotebranch', - remotebranches, plural='remotebranches') +return templateutil.compatlist(context, mapping, 'remotebranch', + remotebranches, plural='remotebranches') def _revsetutil(repo, subset, x, rtypes): """utility function to return a set of revs based on the rtypes""" diff --git a/mercurial/formatter.py b/mercurial/formatter.py --- a/mercurial/formatter.py +++ b/mercurial/formatter.py @@ -359,14 +359,15 @@ class _templateconverter(object): data = util.sortdict(_iteritems(data)) def f(): yield _plainconverter.formatdict(data, key, value, fmt, sep) -return templatekw.hybriddict(data, key=key, value=value, fmt=fmt, gen=f) +return templateutil.hybriddict(data, key=key, value=value, fmt=fmt, + gen=f) @staticmethod def formatlist(data, name, fmt, sep): '''build object that can be evaluated as either plain string or list''' data = list(data) def f(): yield _plainconverter.formatlist(data, name, fmt, sep) -return templatekw.hybridlist(data, name=name, fmt=fmt, gen=f) +return templateutil.hybridlist(data, name=name, fmt=fmt, gen=f) class templateformatter(baseformatter): def __init__(self, ui, out, topic, opts): diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py --- a/mercurial/templatefilters.py +++ b/mercurial/templatefilters.py @@ -18,7 +18,6 @@ from . import ( node, pycompat, registrar, -templatekw, templateutil, url, util, @@ -365,7 +364,7 @@ def slashpath(path): @templatefilter('splitlines') def splitlines(text): """Any text. Split text into a list of lines.""" -return templatekw.hybridlist(text.splitlines(), name='line') +return templ
[PATCH 2 of 5] templater: extract template evaluation utility to new module
# HG changeset patch # User Yuya Nishihara # Date 1520516004 -32400 # Thu Mar 08 22:33:24 2018 +0900 # Node ID aac4772ff9b50425be5dd17ede58d2edb2a53699 # Parent 31bdcdeece08af24761fd359f48766c7274cf71a templater: extract template evaluation utility to new module Prepares for splitting template functions to new module. All eval* functions were moved to templateutil.py, and run* functions had to be moved as well due to the dependency from eval*s. eval*s were aliased as they are commonly used in codebase. _getdictitem() had to be made public. diff --git a/mercurial/templater.py b/mercurial/templater.py --- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -9,7 +9,6 @@ from __future__ import absolute_import, import os import re -import types from .i18n import _ from . import ( @@ -27,15 +26,18 @@ from . import ( scmutil, templatefilters, templatekw, +templateutil, util, ) from .utils import dateutil -class ResourceUnavailable(error.Abort): -pass - -class TemplateNotFound(error.Abort): -pass +evalrawexp = templateutil.evalrawexp +evalfuncarg = templateutil.evalfuncarg +evalboolean = templateutil.evalboolean +evalinteger = templateutil.evalinteger +evalstring = templateutil.evalstring +evalstringliteral = templateutil.evalstringliteral +evalastype = templateutil.evalastype # template parsing @@ -361,237 +363,43 @@ def gettemplate(exp, context): return context._load(exp[1]) raise error.ParseError(_("expected template specifier")) -def findsymbolicname(arg): -"""Find symbolic name for the given compiled expression; returns None -if nothing found reliably""" -while True: -func, data = arg -if func is runsymbol: -return data -elif func is runfilter: -arg = data[0] -else: -return None - -def evalrawexp(context, mapping, arg): -"""Evaluate given argument as a bare template object which may require -further processing (such as folding generator of strings)""" -func, data = arg -return func(context, mapping, data) - -def evalfuncarg(context, mapping, arg): -"""Evaluate given argument as value type""" -thing = evalrawexp(context, mapping, arg) -thing = templatekw.unwrapvalue(thing) -# evalrawexp() may return string, generator of strings or arbitrary object -# such as date tuple, but filter does not want generator. -if isinstance(thing, types.GeneratorType): -thing = stringify(thing) -return thing - -def evalboolean(context, mapping, arg): -"""Evaluate given argument as boolean, but also takes boolean literals""" -func, data = arg -if func is runsymbol: -thing = func(context, mapping, data, default=None) -if thing is None: -# not a template keyword, takes as a boolean literal -thing = util.parsebool(data) -else: -thing = func(context, mapping, data) -thing = templatekw.unwrapvalue(thing) -if isinstance(thing, bool): -return thing -# other objects are evaluated as strings, which means 0 is True, but -# empty dict/list should be False as they are expected to be '' -return bool(stringify(thing)) - -def evalinteger(context, mapping, arg, err=None): -v = evalfuncarg(context, mapping, arg) -try: -return int(v) -except (TypeError, ValueError): -raise error.ParseError(err or _('not an integer')) - -def evalstring(context, mapping, arg): -return stringify(evalrawexp(context, mapping, arg)) - -def evalstringliteral(context, mapping, arg): -"""Evaluate given argument as string template, but returns symbol name -if it is unknown""" -func, data = arg -if func is runsymbol: -thing = func(context, mapping, data, default=data) -else: -thing = func(context, mapping, data) -return stringify(thing) - -_evalfuncbytype = { -bool: evalboolean, -bytes: evalstring, -int: evalinteger, -} - -def evalastype(context, mapping, arg, typ): -"""Evaluate given argument and coerce its type""" -try: -f = _evalfuncbytype[typ] -except KeyError: -raise error.ProgrammingError('invalid type specified: %r' % typ) -return f(context, mapping, arg) - -def runinteger(context, mapping, data): -return int(data) - -def runstring(context, mapping, data): -return data - -def _recursivesymbolblocker(key): -def showrecursion(**args): -raise error.Abort(_("recursive reference '%s' in template") % key) -return showrecursion - def _runrecursivesymbol(context, mapping, key): raise error.Abort(_("recursive reference '%s' in template") % key) -def runsymbol(context, mapping, key, default=''): -v = context.symbol(mapping, key) -if v is None: -# put poison to cut recursion. we can't move this to parsing phase -# because "x = {x}" is allowed if "x" is a keyword. (issue4758) -safemapping = mapping.copy()
[PATCH 1 of 5] templater: move function table to the "context" object
# HG changeset patch # User Yuya Nishihara # Date 1520515236 -32400 # Thu Mar 08 22:20:36 2018 +0900 # Node ID 31bdcdeece08af24761fd359f48766c7274cf71a # Parent 168badbb03b574d2a77ae503d3b77709c68e0537 templater: move function table to the "context" object Prepares for splitting template functions from templater.py. diff --git a/mercurial/templater.py b/mercurial/templater.py --- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -493,8 +493,8 @@ def buildfilter(exp, context): filt = context._filters[n] arg = compileexp(exp[1], context, methods) return (runfilter, (arg, filt)) -if n in funcs: -f = funcs[n] +if n in context._funcs: +f = context._funcs[n] args = _buildfuncargs(exp[1], context, methods, n, f._argspec) return (f, args) raise error.ParseError(_("unknown function '%s'") % n) @@ -595,8 +595,8 @@ def runarithmetic(context, mapping, data def buildfunc(exp, context): n = getsymbol(exp[1]) -if n in funcs: -f = funcs[n] +if n in context._funcs: +f = context._funcs[n] args = _buildfuncargs(exp[2], context, exprmethods, n, f._argspec) return (f, args) if n in context._filters: @@ -1376,6 +1376,7 @@ class engine(object): if filters is None: filters = {} self._filters = filters +self._funcs = funcs # make this a parameter if needed if defaults is None: defaults = {} if resources is None: ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 5] templater: move stringify() to templateutil module
# HG changeset patch # User Yuya Nishihara # Date 1520518246 -32400 # Thu Mar 08 23:10:46 2018 +0900 # Node ID dc412296cebd7c33cbae3b7ed5b0974186105387 # Parent aac4772ff9b50425be5dd17ede58d2edb2a53699 templater: move stringify() to templateutil module As we have a util module, it doesn't make sense to import stringify() from templatefilters.py. diff --git a/mercurial/formatter.py b/mercurial/formatter.py --- a/mercurial/formatter.py +++ b/mercurial/formatter.py @@ -124,6 +124,7 @@ from . import ( templatefilters, templatekw, templater, +templateutil, util, ) from .utils import dateutil @@ -403,7 +404,7 @@ class templateformatter(baseformatter): props['revcache'] = {} props = pycompat.strkwargs(props) g = self._t(ref, **props) -self._out.write(templater.stringify(g)) +self._out.write(templateutil.stringify(g)) def end(self): baseformatter.end(self) diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -35,6 +35,7 @@ from .. import ( repoview, templatefilters, templater, +templateutil, ui as uimod, util, wireproto, @@ -418,7 +419,7 @@ class hgweb(object): try: tmpl = rctx.templater(req) ctype = tmpl('mimetype', encoding=encoding.encoding) -ctype = templater.stringify(ctype) +ctype = templateutil.stringify(ctype) # check read permissions non-static content if cmd != 'static': diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py --- a/mercurial/hgweb/hgwebdir_mod.py +++ b/mercurial/hgweb/hgwebdir_mod.py @@ -37,6 +37,7 @@ from .. import ( pycompat, scmutil, templater, +templateutil, ui as uimod, util, ) @@ -239,7 +240,7 @@ class hgwebdir(object): virtual = req.env.get("PATH_INFO", "").strip('/') tmpl = self.templater(req, nonce) ctype = tmpl('mimetype', encoding=encoding.encoding) -ctype = templater.stringify(ctype) +ctype = templateutil.stringify(ctype) # a static file if virtual.startswith('static/') or 'static' in req.form: diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py --- a/mercurial/logcmdutil.py +++ b/mercurial/logcmdutil.py @@ -33,6 +33,7 @@ from . import ( smartset, templatekw, templater, +templateutil, util, ) from .utils import dateutil @@ -449,13 +450,15 @@ class changesettemplater(changesetprinte self._parts.update(m) if self._parts['docheader']: - self.ui.write(templater.stringify(self.t(self._parts['docheader']))) +self.ui.write( +templateutil.stringify(self.t(self._parts['docheader']))) def close(self): if self._parts['docfooter']: if not self.footer: self.footer = "" -self.footer += templater.stringify(self.t(self._parts['docfooter'])) +self.footer += templateutil.stringify( +self.t(self._parts['docfooter'])) return super(changesettemplater, self).close() def _show(self, ctx, copies, props): @@ -470,11 +473,12 @@ class changesettemplater(changesetprinte # since there's inherently a conflict between header (across items) and # separator (per item) if self._parts['separator'] and index > 0: - self.ui.write(templater.stringify(self.t(self._parts['separator']))) +self.ui.write( +templateutil.stringify(self.t(self._parts['separator']))) # write header if self._parts['header']: -h = templater.stringify(self.t(self._parts['header'], **props)) +h = templateutil.stringify(self.t(self._parts['header'], **props)) if self.buffered: self.header[ctx.rev()] = h else: @@ -484,12 +488,12 @@ class changesettemplater(changesetprinte # write changeset metadata, then patch if requested key = self._parts[self._tref] -self.ui.write(templater.stringify(self.t(key, **props))) +self.ui.write(templateutil.stringify(self.t(key, **props))) self._showpatch(ctx) if self._parts['footer']: if not self.footer: -self.footer = templater.stringify( +self.footer = templateutil.stringify( self.t(self._parts['footer'], **props)) def templatespec(tmpl, mapfile): diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py --- a/mercurial/templatefilters.py +++ b/mercurial/templatefilters.py @@ -19,6 +19,7 @@ from . import ( pycompat, registrar, templatekw, +templateutil, url, util, ) @@ -375,18 +376,7 @@ def stringify(thing): """Any type. Turns the value into
[PATCH 8 of 8] py3: drop encoding.strio()
# HG changeset patch # User Yuya Nishihara # Date 1520325797 21600 # Tue Mar 06 02:43:17 2018 -0600 # Node ID 168badbb03b574d2a77ae503d3b77709c68e0537 # Parent 5ee522c20bc23701248014fa18e90f691f00aec8 py3: drop encoding.strio() Its buffered nature makes TextIOWrapper unsuitable for temporarily wrapping bytes I/O. diff --git a/mercurial/encoding.py b/mercurial/encoding.py --- a/mercurial/encoding.py +++ b/mercurial/encoding.py @@ -7,7 +7,6 @@ from __future__ import absolute_import, print_function -import io import locale import os import unicodedata @@ -581,18 +580,3 @@ def fromutf8b(s): c = pycompat.bytechr(ord(c.decode("utf-8", _utf8strict)) & 0xff) r += c return r - -if pycompat.ispy3: -class strio(io.TextIOWrapper): -"""Wrapper around TextIOWrapper that respects hg's encoding assumptions. - -Also works around Python closing streams. -""" - -def __init__(self, buffer): -super(strio, self).__init__(buffer, encoding=_sysstr(encoding)) - -def __del__(self): -"""Override __del__ so it doesn't close the underlying stream.""" -else: -strio = pycompat.identity ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 4 of 8] util: add public isstdin/isstdout() functions
# HG changeset patch # User Yuya Nishihara # Date 1520324939 21600 # Tue Mar 06 02:28:59 2018 -0600 # Node ID 10e3ea3d8b1dc671f6302ebed4489773c7d79458 # Parent c9ac3a3b0a31abc37a76e5ae3be1b5f14a206cf3 util: add public isstdin/isstdout() functions diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -1430,13 +1430,19 @@ def _sethgexecutable(path): global _hgexecutable _hgexecutable = path -def _isstdout(f): +def _testfileno(f, stdf): fileno = getattr(f, 'fileno', None) try: -return fileno and fileno() == sys.__stdout__.fileno() +return fileno and fileno() == stdf.fileno() except io.UnsupportedOperation: return False # fileno() raised UnsupportedOperation +def isstdin(f): +return _testfileno(f, sys.__stdin__) + +def isstdout(f): +return _testfileno(f, sys.__stdout__) + def shellenviron(environ=None): """return environ with optional override, useful for shelling out""" def py2shell(val): @@ -1464,7 +1470,7 @@ def system(cmd, environ=None, cwd=None, pass cmd = quotecommand(cmd) env = shellenviron(environ) -if out is None or _isstdout(out): +if out is None or isstdout(out): rc = subprocess.call(cmd, shell=True, close_fds=closefds, env=env, cwd=cwd) else: ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 8] ui: inline util.bytesinput() into ui._readline()
# HG changeset patch # User Yuya Nishihara # Date 1520324051 21600 # Tue Mar 06 02:14:11 2018 -0600 # Node ID 0fc636a6f20d51e813b9117961ad18f0eb5f83fb # Parent f7d9876d750e048b4c0e0ec0682928e86a8e8ecb ui: inline util.bytesinput() into ui._readline() Prepares for rework of Python 3 support, which is currently broken due to read-ahead buffer of TextIOWrapper. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -1278,7 +1278,13 @@ class ui(object): # prompt ' ' must exist; otherwise readline may delete entire line # - http://bugs.python.org/issue12833 with self.timeblockedsection('stdio'): -line = util.bytesinput(self.fin, self.fout, r' ') +sin, sout = sys.stdin, sys.stdout +try: +sys.stdin = encoding.strio(self.fin) +sys.stdout = encoding.strio(self.fout) +line = encoding.strtolocal(pycompat.rawinput(r' ')) +finally: +sys.stdin, sys.stdout = sin, sout # When stdin is in binary mode on Windows, it can cause # raw_input() to emit an extra trailing carriage return diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -212,14 +212,6 @@ def rapply(f, xs): return xs return _rapply(f, xs) -def bytesinput(fin, fout, *args, **kwargs): -sin, sout = sys.stdin, sys.stdout -try: -sys.stdin, sys.stdout = encoding.strio(fin), encoding.strio(fout) -return encoding.strtolocal(pycompat.rawinput(*args, **kwargs)) -finally: -sys.stdin, sys.stdout = sin, sout - def bitsfrom(container): bits = 0 for bit in container: ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 5 of 8] ui: do not try readline support if fin/fout aren't standard streams
# HG changeset patch # User Yuya Nishihara # Date 1520325146 21600 # Tue Mar 06 02:32:26 2018 -0600 # Node ID 63a13b91e1ab4d9fa0a713935be58794b9cadab5 # Parent 10e3ea3d8b1dc671f6302ebed4489773c7d79458 ui: do not try readline support if fin/fout aren't standard streams It's unlikely for a non-stdio stream to be a tty. Minimizing readline support makes it much simpler to work around the unicode input() function of Python 3. This also works on chg which duplicates client's tty to stdio fds. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -1264,7 +1264,9 @@ class ui(object): return i def _readline(self): -if self._isatty(self.fin): +usereadline = (self._isatty(self.fin) and self._isatty(self.fout) + and util.isstdin(self.fin) and util.isstdout(self.fout)) +if usereadline: try: # magically add command line editing support, where # available @@ -1273,7 +1275,7 @@ class ui(object): readline.read_history_file # windows sometimes raises something other than ImportError except Exception: -pass +usereadline = False # prompt ' ' must exist; otherwise readline may delete entire line # - http://bugs.python.org/issue12833 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 8] ui: add debug commands to test interactive prompt
# HG changeset patch # User Yuya Nishihara # Date 1520327149 21600 # Tue Mar 06 03:05:49 2018 -0600 # Node ID c9ac3a3b0a31abc37a76e5ae3be1b5f14a206cf3 # Parent 0fc636a6f20d51e813b9117961ad18f0eb5f83fb ui: add debug commands to test interactive prompt Interactive operations aren't easily covered by tests. So let's add commands to test them manually. diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -2459,6 +2459,22 @@ def debugtemplate(ui, repo, tmpl, **opts displayer.show(repo[r], **pycompat.strkwargs(props)) displayer.close() +@command('debuguigetpass', [ +('p', 'prompt', '', _('prompt text'), _('TEXT')), +], _('[-p TEXT]'), norepo=True) +def debuguigetpass(ui, prompt=''): +"""show prompt to type password""" +r = ui.getpass(prompt) +ui.write(('respose: %s\n') % r) + +@command('debuguiprompt', [ +('p', 'prompt', '', _('prompt text'), _('TEXT')), +], _('[-p TEXT]'), norepo=True) +def debuguiprompt(ui, prompt=''): +"""show plain prompt""" +r = ui.prompt(prompt) +ui.write(('response: %s\n') % r) + @command('debugupdatecaches', []) def debugupdatecaches(ui, repo, *pats, **opts): """warm all known caches in the repository""" diff --git a/tests/test-completion.t b/tests/test-completion.t --- a/tests/test-completion.t +++ b/tests/test-completion.t @@ -117,6 +117,8 @@ Show debug commands if there are no othe debugsub debugsuccessorssets debugtemplate + debuguigetpass + debuguiprompt debugupdatecaches debugupgraderepo debugwalk @@ -299,6 +301,8 @@ Show all commands + options debugsub: rev debugsuccessorssets: closest debugtemplate: rev, define + debuguigetpass: prompt + debuguiprompt: prompt debugupdatecaches: debugupgraderepo: optimize, run debugwalk: include, exclude diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -976,6 +976,10 @@ Test list of internal help commands show set of successors for revision debugtemplate parse and apply a template + debuguigetpass + show prompt to type password + debuguiprompt + show plain prompt debugupdatecaches warm all known caches in the repository debugupgraderepo ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 8] hgk: stop using util.bytesinput() to read a single line from stdin
# HG changeset patch # User Yuya Nishihara # Date 1520323525 21600 # Tue Mar 06 02:05:25 2018 -0600 # Node ID f7d9876d750e048b4c0e0ec0682928e86a8e8ecb # Parent b434965f984eff168a7caaa239277b15729bd0b1 hgk: stop using util.bytesinput() to read a single line from stdin Appears that the stdio here is an IPC channel between hg and hgk (tk) processes, which shouldn't need a fancy readline support. diff --git a/hgext/hgk.py b/hgext/hgk.py --- a/hgext/hgk.py +++ b/hgext/hgk.py @@ -51,7 +51,6 @@ from mercurial import ( pycompat, registrar, scmutil, -util, ) cmdtable = {} @@ -105,15 +104,15 @@ def difftree(ui, repo, node1=None, node2 while True: if opts[r'stdin']: -try: -line = util.bytesinput(ui.fin, ui.fout).split(' ') -node1 = line[0] -if len(line) > 1: -node2 = line[1] -else: -node2 = None -except EOFError: +line = ui.fin.readline() +if not line: break +line = line.rstrip(pycompat.oslinesep).split(b' ') +node1 = line[0] +if len(line) > 1: +node2 = line[1] +else: +node2 = None node1 = repo.lookup(node1) if node2: node2 = repo.lookup(node2) @@ -186,12 +185,11 @@ def catfile(ui, repo, type=None, r=None, # prefix = "" if opts[r'stdin']: -try: -(type, r) = util.bytesinput(ui.fin, ui.fout).split(' ') -prefix = "" -except EOFError: +line = ui.fin.readline() +if not line: return - +(type, r) = line.rstrip(pycompat.oslinesep).split(b' ') +prefix = "" else: if not type or not r: ui.warn(_("cat-file: type or revision not supplied\n")) @@ -204,10 +202,10 @@ def catfile(ui, repo, type=None, r=None, n = repo.lookup(r) catcommit(ui, repo, n, prefix) if opts[r'stdin']: -try: -(type, r) = util.bytesinput(ui.fin, ui.fout).split(' ') -except EOFError: +line = ui.fin.readline() +if not line: break +(type, r) = line.rstrip(pycompat.oslinesep).split(b' ') else: break ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 7 of 8] ui: adjust Windows workaround to new _readline() code
# HG changeset patch # User Yuya Nishihara # Date 1520325757 21600 # Tue Mar 06 02:42:37 2018 -0600 # Node ID 5ee522c20bc23701248014fa18e90f691f00aec8 # Parent ad7ff97565b261d82952acc9f941e5dd99f11374 ui: adjust Windows workaround to new _readline() code It's only needed when rawinput() is called. Also made it Py3 compatible. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -1286,6 +1286,10 @@ class ui(object): with self.timeblockedsection('stdio'): if usereadline: line = encoding.strtolocal(pycompat.rawinput(r' ')) +# When stdin is in binary mode on Windows, it can cause +# raw_input() to emit an extra trailing carriage return +if pycompat.oslinesep == b'\r\n' and line.endswith(b'\r'): +line = line[:-1] else: self.fout.write(b' ') self.fout.flush() @@ -1295,10 +1299,6 @@ class ui(object): if line.endswith(pycompat.oslinesep): line = line[:-len(pycompat.oslinesep)] -# When stdin is in binary mode on Windows, it can cause -# raw_input() to emit an extra trailing carriage return -if pycompat.oslinesep == '\r\n' and line and line[-1] == '\r': -line = line[:-1] return line def prompt(self, msg, default="y"): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 6 of 8] ui: do not use rawinput() when we have to replace sys.stdin/stdout
# HG changeset patch # User Yuya Nishihara # Date 1520325533 21600 # Tue Mar 06 02:38:53 2018 -0600 # Node ID ad7ff97565b261d82952acc9f941e5dd99f11374 # Parent 63a13b91e1ab4d9fa0a713935be58794b9cadab5 ui: do not use rawinput() when we have to replace sys.stdin/stdout See the inline comment for why. The current Python3 hack doesn't work if more than one user inputs are expected because TextIOWrapper fills its internal buffer at the first read() request. Maybe we could write an unbuffered TextIOWrapper, but I don't want to make things more complicated. Instead, this patch reinvents raw_input(' ') of no readline support. diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -3,6 +3,7 @@ test-add.t test-addremove-similar.t test-addremove.t test-amend-subrepo.t +test-amend.t test-ancestor.py test-annotate.py test-annotate.t @@ -185,6 +186,8 @@ test-journal-exists.t test-largefiles-cache.t test-largefiles-misc.t test-largefiles-small-disk.t +test-largefiles-update.t +test-lfs-largefiles.t test-locate.t test-lock-badness.t test-log.t @@ -196,11 +199,13 @@ test-manifest.py test-manifest.t test-match.py test-mdiff.py +test-merge-changedelete.t test-merge-closedheads.t test-merge-commit.t test-merge-criss-cross.t test-merge-default.t test-merge-force.t +test-merge-halt.t test-merge-internal-tools-pattern.t test-merge-local.t test-merge-remove.t @@ -228,11 +233,13 @@ test-mq-qgoto.t test-mq-qimport-fail-cleanup.t test-mq-qpush-exact.t test-mq-qqueue.t +test-mq-qrefresh-interactive.t test-mq-qrefresh-replace-log-message.t test-mq-qrefresh.t test-mq-qrename.t test-mq-qsave.t test-mq-safety.t +test-mq-subrepo.t test-mq-symlinks.t test-mv-cp-st-diff.t test-narrow-archive.t diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -1264,6 +1264,10 @@ class ui(object): return i def _readline(self): +# Replacing stdin/stdout temporarily is a hard problem on Python 3 +# because they have to be text streams with *no buffering*. Instead, +# we use rawinput() only if call_readline() will be invoked by +# PyOS_Readline(), so no I/O will be made at Python layer. usereadline = (self._isatty(self.fin) and self._isatty(self.fout) and util.isstdin(self.fin) and util.isstdout(self.fout)) if usereadline: @@ -1280,13 +1284,16 @@ class ui(object): # prompt ' ' must exist; otherwise readline may delete entire line # - http://bugs.python.org/issue12833 with self.timeblockedsection('stdio'): -sin, sout = sys.stdin, sys.stdout -try: -sys.stdin = encoding.strio(self.fin) -sys.stdout = encoding.strio(self.fout) +if usereadline: line = encoding.strtolocal(pycompat.rawinput(r' ')) -finally: -sys.stdin, sys.stdout = sin, sout +else: +self.fout.write(b' ') +self.fout.flush() +line = self.fin.readline() +if not line: +raise EOFError +if line.endswith(pycompat.oslinesep): +line = line[:-len(pycompat.oslinesep)] # When stdin is in binary mode on Windows, it can cause # raw_input() to emit an extra trailing carriage return ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2057: rust implementation of hg status
yuja added a comment. >> Reading that page it seems to claim that filenames should be utf8, not bytes. If utf8, this is what the code does, but if it is bytes that definitely won't work. > > IIRC it's bytes everyplace except Windows, where we pretend utf8 is real? It's MBCS (i.e. ANSI multi-byte characters) on Windows. The plain was to support both MBCS and UTF-8-variant on Windows, but that isn't a thing yet. Perhaps we'll have to write a platform compatibility layer (or serialization/deserialization layer) on top of the Rust's file API, something like vfs.py we have in Python code. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2057 To: Ivzhh, #hg-reviewers, kevincox Cc: yuja, glandium, krbullock, indygreg, durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2639: thirdparty: start vendoring cbor python library
pulkit added a comment. The library imported in this patch has known bugs and can result in segfaults when given nested structures. Also this library is unmaintained and does not supports sets. Therefore, we import a better maintained library which handles all the cases pretty well. This is superseded by https://phab.mercurial-scm.org/D2750. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2639 To: pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2590: cbor: add a __init__.py to top level cbor module
pulkit abandoned this revision. pulkit added a comment. Superseded by https://phab.mercurial-scm.org/D2752. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2590 To: pulkit, #hg-reviewers Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2640: cbor: remove tests files and fix core's test-check*
pulkit abandoned this revision. pulkit added a comment. Superseded by https://phab.mercurial-scm.org/D2751. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2640 To: pulkit, #hg-reviewers Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2594: graft: move logic to read current graft state file in state.py
pulkit updated this revision to Diff 6760. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D2594?vs=6619&id=6760 REVISION DETAIL https://phab.mercurial-scm.org/D2594 AFFECTED FILES mercurial/commands.py mercurial/state.py CHANGE DETAILS diff --git a/mercurial/state.py b/mercurial/state.py --- a/mercurial/state.py +++ b/mercurial/state.py @@ -113,3 +113,8 @@ oldstatefilefns[path] = func return func return dec + +@readoldstatefile('graftstate') +def oldgraftstate(fp): +nodes = fp.read().splitlines() +return {'nodes': nodes} diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -54,6 +54,7 @@ rewriteutil, scmutil, server, +state as statemod, streamclone, tags as tagsmod, templatekw, @@ -2174,7 +2175,9 @@ raise error.Abort(_("can't specify --continue and revisions")) # read in unfinished revisions try: -nodes = repo.vfs.read('graftstate').splitlines() +with repo.vfs('graftstate', 'rb') as fp: +stateopts = statemod.oldgraftstate(fp) +nodes = stateopts['nodes'] revs = [repo[node].rev() for node in nodes] except IOError as inst: if inst.errno != errno.ENOENT: To: pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2595: graft: start using the new state file
pulkit updated this revision to Diff 6761. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D2595?vs=6620&id=6761 REVISION DETAIL https://phab.mercurial-scm.org/D2595 AFFECTED FILES mercurial/commands.py CHANGE DETAILS diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -2169,19 +2169,17 @@ **pycompat.strkwargs(opts)) cont = False +cmdstate = statemod.cmdstate(repo, 'graftstate') if opts.get('continue'): cont = True if revs: raise error.Abort(_("can't specify --continue and revisions")) # read in unfinished revisions -try: -with repo.vfs('graftstate', 'rb') as fp: -stateopts = statemod.oldgraftstate(fp) -nodes = stateopts['nodes'] +if cmdstate: +cmdstate.load() +nodes = cmdstate['nodes'] revs = [repo[node].rev() for node in nodes] -except IOError as inst: -if inst.errno != errno.ENOENT: -raise +else: cmdutil.wrongtooltocontinue(repo, _('graft')) else: cmdutil.checkunfinished(repo) @@ -2306,8 +2304,9 @@ # report any conflicts if stats and stats[3] > 0: # write out state for --continue -nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]] -repo.vfs.write('graftstate', ''.join(nodelines)) +nodelines = [repo[rev].hex() for rev in revs[pos:]] +cmdstate.addopts({'nodes': nodelines}) +cmdstate.save() extra = '' if opts.get('user'): extra += ' --user %s' % util.shellquote(opts['user']) To: pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2750: thirdparty: start vendoring cbor python library
pulkit created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY CBOR stands for Concise Binary Object Representation, which is a data format which is very compact and extensible. This patch moves the python library which can serilaize and deserialize python objects to/from cbor formats. The library is taken from https://github.com/agronholm/cbor2/ from changeset 6dad14d08b841dbbacefa08f4b3505d68072b753. There is another python library for cbor at https://github.com/brianolson/cbor_py/ which is used in evolve extension and was imported in initial version of this series. That library though contains C code and is bit faster, but has known bugs around serializing nested structures, is unmaintained, raises an Exception object instead of a more dedicated Error type. So, it's better to use a bug free and actively maintained library. This library is not yet used and will be used in later commits. 1. no-check-commit because we are importing a third library module REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2750 AFFECTED FILES mercurial/thirdparty/cbor/.travis.yml mercurial/thirdparty/cbor/LICENSE.txt mercurial/thirdparty/cbor/README.rst mercurial/thirdparty/cbor/cbor2/__init__.py mercurial/thirdparty/cbor/cbor2/compat.py mercurial/thirdparty/cbor/cbor2/decoder.py mercurial/thirdparty/cbor/cbor2/encoder.py mercurial/thirdparty/cbor/cbor2/types.py mercurial/thirdparty/cbor/docs/conf.py mercurial/thirdparty/cbor/docs/customizing.rst mercurial/thirdparty/cbor/docs/index.rst mercurial/thirdparty/cbor/docs/modules/decoder.rst mercurial/thirdparty/cbor/docs/modules/encoder.rst mercurial/thirdparty/cbor/docs/modules/types.rst mercurial/thirdparty/cbor/docs/usage.rst mercurial/thirdparty/cbor/docs/versionhistory.rst mercurial/thirdparty/cbor/setup.cfg mercurial/thirdparty/cbor/setup.py mercurial/thirdparty/cbor/tests/test_decoder.py mercurial/thirdparty/cbor/tests/test_encoder.py mercurial/thirdparty/cbor/tests/test_types.py mercurial/thirdparty/cbor/tox.ini CHANGE DETAILS diff --git a/mercurial/thirdparty/cbor/tox.ini b/mercurial/thirdparty/cbor/tox.ini new file mode 100644 --- /dev/null +++ b/mercurial/thirdparty/cbor/tox.ini @@ -0,0 +1,12 @@ +[tox] +envlist = py27, py33, py34, py35, py36, pypy, pypy3, flake8 +skip_missing_interpreters = true + +[testenv] +commands = python -m pytest {posargs} +extras = test + +[testenv:flake8] +deps = flake8 +commands = flake8 cbor2 tests +skip_install = true diff --git a/mercurial/thirdparty/cbor/tests/test_types.py b/mercurial/thirdparty/cbor/tests/test_types.py new file mode 100644 --- /dev/null +++ b/mercurial/thirdparty/cbor/tests/test_types.py @@ -0,0 +1,36 @@ +import pytest + +from cbor2.types import CBORTag, CBORSimpleValue + + +def test_tag_repr(): +assert repr(CBORTag(600, 'blah')) == "CBORTag(600, 'blah')" + + +def test_tag_equals(): +tag1 = CBORTag(500, ['foo']) +tag2 = CBORTag(500, ['foo']) +tag3 = CBORTag(500, ['bar']) +assert tag1 == tag2 +assert not tag1 == tag3 +assert not tag1 == 500 + + +def test_simple_value_repr(): +assert repr(CBORSimpleValue(1)) == "CBORSimpleValue(1)" + + +def test_simple_value_equals(): +tag1 = CBORSimpleValue(1) +tag2 = CBORSimpleValue(1) +tag3 = CBORSimpleValue(21) +assert tag1 == tag2 +assert tag1 == 1 +assert not tag1 == tag3 +assert not tag1 == 21 +assert not tag2 == "21" + + +def test_simple_value_too_big(): +exc = pytest.raises(TypeError, CBORSimpleValue, 256) +assert str(exc.value) == 'simple value too big' diff --git a/mercurial/thirdparty/cbor/tests/test_encoder.py b/mercurial/thirdparty/cbor/tests/test_encoder.py new file mode 100644 --- /dev/null +++ b/mercurial/thirdparty/cbor/tests/test_encoder.py @@ -0,0 +1,318 @@ +import re +from binascii import unhexlify +from collections import OrderedDict +from datetime import datetime, timedelta, date +from decimal import Decimal +from email.mime.text import MIMEText +from fractions import Fraction +from uuid import UUID + +import pytest + +from cbor2.compat import timezone +from cbor2.encoder import dumps, CBOREncodeError, dump, shareable_encoder +from cbor2.types import CBORTag, undefined, CBORSimpleValue + + +@pytest.mark.parametrize('value, expected', [ +(0, '00'), +(1, '01'), +(10, '0a'), +(23, '17'), +(24, '1818'), +(100, '1864'), +(1000, '1903e8'), +(100, '1a000f4240'), +(1, '1b00e8d4a51000'), +(18446744073709551615, '1b'), +(18446744073709551616, 'c24901'), +(-18446744073709551616, '3b'), +(-18446744073709551617, 'c34901'), +(-1, '20'), +(-10, '29'), +(-100, '3863'), +(-1000, '3903e7') +]) +def test_integer(value, expected): +expected = unhexlify(expected) +asser
D2751: cbor: remove unrequired files and fix core test-check*
pulkit created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This patch removes the unrequired files from the cbor library which are docs/, tests/, setup.py, setup.cfg, tox.ini. Also, this patch fixes couple of test-check* tests by making sure they skip testing the third party library cbor. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2751 AFFECTED FILES mercurial/thirdparty/cbor/docs/conf.py mercurial/thirdparty/cbor/docs/customizing.rst mercurial/thirdparty/cbor/docs/index.rst mercurial/thirdparty/cbor/docs/modules/decoder.rst mercurial/thirdparty/cbor/docs/modules/encoder.rst mercurial/thirdparty/cbor/docs/modules/types.rst mercurial/thirdparty/cbor/docs/usage.rst mercurial/thirdparty/cbor/docs/versionhistory.rst mercurial/thirdparty/cbor/setup.cfg mercurial/thirdparty/cbor/setup.py mercurial/thirdparty/cbor/tests/test_decoder.py mercurial/thirdparty/cbor/tests/test_encoder.py mercurial/thirdparty/cbor/tests/test_types.py mercurial/thirdparty/cbor/tox.ini tests/test-check-py3-compat.t tests/test-check-pyflakes.t CHANGE DETAILS diff --git a/tests/test-check-pyflakes.t b/tests/test-check-pyflakes.t --- a/tests/test-check-pyflakes.t +++ b/tests/test-check-pyflakes.t @@ -16,6 +16,7 @@ $ testrepohg locate 'set:**.py or grep("^#!.*python")' \ > -X hgext/fsmonitor/pywatchman \ > -X mercurial/pycompat.py -X contrib/python-zstandard \ + > -X mercurial/thirdparty/cbor \ > 2>/dev/null \ > | xargs pyflakes 2>/dev/null | "$TESTDIR/filterpyflakes.py" diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t --- a/tests/test-check-py3-compat.t +++ b/tests/test-check-py3-compat.t @@ -5,6 +5,7 @@ $ testrepohg files 'set:(**.py)' \ > -X hgdemandimport/demandimportpy2.py \ + > -X mercurial/thirdparty/cbor \ > | sed 's|\\|/|g' | xargs $PYTHON contrib/check-py3-compat.py contrib/python-zstandard/setup.py not using absolute_import contrib/python-zstandard/setup_zstd.py not using absolute_import diff --git a/mercurial/thirdparty/cbor/tox.ini b/mercurial/thirdparty/cbor/tox.ini deleted file mode 100644 --- a/mercurial/thirdparty/cbor/tox.ini +++ /dev/null @@ -1,12 +0,0 @@ -[tox] -envlist = py27, py33, py34, py35, py36, pypy, pypy3, flake8 -skip_missing_interpreters = true - -[testenv] -commands = python -m pytest {posargs} -extras = test - -[testenv:flake8] -deps = flake8 -commands = flake8 cbor2 tests -skip_install = true diff --git a/mercurial/thirdparty/cbor/tests/test_types.py b/mercurial/thirdparty/cbor/tests/test_types.py deleted file mode 100644 --- a/mercurial/thirdparty/cbor/tests/test_types.py +++ /dev/null @@ -1,36 +0,0 @@ -import pytest - -from cbor2.types import CBORTag, CBORSimpleValue - - -def test_tag_repr(): -assert repr(CBORTag(600, 'blah')) == "CBORTag(600, 'blah')" - - -def test_tag_equals(): -tag1 = CBORTag(500, ['foo']) -tag2 = CBORTag(500, ['foo']) -tag3 = CBORTag(500, ['bar']) -assert tag1 == tag2 -assert not tag1 == tag3 -assert not tag1 == 500 - - -def test_simple_value_repr(): -assert repr(CBORSimpleValue(1)) == "CBORSimpleValue(1)" - - -def test_simple_value_equals(): -tag1 = CBORSimpleValue(1) -tag2 = CBORSimpleValue(1) -tag3 = CBORSimpleValue(21) -assert tag1 == tag2 -assert tag1 == 1 -assert not tag1 == tag3 -assert not tag1 == 21 -assert not tag2 == "21" - - -def test_simple_value_too_big(): -exc = pytest.raises(TypeError, CBORSimpleValue, 256) -assert str(exc.value) == 'simple value too big' diff --git a/mercurial/thirdparty/cbor/tests/test_encoder.py b/mercurial/thirdparty/cbor/tests/test_encoder.py deleted file mode 100644 --- a/mercurial/thirdparty/cbor/tests/test_encoder.py +++ /dev/null @@ -1,318 +0,0 @@ -import re -from binascii import unhexlify -from collections import OrderedDict -from datetime import datetime, timedelta, date -from decimal import Decimal -from email.mime.text import MIMEText -from fractions import Fraction -from uuid import UUID - -import pytest - -from cbor2.compat import timezone -from cbor2.encoder import dumps, CBOREncodeError, dump, shareable_encoder -from cbor2.types import CBORTag, undefined, CBORSimpleValue - - -@pytest.mark.parametrize('value, expected', [ -(0, '00'), -(1, '01'), -(10, '0a'), -(23, '17'), -(24, '1818'), -(100, '1864'), -(1000, '1903e8'), -(100, '1a000f4240'), -(1, '1b00e8d4a51000'), -(18446744073709551615, '1b'), -(18446744073709551616, 'c24901'), -(-18446744073709551616, '3b'), -(-18446744073709551617, 'c34901'), -(-1, '20'), -(-10, '29'), -(-100, '3863'), -(-1000, '3903e7') -]) -def test_integer(value, expected): -expected = unhexlify(expected) -assert dumps(value) == expected - - -@pytest.mark.parametrize('va
D2752: cbor: add a __init__.py to top level cbor module
pulkit created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This patch also fixes import in cbor2/ to make them relative. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2752 AFFECTED FILES mercurial/thirdparty/cbor/__init__.py mercurial/thirdparty/cbor/cbor2/__init__.py mercurial/thirdparty/cbor/cbor2/decoder.py mercurial/thirdparty/cbor/cbor2/encoder.py CHANGE DETAILS diff --git a/mercurial/thirdparty/cbor/cbor2/encoder.py b/mercurial/thirdparty/cbor/cbor2/encoder.py --- a/mercurial/thirdparty/cbor/cbor2/encoder.py +++ b/mercurial/thirdparty/cbor/cbor2/encoder.py @@ -6,9 +6,9 @@ from datetime import datetime, date, time from io import BytesIO -from cbor2.compat import iteritems, timezone, long, unicode, as_unicode, bytes_from_list -from cbor2.compat import pack_float16, unpack_float16 -from cbor2.types import CBORTag, undefined, CBORSimpleValue +from .compat import iteritems, timezone, long, unicode, as_unicode, bytes_from_list +from .compat import pack_float16, unpack_float16 +from .types import CBORTag, undefined, CBORSimpleValue class CBOREncodeError(Exception): diff --git a/mercurial/thirdparty/cbor/cbor2/decoder.py b/mercurial/thirdparty/cbor/cbor2/decoder.py --- a/mercurial/thirdparty/cbor/cbor2/decoder.py +++ b/mercurial/thirdparty/cbor/cbor2/decoder.py @@ -3,8 +3,8 @@ from datetime import datetime, timedelta from io import BytesIO -from cbor2.compat import timezone, xrange, byte_as_integer, unpack_float16 -from cbor2.types import CBORTag, undefined, break_marker, CBORSimpleValue +from .compat import timezone, xrange, byte_as_integer, unpack_float16 +from .types import CBORTag, undefined, break_marker, CBORSimpleValue timestamp_re = re.compile(r'^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)' r'(?:\.(\d+))?(?:Z|([+-]\d\d):(\d\d))$') diff --git a/mercurial/thirdparty/cbor/cbor2/__init__.py b/mercurial/thirdparty/cbor/cbor2/__init__.py --- a/mercurial/thirdparty/cbor/cbor2/__init__.py +++ b/mercurial/thirdparty/cbor/cbor2/__init__.py @@ -1,3 +1,3 @@ -from cbor2.decoder import load, loads, CBORDecoder, CBORDecodeError # noqa -from cbor2.encoder import dump, dumps, CBOREncoder, CBOREncodeError, shareable_encoder # noqa -from cbor2.types import CBORTag, CBORSimpleValue, undefined # noqa +from .decoder import load, loads, CBORDecoder, CBORDecodeError # noqa +from .encoder import dump, dumps, CBOREncoder, CBOREncodeError, shareable_encoder # noqa +from .types import CBORTag, CBORSimpleValue, undefined # noqa diff --git a/mercurial/thirdparty/cbor/__init__.py b/mercurial/thirdparty/cbor/__init__.py new file mode 100644 --- /dev/null +++ b/mercurial/thirdparty/cbor/__init__.py @@ -0,0 +1 @@ +from cbor2 import load, dump, CBORDecodeError, CBOREncodeError To: pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2593: state: add logic to parse the state file in old way if cbor fails
pulkit updated this revision to Diff 6759. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D2593?vs=6618&id=6759 REVISION DETAIL https://phab.mercurial-scm.org/D2593 AFFECTED FILES mercurial/state.py CHANGE DETAILS diff --git a/mercurial/state.py b/mercurial/state.py --- a/mercurial/state.py +++ b/mercurial/state.py @@ -77,8 +77,16 @@ def _read(self): """reads the evolvestate file and returns a dictionary which contain data in the same format as it was before storing""" -with self._repo.vfs(self.fname, 'rb') as fp: -return cbor.load(fp) +try: +with self._repo.vfs(self.fname, 'rb') as fp: +ret = cbor.load(fp) +if not isinstance(ret, dict): +raise cbor.CBORDecodeError +return ret +except cbor.CBORDecodeError: # cbor raises an Exception +with self._repo.vfs(self.fname, 'rb') as fp: +oldfn = oldstatefilefns[self.fname] +return oldfn(fp) def delete(self): """drop the evolvestate file if exists""" To: pulkit, #hg-reviewers Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel