Skip to content

Commit

Permalink
Upgrade python packaging to distribute as a platform wheel. (#5)
Browse files Browse the repository at this point in the history
* Upgrade python packaging to distribute as a platform wheel.

Move to setuptools and separate setup.cfg configuration file.
MANIFEST.in file is no longer needed.

Make sknobs extension python2/3 compatible using the py3c library.

Link to README.md added as setuptools applies a sandbox to avoid
use of outside files.

* Note some package dependencies for building.

* Avoid attempt to update system POD file.

* Include py3c headers to avoid build depenency.  Some distros (e.g., AL2) have
no package for this.

* Add include directory for build.
  • Loading branch information
joshuascheid authored Jun 19, 2019
1 parent 3d90c9b commit c29c3a9
Show file tree
Hide file tree
Showing 16 changed files with 612 additions and 25 deletions.
11 changes: 11 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,14 @@ If you wish particular languages not to be built, add one of more of the followi
* `SKNOBS_PYTHON=0`
* `SKNOBS_TCL=0`
* `SKNOBS_VERILOG=0`

System Package Dependencies (RPM package names)
* perl-devel
* python3
* python3-devel
* python3-setuptools

Python Package Dependencies. It is expected that you are running in an
appropriate virtal environment for the version of python for which you wish to
build.
* pip install wheel
3 changes: 3 additions & 0 deletions src/c/external/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
External dependencies.

py3c home: https://py3c.readthedocs.io
34 changes: 34 additions & 0 deletions src/c/external/py3c.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
The MIT License (MIT)
Copyright (c) 2015, Red Hat, Inc. and/or its affiliates
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.
*/

#ifndef _PY3COMPAT_H_
#define _PY3COMPAT_H_

#include <Python.h>

#include <py3c/comparison.h>
#include <py3c/compat.h>
#include <py3c/py3shims.h>

#endif
141 changes: 141 additions & 0 deletions src/c/external/py3c/capsulethunk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/* Copyright (c) 2011, Larry Hastings
* Copyright (c) 2015, py3c contributors
* Licensed under the MIT license; see py3c.h
*
* (Note: Relicensed from PSF: http://bugs.python.org/issue24937#msg250191 )
*/

#ifndef __CAPSULETHUNK_H
#define __CAPSULETHUNK_H

#if ( (PY_VERSION_HEX < 0x02070000) \
|| ((PY_VERSION_HEX >= 0x03000000) \
&& (PY_VERSION_HEX < 0x03010000)) )

#define __PyCapsule_GetField(capsule, field, error_value) \
( PyCapsule_CheckExact(capsule) \
? (((PyCObject *)capsule)->field) \
: (PyErr_SetString(PyExc_TypeError, "CObject required"), (error_value)) \
) \

#define __PyCapsule_SetField(capsule, field, value) \
( PyCapsule_CheckExact(capsule) \
? (((PyCObject *)capsule)->field = value), 0 \
: (PyErr_SetString(PyExc_TypeError, "CObject required"), 1) \
) \


#define PyCapsule_Type PyCObject_Type

#define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule))
#define PyCapsule_IsValid(capsule, name) (PyCObject_Check(capsule))


#define PyCapsule_New(pointer, name, destructor) \
(PyCObject_FromVoidPtr(pointer, (void (*)(void*)) (destructor)))


#define PyCapsule_GetPointer(capsule, name) \
(PyCObject_AsVoidPtr(capsule))

/* Don't call PyCObject_SetPointer here, it fails if there's a destructor */
#define PyCapsule_SetPointer(capsule, pointer) \
__PyCapsule_SetField(capsule, cobject, pointer)


#define PyCapsule_GetDestructor(capsule) \
__PyCapsule_GetField(capsule, destructor, (void (*)(void*)) NULL)

#define PyCapsule_SetDestructor(capsule, dtor) \
__PyCapsule_SetField(capsule, destructor, (void (*)(void*)) dtor)


/*
* Sorry, there's simply no place
* to store a Capsule "name" in a CObject.
*/
#define PyCapsule_GetName(capsule) NULL

static int
PyCapsule_SetName(PyObject *capsule, const char *unused)
{
unused = unused;
PyErr_SetString(PyExc_NotImplementedError,
"can't use PyCapsule_SetName with CObjects");
return 1;
}



#define PyCapsule_GetContext(capsule) \
__PyCapsule_GetField(capsule, desc, (void*) NULL)

#define PyCapsule_SetContext(capsule, context) \
__PyCapsule_SetField(capsule, desc, context)


static void *
PyCapsule_Import(const char *name, int no_block)
{
PyObject *object = NULL;
void *return_value = NULL;
char *trace;
size_t name_length = (strlen(name) + 1) * sizeof(char);
char *name_dup = (char *)PyMem_MALLOC(name_length);

if (!name_dup) {
return NULL;
}

memcpy(name_dup, name, name_length);

trace = name_dup;
while (trace) {
char *dot = strchr(trace, '.');
if (dot) {
*dot++ = '\0';
}

if (object == NULL) {
if (no_block) {
object = PyImport_ImportModuleNoBlock(trace);
} else {
object = PyImport_ImportModule(trace);
if (!object) {
PyErr_Format(PyExc_ImportError,
"PyCapsule_Import could not "
"import module \"%s\"", trace);
}
}
} else {
PyObject *object2 = PyObject_GetAttrString(object, trace);
Py_DECREF(object);
object = object2;
}
if (!object) {
goto EXIT;
}

trace = dot;
}

if (PyCObject_Check(object)) {
PyCObject *cobject = (PyCObject *)object;
return_value = cobject->cobject;
} else {
PyErr_Format(PyExc_AttributeError,
"PyCapsule_Import \"%s\" is not valid",
name);
}

EXIT:
Py_XDECREF(object);
if (name_dup) {
PyMem_FREE(name_dup);
}
return return_value;
}

#endif /* #if PY_VERSION_HEX < 0x02070000 */

#endif /* __CAPSULETHUNK_H */
45 changes: 45 additions & 0 deletions src/c/external/py3c/comparison.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* Copyright (c) 2015, Red Hat, Inc. and/or its affiliates
* Licensed under the MIT license; see py3c.h
*/

#ifndef _PY3C_COMPARISON_H_
#define _PY3C_COMPARISON_H_
#include <Python.h>

/* Rich comparisons */

#ifndef Py_RETURN_NOTIMPLEMENTED
#define Py_RETURN_NOTIMPLEMENTED \
return Py_INCREF(Py_NotImplemented), Py_NotImplemented
#endif

#ifndef Py_UNREACHABLE
#define Py_UNREACHABLE() abort()
#endif

