On Thu, Mar 01, 2012 at 04:30:38PM -0800, Ethan Jackson wrote: > Many of the currently implemented Python daemons, and likely many > daemons to be implemented in the future, could benefit from unixctl > support even if only to implement "exit" and "version" commands. > This patch implements unixctl in Python. > > Signed-off-by: Ethan Jackson <et...@nicira.com>
I noticed that there's some code that insists on "string" objects in various places, which makes me a little nervous because "string" and "unicode" objects in Python seem almost interchangeable but they are not the same and a test for one will not accept the other. There's a lot of "if type(json) in [str, unicode]" type code in the OVS python directory for that reason. > +class _UnixctlCommand(object): > + def __init__(self, usage, min_args, max_args, callback, aux): > + self.usage = usage > + self.min_args = min_args > + self.max_args = max_args > + self.callback = callback > + self.aux = aux > + > + > +def _unixctl_help(conn, unused_argv, unused_aux): > + assert isinstance(conn, UnixctlConnection) > + reply = "The available commands are:\n" > + command_names = sorted(commands.keys()) > + for name in command_names: > + reply += " " > + usage = commands[name].usage > + if usage: > + reply += "%-23s %s" % (name, usage) > + else: > + reply += name > + reply += "\n" > + conn.reply(reply) I keep hearing that string concatenation in Python is really slow. How about this (untested): class _UnixctlCommand(object): def __init__(self, usage, min_args, max_args, callback, aux): self.usage = usage self.min_args = min_args self.max_args = max_args self.callback = callback self.aux = aux def help(self): if self.usage: return "%-23 %s" % (self.name, self.usage) else: return self.name def _unixctl_help(conn, unused_argv, unused_aux): assert isinstance(conn, UnixctlConnection) conn.reply("The available commands are:\n" + ''.join([" %s\n" % commands[name].help() for name in sorted(commands.keys())])) > +def socket_name_from_target(target): > + assert isinstance(target, string) > + > + if target[0] == "/": > + return 0, target ""[0] yields IndexError. Would target.startswith("/") be safer? In UnixctlConnection._reply_impl(), I think that "if not body.endswith('\n')" would be more straightforward: > + if len(body) and body[-1] != '\n': > + body += "\n" I don't quite understand the code below, in UnixctlConnection._process_command(). First we check that all of the arguments are "string" objects, then we convert them to strings with "str"? > + for param in params: > + if not isinstance(param, string): > + error = '"%s" command has non-string argument' % method > + break > + > + if error is None: > + str_params = [str(p) for p in params] > + command.callback(self, str_params, command.aux) > + > + if error: > + self.reply_error(error) > + > + [...] Is it OK to remove elements from a list you're iterating? (I doubt it.) > + for conn in self._conns: > + error = conn.run() > + if error and error != errno.EAGAIN: > + conn._close() > + self._conns.remove(conn) Otherwise this looks good to me. Thank you for doing this work! _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev