Skip to content
This repository has been archived by the owner on Feb 20, 2024. It is now read-only.

Python3 compatibility #18

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ Requirements

* Python 2.4 or later
* Works on Python 2.4 -> 2.7
* Python 3 not yet supported (coming soon)
* Works on Python 3.5
* Python 3.6 not yet supported
* Python package six is required

* New `XRootD <http://xrootd.org/dload.html>`_ client + development headers
* `xrootd-client, xrootd-client-devel` packages
* Version 3.3.3 or above required
Expand Down
8 changes: 4 additions & 4 deletions libs/client/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from filesystem import FileSystem as FileSystem
from file import File as File
from url import URL as URL
from copyprocess import CopyProcess as CopyProcess
from .filesystem import FileSystem as FileSystem
from .file import File as File
from .url import URL as URL
from .copyprocess import CopyProcess as CopyProcess
3 changes: 2 additions & 1 deletion libs/client/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with XRootD. If not, see <http:#www.gnu.org/licenses/>.
#-------------------------------------------------------------------------------
import six

def enum(**enums):
"""Build the equivalent of a C++ enum"""
reverse = dict((value, key) for key, value in enums.iteritems())
reverse = dict((value, key) for key, value in six.iteritems(enums))
enums['reverse_mapping'] = reverse
return type('Enum', (), enums)

Expand Down
3 changes: 2 additions & 1 deletion libs/client/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
# along with XRootD. If not, see <http:#www.gnu.org/licenses/>.
#-------------------------------------------------------------------------------
from XRootD.client.url import URL
import six

class Struct(object):
"""Convert a dict into an object by adding each dict entry to __dict__"""
def __init__(self, entries):
self.__dict__.update(**entries)
def __repr__(self):
return '<%s>' % str(', '.join('%s: %s' % (k, repr(v))
for (k, v) in self.__dict__.iteritems()))
for (k, v) in six.iteritems(self.__dict__)))

