summaryrefslogtreecommitdiff
path: root/meta-phosphor/recipes-devtools/python
diff options
context:
space:
mode:
authorBrad Bishop <bradleyb@fuzziesquirrel.com>2018-08-31 13:25:51 +0300
committerBrad Bishop <bradleyb@fuzziesquirrel.com>2018-09-06 14:44:12 +0300
commitff075f6ee795a590b244d70a90cc312ba1f2d83d (patch)
treea617790bdbfdeef960665ba0242e1f0c93e5301a /meta-phosphor/recipes-devtools/python
parent3e4da38c127bb7e7641adc2fc41f4c33744cb918 (diff)
downloadopenbmc-ff075f6ee795a590b244d70a90cc312ba1f2d83d.tar.xz
meta-phosphor: Move layer content from common/
Adopt a more conventional directory hierarchy. meta-phosphor is still a _long_ way from suitable for hosting on yoctoproject.org but things like this don't help. (From meta-phosphor rev: 471cfcefa74b8c7ceb704cb670e6d915cf27c63b) Change-Id: I3f106b2f6cdc6cec734be28a6090800546f362eb Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Diffstat (limited to 'meta-phosphor/recipes-devtools/python')
-rw-r--r--meta-phosphor/recipes-devtools/python/pyphosphor.bb54
-rw-r--r--meta-phosphor/recipes-devtools/python/python-bottle.inc29
-rw-r--r--meta-phosphor/recipes-devtools/python/python-bottle/LICENSE19
-rw-r--r--meta-phosphor/recipes-devtools/python/python-bottle/json-format.patch31
-rw-r--r--meta-phosphor/recipes-devtools/python/python-bottle_0.12.13.bb10
-rw-r--r--meta-phosphor/recipes-devtools/python/python-gevent-websocket_0.10.1.bb17
-rw-r--r--meta-phosphor/recipes-devtools/python/python-inflection.inc20
-rw-r--r--meta-phosphor/recipes-devtools/python/python-inflection_0.3.1.bb3
-rw-r--r--meta-phosphor/recipes-devtools/python/python-mako_1.0.7.bb11
-rw-r--r--meta-phosphor/recipes-devtools/python/python-pygobject/obsolete_automake_macros.patch23
-rw-r--r--meta-phosphor/recipes-devtools/python/python-pygobject_2.28.7.bb53
-rw-r--r--meta-phosphor/recipes-devtools/python/python-pyyaml_%.bbappend1
-rw-r--r--meta-phosphor/recipes-devtools/python/python/0001-json-Use-int-long.__str__-to-convert-subclasses.patch128
-rw-r--r--meta-phosphor/recipes-devtools/python/python_2.%.bbappend14
-rw-r--r--meta-phosphor/recipes-devtools/python/wsgiref-2.7-manifest.inc33
15 files changed, 446 insertions, 0 deletions
diff --git a/meta-phosphor/recipes-devtools/python/pyphosphor.bb b/meta-phosphor/recipes-devtools/python/pyphosphor.bb
new file mode 100644
index 000000000..ffef08c0d
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/pyphosphor.bb
@@ -0,0 +1,54 @@
+SUMMARY = "Phosphor python library"
+DESCRIPTION = "Phosphor python library."
+HOMEPAGE = "http://github.com/openbmc/pyphosphor"
+PR = "r1"
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${S}/LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e"
+
+inherit allarch
+inherit setuptools
+inherit python-dir
+
+PACKAGE_BEFORE_PN = " \
+ ${PN}-ns \
+ ${PN}-utils-ns \
+ ${PN}-dbus-ns \
+ ${PN}-wsgi-ns \
+ ${PN}-wsgi-apps-ns \
+ ${PN}-utils \
+ ${PN}-dbus \
+ "
+
+RDEPENDS_${PN}-utils-ns += "${PN}-ns"
+RDEPENDS_${PN}-dbus-ns += "${PN}-ns"
+RDEPENDS_${PN}-utils += "${PN}-utils-ns"
+RDEPENDS_${PN}-wsgi-apps-ns += "${PN}-wsgi-ns"
+RDEPENDS_${PN}-wsgi-ns += "${PN}-ns"
+RDEPENDS_${PN}-dbus += " \
+ ${PN}-dbus-ns \
+ python-dbus \
+ python-xml \
+ python-json \
+ python-pickle \
+ "
+RDEPENDS_${PN} += " \
+ ${PN}-ns \
+ ${PN}-dbus \
+ python-subprocess \
+ python-dbus \
+ "
+
+FILES_${PN}-ns = "${PYTHON_SITEPACKAGES_DIR}/obmc/__init__.py*"
+FILES_${PN}-utils-ns = "${PYTHON_SITEPACKAGES_DIR}/obmc/utils/__init__.py*"
+FILES_${PN}-dbus-ns = "${PYTHON_SITEPACKAGES_DIR}/obmc/dbuslib/__init__.py*"
+FILES_${PN}-wsgi-ns = "${PYTHON_SITEPACKAGES_DIR}/obmc/wsgi/__init__.py*"
+FILES_${PN}-wsgi-apps-ns = "${PYTHON_SITEPACKAGES_DIR}/obmc/wsgi/apps/__init__.py*"
+
+FILES_${PN}-utils = "${PYTHON_SITEPACKAGES_DIR}/obmc/utils"
+FILES_${PN}-dbus = "${PYTHON_SITEPACKAGES_DIR}/obmc/dbuslib"
+
+SRC_URI += "git://github.com/openbmc/pyphosphor"
+
+SRCREV = "f63e191ca673a0acd7ab5c45272e1acf51bf7183"
+
+S = "${WORKDIR}/git"
diff --git a/meta-phosphor/recipes-devtools/python/python-bottle.inc b/meta-phosphor/recipes-devtools/python/python-bottle.inc
new file mode 100644
index 000000000..159ded660
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/python-bottle.inc
@@ -0,0 +1,29 @@
+SUMMARY = "Fast and simple WSGI-framework for small web-applications."
+DESCRIPTION = "Bottle is a fast and simple micro-framework for small web \
+applications. It offers request dispatching (Routes) with url parameter \
+support, templates, a built-in HTTP Server and adapters for many third \
+party WSGI/HTTP-server and template engines - all in a single file and \
+with no dependencies other than the Python Standard Library."
+HOMEPAGE = "http://bottlepy.org/"
+SECTION = "devel/python"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${WORKDIR}/LICENSE;md5=94b9b2cc7e46ccea87e00af8970826b5"
+
+inherit allarch
+inherit setuptools
+inherit pypi
+
+RDEPENDS_${PN} += " \
+ python-email \
+ python-json \
+ python-netserver \
+ "
+
+PROVIDES += "${PN}-app"
+PACKAGE_BEFORE_PN += "${PN}-app"
+
+SUMMARY_${PN}-app = "${SRCNAME} app"
+RDEPENDS_${PN}-app = "${PN}"
+FILES_${PN}-app = "${bindir}/bottle.py*"
+
+BBCLASSEXTEND = "nativesdk"
diff --git a/meta-phosphor/recipes-devtools/python/python-bottle/LICENSE b/meta-phosphor/recipes-devtools/python/python-bottle/LICENSE
new file mode 100644
index 000000000..5f3e8de3a
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/python-bottle/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2014, Marcel Hellkamp.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/meta-phosphor/recipes-devtools/python/python-bottle/json-format.patch b/meta-phosphor/recipes-devtools/python/python-bottle/json-format.patch
new file mode 100644
index 000000000..9e754a996
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/python-bottle/json-format.patch
@@ -0,0 +1,31 @@
+Index: bottle-0.12.9/bottle.py
+===================================================================
+--- bottle-0.12.9.orig/bottle.py
++++ bottle-0.12.9/bottle.py
+@@ -1721,8 +1721,10 @@ class JSONPlugin(object):
+ name = 'json'
+ api = 2
+
+- def __init__(self, json_dumps=json_dumps):
++ def __init__(self, json_dumps=json_dumps, **kw):
+ self.json_dumps = json_dumps
++ self.json_kw = { x:y for x,y in kw.iteritems() \
++ if x in ['indent','sort_keys'] }
+
+ def apply(self, callback, route):
+ dumps = self.json_dumps
+@@ -1735,12 +1737,12 @@ class JSONPlugin(object):
+
+ if isinstance(rv, dict):
+ #Attempt to serialize, raises exception on failure
+- json_response = dumps(rv)
++ json_response = dumps(rv, **self.json_kw)
+ #Set content type only if serialization succesful
+ response.content_type = 'application/json'
+ return json_response
+ elif isinstance(rv, HTTPResponse) and isinstance(rv.body, dict):
+- rv.body = dumps(rv.body)
++ rv.body = dumps(rv.body, **self.json_kw)
+ rv.content_type = 'application/json'
+ return rv
+
diff --git a/meta-phosphor/recipes-devtools/python/python-bottle_0.12.13.bb b/meta-phosphor/recipes-devtools/python/python-bottle_0.12.13.bb
new file mode 100644
index 000000000..08d84ff4a
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/python-bottle_0.12.13.bb
@@ -0,0 +1,10 @@
+SRC_URI[sha256sum] = "39b751aee0b167be8dffb63ca81b735bbf1dd0905b3bc42761efedee8f123355"
+SRC_URI[md5sum] = "d2fe1b48c1d49217e78bf326b1cad437"
+
+# There is no license on pypi. See:
+# https://github.com/bottlepy/bottle/commit/55a505b3a54bb7de23e9554cb8ce7f8e160c31a0
+SRC_URI += "file://LICENSE"
+
+SRC_URI += "file://json-format.patch"
+
+require python-bottle.inc
diff --git a/meta-phosphor/recipes-devtools/python/python-gevent-websocket_0.10.1.bb b/meta-phosphor/recipes-devtools/python/python-gevent-websocket_0.10.1.bb
new file mode 100644
index 000000000..8ac2a8982
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/python-gevent-websocket_0.10.1.bb
@@ -0,0 +1,17 @@
+HOMEPAGE = "https://bitbucket.org/noppo/gevent-websocket"
+SUMMARY = "A websocket library for gevent Python networking library"
+DESCRIPTION = "\
+ WebSocket is a computer communications protocol, providing full-duplex \
+ communication channels over a single TCP connection. gevent-websocket \
+ library provides websocket support for gevent. \
+ "
+SECTION = "devel/python"
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=5aa2f1d4ea55d60497aa8c3debf29ab2"
+
+RDEPENDS_${PN} = "python-gevent"
+
+SRC_URI[md5sum] = "e095bf3358175489a956949c1b4de9ff"
+SRC_URI[sha256sum] = "7eaef32968290c9121f7c35b973e2cc302ffb076d018c9068d2f5ca8b2d85fb0"
+
+inherit setuptools pypi
diff --git a/meta-phosphor/recipes-devtools/python/python-inflection.inc b/meta-phosphor/recipes-devtools/python/python-inflection.inc
new file mode 100644
index 000000000..71d218cb2
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/python-inflection.inc
@@ -0,0 +1,20 @@
+SUMMARY = "A port of Ruby on Rails inflector to Python"
+DESCRIPTION = "Inflection is a string transformation library. It singularizes \
+and pluralizes English words, and transforms strings from CamelCase to \
+underscored string. Inflection is a port of Ruby on Rails’ inflector to Python."
+HOMEPAGE = "http://github.com/jpvanhal/inflection"
+SECTION = "devel/python"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=de7833d9c2ce0052a4073928c76a13d7"
+
+inherit allarch
+inherit setuptools
+inherit pypi
+
+RDEPENDS_${PN} += " \
+ ${PYTHON_PN}-re \
+ ${PYTHON_PN}-codecs \
+ "
+RDEPENDS_${PN}_class-native = ""
+
+BBCLASSEXTEND = "native nativesdk"
diff --git a/meta-phosphor/recipes-devtools/python/python-inflection_0.3.1.bb b/meta-phosphor/recipes-devtools/python/python-inflection_0.3.1.bb
new file mode 100644
index 000000000..318171c89
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/python-inflection_0.3.1.bb
@@ -0,0 +1,3 @@
+SRC_URI[sha256sum] = "18ea7fb7a7d152853386523def08736aa8c32636b047ade55f7578c4edeb16ca"
+SRC_URI[md5sum] = "7941165e9f148e0520023941c0886b40"
+require python-inflection.inc
diff --git a/meta-phosphor/recipes-devtools/python/python-mako_1.0.7.bb b/meta-phosphor/recipes-devtools/python/python-mako_1.0.7.bb
new file mode 100644
index 000000000..1bc2efcc8
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/python-mako_1.0.7.bb
@@ -0,0 +1,11 @@
+require recipes-devtools/python/python-mako.inc
+
+inherit setuptools
+
+RDEPENDS_${PN} = "python-threading \
+ python-netclient \
+ python-html \
+"
+RDEPENDS_${PN}_class-native = ""
+
+BBCLASSEXTEND = "native nativesdk"
diff --git a/meta-phosphor/recipes-devtools/python/python-pygobject/obsolete_automake_macros.patch b/meta-phosphor/recipes-devtools/python/python-pygobject/obsolete_automake_macros.patch
new file mode 100644
index 000000000..c2591123b
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/python-pygobject/obsolete_automake_macros.patch
@@ -0,0 +1,23 @@
+Upstream-Status: Accepted [https://bugzilla.gnome.org/show_bug.cgi?id=691101]
+
+Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
+diff -Nurd pygobject-2.27.91/configure.ac pygobject-2.27.91/configure.ac
+--- pygobject-2.27.91/configure.ac 2011-02-23 22:14:37.000000000 +0200
++++ pygobject-2.27.91/configure.ac 2013-01-03 05:13:44.034949954 +0200
+@@ -35,7 +35,7 @@
+ AC_DEFINE(PYGOBJECT_MICRO_VERSION, pygobject_micro_version, [pygobject micro version])
+ AC_SUBST(PYGOBJECT_MICRO_VERSION, pygobject_micro_version)
+
+-AM_CONFIG_HEADER(config.h)
++AC_CONFIG_HEADERS(config.h)
+ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES(yes)])
+ AM_INIT_AUTOMAKE(foreign)
+ AM_MAINTAINER_MODE
+@@ -82,7 +82,6 @@
+ m4_ifdef([LT_OUTPUT], [LT_OUTPUT])
+ AC_ISC_POSIX
+ AC_PROG_CC
+-AM_PROG_CC_STDC
+ AM_PROG_CC_C_O
+
+ # check that we have the minimum version of python necisary to build
diff --git a/meta-phosphor/recipes-devtools/python/python-pygobject_2.28.7.bb b/meta-phosphor/recipes-devtools/python/python-pygobject_2.28.7.bb
new file mode 100644
index 000000000..c6fb6fe26
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/python-pygobject_2.28.7.bb
@@ -0,0 +1,53 @@
+SUMMARY = "Python GObject bindings"
+SECTION = "devel/python"
+LICENSE = "LGPLv2.1"
+
+RECIPE_NO_UPDATE_REASON = "Newer versions of python-pygobject depend on gobject-introspection which doesn't cross-compile"
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=a916467b91076e631dd8edb7424769c7"
+DEPENDS = "python python-pygobject-native libffi glib-2.0"
+DEPENDS_class-native = "python-native libffi-native glib-2.0-native"
+RDEPENDS_class-native = ""
+
+MAJ_VER = "${@d.getVar('PV',1).split('.')[0]}.${@d.getVar('PV',1).split('.')[1]}"
+
+SRC_URI = "${GNOME_MIRROR}/pygobject/${MAJ_VER}/pygobject-${PV}.tar.xz \
+ file://obsolete_automake_macros.patch \
+"
+
+# libtool-native doesn't have fixinstall.patch applied which means
+# that libs get relinked at installation time. This triggers a
+# relinking along the lines of:
+# gcc -L/tmp/foo/media/build1/poky/build/tmp/sysroots/x86_64-linux/usr/lib -lpyglib-2.0-python -o .libs/_glib.so
+# where /tmp/foo is DESTDIR and pyglib-2.0-python may be installed/reinstalled
+# at the same time as the gcc command runs.
+# If this happens between the handoff between gcc and ld, you can see:
+# /bin/ld: cannot find -lpyglib-2.0-python
+# Adding a dependency rule like install-pyglibLTLIBRARIES: install-libLTLIBRARIES
+# would be ideal but automake can't cope with that without manually
+# defining the whole function. Give up and disable parallel make in native builds.
+PARALLEL_MAKEINST_class-native = ""
+
+SRC_URI[md5sum] = "ae48b60c690c4aa894e69e0c97802745"
+SRC_URI[sha256sum] = "bb9d25a3442ca7511385a7c01b057492095c263784ef31231ffe589d83a96a5a"
+S = "${WORKDIR}/pygobject-${PV}"
+
+EXTRA_OECONF += "--disable-introspection"
+
+inherit autotools distutils-base pkgconfig
+
+# necessary to let the call for python-config succeed
+export BUILD_SYS
+export HOST_SYS
+export STAGING_INCDIR
+export STAGING_LIBDIR
+
+PACKAGES += "${PN}-lib"
+
+RDEPENDS_${PN} += "python-textutils"
+
+FILES_${PN} = "${libdir}/python*"
+FILES_${PN}-lib = "${libdir}/lib*.so.*"
+FILES_${PN}-dev += "${bindir} ${datadir}"
+
+BBCLASSEXTEND = "native"
diff --git a/meta-phosphor/recipes-devtools/python/python-pyyaml_%.bbappend b/meta-phosphor/recipes-devtools/python/python-pyyaml_%.bbappend
new file mode 100644
index 000000000..2a590838b
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/python-pyyaml_%.bbappend
@@ -0,0 +1 @@
+BBCLASSEXTEND += "nativesdk"
diff --git a/meta-phosphor/recipes-devtools/python/python/0001-json-Use-int-long.__str__-to-convert-subclasses.patch b/meta-phosphor/recipes-devtools/python/python/0001-json-Use-int-long.__str__-to-convert-subclasses.patch
new file mode 100644
index 000000000..26669d848
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/python/0001-json-Use-int-long.__str__-to-convert-subclasses.patch
@@ -0,0 +1,128 @@
+From b002fd4b884b5f8cd3f429ea2002dd19e91d1d91 Mon Sep 17 00:00:00 2001
+From: Brad Bishop <bradleyb@fuzziesquirrel.com>
+Date: Thu, 7 Jun 2018 09:18:01 -0400
+Subject: [PATCH] json: Use int/long.__str__ to convert subclasses
+
+Based on changes that went into 3.x:
+
+e0805cf10ea84b44a13ad5649267edba7cb83ee9
+a4998a70416c27730e75c0a4225ee2c3552b1618
+---
+ Lib/json/encoder.py | 26 ++++++++++++++++++--------
+ Modules/_json.c | 21 +++++++++++++++++----
+ 2 files changed, 35 insertions(+), 12 deletions(-)
+
+diff --git a/Lib/json/encoder.py b/Lib/json/encoder.py
+index 97ffe8e8a2..3156682fdd 100644
+--- a/Lib/json/encoder.py
++++ b/Lib/json/encoder.py
+@@ -283,6 +283,8 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
+ long=long,
+ str=str,
+ tuple=tuple,
++ _intstr=int.__str__,
++ _longstr=long.__str__,
+ ):
+
+ def _iterencode_list(lst, _current_indent_level):
+@@ -317,8 +319,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
+ yield buf + 'true'
+ elif value is False:
+ yield buf + 'false'
+- elif isinstance(value, (int, long)):
+- yield buf + str(value)
++ elif isinstance(value, int):
++ yield buf + _intstr(value)
++ elif isinstance(value, long):
++ yield buf + _longstr(value)
+ elif isinstance(value, float):
+ yield buf + _floatstr(value)
+ else:
+@@ -374,8 +378,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
+ key = 'false'
+ elif key is None:
+ key = 'null'
+- elif isinstance(key, (int, long)):
+- key = str(key)
++ elif isinstance(key, int):
++ key = _intstr(key)
++ elif isinstance(key, long):
++ key = _longstr(key)
+ elif _skipkeys:
+ continue
+ else:
+@@ -394,8 +400,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
+ yield 'true'
+ elif value is False:
+ yield 'false'
+- elif isinstance(value, (int, long)):
+- yield str(value)
++ elif isinstance(value, int):
++ yield _intstr(value)
++ elif isinstance(value, long):
++ yield _longstr(value)
+ elif isinstance(value, float):
+ yield _floatstr(value)
+ else:
+@@ -423,8 +431,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
+ yield 'true'
+ elif o is False:
+ yield 'false'
+- elif isinstance(o, (int, long)):
+- yield str(o)
++ elif isinstance(o, long):
++ yield _longstr(o)
++ elif isinstance(o, int):
++ yield _intstr(o)
+ elif isinstance(o, float):
+ yield _floatstr(o)
+ elif isinstance(o, (list, tuple)):
+diff --git a/Modules/_json.c b/Modules/_json.c
+index 39ec467b09..f429738145 100644
+--- a/Modules/_json.c
++++ b/Modules/_json.c
+@@ -1981,12 +1981,19 @@ encoder_listencode_obj(PyEncoderObject *s, PyObject *rval, PyObject *obj, Py_ssi
+ return -1;
+ return _steal_list_append(rval, encoded);
+ }
+- else if (PyInt_Check(obj) || PyLong_Check(obj)) {
+- PyObject *encoded = PyObject_Str(obj);
++ else if (PyLong_Check(obj)) {
++ PyObject *encoded = PyLong_Type.tp_str(obj);
+ if (encoded == NULL)
+ return -1;
+ return _steal_list_append(rval, encoded);
+ }
++ else if (PyInt_Check(obj)) {
++ PyObject *encoded = PyInt_Type.tp_str(obj);
++ if (encoded == NULL)
++ return -1;
++ return _steal_list_append(rval, encoded);
++ }
++
+ else if (PyFloat_Check(obj)) {
+ PyObject *encoded = encoder_encode_float(s, obj);
+ if (encoded == NULL)
+@@ -2131,11 +2138,17 @@ encoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ss
+ if (kstr == NULL)
+ goto bail;
+ }
+- else if (PyInt_Check(key) || PyLong_Check(key)) {
+- kstr = PyObject_Str(key);
++ else if (PyLong_Check(key)) {
++ kstr = PyLong_Type.tp_str(key);
+ if (kstr == NULL)
+ goto bail;
+ }
++ else if (PyInt_Check(key)) {
++ kstr = PyInt_Type.tp_str(key);
++ if (kstr == NULL)
++ goto bail;
++ }
++
+ else if (key == Py_True || key == Py_False || key == Py_None) {
+ kstr = _encoded_const(key);
+ if (kstr == NULL)
+--
+2.14.3
+
diff --git a/meta-phosphor/recipes-devtools/python/python_2.%.bbappend b/meta-phosphor/recipes-devtools/python/python_2.%.bbappend
new file mode 100644
index 000000000..6d0ff6901
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/python_2.%.bbappend
@@ -0,0 +1,14 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+SRC_URI += "file://0001-json-Use-int-long.__str__-to-convert-subclasses.patch"
+
+require wsgiref-${PYTHON_MAJMIN}-manifest.inc
+
+PROVIDES_prepend = "${PN}-spwd "
+PACKAGES_prepend = "${PN}-spwd "
+
+SUMMARY_${PN}-spwd = "Shadow database support"
+RDEPENDS_${PN}-spwd = "${PN}-core"
+FILES_${PN}-spwd= " \
+ ${libdir}/python${PYTHON_MAJMIN}/lib-dynload/spwd.so \
+ ${libdir}/python${PYTHON_MAJMIN}/lib-dynload/grp.so \
+ "
diff --git a/meta-phosphor/recipes-devtools/python/wsgiref-2.7-manifest.inc b/meta-phosphor/recipes-devtools/python/wsgiref-2.7-manifest.inc
new file mode 100644
index 000000000..a21d05ee2
--- /dev/null
+++ b/meta-phosphor/recipes-devtools/python/wsgiref-2.7-manifest.inc
@@ -0,0 +1,33 @@
+NAME = "wsgiref"
+
+PROVIDES_prepend = "${PN}-${NAME} ${PN}-${NAME}-headers ${PN}-${NAME}-handlers ${PN}-${NAME}-validate ${PN}-${NAME}-simple_server ${PN}-${NAME}-util "
+PACKAGES_prepend = "${PN}-${NAME} ${PN}-${NAME}-headers ${PN}-${NAME}-handlers ${PN}-${NAME}-validate ${PN}-${NAME}-simple_server ${PN}-${NAME}-util "
+
+package_dir = "${libdir}/python${PYTHON_MAJMIN}/${NAME}"
+
+SUMMARY_${PN}-${NAME}-handlers = "${NAME} handlers"
+RDEPENDS_${PN}-${NAME}-handlers = "${PN}-${NAME}-util ${PN}-${NAME}-headers"
+FILES_${PN}-${NAME}-handlers = "${package_dir}/handlers.py*"
+
+SUMMARY_${PN}-${NAME}-headers = "${NAME} headers"
+RDEPENDS_${PN}-${NAME}-headers = "${PN}-${NAME}"
+FILES_${PN}-${NAME}-headers = "${package_dir}/headers.py*"
+
+SUMMARY_${PN}-${NAME}-simple_server = "${NAME} simple server"
+RDEPENDS_${PN}-${NAME}-simple_server = "${PN}-${NAME}-handlers"
+FILES_${PN}-${NAME}-simple_server = "${package_dir}/simple_server.py*"
+
+SUMMARY_${PN}-${NAME}-util = "${NAME} util"
+RDEPENDS_${PN}-${NAME}-util = "${PN}-${NAME}"
+FILES_${PN}-${NAME}-util = "${package_dir}/util.py*"
+
+SUMMARY_${PN}-${NAME}-validate = "${NAME} validate"
+RDEPENDS_${PN}-${NAME}-validate = "${PN}-${NAME}"
+FILES_${PN}-${NAME}-validate = "${package_dir}/validate.py*"
+
+SUMMARY_${PN}-${NAME} = "WSGI (PEP 333) Reference Library"
+RDEPENDS_${PN}-${NAME} = "${PN}-core"
+FILES_${PN}-${NAME} = " \
+ ${package_dir}/__init__.py* \
+ ${package_dir}.egg-info \
+ "