I don't have a good way to test it without also converting cvs2gitdump
(which is beyond my pythons skills) but leaving this here before it rots
in my local tree ;)
Index: Makefile
===================================================================
RCS file: /cvs/ports/devel/py-rcsparse/Makefile,v
retrieving revision 1.20
diff -u -p -r1.20 Makefile
--- Makefile 12 Jul 2019 20:45:52 -0000 1.20
+++ Makefile 26 Apr 2020 16:13:12 -0000
@@ -8,15 +8,22 @@ GH_COMMIT= 206bca0b90f5780815c0b6c6cbcc
DISTNAME= rcsparse-20151027
PKGNAME= py-${DISTNAME}
+REVISION= 0
-CATEGORIES= devel
+CATEGORIES= devel
# AGPLv3+
PERMIT_PACKAGE= Yes
WANTLIB += ${MODPY_WANTLIB} pthread
+FLAVORS= python3
+FLAVOR?=
+
MODULES= lang/python
-NO_TEST= Yes
+TEST_DEPENDS= ${BUILD_PKGPATH}
+
+do-test:
+ cd ${WRKSRC}; ${MODPY_BIN} testmodule.py
.include <bsd.port.mk>
Index: patches/patch-py-rcsparse_c
===================================================================
RCS file: patches/patch-py-rcsparse_c
diff -N patches/patch-py-rcsparse_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-py-rcsparse_c 26 Apr 2020 16:13:12 -0000
@@ -0,0 +1,138 @@
+$OpenBSD$
+
+Index: py-rcsparse.c
+--- py-rcsparse.c.orig
++++ py-rcsparse.c
+@@ -25,6 +25,13 @@
+ #include "rcsparse.h"
+
+
++#if PY_MAJOR_VERSION >= 3
++#define PyString_AsStringAndSize(a,b,c) PyUnicode_AsUTF8AndSize(a,c)
++#define PyString_CheckExact PyUnicode_CheckExact
++#define PyString_FromString PyUnicode_FromString
++#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
++#endif
++
+ static PyObject *
+ rcstoken2pystr(struct rcstoken *tok)
+ {
+@@ -124,7 +131,11 @@ rcsrev2py(struct rcsrev *rev)
+
+ return Py_BuildValue("NNNNNNN",
+ rcstoken2pystr(rev->rev),
++#if PY_MAJOR_VERSION >= 3
++ PyLong_FromLong(timegm(&tm)),
++#else
+ PyInt_FromLong(timegm(&tm)),
++#endif
+ rcstoken2pystr(rev->author),
+ rcstoken2pystr(rev->state),
+ rcstoklist2py(&rev->branches),
+@@ -275,7 +286,7 @@ static void
+ pyrcsrevtree_dealloc(struct pyrcsrevtree *self)
+ {
+ Py_DECREF((PyObject *)self->pyrcs);
+- self->ob_type->tp_free(self);
++ Py_TYPE(self)->tp_free(self);
+ }
+
+ static PyMappingMethods pyrcsrevtree_mapmethods = {
+@@ -300,7 +311,7 @@ static PyMethodDef pyrcsrevtree_methods[] = {
+ };
+
+ static PyTypeObject pyrcsrevtree_type = {
+- PyObject_HEAD_INIT(&PyType_Type)
++ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ .tp_name= "rcsparse.rcsrevtree",
+ .tp_basicsize= sizeof(struct pyrcsrevtree),
+ .tp_dealloc= (destructor)pyrcsrevtree_dealloc,
+@@ -496,7 +507,7 @@ static void
+ pyrcstokmap_dealloc(struct pyrcstokmap *self)
+ {
+ Py_DECREF((PyObject *)self->pyrcs);
+- self->ob_type->tp_free(self);
++ Py_TYPE(self)->tp_free(self);
+ }
+
+ static PyMappingMethods pyrcstokmap_mapmethods = {
+@@ -521,7 +532,7 @@ static PyMethodDef pyrcstokmap_methods[] = {
+ };
+
+ static PyTypeObject pyrcstokmap_type = {
+- PyObject_HEAD_INIT(&PyType_Type)
++ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ .tp_name= "rcsparse.rcstokmap",
+ .tp_basicsize= sizeof(struct pyrcstokmap),
+ .tp_dealloc= (destructor)pyrcstokmap_dealloc,
+@@ -720,7 +731,7 @@ pyrcsfile_dealloc(struct pyrcsfile *self)
+ if (self->rcs != NULL)
+ rcsclose(self->rcs);
+
+- self->ob_type->tp_free(self);
++ Py_TYPE(self)->tp_free(self);
+ }
+
+ static PyGetSetDef pyrcsfile_getseters[] = {
+@@ -761,21 +772,48 @@ static PyMethodDef pyrcsparse_methods[] = {
+ {NULL}
+ };
+
++#if PY_MAJOR_VERSION >= 3
++static struct PyModuleDef moduledef = {
++ PyModuleDef_HEAD_INIT,
++ "rcsparse", /* m_name */
++ "RCS file parser", /* m_doc */
++ -1, /* m_size */
++ pyrcsparse_methods, /* m_methods */
++ NULL, /* m_reload */
++ NULL, /* m_traverse */
++ NULL, /* m_clear */
++ NULL, /* m_free */
++};
++#endif
++
++#if PY_MAJOR_VERSION >= 3
++#define retnull return NULL
++
+ PyMODINIT_FUNC
++PyInit_rcsparse(void)
++#else
++#define retnull return
++
++PyMODINIT_FUNC
+ initrcsparse(void)
++#endif
+ {
+ PyObject *m;
+
+ if (PyType_Ready(&pyrcsfile_type) < 0)
+- return;
++ retnull;
+ if (PyType_Ready(&pyrcstokmap_type) < 0)
+- return;
++ retnull;
+ if (PyType_Ready(&pyrcsrevtree_type) < 0)
+- return;
++ retnull;
+
++#if PY_MAJOR_VERSION >= 3
++ m = PyModule_Create(&moduledef);
++#else
+ m = Py_InitModule3("rcsparse", pyrcsparse_methods, "RCS file parser");
++#endif
+ if (m == NULL)
+- return;
++ retnull;
+
+ Py_INCREF(&pyrcsfile_type);
+ PyModule_AddObject(m, "rcsfile", (PyObject *)&pyrcsfile_type);
+@@ -783,4 +821,8 @@ initrcsparse(void)
+ PyModule_AddObject(m, "rcstokmap", (PyObject *)&pyrcstokmap_type);
+ Py_INCREF(&pyrcsrevtree_type);
+ PyModule_AddObject(m, "rcsrevtree", (PyObject *)&pyrcsrevtree_type);
++
++#if PY_MAJOR_VERSION >= 3
++ return m;
++#endif
+ }
Index: patches/patch-testmodule_py
===================================================================
RCS file: patches/patch-testmodule_py
diff -N patches/patch-testmodule_py
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-testmodule_py 26 Apr 2020 16:13:12 -0000
@@ -0,0 +1,25 @@
+$OpenBSD$
+
+Index: testmodule.py
+--- testmodule.py.orig
++++ testmodule.py
+@@ -1,13 +1,12 @@
+ import rcsparse
+-import md5
+
+ f=rcsparse.rcsfile('test,v')
+-print f.head
+-print f.branch
++print (f.head)
++print (f.branch)
+ s=f.symbols
+-print s['RELENG_4']
+-print s.items()
++print (s['RELENG_4'])
++print (s.items())
+ r=f.revs
+ i=r.items()
+-print i
+-print f.getlog(f.sym2rev('RELENG_4'))
++print (i)
++print (f.getlog(f.sym2rev('RELENG_4')))
Index: pkg/PLIST
===================================================================
RCS file: /cvs/ports/devel/py-rcsparse/pkg/PLIST,v
retrieving revision 1.3
diff -u -p -r1.3 PLIST
--- pkg/PLIST 31 Oct 2015 16:30:18 -0000 1.3
+++ pkg/PLIST 26 Apr 2020 16:13:12 -0000
@@ -1,4 +1,4 @@
@comment $OpenBSD: PLIST,v 1.3 2015/10/31 16:30:18 sthen Exp $
@conflict rcsparse-*
lib/python${MODPY_VERSION}/site-packages/rcsparse-0.1-py${MODPY_VERSION}.egg-info
-lib/python${MODPY_VERSION}/site-packages/rcsparse.so
+@so lib/python${MODPY_VERSION}/site-packages/rcsparse.so