Skip to content

Commit 57aaf34

Browse files
committed
Boatload of trashy stuff.
1 parent 5d6dc2f commit 57aaf34

File tree

8 files changed

+1873
-87
lines changed

8 files changed

+1873
-87
lines changed

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ markers =
2828
xfail_simple: Expected test to fail on the `simple` implementation.
2929
addopts =
3030
-ra
31-
--strict
31+
--strict-markers
3232
--ignore=docs/conf.py
3333
--ignore=setup.py
3434
--ignore=ci

src/lazy_object_proxy/cext.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,7 +1286,7 @@ static PyObject *Proxy_await(ProxyObject *self)
12861286
return (*meth)(wrapped);
12871287
}
12881288

1289-
PyErr_Format(PyExc_TypeError, " %.100s is missing the __await__ method", type->tp_name);
1289+
PyErr_Format(PyExc_TypeError, "%.100s is missing the __await__ method", type->tp_name);
12901290
return NULL;
12911291
}
12921292

@@ -1308,7 +1308,7 @@ static PyObject *Proxy_aiter(ProxyObject *self)
13081308
return (*meth)(wrapped);
13091309
}
13101310

1311-
PyErr_Format(PyExc_TypeError, " %.100s is missing the __aiter__ method", type->tp_name);
1311+
PyErr_Format(PyExc_TypeError, "%.100s is missing the __aiter__ method", type->tp_name);
13121312
return NULL;
13131313
}
13141314

@@ -1331,7 +1331,7 @@ static PyObject *Proxy_anext(ProxyObject *self)
13311331
return (*meth)(wrapped);
13321332
}
13331333

1334-
PyErr_Format(PyExc_TypeError, " %.100s is missing the __anext__ method", type->tp_name);
1334+
PyErr_Format(PyExc_TypeError, "%.100s is missing the __anext__ method", type->tp_name);
13351335
return NULL;
13361336
}
13371337

src/lazy_object_proxy/simple.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -260,14 +260,17 @@ def __reduce_ex__(self, protocol):
260260
def __aiter__(self):
261261
return self.__wrapped__.__aiter__()
262262

263-
async def __anext__(self):
264-
return await self.__wrapped__.__anext__()
263+
def __anext__(self):
264+
return self.__wrapped__.__anext__()
265265

266266
def __await__(self):
267-
return await self.__wrapped__
267+
if hasattr(self.__wrapped__, '__await__'):
268+
return self.__wrapped__.__await__()
269+
else:
270+
return iter(self.__wrapped__)
268271

269-
async def __aenter__(self):
270-
return await self.__wrapped__.__aenter__()
272+
def __aenter__(self):
273+
return self.__wrapped__.__aenter__()
271274

272-
async def __aexit__(self, *args, **kwargs):
273-
return await self.__wrapped__.__aexit__(*args, **kwargs)
275+
def __aexit__(self, *args, **kwargs):
276+
return self.__wrapped__.__aexit__(*args, **kwargs)

src/lazy_object_proxy/slots.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import operator
2+
from types import GeneratorType, CoroutineType
23

34
from .compat import PY2
45
from .compat import PY3
@@ -414,7 +415,14 @@ def __exit__(self, *args, **kwargs):
414415
return self.__wrapped__.__exit__(*args, **kwargs)
415416

416417
def __iter__(self):
417-
return iter(self.__wrapped__)
418+
if hasattr(self.__wrapped__, '__await__'):
419+
return self.__wrapped__.__await__()
420+
else:
421+
# raise TypeError("'coroutine' object is not iterable")
422+
return iter(self.__wrapped__)
423+
424+
def __next__(self):
425+
return next(self.__wrapped__)
418426

419427
def __call__(self, *args, **kwargs):
420428
return self.__wrapped__(*args, **kwargs)
@@ -426,16 +434,20 @@ def __reduce_ex__(self, protocol):
426434
return identity, (self.__wrapped__,)
427435

428436
def __aiter__(self):
429-
return self.__wrapped__.__aiter__()
430-
431-
def __await__(self):
432-
return self.__wrapped__.__await__()
437+
return self
433438

434439
async def __anext__(self):
435440
return await self.__wrapped__.__anext__()
436441

437-
async def __aenter__(self):
438-
return await self.__wrapped__.__aenter__()
442+
def __await__(self):
443+
if hasattr(self.__wrapped__, '__await__'):
444+
return self.__wrapped__.__await__()
445+
else:
446+
return (yield from self.__wrapped__)
447+
448+
449+
def __aenter__(self):
450+
return self.__wrapped__.__aenter__()
439451

440-
async def __aexit__(self, *args, **kwargs):
441-
return await self.__wrapped__.__aexit__(*args, **kwargs)
452+
def __aexit__(self, *args, **kwargs):
453+
return self.__wrapped__.__aexit__(*args, **kwargs)

tests/conftest.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import pytest
2+
3+
@pytest.fixture(scope="session")
4+
def lop_loader():
5+
def load_implementation(name):
6+
class FakeModule:
7+
subclass = False
8+
kind = name
9+
if name == "slots":
10+
from lazy_object_proxy.slots import Proxy
11+
elif name == "simple":
12+
from lazy_object_proxy.simple import Proxy
13+
elif name == "cext":
14+
try:
15+
from lazy_object_proxy.cext import Proxy
16+
except ImportError:
17+
if PYPY:
18+
pytest.skip(msg="C Extension not available.")
19+
else:
20+
raise
21+
elif name == "objproxies":
22+
Proxy = pytest.importorskip("objproxies").LazyProxy
23+
elif name == "django":
24+
Proxy = pytest.importorskip("django.utils.functional").SimpleLazyObject
25+
else:
26+
raise RuntimeError("Unsupported param: %r." % name)
27+
28+
Proxy
29+
30+
return FakeModule
31+
return load_implementation
32+
33+
@pytest.fixture(scope="session", params=[
34+
"slots", "cext",
35+
"simple",
36+
# "external-django", "external-objproxies"
37+
])
38+
def lop_implementation(request, lop_loader):
39+
return lop_loader(request.param)
40+
41+
42+
@pytest.fixture(scope="session", params=[True, False], ids=['subclassed', 'normal'])
43+
def lop_subclass(request, lop_implementation):
44+
if request.param:
45+
class submod(lop_implementation):
46+
subclass = True
47+
Proxy = type("SubclassOf_" + lop_implementation.Proxy.__name__,
48+
(lop_implementation.Proxy,), {})
49+
50+
return submod
51+
else:
52+
return lop_implementation
53+
54+
55+
@pytest.fixture(scope="function")
56+
def lop(request, lop_subclass):
57+
if request.node.get_closest_marker('xfail_subclass'):
58+
request.applymarker(pytest.mark.xfail(
59+
reason="This test can't work because subclassing disables certain "
60+
"features like __doc__ and __module__ proxying."
61+
))
62+
if request.node.get_closest_marker('xfail_simple'):
63+
request.applymarker(pytest.mark.xfail(
64+
reason="The lazy_object_proxy.simple.Proxy has some limitations."
65+
))
66+
67+
return lop_subclass

0 commit comments

Comments
 (0)