#ifndef Py_RETURN_RICHCOMPARE
#define Py_RETURN_RICHCOMPARE(val1, val2, op) \
do { \
switch (op) { \
case Py_EQ: if ((val1) == (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \
case Py_NE: if ((val1) != (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \
case Py_LT: if ((val1) < (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \
case Py_GT: if ((val1) > (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \
case Py_LE: if ((val1) <= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \
case Py_GE: if ((val1) >= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \
default: \
Py_UNREACHABLE(); \
} \
} while (0)
#endif

#define PY3C_RICHCMP(val1, val2, op) \
((op) == Py_EQ) ? PyBool_FromLong((val1) == (val2)) : \
((op) == Py_NE) ? PyBool_FromLong((val1) != (val2)) : \
((op) == Py_LT) ? PyBool_FromLong((val1) < (val2)) : \
((op) == Py_GT) ? PyBool_FromLong((val1) > (val2)) : \
((op) == Py_LE) ? PyBool_FromLong((val1) <= (val2)) : \
((op) == Py_GE) ? PyBool_FromLong((val1) >= (val2)) : \
(Py_INCREF(Py_NotImplemented), Py_NotImplemented)

#endif
139 changes: 139 additions & 0 deletions src/c/external/py3c/compat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/* Copyright (c) 2015, Red Hat, Inc. and/or its affiliates
* Licensed under the MIT license; see py3c.h
*/

#ifndef _PY3C_COMPAT_H_
#define _PY3C_COMPAT_H_
#include <Python.h>

#if PY_MAJOR_VERSION >= 3

/***** Python 3 *****/

#define IS_PY3 1

/* Strings */

#define PyStr_Type PyUnicode_Type
#define PyStr_Check PyUnicode_Check
#define PyStr_CheckExact PyUnicode_CheckExact
#define PyStr_FromString PyUnicode_FromString
#define PyStr_FromStringAndSize PyUnicode_FromStringAndSize
#define PyStr_FromFormat PyUnicode_FromFormat
#define PyStr_FromFormatV PyUnicode_FromFormatV
#define PyStr_AsString PyUnicode_AsUTF8
#define PyStr_Concat PyUnicode_Concat
#define PyStr_Format PyUnicode_Format
#define PyStr_InternInPlace PyUnicode_InternInPlace
#define PyStr_InternFromString PyUnicode_InternFromString
#define PyStr_Decode PyUnicode_Decode

#define PyStr_AsUTF8String PyUnicode_AsUTF8String /* returns PyBytes */
#define PyStr_AsUTF8 PyUnicode_AsUTF8
#define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize

/* Ints */

#define PyInt_Type PyLong_Type
#define PyInt_Check PyLong_Check
#define PyInt_CheckExact PyLong_CheckExact
#define PyInt_FromString PyLong_FromString
#define PyInt_FromLong PyLong_FromLong
#define PyInt_FromSsize_t PyLong_FromSsize_t
#define PyInt_FromSize_t PyLong_FromSize_t
#define PyInt_AsLong PyLong_AsLong
#define PyInt_AS_LONG PyLong_AS_LONG
#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
#define PyInt_AsSsize_t PyLong_AsSsize_t

/* Module init */

#define MODULE_INIT_FUNC(name) \
PyMODINIT_FUNC PyInit_ ## name(void); \
PyMODINIT_FUNC PyInit_ ## name(void)

#else

/***** Python 2 *****/

#define IS_PY3 0

/* Strings */

#define PyStr_Type PyString_Type
#define PyStr_Check PyString_Check
#define PyStr_CheckExact PyString_CheckExact
#define PyStr_FromString PyString_FromString
#define PyStr_FromStringAndSize PyString_FromStringAndSize
#define PyStr_FromFormat PyString_FromFormat
#define PyStr_FromFormatV PyString_FromFormatV
#define PyStr_AsString PyString_AsString
#define PyStr_Format PyString_Format
#define PyStr_InternInPlace PyString_InternInPlace
#define PyStr_InternFromString PyString_InternFromString
#define PyStr_Decode PyString_Decode

#ifdef __GNUC__
static PyObject *PyStr_Concat(PyObject *left, PyObject *right) __attribute__ ((unused));
#endif
static PyObject *PyStr_Concat(PyObject *left, PyObject *right) {
PyObject *str = left;
Py_INCREF(left); /* reference to old left will be stolen */
PyString_Concat(&str, right);
if (str) {
return str;
} else {
return NULL;
}
}

#define PyStr_AsUTF8String(str) (Py_INCREF(str), (str))
#define PyStr_AsUTF8 PyString_AsString
#define PyStr_AsUTF8AndSize(pystr, sizeptr) \
((*sizeptr=PyString_Size(pystr)), PyString_AsString(pystr))

#define PyBytes_Type PyString_Type
#define PyBytes_Check PyString_Check
#define PyBytes_CheckExact PyString_CheckExact
#define PyBytes_FromString PyString_FromString
#define PyBytes_FromStringAndSize PyString_FromStringAndSize
#define PyBytes_FromFormat PyString_FromFormat
#define PyBytes_FromFormatV PyString_FromFormatV
#define PyBytes_Size PyString_Size
#define PyBytes_GET_SIZE PyString_GET_SIZE
#define PyBytes_AsString PyString_AsString
#define PyBytes_AS_STRING PyString_AS_STRING
#define PyBytes_AsStringAndSize PyString_AsStringAndSize
#define PyBytes_Concat PyString_Concat
#define PyBytes_ConcatAndDel PyString_ConcatAndDel
#define _PyBytes_Resize _PyString_Resize

/* Floats */

#define PyFloat_FromString(str) PyFloat_FromString(str, NULL)

/* Module init */

#define PyModuleDef_HEAD_INIT 0

typedef struct PyModuleDef {
int m_base;
const char* m_name;
const char* m_doc;
Py_ssize_t m_size;
PyMethodDef *m_methods;
} PyModuleDef;

#define PyModule_Create(def) \
Py_InitModule3((def)->m_name, (def)->m_methods, (def)->m_doc)

#define MODULE_INIT_FUNC(name) \
static PyObject *PyInit_ ## name(void); \
PyMODINIT_FUNC init ## name(void); \
PyMODINIT_FUNC init ## name(void) { PyInit_ ## name(); } \
static PyObject *PyInit_ ## name(void)


#endif

#endif
Loading

0 comments on commit c29c3a9

Please sign in to comment.