D3396: wireproto: move command registration types to wireprototypes
This revision was automatically updated to reflect the committed changes. Closed by commit rHG352932a11905: wireproto: move command registration types to wireprototypes (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3396?vs=8367&id=8385 REVISION DETAIL https://phab.mercurial-scm.org/D3396 AFFECTED FILES mercurial/wireproto.py mercurial/wireprototypes.py mercurial/wireprotov2server.py CHANGE DETAILS diff --git a/mercurial/wireprotov2server.py b/mercurial/wireprotov2server.py --- a/mercurial/wireprotov2server.py +++ b/mercurial/wireprotov2server.py @@ -438,7 +438,7 @@ raise error.ProgrammingError('%s command already registered ' 'for version 2' % name) -wireproto.commandsv2[name] = wireproto.commandentry( +wireproto.commandsv2[name] = wireprototypes.commandentry( func, args=args, transports=transports, permission=permission) return func diff --git a/mercurial/wireprototypes.py b/mercurial/wireprototypes.py --- a/mercurial/wireprototypes.py +++ b/mercurial/wireprototypes.py @@ -241,3 +241,81 @@ doesn't have that permission, the exception should raise or abort in a protocol specific manner. """ + +class commandentry(object): +"""Represents a declared wire protocol command.""" +def __init__(self, func, args='', transports=None, + permission='push'): +self.func = func +self.args = args +self.transports = transports or set() +self.permission = permission + +def _merge(self, func, args): +"""Merge this instance with an incoming 2-tuple. + +This is called when a caller using the old 2-tuple API attempts +to replace an instance. The incoming values are merged with +data not captured by the 2-tuple and a new instance containing +the union of the two objects is returned. +""" +return commandentry(func, args=args, transports=set(self.transports), +permission=self.permission) + +# Old code treats instances as 2-tuples. So expose that interface. +def __iter__(self): +yield self.func +yield self.args + +def __getitem__(self, i): +if i == 0: +return self.func +elif i == 1: +return self.args +else: +raise IndexError('can only access elements 0 and 1') + +class commanddict(dict): +"""Container for registered wire protocol commands. + +It behaves like a dict. But __setitem__ is overwritten to allow silent +coercion of values from 2-tuples for API compatibility. +""" +def __setitem__(self, k, v): +if isinstance(v, commandentry): +pass +# Cast 2-tuples to commandentry instances. +elif isinstance(v, tuple): +if len(v) != 2: +raise ValueError('command tuples must have exactly 2 elements') + +# It is common for extensions to wrap wire protocol commands via +# e.g. ``wireproto.commands[x] = (newfn, args)``. Because callers +# doing this aren't aware of the new API that uses objects to store +# command entries, we automatically merge old state with new. +if k in self: +v = self[k]._merge(v[0], v[1]) +else: +# Use default values from @wireprotocommand. +v = commandentry(v[0], args=v[1], + transports=set(TRANSPORTS), + permission='push') +else: +raise ValueError('command entries must be commandentry instances ' + 'or 2-tuples') + +return super(commanddict, self).__setitem__(k, v) + +def commandavailable(self, command, proto): +"""Determine if a command is available for the requested protocol.""" +assert proto.name in TRANSPORTS + +entry = self.get(command) + +if not entry: +return False + +if proto.name not in entry.transports: +return False + +return True diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -173,89 +173,11 @@ return compengines -class commandentry(object): -"""Represents a declared wire protocol command.""" -def __init__(self, func, args='', transports=None, - permission='push'): -self.func = func -self.args = args -self.transports = transports or set() -self.permission = permission - -def _merge(self, func, args): -"""Merge this instance with an incoming 2-tuple. - -This is called when a caller using the old 2-tuple API attempts -to replace an instance. The incoming values are merged with -data not captured by the 2
D3396: wireproto: move command registration types to wireprototypes
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY These are shared across wire protocol implementations. wireprototypes is our module for common code. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3396 AFFECTED FILES mercurial/wireproto.py mercurial/wireprototypes.py mercurial/wireprotov2server.py CHANGE DETAILS diff --git a/mercurial/wireprotov2server.py b/mercurial/wireprotov2server.py --- a/mercurial/wireprotov2server.py +++ b/mercurial/wireprotov2server.py @@ -438,7 +438,7 @@ raise error.ProgrammingError('%s command already registered ' 'for version 2' % name) -wireproto.commandsv2[name] = wireproto.commandentry( +wireproto.commandsv2[name] = wireprototypes.commandentry( func, args=args, transports=transports, permission=permission) return func diff --git a/mercurial/wireprototypes.py b/mercurial/wireprototypes.py --- a/mercurial/wireprototypes.py +++ b/mercurial/wireprototypes.py @@ -241,3 +241,81 @@ doesn't have that permission, the exception should raise or abort in a protocol specific manner. """ + +class commandentry(object): +"""Represents a declared wire protocol command.""" +def __init__(self, func, args='', transports=None, + permission='push'): +self.func = func +self.args = args +self.transports = transports or set() +self.permission = permission + +def _merge(self, func, args): +"""Merge this instance with an incoming 2-tuple. + +This is called when a caller using the old 2-tuple API attempts +to replace an instance. The incoming values are merged with +data not captured by the 2-tuple and a new instance containing +the union of the two objects is returned. +""" +return commandentry(func, args=args, transports=set(self.transports), +permission=self.permission) + +# Old code treats instances as 2-tuples. So expose that interface. +def __iter__(self): +yield self.func +yield self.args + +def __getitem__(self, i): +if i == 0: +return self.func +elif i == 1: +return self.args +else: +raise IndexError('can only access elements 0 and 1') + +class commanddict(dict): +"""Container for registered wire protocol commands. + +It behaves like a dict. But __setitem__ is overwritten to allow silent +coercion of values from 2-tuples for API compatibility. +""" +def __setitem__(self, k, v): +if isinstance(v, commandentry): +pass +# Cast 2-tuples to commandentry instances. +elif isinstance(v, tuple): +if len(v) != 2: +raise ValueError('command tuples must have exactly 2 elements') + +# It is common for extensions to wrap wire protocol commands via +# e.g. ``wireproto.commands[x] = (newfn, args)``. Because callers +# doing this aren't aware of the new API that uses objects to store +# command entries, we automatically merge old state with new. +if k in self: +v = self[k]._merge(v[0], v[1]) +else: +# Use default values from @wireprotocommand. +v = commandentry(v[0], args=v[1], + transports=set(TRANSPORTS), + permission='push') +else: +raise ValueError('command entries must be commandentry instances ' + 'or 2-tuples') + +return super(commanddict, self).__setitem__(k, v) + +def commandavailable(self, command, proto): +"""Determine if a command is available for the requested protocol.""" +assert proto.name in TRANSPORTS + +entry = self.get(command) + +if not entry: +return False + +if proto.name not in entry.transports: +return False + +return True diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -173,89 +173,11 @@ return compengines -class commandentry(object): -"""Represents a declared wire protocol command.""" -def __init__(self, func, args='', transports=None, - permission='push'): -self.func = func -self.args = args -self.transports = transports or set() -self.permission = permission - -def _merge(self, func, args): -"""Merge this instance with an incoming 2-tuple. - -This is called when a caller using the old 2-tuple API attempts -to replace an instance. The incoming values are merged with -data not captured by the 2-tuple and a new instance containing -the uni