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

unqualified exec is not allowed (Python 2.7.6) #1408

Closed
topiwala opened this issue Aug 12, 2015 · 11 comments
Closed

unqualified exec is not allowed (Python 2.7.6) #1408

topiwala opened this issue Aug 12, 2015 · 11 comments

Comments

@topiwala
Copy link

Followed the recipe in the manual for block cipher when packaging, but on extracting the executable, get the following error:

  File "<string>", line 28, in <module>
  File "/usr/local/lib/python2.7/dist-packages/PyInstaller-2.1.1dev_9d0e0ad-py2.7.egg/PyInstaller/loader/pyi_importers.py", line 203, in load_module
    is_pkg, bytecode = self._pyz_archive.extract(fullname)
  File "/usr/local/lib/python2.7/dist-packages/PyInstaller-2.1.1dev_9d0e0ad-py2.7.egg/PyInstaller/loader/pyi_archive.py", line 377, in extract
    raise ImportError("PYZ entry '%s' failed to decompress" % name)
ImportError: PYZ entry 'os' failed to decompress

I also had to add

import PyInstaller.loader.pyi_crypto as pyi_crypto

to be able to follow the manual's example.

Does anyone have a recipe that I can follow?

@htgoebel
Copy link
Member

Please try if this occurs on the current python3-branch-head, too.

@matysek
Copy link
Member

matysek commented Aug 12, 2015

@topiwala There is no specific cypher recipe in the wiki. But the manual for the python3 branch contains this .spec example:

block_cipher = pyi_crypto.PyiBlockCipher(key='test_key')
a = Analysis(['test_onefile_crypto.py'], cipher=block_cipher)
pyz = PYZ(a.pure, cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='test_onefile_crypto')

Please note that you do not need to use the line import PyInstaller.loader.pyi_crypto as pyi_crypto anymore.

@matysek matysek added the state:need info Need more information for solve or help. label Aug 14, 2015
@topiwala
Copy link
Author

I have a python2.7 project, and I don't think we can move to python3. I tried packaging with python3 branch, and ran into this error:

Is there any other way? Perhaps a merge of the changes from this branch into the main dev branch for just the cipher support?

Traceback (most recent call last):
  File "/usr/local/bin/pyinstaller", line 9, in <module>
    load_entry_point('PyInstaller==3.0.dev7165951', 'console_scripts', 'pyinstaller')()
  File "/usr/local/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 552, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/local/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2672, in load_entry_point
    return ep.load()
  File "/usr/local/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2345, in load
    return self.resolve()
  File "/usr/local/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2351, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/usr/local/lib/python2.7/dist-packages/PyInstaller-3.0.dev7165951-py2.7.egg/PyInstaller/main.py", line 20, in <module>
    import PyInstaller.building.build_main
  File "/usr/local/lib/python2.7/dist-packages/PyInstaller-3.0.dev7165951-py2.7.egg/PyInstaller/building/build_main.py", line 614
    exec(text, spec_namespace)
SyntaxError: unqualified exec is not allowed in function 'build' it contains a nested function with free variables

@codewarrior0
Copy link
Contributor

I think that's a bug - the exec() should have both locals and globals arguments.

@codewarrior0
Copy link
Contributor

Can you try changing this line: exec(text, spec_namespace)

To this: exec(text, spec_namespace, {})

And tell me if it fixes the problem?

@topiwala
Copy link
Author

That didn't work. However, a minor modification

exec text in spec_namespace

caused me to get further along, until I hit the error below:

from PyInstaller.utils.hooks.hookutils import relpath_to_config_or_make
Traceback (most recent call last):
  File "/usr/local/bin/pyinstaller", line 9, in <module>
    load_entry_point('PyInstaller===3.0dev-7165951-mod', 'console_scripts', 'pyinstaller')()
  File "/usr/local/lib/python2.7/dist-packages/PyInstaller-3.0dev_7165951_mod-py2.7.egg/PyInstaller/main.py", line 97, in run
    run_build(opts, spec_file, pyi_config)
  File "/usr/local/lib/python2.7/dist-packages/PyInstaller-3.0dev_7165951_mod-py2.7.egg/PyInstaller/main.py", line 50, in run_build
    PyInstaller.building.build_main.main(pyi_config, spec_file, **opts.__dict__)
  File "/usr/local/lib/python2.7/dist-packages/PyInstaller-3.0dev_7165951_mod-py2.7.egg/PyInstaller/building/build_main.py", line 671, in main
    build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
  File "/usr/local/lib/python2.7/dist-packages/PyInstaller-3.0dev_7165951_mod-py2.7.egg/PyInstaller/building/build_main.py", line 614, in build
    exec text in spec_namespace
  File "<string>", line 96, in <module>
  File "/usr/local/lib/python2.7/dist-packages/PyInstaller-3.0dev_7165951_mod-py2.7.egg/PyInstaller/building/build_main.py", line 181, in __init__
    self.__postinit__()
  File "/usr/local/lib/python2.7/dist-packages/PyInstaller-3.0dev_7165951_mod-py2.7.egg/PyInstaller/building/datastruct.py", line 151, in __postinit__
    self.assemble()
  File "/usr/local/lib/python2.7/dist-packages/PyInstaller-3.0dev_7165951_mod-py2.7.egg/PyInstaller/building/build_main.py", line 382, in assemble
    imphook_object = ImportHook(imported_name, hooks_cache[imported_name])
  File "/usr/local/lib/python2.7/dist-packages/PyInstaller-3.0dev_7165951_mod-py2.7.egg/PyInstaller/building/imphook.py", line 255, in __init__
    self._module = importlib_load_source('pyi_hook.'+self._name, self._filename)
  File "/usr/local/lib/python2.7/dist-packages/PyInstaller-3.0dev_7165951_mod-py2.7.egg/PyInstaller/hooks/hook-distutils.py", line 24, in <module>
    _MAKEFILE = sysconfig.get_makefile_filename()
