Skip to content

Commit 075931d

Browse files
author
Fabian Pedregosa
committed
Python 3 compatibility.
Simplified version of scipy strategy: copy files into build/py3k, and patch them using lib2to3.
1 parent e1ecda6 commit 075931d

File tree

5 files changed

+117
-24
lines changed

5 files changed

+117
-24
lines changed

scikits/learn/qda.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#
77
# License: BSD Style.
88

9-
import exceptions
109
import warnings
1110

1211
import numpy as np
@@ -83,7 +82,7 @@ def fit(self, X, y, store_covariances=False, tol=1.0e-4, **params):
8382
X = np.asanyarray(X)
8483
y = np.asanyarray(y)
8584
if X.ndim!=2:
86-
raise exceptions.ValueError('X must be a 2D array')
85+
raise ValueError('X must be a 2D array')
8786
if X.shape[0] != y.shape[0]:
8887
raise ValueError(
8988
'Incompatible shapes: X has %s samples, while y '
@@ -100,7 +99,7 @@ def fit(self, X, y, store_covariances=False, tol=1.0e-4, **params):
10099
classes = np.unique(y)
101100
n_classes = classes.size
102101
if n_classes < 2:
103-
raise exceptions.ValueError('y has less than 2 classes')
102+
raise ValueError('y has less than 2 classes')
104103
classes_indices = [(y == c).ravel() for c in classes]
105104
if self.priors is None:
106105
counts = np.array(ndimage.measurements.sum(

scikits/learn/utils/sparsetools/csgraph.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# This file was automatically generated by SWIG (http://www.swig.org).
2-
# Version 1.3.40
2+
# Version 2.0.1+capsulehack
33
#
44
# Do not make changes to this file unless you know what you are doing--modify
55
# the SWIG interface file instead.

scikits/learn/utils/sparsetools/csgraph_wrap.cxx

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* ----------------------------------------------------------------------------
22
* This file was automatically generated by SWIG (http://www.swig.org).
3-
* Version 1.3.40
3+
* Version 2.0.1+capsulehack
44
*
55
* This file is not intended to be easily readable and contains a number of
66
* coding conventions designed to improve portability and efficiency. Do not make
@@ -201,7 +201,7 @@ template <typename T> T SwigValueInit() {
201201
/*
202202
Flags/methods for returning states.
203203
204-
The SWIG conversion methods, as ConvertPtr, return and integer
204+
The SWIG conversion methods, as ConvertPtr, return an integer
205205
that tells if the conversion was successful or not. And if not,
206206
an error code can be returned (see swigerrors.swg for the codes).
207207
@@ -1088,9 +1088,6 @@ SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *self, PyObject *func)
10881088

10891089

10901090
/* -----------------------------------------------------------------------------
1091-
* See the LICENSE file for information on copyright, usage and redistribution
1092-
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
1093-
*
10941091
* pyrun.swg
10951092
*
10961093
* This file contains the runtime support for Python modules
@@ -1137,8 +1134,18 @@ SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *self, PyObject *func)
11371134
#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg
11381135
#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code)
11391136
#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg)
1140-
#define SWIG_fail goto fail
1137+
#define SWIG_fail goto fail
11411138

1139+
/*
1140+
* Python 2.7 and newer and Python 3.1 and newer should use Capsules API instead of
1141+
* CObjects API.
1142+
*/
1143+
#if ((PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 6) || \
1144+
(PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION > 0))
1145+
#define USE_CAPSULES
1146+
#define TYPE_POINTER_NAME \
1147+
((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION ".type_pointer_capsule" SWIG_TYPE_TABLE_NAME)
1148+
#endif
11421149

11431150
/* Runtime API implementation */
11441151

@@ -2071,10 +2078,13 @@ _SWIG_This(void)
20712078
return SWIG_Python_str_FromChar("this");
20722079
}
20732080

2081+
static PyObject *swig_this = NULL;
2082+
20742083
SWIGRUNTIME PyObject *
20752084
SWIG_This(void)
20762085
{
2077-
static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This();
2086+
if (swig_this == NULL)
2087+
swig_this = _SWIG_This();
20782088
return swig_this;
20792089
}
20802090

@@ -2178,7 +2188,7 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
21782188
int newmemory = 0;
21792189
*ptr = SWIG_TypeCast(tc,vptr,&newmemory);
21802190
if (newmemory == SWIG_CAST_NEW_MEMORY) {
2181-
assert(own);
2191+
assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
21822192
if (own)
21832193
*own = *own | SWIG_CAST_NEW_MEMORY;
21842194
}
@@ -2447,9 +2457,13 @@ SWIG_Python_GetModule(void) {
24472457
if (!type_pointer) {
24482458
#ifdef SWIG_LINK_RUNTIME
24492459
type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
2460+
#else
2461+
#ifdef USE_CAPSULES
2462+
type_pointer = PyCapsule_Import(TYPE_POINTER_NAME, 0);
24502463
#else
24512464
type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
24522465
(char*)"type_pointer" SWIG_TYPE_TABLE_NAME);
2466+
#endif
24532467
if (PyErr_Occurred()) {
24542468
PyErr_Clear();
24552469
type_pointer = (void *)0;
@@ -2494,9 +2508,14 @@ PyModule_AddObject(PyObject *m, char *name, PyObject *o)
24942508
SWIGRUNTIME void
24952509
SWIG_Python_DestroyModule(void *vptr)
24962510
{
2511+
size_t i;
2512+
#ifdef USE_CAPSULES
2513+
swig_module_info *swig_module =
2514+
(swig_module_info *) PyCapsule_GetPointer((PyObject *)vptr, TYPE_POINTER_NAME);
2515+
#else
24972516
swig_module_info *swig_module = (swig_module_info *) vptr;
2517+
#endif
24982518
swig_type_info **types = swig_module->types;
2499-
size_t i;
25002519
for (i =0; i < swig_module->size; ++i) {
25012520
swig_type_info *ty = types[i];
25022521
if (ty->owndata) {
@@ -2505,6 +2524,7 @@ SWIG_Python_DestroyModule(void *vptr)
25052524
}
25062525
}
25072526
Py_DECREF(SWIG_This());
2527+
swig_this = NULL;
25082528
}
25092529

25102530
SWIGRUNTIME void
@@ -2518,9 +2538,18 @@ SWIG_Python_SetModule(swig_module_info *swig_module) {
25182538
PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
25192539
swig_empty_runtime_method_table);
25202540
#endif
2541+
#ifdef USE_CAPSULES
2542+
PyObject *pointer = PyCapsule_New((void *)swig_module, TYPE_POINTER_NAME,
2543+
(PyCapsule_Destructor)SWIG_Python_DestroyModule);
2544+
#else
25212545
PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule);
2546+
#endif
25222547
if (pointer && module) {
2548+
#ifdef USE_CAPSULES
2549+
PyModule_AddObject(module, (char*)"type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer);
2550+
#else
25232551
PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer);
2552+
#endif
25242553
} else {
25252554
Py_XDECREF(pointer);
25262555
}
@@ -2541,12 +2570,20 @@ SWIG_Python_TypeQuery(const char *type)
25412570
PyObject *obj = PyDict_GetItem(cache, key);
25422571
swig_type_info *descriptor;
25432572
if (obj) {
2573+
#ifdef USE_CAPSULES
2574+
descriptor = (swig_type_info *) PyCapsule_GetPointer(obj, type);
2575+
#else
25442576
descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj);
2577+
#endif
25452578
} else {
25462579
swig_module_info *swig_module = SWIG_Python_GetModule();
25472580
descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
25482581
if (descriptor) {
2582+
#ifdef USE_CAPSULES
2583+
obj = PyCapsule_New(descriptor, type, NULL);
2584+
#else
25492585
obj = PyCObject_FromVoidPtr(descriptor, NULL);
2586+
#endif
25502587
PyDict_SetItem(cache, key, obj);
25512588
Py_DECREF(obj);
25522589
}
@@ -2708,7 +2745,7 @@ static swig_module_info swig_module = {swig_types, 1, 0, 0, 0, 0};
27082745
#endif
27092746
#define SWIG_name "_csgraph"
27102747

2711-
#define SWIGVERSION 0x010340
2748+
#define SWIGVERSION 0x020001
27122749
#define SWIG_VERSION SWIGVERSION
27132750

27142751

@@ -2781,6 +2818,7 @@ namespace swig {
27812818
}
27822819

27832820

2821+
#include "py3k.h"
27842822
#define SWIG_FILE_WITH_INIT
27852823
#include "Python.h"
27862824
#include "numpy/arrayobject.h"
@@ -3919,15 +3957,15 @@ extern "C" {
39193957
}
39203958
}
39213959
if (ci) {
3922-
size_t shift = (ci->ptype) - types;
3923-
swig_type_info *ty = types_initial[shift];
3924-
size_t ldoc = (c - methods[i].ml_doc);
3925-
size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
3926-
char *ndoc = (char*)malloc(ldoc + lptr + 10);
3927-
if (ndoc) {
3928-
char *buff = ndoc;
3929-
void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
3930-
if (ptr) {
3960+
void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
3961+
if (ptr) {
3962+
size_t shift = (ci->ptype) - types;
3963+
swig_type_info *ty = types_initial[shift];
3964+
size_t ldoc = (c - methods[i].ml_doc);
3965+
size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
3966+
char *ndoc = (char*)malloc(ldoc + lptr + 10);
3967+
if (ndoc) {
3968+
char *buff = ndoc;
39313969
strncpy(buff, methods[i].ml_doc, ldoc);
39323970
buff += ldoc;
39333971
strncpy(buff, "swig_ptr: ", 10);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Undefine macros defined by SWIG
3+
*/
4+
#if PY_VERSION_HEX >= 0x03000000
5+
6+
#ifdef PyInt_Check
7+
#undef PyInt_Check
8+
#endif
9+
10+
static int __pyfile_check_guard(PyObject *x)
11+
{
12+
return 0;
13+
}
14+
#define PyFile_Check(x) __pyfile_check_guard((x))
15+
static int __pyinstance_check_guard(PyObject *x)
16+
{
17+
return 0;
18+
}
19+
#define PyInstance_Check(x) __pyinstance_check_guard((x))
20+
21+
#endif
22+
23+
#include "numpy/npy_3kcompat.h"

setup.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
descr = """A set of python modules for machine learning and data mining"""
77

8-
import os
8+
import sys, os, shutil
99

1010
DISTNAME = 'scikits.learn'
1111
DESCRIPTION = 'A set of python modules for machine learning and data mining'
@@ -33,6 +33,39 @@ def configuration(parent_package='',top_path=None):
3333
return config
3434

3535
if __name__ == "__main__":
36+
37+
old_path = os.getcwd()
38+
local_path = os.path.dirname(os.path.abspath(sys.argv[0]))
39+
# python 3 compatibility stuff.
40+
# Simplified version of scipy strategy: copy files into
41+
# build/py3k, and patch them using lib2to3.
42+
if sys.version_info[0] == 3:
43+
try:
44+
import lib2to3cache
45+
except ImportError:
46+
pass
47+
local_path = os.path.join(local_path, 'build', 'py3k')
48+
if os.path.exists(local_path):
49+
shutil.rmtree(local_path)
50+
print("Copying source tree into build/py3k for 2to3 transformation ...")
51+
shutil.copytree(os.path.join(old_path, 'scikits'),
52+
os.path.join(local_path, 'scikits'))
53+
import lib2to3.main
54+
from io import StringIO
55+
print("Converting to Python3 via 2to3...")
56+
_old_stdout = sys.stdout
57+
try:
58+
sys.stdout = StringIO() # supress noisy output
59+
res = lib2to3.main.main("lib2to3.fixes", ['-w'] + [local_path])
60+
finally:
61+
sys.stdout = _old_stdout
62+
63+
if res != 0:
64+
raise Exception('2to3 failed, exiting ...')
65+
66+
os.chdir(local_path)
67+
sys.path.insert(0,local_path)
68+
3669
setup(configuration = configuration,
3770
name = DISTNAME,
3871
maintainer = MAINTAINER,

0 commit comments

Comments
 (0)