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

Problems using a package #18

Closed
manfredlotz opened this issue Jul 16, 2021 · 14 comments
Closed

Problems using a package #18

manfredlotz opened this issue Jul 16, 2021 · 14 comments

Comments

@manfredlotz
Copy link

Hi there, the following simple script doesn't work

#!/usr/bin/env zxpy

import toml

def main():
    toml_string = """
[test]
x = "something"
"""
    parsed_toml = toml.loads(toml_string)
    print(parsed_toml)


if __name__ == '__main__':
    main()

I get

Traceback (most recent call last):
  File "/home/manfred/.local/bin/zxpy", line 8, in <module>
    sys.exit(cli())
  File "/home/manfred/.local/lib/python3.8/site-packages/zx.py", line 56, in cli
    run_zxpy(filename, module)
  File "/home/manfred/.local/lib/python3.8/site-packages/zx.py", line 121, in run_zxpy
    exec(code, None, {'__name__': '__main__'})
  File "./x.py", line 15, in <module>
    main()
  File "./x.py", line 10, in main
    parsed_toml = toml.loads(toml_string)
NameError: name 'toml' is not defined
@tusharsadhwani
Copy link
Owner

This seems to run fine for me.

Can you run python -m pydoc toml without any virtualenvs activated, and ensure that it's location is inside /home/manfred/.local/lib/python3.8/site-packages

For reference look at the FILE part of this output:

> python3 -m pydoc toml
Help on package toml:

NAME
    toml - Python module which parses and emits TOML.

...

FILE
    /home/tushar/.local/lib/python3.9/site-packages/toml/__init__.py

@manfredlotz
Copy link
Author

Running python -m pydoc toml gives the same output as yours.

Here toml is a system package

$ dpkg -L python3-toml                                    
/.
/usr
/usr/lib
/usr/lib/python3
/usr/lib/python3/dist-packages
/usr/lib/python3/dist-packages/toml
/usr/lib/python3/dist-packages/toml/__init__.py
/usr/lib/python3/dist-packages/toml/decoder.py
/usr/lib/python3/dist-packages/toml/encoder.py
/usr/lib/python3/dist-packages/toml/ordered.py
/usr/lib/python3/dist-packages/toml/tz.py
/usr/lib/python3/dist-packages/toml-0.10.0.egg-info
/usr/lib/python3/dist-packages/toml-0.10.0.egg-info/PKG-INFO
/usr/lib/python3/dist-packages/toml-0.10.0.egg-info/dependency_links.txt
/usr/lib/python3/dist-packages/toml-0.10.0.egg-info/top_level.txt
/usr/share
/usr/share/doc
/usr/share/doc/python3-toml
/usr/share/doc/python3-toml/changelog.Debian.gz
/usr/share/doc/python3-toml/copyright

@manfredlotz
Copy link
Author

I shortened the not working example to

#!/usr/bin/env zxpy

import toml

def main():
    print(toml.__dir__())

if __name__ == '__main__':
    main()

This doesn't work but the following works fine

#!/usr/bin/env zxpy

import toml

print(toml.__dir__())

@tusharsadhwani
Copy link
Owner

tusharsadhwani commented Jul 16, 2021

It seems that zxpy is installed into /usr/XYZ/.local/lib/python3.8 python for you, while toml is installed in /usr/lib/python3.

I'm not 100% sure what the relationship between those two is, but if you can ensure that zxpy and toml are both installed for the same python, it should work.

@manfredlotz
Copy link
Author

manfredlotz commented Jul 16, 2021

  • zxpy is installed in /home/manfred/.local/lib/python3.8/site-packages/
  • toml is installed in /usr/lib/python3/dist-packages/toml

which is no problem for Python.

There is no virtualenv in play, and I have only one Python 3 systemwide installed

@Jackenmen
Copy link
Contributor

This is a regression in zxpy 1.4.1 and does not happen on zxpy 1.4.0.

This is reproducible with the usage of venv just fine as well.

It is most likely related to zxpy playing with locals

@tusharsadhwani
Copy link
Owner

Yup, you're right.

I just realised I was testing on 1.4.0. Thanks @jack1142

@Jackenmen
Copy link
Contributor

Looking at the code, I wonder, why is __name__ put in locals rather than globals? Passing locals to exec makes the whole code executed as if it were embedded in a class definition which translates to something like:

class X:
    __name__ = "__main__"

    import toml

    def main():
        print(toml.__dir__())

    if __name__ == '__main__':
        main()

@tusharsadhwani
Copy link
Owner

@jack1142 it's because it seemed to work :P and it's also because I couldn't figure out how to extract the globals from the compiled module, and update them. Do you know how that can be done?

@Jackenmen
Copy link
Contributor

and it's also because I couldn't figure out how to extract the globals from the compiled module, and update them

I don't think that needs to be done? The globals don't exist in the compiled form, only the code that defines them does. They should only exist once they actually get declared at runtime and the compiled code runs once you use exec.

Did you run into some issue when just doing this?

exec(code, {'__name__': '__main__'})

@tusharsadhwani
Copy link
Owner

@jack1142 IIRC yes, but let me try again

@tusharsadhwani
Copy link
Owner

@jack1142 alright that seems to work xD thanks about that

@manfredlotz I'll be releasing a new patch with the fix and reply soon

@tusharsadhwani
Copy link
Owner

@manfredlotz Alright, try again after doing pip install zxpy==1.4.2?

@manfredlotz
Copy link
Author

Yep, working fine now.

You are really quick. Much appreciated. Thanks a lot @tusharsadhwani and @jack1142 .

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

No branches or pull requests

3 participants