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

python_eval unable to access all macro defined variables #7

Closed
lgfausak opened this issue Jun 9, 2019 · 4 comments
Closed

python_eval unable to access all macro defined variables #7

lgfausak opened this issue Jun 9, 2019 · 4 comments
Assignees
Labels
rtfm Solution to be found in the fine manual

Comments

@lgfausak
Copy link

lgfausak commented Jun 9, 2019

the arguments in a macro are not reference-able if the macro does a repeat. For example:

- defmacro:
    name: TESTARG
    args: [ FIRST ]
    value:
      { data: { if: { python_eval: '1 == FIRST' }, then: "equals one", else: "not equals one" } }
---
- { TESTARG: { FIRST: 0 } }

when I run this script, I get:

- data: not equals one

Note: the FIRST argument is being referenced in the python_eval. Now consider this:

- defmacro:
    name: TESTARG
    args: [ FIRST ]
    value:
      - repeat:
          for: rux
          in: { range: [ 1, 4 ] }
          body:
            - { data: { if: { python_eval: 'rux == FIRST' }, then: "equals one", else: "not equals one" } }
#            - { "rux": rux, data: FIRST }
---
- { TESTARG: { FIRST: 2 } }

when I run this script, I get this error:

<type 'exceptions.NameError'>
name 'FIRST' is not defined

If I comment out the python_eval and uncomment the data: FIRST:

- defmacro:
    name: TESTARG
    args: [ FIRST ]
    value:
      - repeat:
          for: rux
          in: { range: [ 1, 4 ] }
          body:
#            - { data: { if: { python_eval: 'rux == FIRST' }, then: "equals one", else: "not equals one" } }
            - { "rux": rux, data: FIRST }
---
- { TESTARG: { FIRST: 2 } }

I now see this result:

- - - - data: 2
        rux: 1
    - - data: 2
        rux: 2
    - - data: 2
        rux: 3
    - - data: 2
        rux: 4

I guess this has something to do with . nesting a macro and trying to reference parent data?

@birchb1024
Copy link
Owner

Hi Greg,
I'm going to respond RFTM on this one ;-) (wink) Quote the manual "Python cannot see bindings in the environment hierarchy directly". python_eval is only there to provide more complex math and other fundamentals the macro processor does not have. So python eval() does not search the tree of closures looking for variables bound in earlier macro definitions or repeat scopes.

The good news is you don't need to use python_eval to to get bindings resolved. The code below produces the results you expect without python_eval.

Sidenote: The Go version of Yamp 'goyamp', does not have a Python interpreter to hand so I am building an 'execute:' builtin to fork a subprocess and transfer YAML/JSON in and out.. Maybe I will backport execute: into Yamp also. But I digress

- defmacro:
    name: TESTARG
    args: [ FIRST ]
    value:
      repeat:
          for: rux
          in: { range: [ 1, 4 ] }
          body:
            if: { ==: [rux, FIRST] }
            then: "{{rux}} equals {{FIRST}}"
            else: "{{rux}} not equals {{FIRST}}"
---
TESTARG: { FIRST: 2 }

This gives :

---
- 1 not equals 2
- 2 equals 2
- 3 not equals 2
- 4 not equals 2

@birchb1024 birchb1024 added the wontfix This will not be worked on label Jun 10, 2019
@birchb1024 birchb1024 self-assigned this Jun 10, 2019
@birchb1024 birchb1024 added rtfm Solution to be found in the fine manual and removed wontfix This will not be worked on labels Jun 10, 2019
@lgfausak
Copy link
Author

unfortunately the code i produced was just to illustrate the issue. i am using python_eval to do more complex math, and it cannot do it because the variable is not available. it feels weird that the variable passed to the macro is not available to (some) of the macro execution patterns. i would expect

{ ==: [ rux, FIRST ] }

to return the same result as

{ python_eval: 'rux == FIRST' }

an execute, as you mention, would probably make it explicit. You are thinking a builtin?

execute: { command: ls, arg1: rux, arg2: FIRST }

thanks for looking at it.

@birchb1024 birchb1024 reopened this Jun 11, 2019
@birchb1024
Copy link
Owner

Hi greg,

OK just for you I will provide a utility function inside Python to get what you want. Something like:

{ python_eval: 'value(rux) == value(FIRST)' }

The utility function value() performs proper variable lookup, scanning environments etc.

How does that look?

PS I would love to know about the more complex math you mention. code please? I can add it to the test scenarios...

@birchb1024 birchb1024 changed the title defmacro ARG not able to reference python_eval unable to access all macro defined variables Jun 11, 2019
@birchb1024
Copy link
Owner

OK python_eval can now access all the things as you requested. - but without value(). So it works as in the original issue posting.

The code { python_eval: 'rux == FIRST' } will fetch the FIRST value from the environment hierarchy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rtfm Solution to be found in the fine manual
Projects
None yet
Development

No branches or pull requests

2 participants