Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Apr 14, 2024. It is now read-only.

Commit fc02456

Browse filesBrowse files
committed
Merge pull request #7 from mok0/master
Python 3 modifications
2 parents 90326fb + 8eb3d87 commit fc02456
Copy full SHA for fc02456

16 files changed

+148
-81
lines changed

‎async/__init__.py

Copy file name to clipboardExpand all lines: async/__init__.py
+8-7Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@ def _init_atexit():
99
"""Setup an at-exit job to be sure our workers are shutdown correctly before
1010
the interpreter quits"""
1111
import atexit
12-
import thread
12+
from . import thread
1313
atexit.register(thread.do_terminate_threads)
1414

1515
def _init_signals():
1616
"""Assure we shutdown our threads correctly when being interrupted"""
1717
import signal
18-
import thread
18+
from . import thread
1919
import sys
2020

2121
prev_handler = signal.getsignal(signal.SIGINT)
2222
def thread_interrupt_handler(signum, frame):
2323
thread.do_terminate_threads()
24-
if callable(prev_handler):
24+
if isinstance(prev_handler, collections.Callable):
2525
prev_handler(signum, frame)
2626
raise KeyboardInterrupt()
2727
# END call previous handler
@@ -30,7 +30,7 @@ def thread_interrupt_handler(signum, frame):
3030
signal.signal(signal.SIGINT, thread_interrupt_handler)
3131
except ValueError:
3232
# happens if we don't try it from the main thread
33-
print >> sys.stderr, "Failed to setup thread-interrupt handler. This is usually not critical"
33+
print("Failed to setup thread-interrupt handler. This is usually not critical", file=sys.stderr)
3434
# END exception handling
3535

3636

@@ -41,6 +41,7 @@ def thread_interrupt_handler(signum, frame):
4141

4242

4343
# initial imports
44-
from task import *
45-
from pool import *
46-
from channel import *
44+
from .task import *
45+
from .pool import *
46+
from .channel import *
47+
import collections

‎async/channel.py

Copy file name to clipboardExpand all lines: async/channel.py
+7-7Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
# This module is part of async and is released under
44
# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
55
"""Contains a queue based channel implementation"""
6-
from Queue import (
6+
from queue import (
77
Empty,
88
Full
99
)
1010

11-
from util import (
11+
from .util import (
1212
AsyncQueue,
1313
SyncQueue,
1414
ReadOnly
@@ -154,7 +154,7 @@ def __init__(self, device):
154154
def __iter__(self):
155155
return self
156156

157-
def next(self):
157+
def __next__(self):
158158
"""Implements the iterator protocol, iterating individual items"""
159159
items = self.read(1)
160160
if items:
@@ -220,7 +220,7 @@ def read(self, count=0, block=True, timeout=None):
220220
out.append(queue.get(False))
221221
# END for each item
222222
else:
223-
for i in xrange(count):
223+
for i in range(count):
224224
out.append(queue.get(False))
225225
# END for each item
226226
# END handle count
@@ -230,7 +230,7 @@ def read(self, count=0, block=True, timeout=None):
230230
else:
231231
# to get everything into one loop, we set the count accordingly
232232
if count == 0:
233-
count = sys.maxint
233+
count = sys.maxsize
234234
# END handle count
235235

236236
i = 0
@@ -353,9 +353,9 @@ def read(self, count=0, block=True, timeout=None):
353353
else:
354354
out = list()
355355
it = self._iter
356-
for i in xrange(count):
356+
for i in range(count):
357357
try:
358-
out.append(it.next())
358+
out.append(next(it))
359359
except StopIteration:
360360
self._empty = True
361361
break

‎async/mod/zlibmodule.c

Copy file name to clipboardExpand all lines: async/mod/zlibmodule.c
+66-1Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,21 @@
33

44
/* Windows users: read Python's PCbuild\readme.txt */
55

6-
76
#include "Python.h"
87
#include "zlib.h"
98

9+
#if PY_MAJOR_VERSION >= 3
10+
#define PyInt_FromLong PyLong_FromLong
11+
#define PyString_FromString PyUnicode_FromString
12+
#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
13+
#define PyString_AS_STRING PyUnicode_AS_UNICODE
14+
#define _PyString_Resize PyUnicode_Resize
15+
#define PyText_AS_UTF8 _PyUnicode_AsString
16+
#define PyText_Check PyUnicode_Check
17+
#endif
18+
19+
20+
1021
#ifdef WITH_THREAD
1122
#include "pythread.h"
1223

@@ -897,6 +908,23 @@ static PyMethodDef Decomp_methods[] =
897908
{NULL, NULL}
898909
};
899910

911+
912+
/*
913+
Py_FindMethod gone in Python 3, so Comp_getattr and Decomp_getattr
914+
have to be rewritten. I googled the following tip somewhere:
915+
916+
"The same functionality can be achieved with the tp_getattro slot:
917+
implement your special dynamic attributes there, and then call
918+
PyObject_GenericGetAttr for the default behavior. You may have a
919+
look at the implementation of the pyexpat module:
920+
Modules/pyexpat.c, function xmlparse_getattro."
921+
922+
Looking at xmlparse_getattro [1] it seems it could be readily adopted
923+
here.
924+
925+
[1] http://svn.python.org/projects/python/branches/py3k/Modules/pyexpat.c
926+
*/
927+
900928
static PyObject *
901929
Comp_getattr(compobject *self, char *name)
902930
{
@@ -1052,17 +1080,50 @@ PyDoc_STRVAR(zlib_module_documentation,
10521080
"Compressor objects support compress() and flush() methods; decompressor\n"
10531081
"objects support decompress() and flush().");
10541082

1083+
#if PY_MAJOR_VERSION >= 3
1084+
/* See http://python3porting.com/cextensions.html */
1085+
static struct PyModuleDef zlib_moddef = {
1086+
PyModuleDef_HEAD_INIT,
1087+
"zlib",
1088+
zlib_module_documentation,
1089+
-1,
1090+
zlib_methods,
1091+
NULL, NULL, NULL, NULL
1092+
};
1093+
#endif
1094+
1095+
1096+
10551097
PyMODINIT_FUNC
10561098
PyInit_zlib(void)
10571099
{
10581100
PyObject *m, *ver;
1101+
1102+
#if PY_MAJOR_VERSION >= 3
1103+
/* Use this version check as a replacement for Py_InitModule4 */
1104+
ver = PySys_GetObject("version");
1105+
if (ver == NULL || !PyText_Check(ver) ||
1106+
strncmp(PyText_AS_UTF8(ver), PY_VERSION, 3) != 0) {
1107+
PyErr_Format(PyExc_ImportError,
1108+
"this module was compiled for Python %c%c%c",
1109+
PY_VERSION[0], PY_VERSION[1], PY_VERSION[2]);
1110+
return NULL;
1111+
}
1112+
#endif
1113+
10591114
Py_TYPE(&Comptype) = &PyType_Type;
10601115
Py_TYPE(&Decomptype) = &PyType_Type;
1116+
#if PY_MAJOR_VERSION >= 3
1117+
m = PyModule_Create(&zlib_moddef);
1118+
if (m == NULL)
1119+
return m;
1120+
#else
10611121
m = Py_InitModule4("zlib", zlib_methods,
10621122
zlib_module_documentation,
10631123
(PyObject*)NULL,PYTHON_API_VERSION);
10641124
if (m == NULL)
10651125
return;
1126+
#endif
10661127

10671128
ZlibError = PyErr_NewException("zlib.error", NULL, NULL);
10681129
if (ZlibError != NULL) {
@@ -1101,4 +1162,8 @@ PyInit_zlib(void)
11011162
PyModule_AddObject(m, "ZLIB_VERSION", ver);
11021163

11031164
PyModule_AddStringConstant(m, "__version__", "1.0");
1165+
1166+
#if PY_MAJOR_VERSION >= 3
1167+
return m;
1168+
#endif
11041169
}

‎async/pool.py

Copy file name to clipboardExpand all lines: async/pool.py
+8-7Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@
33
# This module is part of async and is released under
44
# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
55
"""Implementation of a thread-pool working with channels"""
6-
from thread import (
6+
from .thread import (
77
WorkerThread,
88
StopProcessing,
99
)
1010
from threading import Lock
1111

12-
from util import (
12+
from .util import (
1313
AsyncQueue,
1414
DummyLock
1515
)
1616

17-
from Queue import (
17+
from queue import (
1818
Queue,
1919
Empty
2020
)
2121

22-
from graph import Graph
23-
from channel import (
22+
from .graph import Graph
23+
from .channel import (
2424
mkchannel,
2525
ChannelWriter,
2626
Channel,
@@ -31,6 +31,7 @@
3131
import sys
3232
import weakref
3333
from time import sleep
34+
from functools import reduce
3435

3536

3637
__all__ = ('PoolReader', 'Pool', 'ThreadPool')
@@ -284,7 +285,7 @@ def _prepare_channel_read(self, task, count):
284285
# to process too much. This can be defined per task
285286
qput = self._queue.put
286287
if numchunks > 1:
287-
for i in xrange(numchunks):
288+
for i in range(numchunks):
288289
qput((task.process, chunksize))
289290
# END for each chunk to put
290291
else:
@@ -297,7 +298,7 @@ def _prepare_channel_read(self, task, count):
297298
else:
298299
# no workers, so we have to do the work ourselves
299300
if numchunks > 1:
300-
for i in xrange(numchunks):
301+
for i in range(numchunks):
301302
task.process(chunksize)
302303
# END for each chunk to put
303304
else:

‎async/task.py

Copy file name to clipboardExpand all lines: async/task.py
+5-5Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
#
33
# This module is part of async and is released under
44
# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
5-
from graph import Node
6-
from util import ReadOnly
7-
from channel import IteratorReader
5+
from .graph import Node
6+
from .util import ReadOnly
7+
from .channel import IteratorReader
88

99
import threading
1010
import weakref
@@ -128,7 +128,7 @@ def process(self, count=0):
128128
self._num_writers -= 1
129129
self._wlock.release()
130130
# END handle writer count
131-
except Exception, e:
131+
except Exception as e:
132132
# be sure our task is not scheduled again
133133
self.set_done()
134134

@@ -226,7 +226,7 @@ def reader(self):
226226
""":return: input channel from which we read"""
227227
# the instance is bound in its instance method - lets use this to keep
228228
# the refcount at one ( per consumer )
229-
return self._read.im_self
229+
return self._read.__self__
230230

231231
def set_read(self, read):
232232
"""Adjust the read method to the given one"""

‎async/test/task.py

Copy file name to clipboardExpand all lines: async/test/task.py
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def _assert(self, pc, fc, check_scheduled=False):
3939
:return: self"""
4040
self.lock.acquire()
4141
if self.item_count != fc:
42-
print self.item_count, fc
42+
print(self.item_count, fc)
4343
assert self.item_count == fc
4444
self.lock.release()
4545

@@ -166,7 +166,7 @@ def add_task_chain(p, ni, count=1, fail_setup=list(), feeder_channel=None, id_of
166166
tasks = [feeder]
167167

168168
inrc = frc
169-
for tc in xrange(count):
169+
for tc in range(count):
170170
t = transformercls(inrc, tc+id_offset, None)
171171

172172
t.fun = make_proxy_method(t)
@@ -198,7 +198,7 @@ def make_iterator_task(ni, taskcls=TestThreadTask, **kwargs):
198198
""":return: task which yields ni items
199199
:param taskcls: the actual iterator type to use
200200
:param kwargs: additional kwargs to be passed to the task"""
201-
t = taskcls(iter(range(ni)), 'iterator', None, **kwargs)
201+
t = taskcls(iter(list(range(ni))), 'iterator', None, **kwargs)
202202
if isinstance(t, _TestTaskBase):
203203
t.fun = make_proxy_method(t)
204204
return t

‎async/test/test_channel.py

Copy file name to clipboardExpand all lines: async/test/test_channel.py
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# This module is part of async and is released under
44
# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
55
"""Channel testing"""
6-
from lib import *
6+
from .lib import *
77
from async.channel import *
88

99
import time
@@ -83,7 +83,7 @@ def post_read(items):
8383

8484

8585
# ITERATOR READER
86-
reader = IteratorReader(iter(range(10)))
86+
reader = IteratorReader(iter(list(range(10))))
8787
assert len(reader.read(2)) == 2
8888
assert len(reader.read(0)) == 8
8989
# its empty now
@@ -95,7 +95,7 @@ def post_read(items):
9595

9696

9797
# test general read-iteration - its supported by all readers
98-
reader = IteratorReader(iter(range(10)))
98+
reader = IteratorReader(iter(list(range(10))))
9999
assert len(list(reader)) == 10
100100

101101
# NOTE: its thread-safety is tested by the pool

‎async/test/test_example.py

Copy file name to clipboardExpand all lines: async/test/test_example.py
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# This module is part of async and is released under
44
# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
55
"""Module containing examples from the documentaiton"""
6-
from lib import *
6+
from .lib import *
77

88
from async.pool import *
99
from async.task import *
@@ -25,7 +25,7 @@ def test_usage(self):
2525
assert p.size() == 1
2626

2727
# A task performing processing on items from an iterator
28-
t = IteratorThreadTask(iter(range(10)), "power", lambda i: i*i)
28+
t = IteratorThreadTask(iter(list(range(10))), "power", lambda i: i*i)
2929
reader = p.add_task(t)
3030

3131
# read all items - they where procesed by worker 1
@@ -34,7 +34,7 @@ def test_usage(self):
3434

3535

3636
# chaining
37-
t = IteratorThreadTask(iter(range(10)), "power", lambda i: i*i)
37+
t = IteratorThreadTask(iter(list(range(10))), "power", lambda i: i*i)
3838
reader = p.add_task(t)
3939

4040
# chain both by linking their readers

‎async/test/test_graph.py

Copy file name to clipboardExpand all lines: async/test/test_graph.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# This module is part of async and is released under
44
# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
55
"""Channel testing"""
6-
from lib import *
6+
from .lib import *
77
from async.graph import *
88

99
import time

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.