Iterator in conjunction with Python properties fail
graph-tool
version?
Are you running the latest 2.35
Do you observe the problem with the current git version?
I will give a minimal example. It would be nice, if you test it yourself, since compiling graph-tool costs me several hours.
Are you using Macports or Homebrew? If yes, please submit an issue there instead:
No
graph-tool
manually?
Did you compile Part of, I use Gentoo with the distribution package.
graph-tool
, boost-python
and Python
?
If you answered yes above, did you use the exact same compiler to build Yes
A minimal and self-contained example that shows the problem.
This code should print the same in all 3 for loops but does not.
#!/usr/bin/env python3
import graph_tool
class Foo:
def __init__(self):
self.g = graph_tool.Graph()
self.g.vp["foo"] = self.g.new_vp("bool")
for i in range(10):
v = self.g.add_vertex()
if i % 2 == 0:
self.g.vp.foo[v] = True
@property
def a(self):
return graph_tool.GraphView(self.g, vfilt=self.g.vp.foo)
foo = Foo()
t1 = foo.a
for i in t1.vertices():
print("1.", i)
for i in foo.a.vertices():
print("2.", i)
t2 = foo.a.vertices()
for i in t2:
print("3.", i)
This prints only
1. 0
1. 2
1. 4
1. 6
1. 8
So basically it ignores the next 2 for loops.
Your operating system.
Gentoo
The Python version you are using.
Gentoo allows multiple. I tested with 3.6, 3.7 and 3.8 (always the same bug).
If you compiled graph-tool manually: Your compiler version, as well as the version of Boost being used.
GCC 9.2.0, Boost 1.72.0
./configure
output, as well as the entire contents of the config.log
file and the entire compilation output.
If you are reporting a compilation error, please provide the entire No.
Additional information
see this minimal example for a pure Python working example that mimics the above script:
#!/usr/bin/env python3
class Iterator:
def __init__(self):
self.x = 0
def __iter__(self):
return self
def __next__(self):
if self.x > 3:
raise StopIteration
self.x += 1
return self.x
class Sub:
def it(self):
return Iterator()
class Foo:
@property
def a(self):
return Sub()
foo = Foo()
t1 = foo.a
for i in t1.it():
print("1:", i)
for i in foo.a.it():
print("2:", i)
t2 = foo.a.it()
for i in t2:
print("3:", i)