Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

grc: cpp generation fails to generate vector variable #4955

Open
dl1ksv opened this issue Jul 26, 2021 · 5 comments
Open

grc: cpp generation fails to generate vector variable #4955

dl1ksv opened this issue Jul 26, 2021 · 5 comments

Comments

@dl1ksv
Copy link
Contributor

dl1ksv commented Jul 26, 2021

Define in grc a variable block with value
[float(x) for x in range(4)]

Python code will be generated but cpp code generation fails with:

Traceback (most recent call last):
  File "/usr/local/gnuradio/lib64/python3.9/site-packages/gnuradio/grc/gui/Application.py", line 720, in _handle_action
    generator.write()
  File "/usr/local/gnuradio/lib64/python3.9/site-packages/gnuradio/grc/core/generator/cpp_top_block.py", line 66, in write
    self._variable_types()
  File "/usr/local/gnuradio/lib64/python3.9/site-packages/gnuradio/grc/core/generator/cpp_top_block.py", line 301, in _variable_types
    var.format_expr(var_types[str(var.params['id'].value)])
  File "/usr/local/gnuradio/lib64/python3.9/site-packages/gnuradio/grc/core/blocks/block.py", line 479, in format_expr
    self.vtype = get_type(value, py_type)
  File "/usr/local/gnuradio/lib64/python3.9/site-packages/gnuradio/grc/core/blocks/block.py", line 460, in get_type
    return 'std::vector<' + get_type(str(evaluated[0]), type(evaluated[0])) + '>'
TypeError: 'NoneType' object is not subscriptable

That is why in in block.py

       def format_expr(self, py_type):
        """
        Evaluate the value of the variable block and decide its type.
        Returns:
            None
        """
        value = self.params['value'].value
        self.cpp_templates = copy.copy(self.orig_cpp_templates)

        # Determine the lvalue type
        def get_type(element, _vtype):
            evaluated = None
            try:
                evaluated = ast.literal_eval(element)`


evaluated = ast.literal_eval(element) fails for
element = [float(x) for x in range(4)]

with ValueError: malformed node or string: <ast.ListComp object at 0x7fd8a0e92eb0>

@solomonbstoner
Copy link
Contributor

Just to clarify on what the expected behavior is, are we expecting the following line?

std::vector<double> variable_0 = {1.0, 2.0, 3.0, 4.0};

I produced it using [1.0, 2.0, 3.0, 4.0] in the variable value. I got the same error with [float(x) for x in range(4)].

@dl1ksv
Copy link
Contributor Author

dl1ksv commented Aug 26, 2021

Yes , the expected behavior is to get

std::vector input_vector = {0.0, 1.0, 2.0, 3};
And as follow up:
some python examples contain settings in grc like

variable_block1 vl with value 4
variable_block2 with vect value [float(x) for x in range(vl)]

@solomonbstoner
Copy link
Contributor

Ok. Assign that to me. Ill try to fix it.

@solomonbstoner
Copy link
Contributor

solomonbstoner commented Aug 28, 2021

I believe the problem lies with ast.literal_eval. I got the same "malformed node or string" error with the code below

import ast
ast.literal_eval("[float(x) for x in range(4)]")

This problem would be fixed by replacing ast.literal_eval with eval.

eval("[float(x) for x in range(4)]")

This bug disappears once I replace ast.literal_eval with eval in lines 436 and 482.

       # Determine the lvalue type
        def get_type(element, _vtype):
            evaluated = None
            try:
                evaluated = eval(element)
# ...
                if _vtype == None:
                    _vtype = type(evaluated)

        if self.vtype in ['bool', 'gr_complex'] or 'std::map' in self.vtype or 'std::vector' in self.vtype:
            evaluated = eval(value)
# ...

Not sure if its wise to change it though. eval not as safe as ast.literal_eval, but I dont think we have a choice as the latter "only considers a small subset of Python's syntax to be valid", which I believe is why we had this problem to begin with.

@marcusmueller
Copy link
Member

On main, with this fg:

repro4955

https://gist.github.com/marcusmueller/c9741d435e8ec7aa5ba23db90a987334

we get a different error:

Traceback (most recent call last):
  File "/home/marcus/.usrlocal/lib64/python3.11/site-packages/gnuradio/grc/gui/Application.py", line 758, in _handle_action
    generator.write()
  File "/home/marcus/.usrlocal/lib64/python3.11/site-packages/gnuradio/grc/core/generator/cpp_top_block.py", line 84, in write
    self._variable_types()
  File "/home/marcus/.usrlocal/lib64/python3.11/site-packages/gnuradio/grc/core/generator/cpp_top_block.py", line 346, in _variable_types
    var.format_expr(var_types[str(var.params['id'].value)])
  File "/home/marcus/.usrlocal/lib64/python3.11/site-packages/gnuradio/grc/core/blocks/block.py", line 475, in format_expr
    self.vtype = get_type(value, py_type)
                 ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/marcus/.usrlocal/lib64/python3.11/site-packages/gnuradio/grc/core/blocks/block.py", line 460, in get_type
    return f"std::vector<{get_type(str(evaluated[0]), type(evaluated[0]))}>"
                                       ~~~~~~~~~^^^
TypeError: 'NoneType' object is not subscriptable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants