On Wed, Nov 6, 2019, 11:50 PM Mark Michelson <[email protected]> wrote:
> Acked-by: Mark Michelson <[email protected]> > Thanks for the review. Looks like the patch failed in CI. Below changes in Makefile.am fixed it. I applied this patch to master with the below additional changes. Thanks Numan diff --git a/Makefile.am b/Makefile.am index 88ede2d82..1e41e49ea 100644 --- a/Makefile.am +++ b/Makefile.am ALL_LOCAL = @@ -165,7 +165,7 @@ ro_shell = printf '\043 Generated automatically -- do not modify! -*- buffer- SUFFIXES += .in .in: - $(AM_V_GEN)PYTHONPATH=$$PYTHONPATH$(psep)$(srcdir)/python $(PYTHON) $(srcdir)/build-aux/soexpand.py -I$(srcdir) -I$(OVS_SRCDIR) < $< | \ + $(AM_V_GEN)PYTHONPATH=$(OVS_SRCDIR)/python$(psep)$$PYTHONPATH$(psep)$(srcdir)/python $(PYTHON) $(srcdir)/build-aux/soexpand.py -I$(srcdir) -I$(OVS_SRCDIR) < $< | \ $(PYTHON) $(srcdir)/build-aux/dpdkstrip.py $(DPDKSTRIP_FLAGS) | \ sed \ -e 's,[@]PKIDIR[@],$(PKIDIR),g' \ @@ -424,8 +424,8 @@ endif CLEANFILES += flake8-check include $(srcdir)/manpages.mk -$(srcdir)/manpages.mk: $(MAN_ROOTS) build-aux/sodepends.py python/build/soutil.py - @PYTHONPATH=$$PYTHONPATH$(psep)$(srcdir)/python $(PYTHON) $(srcdir)/build-aux/sodepends.py -I. -I$(srcdir) -I$(OVS_MANDIR) $(MAN_ROOTS) >$(@F).tmp +$(srcdir)/manpages.mk: $(MAN_ROOTS) build-aux/sodepends.py $(OVS_SRCDIR)/python/build/soutil.py + @PYTHONPATH=$(OVS_SRCDIR)/python$(psep)$$PYTHONPATH$(psep)$(srcdir)/python $(PYTHON) $(srcdir)/build-aux/sodepends.py -I. -I$(srcdir) -I$(OVS_MANDIR) $(MAN_ROOTS) >$(@F).tmp @if cmp -s $(@F).tmp $@; then \ touch $@; \ rm -f $(@F).tmp; \ > On 11/6/19 6:52 AM, [email protected] wrote: > > From: Numan Siddique <[email protected]> > > > > The python/ directory belongs to Open vSwitch repo. > > This patch uses the python utils required for building OVN from > > the configured OVS source directory and deletes the python directory. > > > > Signed-off-by: Numan Siddique <[email protected]> > > --- > > Makefile.am | 5 +- > > python/.gitignore | 2 - > > python/README.rst | 1 - > > python/automake.mk | 123 - > > python/build/__init__.py | 0 > > python/build/nroff.py | 398 --- > > python/build/soutil.py | 56 - > > python/ovs/.gitignore | 1 - > > python/ovs/__init__.py | 1 - > > python/ovs/_json.c | 269 -- > > python/ovs/compat/__init__.py | 0 > > python/ovs/compat/sortedcontainers/LICENSE | 13 - > > .../ovs/compat/sortedcontainers/__init__.py | 52 - > > .../ovs/compat/sortedcontainers/sorteddict.py | 741 ----- > > .../ovs/compat/sortedcontainers/sortedlist.py | 2508 ----------------- > > .../ovs/compat/sortedcontainers/sortedset.py | 327 --- > > python/ovs/daemon.py | 652 ----- > > python/ovs/db/__init__.py | 1 - > > python/ovs/db/custom_index.py | 154 - > > python/ovs/db/data.py | 585 ---- > > python/ovs/db/error.py | 34 - > > python/ovs/db/idl.py | 2030 ------------- > > python/ovs/db/parser.py | 118 - > > python/ovs/db/schema.py | 304 -- > > python/ovs/db/types.py | 647 ----- > > python/ovs/dirs.py | 31 - > > python/ovs/dirs.py.template | 31 - > > python/ovs/fatal_signal.py | 183 -- > > python/ovs/fcntl_win.py | 46 - > > python/ovs/json.py | 531 ---- > > python/ovs/jsonrpc.py | 616 ---- > > python/ovs/ovsuuid.py | 70 - > > python/ovs/poller.py | 290 -- > > python/ovs/process.py | 41 - > > python/ovs/reconnect.py | 608 ---- > > python/ovs/socket_util.py | 335 --- > > python/ovs/stream.py | 831 ------ > > python/ovs/timeval.py | 81 - > > python/ovs/unixctl/__init__.py | 91 - > > python/ovs/unixctl/client.py | 68 - > > python/ovs/unixctl/server.py | 260 -- > > python/ovs/util.py | 95 - > > python/ovs/vlog.py | 475 ---- > > python/ovs/winutils.py | 266 -- > > python/ovstest/__init__.py | 1 - > > python/ovstest/args.py | 283 -- > > python/ovstest/rpcserver.py | 383 --- > > python/ovstest/tcp.py | 120 - > > python/ovstest/tests.py | 250 -- > > python/ovstest/udp.py | 85 - > > python/ovstest/util.py | 253 -- > > python/ovstest/vswitch.py | 107 - > > python/setup.py | 102 - > > tests/atlocal.in | 2 +- > > tests/ovn-controller-vtep.at | 2 + > > 55 files changed, 5 insertions(+), 15554 deletions(-) > > delete mode 100644 python/.gitignore > > delete mode 100644 python/README.rst > > delete mode 100644 python/automake.mk > > delete mode 100644 python/build/__init__.py > > delete mode 100644 python/build/nroff.py > > delete mode 100755 python/build/soutil.py > > delete mode 100644 python/ovs/.gitignore > > delete mode 100644 python/ovs/__init__.py > > delete mode 100644 python/ovs/_json.c > > delete mode 100644 python/ovs/compat/__init__.py > > delete mode 100644 python/ovs/compat/sortedcontainers/LICENSE > > delete mode 100644 python/ovs/compat/sortedcontainers/__init__.py > > delete mode 100644 python/ovs/compat/sortedcontainers/sorteddict.py > > delete mode 100644 python/ovs/compat/sortedcontainers/sortedlist.py > > delete mode 100644 python/ovs/compat/sortedcontainers/sortedset.py > > delete mode 100644 python/ovs/daemon.py > > delete mode 100644 python/ovs/db/__init__.py > > delete mode 100644 python/ovs/db/custom_index.py > > delete mode 100644 python/ovs/db/data.py > > delete mode 100644 python/ovs/db/error.py > > delete mode 100644 python/ovs/db/idl.py > > delete mode 100644 python/ovs/db/parser.py > > delete mode 100644 python/ovs/db/schema.py > > delete mode 100644 python/ovs/db/types.py > > delete mode 100644 python/ovs/dirs.py > > delete mode 100644 python/ovs/dirs.py.template > > delete mode 100644 python/ovs/fatal_signal.py > > delete mode 100644 python/ovs/fcntl_win.py > > delete mode 100644 python/ovs/json.py > > delete mode 100644 python/ovs/jsonrpc.py > > delete mode 100644 python/ovs/ovsuuid.py > > delete mode 100644 python/ovs/poller.py > > delete mode 100644 python/ovs/process.py > > delete mode 100644 python/ovs/reconnect.py > > delete mode 100644 python/ovs/socket_util.py > > delete mode 100644 python/ovs/stream.py > > delete mode 100644 python/ovs/timeval.py > > delete mode 100644 python/ovs/unixctl/__init__.py > > delete mode 100644 python/ovs/unixctl/client.py > > delete mode 100644 python/ovs/unixctl/server.py > > delete mode 100644 python/ovs/util.py > > delete mode 100644 python/ovs/vlog.py > > delete mode 100644 python/ovs/winutils.py > > delete mode 100644 python/ovstest/__init__.py > > delete mode 100644 python/ovstest/args.py > > delete mode 100644 python/ovstest/rpcserver.py > > delete mode 100644 python/ovstest/tcp.py > > delete mode 100644 python/ovstest/tests.py > > delete mode 100644 python/ovstest/udp.py > > delete mode 100644 python/ovstest/util.py > > delete mode 100644 python/ovstest/vswitch.py > > delete mode 100644 python/setup.py > > > > diff --git a/Makefile.am b/Makefile.am > > index 88ede2d82..59c1605fe 100644 > > --- a/Makefile.am > > +++ b/Makefile.am > > @@ -70,7 +70,7 @@ endif > > # foo/__init__.py into an (older) version with plain foo.py, since > > # foo/__init__.pyc will cause Python to ignore foo.py. > > run_python = \ > > - PYTHONPATH=$(top_srcdir)/python$(psep)$$PYTHONPATH \ > > + PYTHONPATH=$(OVS_SRCDIR)/python$(psep)$$PYTHONPATH \ > > PYTHONDONTWRITEBYTECODE=yes $(PYTHON) > > > > ALL_LOCAL = > > @@ -424,7 +424,7 @@ endif > > CLEANFILES += flake8-check > > > > include $(srcdir)/manpages.mk > > -$(srcdir)/manpages.mk: $(MAN_ROOTS) build-aux/sodepends.py > python/build/soutil.py > > +$(srcdir)/manpages.mk: $(MAN_ROOTS) build-aux/sodepends.py > $(OVS_SRCDIR)/python/build/soutil.py > > @PYTHONPATH=$$PYTHONPATH$(psep)$(srcdir)/python $(PYTHON) > $(srcdir)/build-aux/sodepends.py -I. -I$(srcdir) -I$(OVS_MANDIR) > $(MAN_ROOTS) >$(@F).tmp > > @if cmp -s $(@F).tmp $@; then \ > > touch $@; \ > > @@ -495,7 +495,6 @@ include lib/ovsdb_automake.mk > > include ipsec/automake.mk > > include rhel/automake.mk > > include xenserver/automake.mk > > -include python/automake.mk > > include tutorial/automake.mk > > include selinux/automake.mk > > include controller/automake.mk > > diff --git a/python/.gitignore b/python/.gitignore > > deleted file mode 100644 > > index 60ace6f05..000000000 > > --- a/python/.gitignore > > +++ /dev/null > > @@ -1,2 +0,0 @@ > > -dist/ > > -*.egg-info > > diff --git a/python/README.rst b/python/README.rst > > deleted file mode 100644 > > index 4f4742c53..000000000 > > --- a/python/README.rst > > +++ /dev/null > > @@ -1 +0,0 @@ > > -Python library for working with Open vSwitch > > diff --git a/python/automake.mk b/python/automake.mk > > deleted file mode 100644 > > index 5a1e1da8a..000000000 > > --- a/python/automake.mk > > +++ /dev/null > > @@ -1,123 +0,0 @@ > > -ovstest_pyfiles = \ > > - python/ovstest/__init__.py \ > > - python/ovstest/args.py \ > > - python/ovstest/rpcserver.py \ > > - python/ovstest/tcp.py \ > > - python/ovstest/tests.py \ > > - python/ovstest/udp.py \ > > - python/ovstest/util.py \ > > - python/ovstest/vswitch.py > > - > > -ovs_pyfiles = \ > > - python/ovs/__init__.py \ > > - python/ovs/compat/__init__.py \ > > - python/ovs/compat/sortedcontainers/__init__.py \ > > - python/ovs/compat/sortedcontainers/sortedlist.py \ > > - python/ovs/compat/sortedcontainers/sorteddict.py \ > > - python/ovs/compat/sortedcontainers/sortedset.py \ > > - python/ovs/daemon.py \ > > - python/ovs/fcntl_win.py \ > > - python/ovs/db/__init__.py \ > > - python/ovs/db/custom_index.py \ > > - python/ovs/db/data.py \ > > - python/ovs/db/error.py \ > > - python/ovs/db/idl.py \ > > - python/ovs/db/parser.py \ > > - python/ovs/db/schema.py \ > > - python/ovs/db/types.py \ > > - python/ovs/fatal_signal.py \ > > - python/ovs/json.py \ > > - python/ovs/jsonrpc.py \ > > - python/ovs/ovsuuid.py \ > > - python/ovs/poller.py \ > > - python/ovs/process.py \ > > - python/ovs/reconnect.py \ > > - python/ovs/socket_util.py \ > > - python/ovs/stream.py \ > > - python/ovs/timeval.py \ > > - python/ovs/unixctl/__init__.py \ > > - python/ovs/unixctl/client.py \ > > - python/ovs/unixctl/server.py \ > > - python/ovs/util.py \ > > - python/ovs/version.py \ > > - python/ovs/vlog.py \ > > - python/ovs/winutils.py > > -# These python files are used at build time but not runtime, > > -# so they are not installed. > > -EXTRA_DIST += \ > > - python/build/__init__.py \ > > - python/build/nroff.py \ > > - python/build/soutil.py > > - > > -# PyPI support. > > -EXTRA_DIST += \ > > - python/ovs/compat/sortedcontainers/LICENSE \ > > - python/README.rst \ > > - python/setup.py > > - > > -# C extension support. > > -EXTRA_DIST += python/ovs/_json.c > > - > > -PYFILES = $(ovs_pyfiles) python/ovs/dirs.py $(ovstest_pyfiles) > > -EXTRA_DIST += $(PYFILES) > > -PYCOV_CLEAN_FILES += $(PYFILES:.py=.py,cover) > > - > > -FLAKE8_PYFILES += \ > > - $(filter-out python/ovs/compat/% python/ovs/dirs.py,$(PYFILES)) \ > > - python/setup.py \ > > - python/build/__init__.py \ > > - python/build/nroff.py \ > > - python/ovs/dirs.py.template > > - > > -if HAVE_PYTHON > > -nobase_pkgdata_DATA = $(ovs_pyfiles) $(ovstest_pyfiles) > > -ovs-install-data-local: > > - $(MKDIR_P) python/ovs > > - sed \ > > - -e '/^##/d' \ > > - -e 's,[@]pkgdatadir[@],$(pkgdatadir),g' \ > > - -e 's,[@]RUNDIR[@],$(RUNDIR),g' \ > > - -e 's,[@]LOGDIR[@],$(LOGDIR),g' \ > > - -e 's,[@]bindir[@],$(bindir),g' \ > > - -e 's,[@]sysconfdir[@],$(sysconfdir),g' \ > > - -e 's,[@]DBDIR[@],$(DBDIR),g' \ > > - < $(srcdir)/python/ovs/dirs.py.template \ > > - > python/ovs/dirs.py.tmp > > - $(MKDIR_P) $(DESTDIR)$(pkgdatadir)/python/ovs > > - $(INSTALL_DATA) python/ovs/dirs.py.tmp > $(DESTDIR)$(pkgdatadir)/python/ovs/dirs.py > > - rm python/ovs/dirs.py.tmp > > - > > -python-sdist: $(srcdir)/python/ovs/version.py $(ovs_pyfiles) > python/ovs/dirs.py > > - (cd python/ && $(PYTHON) setup.py sdist) > > - > > -pypi-upload: $(srcdir)/python/ovs/version.py $(ovs_pyfiles) > python/ovs/dirs.py > > - (cd python/ && $(PYTHON) setup.py sdist upload) > > -else > > -ovs-install-data-local: > > - @: > > -endif > > -install-data-local: ovs-install-data-local > > - > > -UNINSTALL_LOCAL += ovs-uninstall-local > > -ovs-uninstall-local: > > - rm -f $(DESTDIR)$(pkgdatadir)/python/ovs/dirs.py > > - > > -ALL_LOCAL += $(srcdir)/python/ovs/version.py > > -$(srcdir)/python/ovs/version.py: config.status > > - $(AM_V_GEN)$(ro_shell) > $(@F).tmp && \ > > - echo 'VERSION = "$(VERSION)"' >> $(@F).tmp && \ > > - if cmp -s $(@F).tmp $@; then touch $@; rm $(@F).tmp; else mv > $(@F).tmp $@; fi > > - > > -ALL_LOCAL += $(srcdir)/python/ovs/dirs.py > > -$(srcdir)/python/ovs/dirs.py: python/ovs/dirs.py.template > > - $(AM_V_GEN)sed \ > > - -e '/^##/d' \ > > - -e 's,[@]pkgdatadir[@],/usr/local/share/openvswitch,g' \ > > - -e 's,[@]RUNDIR[@],/var/run,g' \ > > - -e 's,[@]LOGDIR[@],/usr/local/var/log,g' \ > > - -e 's,[@]bindir[@],/usr/local/bin,g' \ > > - -e 's,[@]sysconfdir[@],/usr/local/etc,g' \ > > - -e 's,[@]DBDIR[@],/usr/local/etc/openvswitch,g' \ > > - < $? > [email protected] && \ > > - mv [email protected] $@ > > -EXTRA_DIST += python/ovs/dirs.py.template > > diff --git a/python/build/__init__.py b/python/build/__init__.py > > deleted file mode 100644 > > index e69de29bb..000000000 > > diff --git a/python/build/nroff.py b/python/build/nroff.py > > deleted file mode 100644 > > index a94907757..000000000 > > --- a/python/build/nroff.py > > +++ /dev/null > > @@ -1,398 +0,0 @@ > > -# Copyright (c) 2010, 2011, 2012, 2015, 2016, 2017 Nicira, Inc. > > -# > > -# Licensed under the Apache License, Version 2.0 (the "License"); > > -# you may not use this file except in compliance with the License. > > -# You may obtain a copy of the License at: > > -# > > -# http://www.apache.org/licenses/LICENSE-2.0 > > -# > > -# Unless required by applicable law or agreed to in writing, software > > -# distributed under the License is distributed on an "AS IS" BASIS, > > -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > > -# See the License for the specific language governing permissions and > > -# limitations under the License. > > - > > -import re > > -import sys > > - > > -from ovs.db import error > > - > > - > > -def text_to_nroff(s, font=r'\fR', escape_dot=True): > > - def escape(match): > > - c = match.group(0) > > - > > - # In Roman type, let -- in XML be \- in nroff. That gives us a > way to > > - # write minus signs, which is important in some places in > manpages. > > - # > > - # Bold in nroff usually represents literal text, where there's > no > > - # distinction between hyphens and minus sign. The convention > in nroff > > - # appears to be to use a minus sign in such cases, so we follow > that > > - # convention. > > - # > > - # Finally, we always output - as a minus sign when it is > followed by a > > - # digit. > > - if c.startswith('-'): > > - if c == '--' and font == r'\fR': > > - return r'\-' > > - if c != '-' or font in (r'\fB', r'\fL'): > > - return c.replace('-', r'\-') > > - else: > > - return '-' > > - > > - if c == '\\': > > - return r'\e' > > - elif c == '"': > > - return r'\(dq' > > - elif c == "'": > > - return r'\(cq' > > - elif c == ".": > > - if escape_dot: > > - # groff(7) says that . can be escaped by \. but in > practice > > - # groff still gives an error with \. at the beginning > of a > > - # line. > > - return r'\[char46]' > > - else: > > - return '.' > > - else: > > - raise error.Error("bad escape") > > - > > - # Escape - \ " ' . as needed by nroff. > > - s = re.sub('(-[0-9]|--|[-"\'\\\\.])', escape, s) > > - return s > > - > > - > > -def escape_nroff_literal(s, font=r'\fB'): > > - return font + r'%s\fR' % text_to_nroff(s, font) > > - > > - > > -def inline_xml_to_nroff(node, font, to_upper=False, newline='\n'): > > - if node.nodeType == node.TEXT_NODE: > > - if to_upper: > > - s = text_to_nroff(node.data.upper(), font) > > - else: > > - s = text_to_nroff(node.data, font) > > - return s.replace('\n', newline) > > - elif node.nodeType == node.ELEMENT_NODE: > > - if node.tagName in ['code', 'em', 'option', 'env', 'b']: > > - s = r'\fB' > > - for child in node.childNodes: > > - s += inline_xml_to_nroff(child, r'\fB', to_upper, > newline) > > - return s + font > > - elif node.tagName == 'ref': > > - if node.hasAttribute('column'): > > - s = node.attributes['column'].nodeValue > > - if node.hasAttribute('key'): > > - s += ':' + node.attributes['key'].nodeValue > > - elif node.hasAttribute('table'): > > - s = node.attributes['table'].nodeValue > > - elif node.hasAttribute('group'): > > - s = node.attributes['group'].nodeValue > > - elif node.hasAttribute('db'): > > - s = node.attributes['db'].nodeValue > > - elif node.hasAttribute('field'): > > - s = node.attributes['field'].nodeValue > > - elif node.hasAttribute('section'): > > - s = node.attributes['section'].nodeValue > > - else: > > - raise error.Error("'ref' lacks required attributes: %s" > > - % list(node.attributes.keys())) > > - return r'\fB' + re.sub(r'\s+', ' ', s) + font > > - elif node.tagName in ['var', 'dfn', 'i', 'cite']: > > - s = r'\fI' > > - for child in node.childNodes: > > - s += inline_xml_to_nroff(child, r'\fI', to_upper, > newline) > > - return s + font > > - elif node.tagName in ['literal']: > > - s = r'\fL' > > - for child in node.childNodes: > > - s += inline_xml_to_nroff(child, r'\fL') > > - return s + font > > - elif node.tagName == 'url': > > - return ('\n.URL "' > > - + text_to_nroff(node.attributes['href'].nodeValue, > > - escape_dot=False) > > - + '"\n') > > - else: > > - raise error.Error("element <%s> unknown or invalid here" > > - % node.tagName) > > - elif node.nodeType == node.COMMENT_NODE: > > - return '' > > - else: > > - raise error.Error("unknown node %s in inline xml" % node) > > - > > - > > -def pre_to_nroff(nodes, para, font): > > - # This puts 'font' at the beginning of each line so that leading and > > - # trailing whitespace stripping later doesn't removed leading spaces > > - # from preformatted text. > > - s = para + '\n.nf\n' + font > > - for node in nodes: > > - s += inline_xml_to_nroff(node, font, False, '\n.br\n' + font) > + '\\fR' > > - s += '\n.fi\n' > > - return s > > - > > - > > -def tbl_to_nroff(nodes, para): > > - s = para + '\n.TS\n' > > - for node in nodes: > > - if node.nodeType != node.TEXT_NODE: > > - fatal("<tbl> element may only have text children") > > - s += node.data + '\n' > > - s += '.TE\n' > > - return s > > - > > - > > -def fatal(msg): > > - sys.stderr.write('%s\n' % msg) > > - sys.exit(1) > > - > > - > > -def put_text(text, x, y, s): > > - x = int(x) > > - y = int(y) > > - extend = x + len(s) - len(text[y]) > > - if extend > 0: > > - text[y] += ' ' * extend > > - text[y] = text[y][:x] + s + text[y][x + len(s):] > > - > > - > > -def put_centered(text, x, width, y, s): > > - put_text(text, x + (width - len(s)) / 2, y, s) > > - > > - > > -def diagram_header_to_nroff(header_node, text, x): > > - # Parse header. > > - header_fields = [] > > - i = 0 > > - for node in header_node.childNodes: > > - if node.nodeType == node.ELEMENT_NODE and node.tagName == > 'bits': > > - name = node.attributes['name'].nodeValue > > - width = node.attributes['width'].nodeValue > > - above = node.getAttribute('above') > > - below = node.getAttribute('below') > > - fill = node.getAttribute('fill') > > - header_fields += [{"name": name, > > - "tag": "B%d" % i, > > - "width": width, > > - "above": above, > > - "below": below, > > - "fill": fill}] > > - i += 1 > > - elif node.nodeType == node.COMMENT_NODE: > > - pass > > - elif node.nodeType == node.TEXT_NODE and node.data.isspace(): > > - pass > > - else: > > - fatal("unknown node %s in diagram <header> element" % node) > > - > > - # Format pic version. > > - pic_s = "" > > - for f in header_fields: > > - name = f['name'].replace('...', '. . .') > > - pic_s += " %s: box \"%s\" width %s" % (f['tag'], name, > f['width']) > > - if f['fill'] == 'yes': > > - pic_s += " fill" > > - pic_s += '\n' > > - for f in header_fields: > > - pic_s += " \"%s\" at %s.n above\n" % (f['above'], f['tag']) > > - pic_s += " \"%s\" at %s.s below\n" % (f['below'], f['tag']) > > - name = header_node.getAttribute('name') > > - if name == "": > > - visible = " invis" > > - else: > > - visible = "" > > - pic_s += "line <->%s \"%s\" above " % (visible, name) > > - pic_s += "from %s.nw + (0,textht) " % header_fields[0]['tag'] > > - pic_s += "to %s.ne + (0,textht)\n" % header_fields[-1]['tag'] > > - > > - # Format text version. > > - header_width = 1 > > - for f in header_fields: > > - field_width = max(len(f['above']), len(f['below']), > len(f['name'])) > > - f['width'] = field_width > > - header_width += field_width + 1 > > - min_header_width = 2 + len(name) > > - while min_header_width > header_width: > > - for f in header_fields: > > - f['width'] += 1 > > - header_width += 1 > > - if header_width >= min_header_width: > > - break > > - > > - if name != "": > > - put_centered(text, x, header_width, 0, name) > > - if header_width >= 4: > > - arrow = '<' + '-' * (header_width - 4) + '>' > > - put_text(text, x + 1, 1, arrow) > > - for f in header_fields: > > - box1 = '+' + '-' * f['width'] + '+' > > - box2 = '|' + ' ' * f['width'] + '|' > > - put_text(text, x, 3, box1) > > - put_text(text, x, 4, box2) > > - put_text(text, x, 5, box1) > > - > > - put_centered(text, x + 1, f['width'], 2, f['above']) > > - put_centered(text, x + 1, f['width'], 4, f['name']) > > - put_centered(text, x + 1, f['width'], 6, f['below']) > > - > > - x += f['width'] + 1 > > - > > - return pic_s, x + 1 > > - > > - > > -def diagram_to_nroff(nodes, para): > > - pic_s = '' > > - text = [''] * 7 > > - x = 0 > > - move = False > > - for node in nodes: > > - if node.nodeType == node.ELEMENT_NODE and node.tagName == > 'header': > > - if move: > > - pic_s += "move .1\n" > > - x += 1 > > - elif x > 0: > > - x -= 1 > > - pic_header, x = diagram_header_to_nroff(node, text, x) > > - pic_s += "[\n" + pic_header + "]\n" > > - move = True > > - elif node.nodeType == node.ELEMENT_NODE and node.tagName == > 'nospace': > > - move = False > > - elif node.nodeType == node.ELEMENT_NODE and node.tagName == > 'dots': > > - pic_s += "move .1\n" > > - pic_s += '". . ." ljust\n' > > - > > - put_text(text, x, 4, " ... ") > > - x += 5 > > - elif node.nodeType == node.COMMENT_NODE: > > - pass > > - elif node.nodeType == node.TEXT_NODE and node.data.isspace(): > > - pass > > - else: > > - fatal("unknown node %s in diagram <header> element" % node) > > - > > - text_s = '.br\n'.join(["\\fL%s\n" % s for s in text if s != ""]) > > - return para + """ > > -.\\" check if in troff mode (TTY) > > -.if t \\{ > > -.PS > > -boxht = .2 > > -textht = 1/6 > > -fillval = .2 > > -""" + pic_s + """\ > > -.PE > > -\\} > > -.\\" check if in nroff mode: > > -.if n \\{ > > -.nf > > -""" + text_s + """\ > > -.fi > > -\\}""" > > - > > - > > -def block_xml_to_nroff(nodes, para='.PP'): > > - HEADER_TAGS = ('h1', 'h2', 'h3', 'h4') > > - s = '' > > - prev = '' > > - for node in nodes: > > - if node.nodeType == node.TEXT_NODE: > > - if s == '' and para != '.IP': > > - s = para + '\n' > > - text = re.sub(r'\s+', ' ', node.data) > > - if s.endswith(' '): > > - text = text.lstrip() > > - s += text_to_nroff(text) > > - s = s.lstrip() > > - elif node.nodeType == node.ELEMENT_NODE: > > - if node.tagName in ['ul', 'ol']: > > - if s != "": > > - s += "\n" > > - s += ".RS\n" > > - i = 0 > > - for li_node in node.childNodes: > > - if (li_node.nodeType == node.ELEMENT_NODE > > - and li_node.tagName == 'li'): > > - i += 1 > > - if node.tagName == 'ul': > > - s += ".IP \\(bu\n" > > - else: > > - s += ".IP %d. .4in\n" % i > > - s += block_xml_to_nroff(li_node.childNodes, > ".IP") > > - elif li_node.nodeType == node.COMMENT_NODE: > > - pass > > - elif (li_node.nodeType != node.TEXT_NODE > > - or not li_node.data.isspace()): > > - raise error.Error("<%s> element may only have " > > - "<li> children" % > node.tagName) > > - s += ".RE\n" > > - elif node.tagName == 'dl': > > - indent = True > > - if prev in HEADER_TAGS: > > - indent = False > > - if s != "": > > - s += "\n" > > - if indent: > > - s += ".RS\n" > > - prev = "dd" > > - for li_node in node.childNodes: > > - if (li_node.nodeType == node.ELEMENT_NODE > > - and li_node.tagName == 'dt'): > > - if prev == 'dd': > > - s += '.TP\n' > > - else: > > - s += '.TQ .5in\n' > > - prev = 'dt' > > - elif (li_node.nodeType == node.ELEMENT_NODE > > - and li_node.tagName == 'dd'): > > - if prev == 'dd': > > - s += '.IP\n' > > - prev = 'dd' > > - elif li_node.nodeType == node.COMMENT_NODE: > > - continue > > - elif (li_node.nodeType != node.TEXT_NODE > > - or not li_node.data.isspace()): > > - raise error.Error("<dl> element may only have " > > - "<dt> and <dd> children") > > - s += block_xml_to_nroff(li_node.childNodes, ".IP") > > - if indent: > > - s += ".RE\n" > > - elif node.tagName == 'p': > > - if s != "": > > - if not s.endswith("\n"): > > - s += "\n" > > - s += para + "\n" > > - s += block_xml_to_nroff(node.childNodes, para) > > - elif node.tagName in HEADER_TAGS: > > - if s != "": > > - if not s.endswith("\n"): > > - s += "\n" > > - nroffTag, font = {'h1': ('SH', r'\fR'), > > - 'h2': ('SS', r'\fB'), > > - 'h3': ('ST', r'\fI'), > > - 'h4': ('SU', r'\fI')}[node.tagName] > > - to_upper = node.tagName == 'h1' > > - s += ".%s \"" % nroffTag > > - for child_node in node.childNodes: > > - s += inline_xml_to_nroff(child_node, font, to_upper) > > - s += "\"\n" > > - elif node.tagName == 'pre': > > - fixed = node.getAttribute('fixed') > > - if fixed == 'yes': > > - font = r'\fL' > > - else: > > - font = r'\fB' > > - s += pre_to_nroff(node.childNodes, para, font) > > - elif node.tagName == 'tbl': > > - s += tbl_to_nroff(node.childNodes, para) > > - elif node.tagName == 'diagram': > > - s += diagram_to_nroff(node.childNodes, para) > > - else: > > - s += inline_xml_to_nroff(node, r'\fR') > > - prev = node.tagName > > - elif node.nodeType == node.COMMENT_NODE: > > - pass > > - else: > > - raise error.Error("unknown node %s in block xml" % node) > > - if s != "" and not s.endswith('\n'): > > - s += '\n' > > - return s > > diff --git a/python/build/soutil.py b/python/build/soutil.py > > deleted file mode 100755 > > index b8027af86..000000000 > > --- a/python/build/soutil.py > > +++ /dev/null > > @@ -1,56 +0,0 @@ > > -#! /usr/bin/env python > > - > > -# Copyright (c) 2008, 2017 Nicira, Inc. > > -# > > -# Licensed under the Apache License, Version 2.0 (the "License"); > > -# you may not use this file except in compliance with the License. > > -# You may obtain a copy of the License at: > > -# > > -# http://www.apache.org/licenses/LICENSE-2.0 > > -# > > -# Unless required by applicable law or agreed to in writing, software > > -# distributed under the License is distributed on an "AS IS" BASIS, > > -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > > -# See the License for the specific language governing permissions and > > -# limitations under the License. > > - > > -import getopt > > -import os > > -import re > > -import sys > > - > > - > > -def parse_include_dirs(): > > - include_dirs = [] > > - options, args = getopt.gnu_getopt(sys.argv[1:], 'I:', ['include=']) > > - for key, value in options: > > - if key in ['-I', '--include']: > > - include_dirs.append(value) > > - else: > > - assert False > > - > > - include_dirs.append('.') > > - return include_dirs, args > > - > > - > > -def find_file(include_dirs, name): > > - for dir in include_dirs: > > - file = "%s/%s" % (dir, name) > > - try: > > - os.stat(file) > > - return file > > - except OSError: > > - pass > > - sys.stderr.write("%s not found in: %s\n" % (name, ' > '.join(include_dirs))) > > - return None > > - > > - > > -so_re = re.compile(r'^\.so (\S+)$') > > - > > - > > -def extract_include_directive(line): > > - m = so_re.match(line) > > - if m: > > - return m.group(1) > > - else: > > - return None > > diff --git a/python/ovs/.gitignore b/python/ovs/.gitignore > > deleted file mode 100644 > > index 985278646..000000000 > > --- a/python/ovs/.gitignore > > +++ /dev/null > > @@ -1 +0,0 @@ > > -version.py > > diff --git a/python/ovs/__init__.py b/python/ovs/__init__.py > > deleted file mode 100644 > > index 218d8921e..000000000 > > --- a/python/ovs/__init__.py > > +++ /dev/null > > @@ -1 +0,0 @@ > > -# This file intentionally left blank. > > diff --git a/python/ovs/_json.c b/python/ovs/_json.c > > deleted file mode 100644 > > index ef7bb4b8e..000000000 > > --- a/python/ovs/_json.c > > +++ /dev/null > > @@ -1,269 +0,0 @@ > > -#include "Python.h" > > -#include <openvswitch/json.h> > > -#include "structmember.h" > > - > > -#if PY_MAJOR_VERSION >= 3 > > -#define IS_PY3K > > -#endif > > - > > -typedef struct { > > - PyObject_HEAD > > - struct json_parser *_parser; > > -} json_ParserObject; > > - > > -static void > > -Parser_dealloc(json_ParserObject * p) > > -{ > > - json_parser_abort(p->_parser); > > - Py_TYPE(p)->tp_free(p); > > -} > > - > > -static PyObject * > > -Parser_new(PyTypeObject * type, PyObject * args, PyObject * kwargs) > > -{ > > - json_ParserObject *self; > > - static char *kwlist[] = { "check_trailer", NULL }; > > - PyObject *check_trailer = NULL; > > - int ct_int = 0; > > - > > - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, > > - &check_trailer)) { > > - return NULL; > > - } > > - > > - if (check_trailer != NULL) { > > - ct_int = PyObject_IsTrue(check_trailer); > > - if (ct_int < 0) { > > - return NULL; > > - } else if (ct_int) { > > - ct_int = JSPF_TRAILER; > > - } > > - } > > - > > - self = (json_ParserObject *) type->tp_alloc(type, 0); > > - if (self != NULL) { > > - self->_parser = json_parser_create(ct_int); > > - } > > - > > - return (PyObject *) self; > > -} > > - > > -static PyObject * > > -Parser_feed(json_ParserObject * self, PyObject * args) > > -{ > > - Py_ssize_t input_sz; > > - PyObject *input; > > - size_t rd; > > - char *input_str; > > - > > - if (self->_parser == NULL) { > > - return NULL; > > - } > > - > > - if (!PyArg_UnpackTuple(args, "input", 1, 1, &input)) { > > - return NULL; > > - } > > -#ifdef IS_PY3K > > - if ((input_str = PyUnicode_AsUTF8AndSize(input, &input_sz)) == > NULL) { > > -#else > > - if (PyString_AsStringAndSize(input, &input_str, &input_sz) < 0) { > > -#endif > > - return NULL; > > - } > > - > > - rd = json_parser_feed(self->_parser, input_str, (size_t) input_sz); > > - > > -#ifdef IS_PY3K > > - return PyLong_FromSize_t(rd); > > -#else > > - return PyInt_FromSize_t(rd); > > -#endif > > -} > > - > > -static PyObject * > > -Parser_is_done(json_ParserObject * self) > > -{ > > - if (self->_parser == NULL) { > > - return NULL; > > - } > > - return PyBool_FromLong(json_parser_is_done(self->_parser)); > > -} > > - > > -static PyObject * > > -json_to_python(struct json *json) > > -{ > > - switch (json->type) { > > - case JSON_NULL: > > - Py_RETURN_NONE; > > - case JSON_FALSE: > > - Py_RETURN_FALSE; > > - case JSON_TRUE: > > - Py_RETURN_TRUE; > > - case JSON_OBJECT:{ > > - struct shash_node *node; > > - PyObject *dict = PyDict_New(); > > - > > - if (dict == NULL) { > > - return PyErr_NoMemory(); > > - } > > - SHASH_FOR_EACH (node, json->object) { > > - PyObject *key = PyUnicode_FromString(node->name); > > - PyObject *val = json_to_python(node->data); > > - > > - if (!(key && val) || PyDict_SetItem(dict, key, val)) { > > - Py_XDECREF(key); > > - Py_XDECREF(val); > > - Py_XDECREF(dict); > > - return NULL; > > - } > > - > > - Py_XDECREF(key); > > - Py_XDECREF(val); > > - } > > - return dict; > > - } > > - case JSON_ARRAY:{ > > - int i; > > - PyObject *arr = PyList_New(json->array.n); > > - > > - if (arr == NULL) { > > - return PyErr_NoMemory(); > > - } > > - for (i = 0; i < json->array.n; i++) { > > - PyObject *item = json_to_python(json->array.elems[i]); > > - > > - if (!item || PyList_SetItem(arr, i, item)) { > > - Py_XDECREF(arr); > > - return NULL; > > - } > > - } > > - return arr; > > - } > > - case JSON_REAL: > > - if (json->real != 0) { > > - return PyFloat_FromDouble(json->real); > > - } /* fall through to treat 0 as int */ > > - case JSON_INTEGER: > > -#ifdef IS_PY3K > > - return PyLong_FromLong((long) json->integer); > > -#else > > - return PyInt_FromLong((long) json->integer); > > -#endif > > - > > - case JSON_STRING: > > - return PyUnicode_FromString(json->string); > > - default: > > - return NULL; > > - } > > -} > > - > > -static PyObject * > > -Parser_finish(json_ParserObject * self) > > -{ > > - struct json *json; > > - PyObject *obj; > > - > > - if (self->_parser == NULL) { > > - return NULL; > > - } > > - > > - json = json_parser_finish(self->_parser); > > - self->_parser = NULL; > > - obj = json_to_python(json); > > - json_destroy(json); > > - return obj; > > -} > > - > > -static PyMethodDef Parser_methods[] = { > > - {"feed", (PyCFunction) Parser_feed, METH_VARARGS, > > - "Feed data to the parser and return the index of the last > object."}, > > - {"is_done", (PyCFunction) Parser_is_done, METH_NOARGS, > > - "Whether the parser has finished decoding an object."}, > > - {"finish", (PyCFunction) Parser_finish, METH_NOARGS, > > - "Finish parsing and return Python object parsed."}, > > - {NULL}, > > -}; > > - > > -static PyTypeObject json_ParserType = { > > - PyVarObject_HEAD_INIT(NULL, 0) > > - "ovs._json.Parser", /* tp_name */ > > - sizeof (json_ParserObject), /* tp_basicsize */ > > - 0, /* tp_itemsize */ > > - (destructor) Parser_dealloc, /* tp_dealloc */ > > - 0, /* tp_print */ > > - 0, /* tp_getattr */ > > - 0, /* tp_setattr */ > > - 0, /* tp_compare */ > > - 0, /* tp_repr */ > > - 0, /* tp_as_number */ > > - 0, /* tp_as_sequence */ > > - 0, /* tp_as_mapping */ > > - 0, /* tp_hash */ > > - 0, /* tp_call */ > > - 0, /* tp_str */ > > - 0, /* tp_getattro */ > > - 0, /* tp_setattro */ > > - 0, /* tp_as_buffer */ > > - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ > > - "Parser objects", /* tp_doc */ > > - 0, /* tp_traverse */ > > - 0, /* tp_clear */ > > - 0, /* tp_richcompare */ > > - 0, /* tp_weaklistoffset */ > > - 0, /* tp_iter */ > > - 0, /* tp_iternext */ > > - Parser_methods, /* tp_methods */ > > - 0, /* tp_members */ > > - 0, /* tp_getset */ > > - 0, /* tp_base */ > > - 0, /* tp_dict */ > > - 0, /* tp_descr_get */ > > - 0, /* tp_descr_set */ > > - 0, /* tp_dictoffset */ > > - 0, /* tp_init */ > > - 0, /* tp_alloc */ > > - Parser_new, /* tp_new */ > > -}; > > - > > -#ifdef IS_PY3K > > -static struct PyModuleDef moduledef = { > > - PyModuleDef_HEAD_INIT, > > - "ovs._json", /* m_name */ > > - "OVS JSON Parser module", /* m_doc */ > > - 0, /* m_size */ > > - 0, /* m_methods */ > > - 0, /* m_slots */ > > - 0, /* m_traverse */ > > - 0, /* m_clear */ > > - 0, /* m_free */ > > -}; > > - > > -#define INITERROR return NULL > > -#else /* !IS_PY3K */ > > -#define INITERROR return > > -#endif > > - > > -PyMODINIT_FUNC > > -#ifdef IS_PY3K > > -PyInit__json(void) > > -#else > > -init_json(void) > > -#endif > > -{ > > - PyObject *m; > > - > > - if (PyType_Ready(&json_ParserType) < 0) { > > - INITERROR; > > - } > > -#ifdef IS_PY3K > > - m = PyModule_Create(&moduledef); > > -#else > > - m = Py_InitModule3("ovs._json", NULL, "OVS JSON Parser module"); > > -#endif > > - > > - Py_INCREF(&json_ParserType); > > - PyModule_AddObject(m, "Parser", (PyObject *) & json_ParserType); > > -#ifdef IS_PY3K > > - return m; > > -#endif > > -} > > diff --git a/python/ovs/compat/__init__.py > b/python/ovs/compat/__init__.py > > deleted file mode 100644 > > index e69de29bb..000000000 > > diff --git a/python/ovs/compat/sortedcontainers/LICENSE > b/python/ovs/compat/sortedcontainers/LICENSE > > deleted file mode 100644 > > index 8794014e0..000000000 > > --- a/python/ovs/compat/sortedcontainers/LICENSE > > +++ /dev/null > > @@ -1,13 +0,0 @@ > > -Copyright 2014-2016 Grant Jenks > > - > > -Licensed under the Apache License, Version 2.0 (the "License"); > > -you may not use this file except in compliance with the License. > > -You may obtain a copy of the License at > > - > > - http://www.apache.org/licenses/LICENSE-2.0 > > - > > -Unless required by applicable law or agreed to in writing, software > > -distributed under the License is distributed on an "AS IS" BASIS, > > -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > > -See the License for the specific language governing permissions and > > -limitations under the License. > > diff --git a/python/ovs/compat/sortedcontainers/__init__.py > b/python/ovs/compat/sortedcontainers/__init__.py > > deleted file mode 100644 > > index 392adfad6..000000000 > > --- a/python/ovs/compat/sortedcontainers/__init__.py > > +++ /dev/null > > @@ -1,52 +0,0 @@ > > -"""Sorted Container Types: SortedList, SortedDict, SortedSet > > - > > -SortedContainers is an Apache2 licensed containers library, written in > > -pure-Python, and fast as C-extensions. > > - > > - > > -Python's standard library is great until you need a sorted collections > > -type. Many will attest that you can get really far without one, but the > moment > > -you **really need** a sorted list, dict, or set, you're faced with a > dozen > > -different implementations, most using C-extensions without great > documentation > > -and benchmarking. > > - > > -In Python, we can do better. And we can do it in pure-Python! > > - > > -:: > > - > > - >>> from sortedcontainers import SortedList, SortedDict, SortedSet > > - >>> sl = SortedList(xrange(10000000)) > > - >>> 1234567 in sl > > - True > > - >>> sl[7654321] > > - 7654321 > > - >>> sl.add(1234567) > > - >>> sl.count(1234567) > > - 2 > > - >>> sl *= 3 > > - >>> len(sl) > > - 30000003 > > - > > -SortedContainers takes all of the work out of Python sorted types - > making your > > -deployment and use of Python easy. There's no need to install a C > compiler or > > -pre-build and distribute custom extensions. Performance is a feature and > > -testing has 100% coverage with unit tests and hours of stress. > > - > > -:copyright: (c) 2016 by Grant Jenks. > > -:license: Apache 2.0, see LICENSE for more details. > > - > > -""" > > - > > - > > -from .sortedlist import SortedList, SortedListWithKey > > -from .sortedset import SortedSet > > -from .sorteddict import SortedDict > > - > > -__all__ = ['SortedList', 'SortedSet', 'SortedDict', 'SortedListWithKey'] > > - > > -__title__ = 'sortedcontainers' > > -__version__ = '1.5.9' > > -__build__ = 0x010509 > > -__author__ = 'Grant Jenks' > > -__license__ = 'Apache 2.0' > > -__copyright__ = 'Copyright 2016 Grant Jenks' > > diff --git a/python/ovs/compat/sortedcontainers/sorteddict.py > b/python/ovs/compat/sortedcontainers/sorteddict.py > > deleted file mode 100644 > > index 5d425fee6..000000000 > > --- a/python/ovs/compat/sortedcontainers/sorteddict.py > > +++ /dev/null > > @@ -1,741 +0,0 @@ > > -"""Sorted dictionary implementation. > > - > > -""" > > - > > -from collections import Set, Sequence > > -from collections import KeysView as AbstractKeysView > > -from collections import ValuesView as AbstractValuesView > > -from collections import ItemsView as AbstractItemsView > > -from sys import hexversion > > - > > -from .sortedlist import SortedList, recursive_repr, SortedListWithKey > > -from .sortedset import SortedSet > > - > > -NONE = object() > > - > > - > > -class _IlocWrapper(object): > > - "Positional indexing support for sorted dictionary objects." > > - # pylint: disable=protected-access, too-few-public-methods > > - def __init__(self, _dict): > > - self._dict = _dict > > - def __len__(self): > > - return len(self._dict) > > - def __getitem__(self, index): > > - """ > > - Very efficiently return the key at index *index* in iteration. > Supports > > - negative indices and slice notation. Raises IndexError on > invalid > > - *index*. > > - """ > > - return self._dict._list[index] > > - def __delitem__(self, index): > > - """ > > - Remove the ``sdict[sdict.iloc[index]]`` from *sdict*. Supports > negative > > - indices and slice notation. Raises IndexError on invalid > *index*. > > - """ > > - _dict = self._dict > > - _list = _dict._list > > - _delitem = _dict._delitem > > - > > - if isinstance(index, slice): > > - keys = _list[index] > > - del _list[index] > > - for key in keys: > > - _delitem(key) > > - else: > > - key = _list[index] > > - del _list[index] > > - _delitem(key) > > - > > - > > -class SortedDict(dict): > > - """SortedDict provides the same methods as a dict. Additionally, > SortedDict > > - efficiently maintains its keys in sorted order. Consequently, the > keys > > - method will return the keys in sorted order, the popitem method > will remove > > - the item with the highest key, etc. > > - > > - """ > > - def __init__(self, *args, **kwargs): > > - """SortedDict provides the same methods as a dict. > Additionally, SortedDict > > - efficiently maintains its keys in sorted order. Consequently, > the keys > > - method will return the keys in sorted order, the popitem method > will > > - remove the item with the highest key, etc. > > - > > - An optional *key* argument defines a callable that, like the > `key` > > - argument to Python's `sorted` function, extracts a comparison > key from > > - each dict key. If no function is specified, the default > compares the > > - dict keys directly. The `key` argument must be provided as a > positional > > - argument and must come before all other arguments. > > - > > - An optional *iterable* argument provides an initial series of > items to > > - populate the SortedDict. Each item in the series must itself > contain > > - two items. The first is used as a key in the new dictionary, > and the > > - second as the key's value. If a given key is seen more than > once, the > > - last value associated with it is retained in the new dictionary. > > - > > - If keyword arguments are given, the keywords themselves with > their > > - associated values are added as items to the dictionary. If a > key is > > - specified both in the positional argument and as a keyword > argument, the > > - value associated with the keyword is retained in the > dictionary. For > > - example, these all return a dictionary equal to ``{"one": 2, > "two": > > - 3}``: > > - > > - * ``SortedDict(one=2, two=3)`` > > - * ``SortedDict({'one': 2, 'two': 3})`` > > - * ``SortedDict(zip(('one', 'two'), (2, 3)))`` > > - * ``SortedDict([['two', 3], ['one', 2]])`` > > - > > - The first example only works for keys that are valid Python > > - identifiers; the others work with any valid keys. > > - > > - """ > > - # pylint: disable=super-init-not-called > > - if args and (args[0] is None or callable(args[0])): > > - self._key = args[0] > > - args = args[1:] > > - else: > > - self._key = None > > - > > - if self._key is None: > > - self._list = SortedList() > > - else: > > - self._list = SortedListWithKey(key=self._key) > > - > > - # Cache function pointers to dict methods. > > - > > - _dict = super(SortedDict, self) > > - self._dict = _dict > > - self._clear = _dict.clear > > - self._delitem = _dict.__delitem__ > > - self._iter = _dict.__iter__ > > - self._pop = _dict.pop > > - self._setdefault = _dict.setdefault > > - self._setitem = _dict.__setitem__ > > - self._dict_update = _dict.update > > - > > - # Cache function pointers to SortedList methods. > > - > > - _list = self._list > > - self._list_add = _list.add > > - self.bisect_left = _list.bisect_left > > - self.bisect = _list.bisect_right > > - self.bisect_right = _list.bisect_right > > - self._list_clear = _list.clear > > - self.index = _list.index > > - self._list_pop = _list.pop > > - self._list_remove = _list.remove > > - self._list_update = _list.update > > - self.irange = _list.irange > > - self.islice = _list.islice > > - self._reset = _list._reset # pylint: disable=protected-access > > - > > - if self._key is not None: > > - self.bisect_key_left = _list.bisect_key_left > > - self.bisect_key_right = _list.bisect_key_right > > - self.bisect_key = _list.bisect_key > > - self.irange_key = _list.irange_key > > - > > - self.iloc = _IlocWrapper(self) > > - > > - self._update(*args, **kwargs) > > - > > - @property > > - def key(self): > > - """Key function used to extract comparison key for sorting.""" > > - return self._key > > - > > - def clear(self): > > - """Remove all elements from the dictionary.""" > > - self._clear() > > - self._list_clear() > > - > > - def __delitem__(self, key): > > - """ > > - Remove ``d[key]`` from *d*. Raises a KeyError if *key* is not > in the > > - dictionary. > > - """ > > - self._delitem(key) > > - self._list_remove(key) > > - > > - def __iter__(self): > > - """ > > - Return an iterator over the sorted keys of the dictionary. > > - > > - Iterating the Mapping while adding or deleting keys may raise a > > - `RuntimeError` or fail to iterate over all entries. > > - """ > > - return iter(self._list) > > - > > - def __reversed__(self): > > - """ > > - Return a reversed iterator over the sorted keys of the > dictionary. > > - > > - Iterating the Mapping while adding or deleting keys may raise a > > - `RuntimeError` or fail to iterate over all entries. > > - """ > > - return reversed(self._list) > > - > > - def __setitem__(self, key, value): > > - """Set `d[key]` to *value*.""" > > - if key not in self: > > - self._list_add(key) > > - self._setitem(key, value) > > - > > - def copy(self): > > - """Return a shallow copy of the sorted dictionary.""" > > - return self.__class__(self._key, self._iteritems()) > > - > > - __copy__ = copy > > - > > - @classmethod > > - def fromkeys(cls, seq, value=None): > > - """ > > - Create a new dictionary with keys from *seq* and values set to > *value*. > > - """ > > - return cls((key, value) for key in seq) > > - > > - if hexversion < 0x03000000: > > - def items(self): > > - """ > > - Return a list of the dictionary's items (``(key, value)`` > pairs). > > - """ > > - return list(self._iteritems()) > > - else: > > - def items(self): > > - """ > > - Return a new ItemsView of the dictionary's items. In > addition to > > - the methods provided by the built-in `view` the ItemsView is > > - indexable (e.g. ``d.items()[5]``). > > - """ > > - return ItemsView(self) > > - > > - def iteritems(self): > > - """ > > - Return an iterator over the items (``(key, value)`` pairs). > > - > > - Iterating the Mapping while adding or deleting keys may raise a > > - `RuntimeError` or fail to iterate over all entries. > > - """ > > - return iter((key, self[key]) for key in self._list) > > - > > - _iteritems = iteritems > > - > > - if hexversion < 0x03000000: > > - def keys(self): > > - """Return a SortedSet of the dictionary's keys.""" > > - return SortedSet(self._list, key=self._key) > > - else: > > - def keys(self): > > - """ > > - Return a new KeysView of the dictionary's keys. In > addition to the > > - methods provided by the built-in `view` the KeysView is > indexable > > - (e.g. ``d.keys()[5]``). > > - """ > > - return KeysView(self) > > - > > - def iterkeys(self): > > - """ > > - Return an iterator over the sorted keys of the Mapping. > > - > > - Iterating the Mapping while adding or deleting keys may raise a > > - `RuntimeError` or fail to iterate over all entries. > > - """ > > - return iter(self._list) > > - > > - if hexversion < 0x03000000: > > - def values(self): > > - """Return a list of the dictionary's values.""" > > - return list(self._itervalues()) > > - else: > > - def values(self): > > - """ > > - Return a new :class:`ValuesView` of the dictionary's values. > > - In addition to the methods provided by the built-in `view` > the > > - ValuesView is indexable (e.g., ``d.values()[5]``). > > - """ > > - return ValuesView(self) > > - > > - def itervalues(self): > > - """ > > - Return an iterator over the values of the Mapping. > > - > > - Iterating the Mapping while adding or deleting keys may raise a > > - `RuntimeError` or fail to iterate over all entries. > > - """ > > - return iter(self[key] for key in self._list) > > - > > - _itervalues = itervalues > > - > > - def pop(self, key, default=NONE): > > - """ > > - If *key* is in the dictionary, remove it and return its value, > > - else return *default*. If *default* is not given and *key* is > not in > > - the dictionary, a KeyError is raised. > > - """ > > - if key in self: > > - self._list_remove(key) > > - return self._pop(key) > > - else: > > - if default is NONE: > > - raise KeyError(key) > > - else: > > - return default > > - > > - def popitem(self, last=True): > > - """ > > - Remove and return a ``(key, value)`` pair from the dictionary. > If > > - last=True (default) then remove the *greatest* `key` from the > > - diciontary. Else, remove the *least* key from the dictionary. > > - > > - If the dictionary is empty, calling `popitem` raises a > > - KeyError`. > > - """ > > - if not self: > > - raise KeyError('popitem(): dictionary is empty') > > - > > - key = self._list_pop(-1 if last else 0) > > - value = self._pop(key) > > - > > - return (key, value) > > - > > - def peekitem(self, index=-1): > > - """Return (key, value) item pair at index. > > - > > - Unlike ``popitem``, the sorted dictionary is not modified. Index > > - defaults to -1, the last/greatest key in the dictionary. Specify > > - ``index=0`` to lookup the first/least key in the dictiony. > > - > > - If index is out of range, raise IndexError. > > - > > - """ > > - key = self._list[index] > > - return key, self[key] > > - > > - def setdefault(self, key, default=None): > > - """ > > - If *key* is in the dictionary, return its value. If not, > insert *key* > > - with a value of *default* and return *default*. *default* > defaults to > > - ``None``. > > - """ > > - if key in self: > > - return self[key] > > - > > - self._setitem(key, default) > > - self._list_add(key) > > - return default > > - > > - def update(self, *args, **kwargs): > > - """ > > - Update the dictionary with the key/value pairs from *other*, > overwriting > > - existing keys. > > - > > - *update* accepts either another dictionary object or an > iterable of > > - key/value pairs (as a tuple or other iterable of length two). > If > > - keyword arguments are specified, the dictionary is then updated > with > > - those key/value pairs: ``d.update(red=1, blue=2)``. > > - """ > > - if not self: > > - self._dict_update(*args, **kwargs) > > - self._list_update(self._iter()) > > - return > > - > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