class LocationInfo(Struct):
"""Path location information (a list of discovered file locations).
Expand Down
13 changes: 7 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
from distutils import sysconfig
from os import getenv, walk, path
import subprocess
import six

# Remove the "-Wstrict-prototypes" compiler option, which isn't valid for C++.
cfg_vars = sysconfig.get_config_vars()
opt = cfg_vars["OPT"]
cfg_vars["OPT"] = " ".join( flag for flag in opt.split() if flag != '-Wstrict-prototypes' )

xrdlibdir = getenv( 'XRD_LIBDIR' ) or '/usr/lib'
xrdincdir = getenv( 'XRD_INCDIR' ) or '/usr/include/xrootd'
xrdlibdir = getenv( 'XRD_LIBDIR' ) or '/opt/xrootd/lib'
xrdincdir = getenv( 'XRD_INCDIR' ) or '/opt/xrootd/include/xrootd'

print 'XRootD library dir:', xrdlibdir
print 'XRootD include dir:', xrdincdir
print ('XRootD library dir:', xrdlibdir)
print ('XRootD include dir:', xrdincdir)

sources = list()
depends = list()
Expand All @@ -26,10 +27,10 @@

p = subprocess.Popen(["./genversion.sh"], stdout=subprocess.PIPE)
version, err = p.communicate()
print version
print (version)

setup( name = 'pyxrootd',
version = version,
version = str(version),
author = 'XRootD Developers',
author_email = 'xrootd-dev@slac.stanford.edu',
url = 'http://xrootd.org',
Expand Down
4 changes: 4 additions & 0 deletions src/ChunkIterator.hh
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,12 @@ namespace PyXRootD
//! ChunkIterator type structure
//----------------------------------------------------------------------------
static PyTypeObject ChunkIteratorType = {
#if PY_MAJOR_VERSION >= 3
PyVarObject_HEAD_INIT(NULL, 0)
#else
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
#endif
"client.File.ChunkIterator", /* tp_name */
sizeof(ChunkIterator), /* tp_basicsize */
0, /* tp_itemsize */
Expand Down
15 changes: 15 additions & 0 deletions src/PyXRootD.hh
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,24 @@
#include <string>
#include "structmember.h"

#if PY_MAJOR_VERSION >= 3
#define IS_PY3K
#define PyString_AsString PyUnicode_AsUTF8
#define PyString_Check PyUnicode_Check
#define PyInt_FromLong PyLong_FromLong
#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
#define METH_KEYWORDS METH_VARARGS
#define PyString_Size PyUnicode_GET_SIZE
#define PyInt_FromLong PyLong_FromLong
#define PyInt_Check PyLong_Check
#define PyInt_AsLong PyLong_AsLong
#define initclient PyInit_client
#define PyString_FromString PyUnicode_FromString
#else
#if PY_MINOR_VERSION <= 5
#define PyUnicode_FromString PyString_FromString
#endif
#endif

#define async( func ) \
Py_BEGIN_ALLOW_THREADS \
Expand Down
12 changes: 10 additions & 2 deletions src/PyXRootDCopyProcess.hh
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ namespace PyXRootD
{
delete self->process;
delete self->results;
#if PY_MAJOR_VERSION >= 3
Py_TYPE(self)->tp_free( (PyObject*) self );
#else
self->ob_type->tp_free( (PyObject*) self );
#endif
}

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -97,8 +101,12 @@ namespace PyXRootD
//! CopyProcess binding type object
//----------------------------------------------------------------------------
static PyTypeObject CopyProcessType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
#if PY_MAJOR_VERSION >= 3
PyVarObject_HEAD_INIT(NULL, 0)
#else
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
#endif
"pyxrootd.CopyProcess", /* tp_name */
sizeof(CopyProcess), /* tp_basicsize */
0, /* tp_itemsize */
Expand Down
17 changes: 15 additions & 2 deletions src/PyXRootDFile.hh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@

#include <deque>

#if PY_MAJOR_VERSION >=3
# define Py_TPFLAGS_HAVE_ITER 0
#endif

namespace PyXRootD
{
//----------------------------------------------------------------------------
Expand Down Expand Up @@ -98,7 +102,11 @@ namespace PyXRootD
delete self->file;
delete self->partial;
delete self->surplus;
#if PY_MAJOR_VERSION >= 3
Py_TYPE(self)->tp_free( (PyObject*) self );
#else
self->ob_type->tp_free( (PyObject*) self );
#endif
}

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -214,8 +222,13 @@ namespace PyXRootD
//! File binding type object
//----------------------------------------------------------------------------
static PyTypeObject FileType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */

#if PY_MAJOR_VERSION >= 3
PyVarObject_HEAD_INIT(NULL, 0)
#else
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
#endif
"pyxrootd.File", /* tp_name */
sizeof(File), /* tp_basicsize */
0, /* tp_itemsize */
Expand Down
13 changes: 11 additions & 2 deletions src/PyXRootDFileSystem.hh
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ namespace PyXRootD
{
delete self->filesystem;
Py_XDECREF( self->url );
#if PY_MAJOR_VERSION >= 3
Py_TYPE(self)->tp_free( (PyObject*) self );
#else
self->ob_type->tp_free( (PyObject*) self );
#endif
}

//----------------------------------------------------------------------------
Expand All @@ -150,8 +154,13 @@ namespace PyXRootD
//----------------------------------------------------------------------------
//! FileSystem binding type object
//----------------------------------------------------------------------------
static PyTypeObject FileSystemType =
{ PyObject_HEAD_INIT(NULL) 0, /* ob_size */
static PyTypeObject FileSystemType = {
#if PY_MAJOR_VERSION >= 3
PyVarObject_HEAD_INIT(NULL, 0)
#else
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
#endif
"pyxrootd.FileSystem", /* tp_name */
sizeof(FileSystem), /* tp_basicsize */
0, /* tp_itemsize */
Expand Down
59 changes: 53 additions & 6 deletions src/PyXRootDModule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ namespace PyXRootD
//----------------------------------------------------------------------------
//! Module initialization function
//----------------------------------------------------------------------------
#if PY_MAJOR_VERSION >= 3
PyMODINIT_FUNC PyInit_client( void )
#else
PyMODINIT_FUNC initclient( void )
#endif
{
// Ensure GIL state is initialized
Py_Initialize();
Expand All @@ -55,30 +59,73 @@ namespace PyXRootD
}

FileSystemType.tp_new = PyType_GenericNew;
if ( PyType_Ready( &FileSystemType ) < 0 ) return;
Py_INCREF( &FileSystemType );
if ( PyType_Ready( &FileSystemType ) < 0 )
#if PY_MAJOR_VERSION >= 3
return 0;
#else
return;
#endif
Py_INCREF( &FileSystemType );

FileType.tp_new = PyType_GenericNew;
if ( PyType_Ready( &FileType ) < 0 ) return;
if ( PyType_Ready( &FileType ) < 0 )
#if PY_MAJOR_VERSION >= 3
return 0;
#else
return;
#endif
Py_INCREF( &FileType );

URLType.tp_new = PyType_GenericNew;
if ( PyType_Ready( &URLType ) < 0 ) return;
if ( PyType_Ready( &URLType ) < 0 )
#if PY_MAJOR_VERSION >= 3
return 0;
#else
return;
#endif
Py_INCREF( &URLType );

CopyProcessType.tp_new = PyType_GenericNew;
if ( PyType_Ready( &CopyProcessType ) < 0 ) return;
if ( PyType_Ready( &CopyProcessType ) < 0 )
#if PY_MAJOR_VERSION >= 3
return 0;
#else
return;
#endif
Py_INCREF( &CopyProcessType );

#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"client", //m_name
client_module_doc, //m_doc
-1, //m_name
module_methods, //m_functions
NULL, //m_reload
NULL, //m_traverse
NULL, //m_clear
NULL, //m_free
};
ClientModule = PyModule_Create(&moduledef);
#else
ClientModule = Py_InitModule3("client", module_methods, client_module_doc);
#endif


if (ClientModule == NULL) {
return;
#if PY_MAJOR_VERSION >= 3
return 0;
#else
return;
#endif
}

PyModule_AddObject( ClientModule, "FileSystem", (PyObject *) &FileSystemType );
PyModule_AddObject( ClientModule, "File", (PyObject *) &FileType );
PyModule_AddObject( ClientModule, "URL", (PyObject *) &URLType );
PyModule_AddObject( ClientModule, "CopyProcess", (PyObject *) &CopyProcessType );
#if PY_MAJOR_VERSION >= 3
return ClientModule;
#endif
}
}
12 changes: 10 additions & 2 deletions src/PyXRootDURL.hh
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ namespace PyXRootD
static void URL_dealloc( URL *self )
{
delete self->url;
#if PY_MAJOR_VERSION >= 3
Py_TYPE(self)->tp_free( (PyObject*) self );
#else
self->ob_type->tp_free( (PyObject*) self );
#endif
}

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -134,8 +138,12 @@ namespace PyXRootD
//! URL binding type object
//----------------------------------------------------------------------------
static PyTypeObject URLType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
#if PY_MAJOR_VERSION >= 3
PyVarObject_HEAD_INIT(NULL, 0)
#else
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
#endif
"pyxrootd.URL", /* tp_name */
sizeof(URL), /* tp_basicsize */
0, /* tp_itemsize */
Expand Down