AttributeError: 'module' object has no attribute 'get_makefile_filename'

@codewarrior0
Copy link
Contributor

These are your system specs from another issue:

Python: 2.7.6
OS: Ubuntu 14.04.1 LTS (64-bit)
Kernel version: 3.13.0-32-generic

I have a feeling this would work for you on Python 2.7.9 (it has further changes for python 3 compatibility), but I found out 2.7.6 is the last version offered on that version of Ubuntu, so I won't ask you to change Python versions.

The exec problem is Python issue 21591, fixed in 2.7.9, so we'll need to use a different syntax for executing the specfile (maybe runpy.run_path()?).

The get_makefile_filename problem is Python issue 22199 which says the old attribute was _get_makefile_filename, also fixed in 2.7.9. So we'll have to check for the old attribute first.

(Or we could just say "Requires Python 2.7.9" and then @topiwala is out of luck...)

@htgoebel
Copy link
Member

I tested this with Python 2.7.4:

fails

def build():
    namespace = {
        'TkPKG': lambda *args, **kwargs: _old_api_error('TkPKG'),
    }
    exec("print 'hallo'", namespace)
build()

fails

def build():
    def TkPKG(*args, **kwargs): _old_api_error('TkPKG')
    namespace = {'TkPKG': TkPKG}
    exec("print 'hallo'", namespace)
build()

passes (but does not what we want)

def build():
    def TkPKG(*args, **kwargs): pass # mind the `pass` here!
    namespace = {'TkPKG': TkPKG}
    exec("print 'hallo'", namespace)
build()

passes

def TkPKG(*args, **kwargs): _old_api_error('TkPKG')
def build():
    namespace = {'TkPKG': TkPKG}
    exec("print 'hallo'", namespace)
build()

passes

def build():
    def TkPKG(*args, **kwargs): 
        global _old_api_error
        _old_api_error('TkPKG')
    namespace = {'TkPKG': TkPKG}
    exec("print 'hallo'", namespace)
build()

I'm going to implement this work-around.

@htgoebel htgoebel self-assigned this Aug 18, 2015
htgoebel added a commit that referenced this issue Aug 18, 2015
In Python < 2.7.9 the function has an underscore prefix.

See issue #1408.
@uzpei
Copy link

uzpei commented Sep 2, 2015

I have the same issue as topiwala - I cannot use a block cipher with my Python 2.7 project (same error). System info:

Python 2.7.6
LSB Version:    core-2.0-amd64:core-2.0-noarch:core-3.0-amd64:core-3.0-noarch:core-3.1-amd64:core-3.1-noarch:core-3.2-amd64:core-3.2-noarch:core-4.0-amd64:core-4.0-noarch:core-4.1-amd64:core-4.1-noarch:security-4.0-amd64:security-4.0-noarch:security-4.1-amd64:security-4.1-noarch
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.3 LTS
Release:    14.04
Codename:   trusty

@htgoebel htgoebel removed the state:need info Need more information for solve or help. label Nov 18, 2015
@htgoebel htgoebel added this to the PyInstaller 3.1 milestone Nov 18, 2015
@htgoebel htgoebel changed the title Cipher recipe unqualified exec is not allowed (Python 2.7.6) Dec 22, 2015
@htgoebel
Copy link
Member

Ups, I already fixed this in fd59a96, but did not close the issue.

@htgoebel
Copy link
Member

@uzpei This ticket was discussing several different issues.Please open a new ticket describing "same error". Thanks,

@pyinstaller pyinstaller locked and limited conversation to collaborators Dec 22, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants