AttributeError: 'function' object has no attribute 'to_basic_block' (GR 3.7.0)

I’ve stepped up to GR 3.7.0, re-used gr_modtool to freshly re-create my
OOT module, everything builds, tests, installs OK. GRC has my OOT blocks
listed and I can put them on my flowgraph.

One of my OOT blocks is a function that takes in shorts and outputs
shorts (a 1-to-2 interpolator).

I have a simple flowgraph created in GRC: File Source -> My block ->
File sync .

GRC is happy until I run the flowgraph, and I get this:

Executing: “<…> /top_block.py”

Traceback (most recent call last):
File “<…> /top_block.py”, line 54, in
tb = top_block()
File “<…> /top_block.py”, line 39, in init
self.connect((self.my_block_s_to_s_0, 0), (self.blocks_file_sink_0,
0))
File
“/usr/local/lib/python2.7/dist-packages/gnuradio/gr/top_block.py”, line
130, in connect
self._connect(points[i-1], points[i])
File
“/usr/local/lib/python2.7/dist-packages/gnuradio/gr/top_block.py”, line
141, in _connect
self._tb.primitive_connect(src_block.to_basic_block(), src_port,
AttributeError: ‘function’ object has no attribute ‘to_basic_block’

Platform: Ubuntu 12.04 on VMware x86

The File Source and Sink blocks came from the “File Operators”
collection in GRC.

If I delete my block from the middle, leaving File Source -> File Sink,
it runs OK.

Any ideas? This worked fine when the system was GR 3.6.4.2 based.

Thanks,
Tim

One of my OOT blocks is a function that takes in shorts and outputs shorts (a
1-to-2 interpolator).

I have a simple flowgraph created in GRC: File Source -> My block -> File
sync .

GRC is happy until I run the flowgraph, and I get this:

Executing: “<…> /top_block.py”

Traceback (most recent call last):
File “<…> /top_block.py”, line 54, in
tb = top_block()
File “<…> /top_block.py”, line 39, in init
self.connect((self.my_block_s_to_s_0, 0), (self.blocks_file_sink_0, 0))
File “/usr/local/lib/python2.7/dist-packages/gnuradio/gr/top_block.py”, line
130, in connect

self._connect(points[i-1], points[i])

File “/usr/local/lib/python2.7/dist-packages/gnuradio/gr/top_block.py”, line
141, in _connect

self._tb.primitive_connect(src_block.to_basic_block(), src_port,

AttributeError: ‘function’ object has no attribute ‘to_basic_block’

I have found the error (or at least I am closer): The Python code that
GRC generates is slightly different between v3.6.4.2 and v3.7.0 for the
same test flowgraph. Namely, the newer version omits an empty set of
parens, thusly:

From v3.6.4.2 :

##################################################
# Blocks
##################################################
self.my_oot_my_block_0 = my_oot.my_block()

From v3.7.0 :

##################################################
# Blocks
##################################################
self.my_oot_my_block_0 = my_oot.my_block

My block has no parameters (thus the empty parens).

If I manually edit the v3.7.0 generated py code to add the missing
parens, it all works fine as with v3.6.4.2.

Question: Is this a v3.7.0 bug, or some subtle coding error in my OOT
module? As far as I can tell, I converted it according to the 3.6 -> 3.7
recipe.

One of my OOT blocks is a function that takes in shorts and outputs shorts (a
1-to-2 interpolator).

I have a simple flowgraph created in GRC: File Source -> My block -> File
sync .

GRC is happy until I run the flowgraph, and I get this:

Executing: “<…> /top_block.py”

Traceback (most recent call last):
File “<…> /top_block.py”, line 54, in
tb = top_block()
File “<…> /top_block.py”, line 39, in init
self.connect((self.my_block_s_to_s_0, 0), (self.blocks_file_sink_0, 0))
File “/usr/local/lib/python2.7/dist-packages/gnuradio/gr/top_block.py”, line
130, in connect

self._connect(points[i-1], points[i])

File “/usr/local/lib/python2.7/dist-packages/gnuradio/gr/top_block.py”, line
141, in _connect

self._tb.primitive_connect(src_block.to_basic_block(), src_port,

AttributeError: ‘function’ object has no attribute ‘to_basic_block’

I have found the error (or at least I am closer): The Python code that GRC
generates is slightly different between v3.6.4.2 and v3.7.0 for the same test
flowgraph. Namely, the newer version omits an empty set of parens, thusly:

From v3.6.4.2 :

##################################################

Blocks

##################################################
self.my_oot_my_block_0 = my_oot.my_block()

From v3.7.0 :

##################################################

Blocks

##################################################
self.my_oot_my_block_0 = my_oot.my_block

My block has no parameters (thus the empty parens).

If I manually edit the v3.7.0 generated py code to add the missing parens, it
all works fine as with v3.6.4.2.

Question: Is this a v3.7.0 bug, or some subtle coding error in my OOT module? As
far as I can tell, I converted it according to the 3.6 -> 3.7 recipe.

Answer: This was my subtle coding error. I left the empty parens out of
the XML file’s ‘make’ entry (last line below).

File: my_oot_my_block.xml

my_block my_oot_my_block my_oot import my_oot my_oot.my_block <- Forgot () after the name. Case closed.

I’ve stepped up to GR 3.7.0, re-used gr_modtool to freshly re-create my OOT
module, everything builds, tests, installs OK. GRC has my OOT blocks listed and I
can put them on my flowgraph.

One of my OOT blocks is a function that takes in shorts and outputs shorts (a
1-to-2 interpolator).

I have a simple flowgraph created in GRC: File Source -> My block -> File sync
.

GRC is happy until I run the flowgraph, and I get this:

Executing: “<…> /top_block.py”

Traceback (most recent call last):
File “<…> /top_block.py”, line 54, in
tb = top_block()
File “<…> /top_block.py”, line 39, in init
self.connect((self.my_block_s_to_s_0, 0), (self.blocks_file_sink_0, 0))
File “/usr/local/lib/python2.7/dist-packages/gnuradio/gr/top_block.py”, line
130, in connect
self._connect(points[i-1], points[i])
File “/usr/local/lib/python2.7/dist-packages/gnuradio/gr/top_block.py”, line
141, in _connect
self._tb.primitive_connect(src_block.to_basic_block(), src_port,
AttributeError: ‘function’ object has no attribute ‘to_basic_block’

An update.

First, I believe I exhaustively eradicated older installed versions of
GR by searching and deleting for anything named ‘gnuradio’ under /usr,
re-built GR and re-installed. But, same results.

Using the pdb single step debugger and also just looking at the code, I
have a question about top_block.py (under
/usr/local/lib/python2.7/dist-packages/gnuradio/gr):

def _connect(self, src, dst):
    (src_block, src_port) = self._coerce_endpoint(src)
    (dst_block, dst_port) = self._coerce_endpoint(dst)
    self._tb.primitive_connect(src_block.to_basic_block(), src_port,
                               dst_block.to_basic_block(), dst_port)

def _coerce_endpoint(self, endp):
    if hasattr(endp, 'to_basic_block'):
        return (endp, 0)
    else:
        if hasattr(endp, "__getitem__") and len(endp) == 2:
            return endp # Assume user put (block, port)
        else:
            raise ValueError("unable to coerce endpoint")

I’m not a python expert, but “_coerce_endpoint” is checking if the
attribute ‘to_basic_block’ exists… But then the “_connect” function
goes right ahead and tries to use it as it prepares to call
“primitive_connect”, which is what the error is about… And single
stepping through the python code seems to verify that… (in my case,
the test for getitem and len(endp) == 2 is the path the code takes).

I also don’t understand why “_coerce_endpoint” in that path returns ony
“endp”, but in its other leg, returns “(endp, 0)”? Seems like the caller
wants to assign 2 values (src_block, src_port)…

This part of the top_block.py code is the same between 3.6.4.2 and
3.7.0…