Nuitka / Nuitka

Nuitka is a Python compiler written in Python. It's fully compatible with Python 2.6, 2.7, 3.4-3.12. You feed it your Python app, it does a lot of clever things, and spits out an executable or extension module.
http://nuitka.net
Apache License 2.0
11.72k stars 636 forks source link

Nuitka won't work with Astropy #2313

Closed MatCat776 closed 1 year ago

MatCat776 commented 1 year ago

python3 -m nuitka --version 1.7 Commercial: None Python: 3.9.10 (main, Jun 29 2023, 21:55:15) Flavor: Unknown Executable: /usr/local/bin/python3 OS: Linux Arch: x86_64 Distribution: Centos (based on Fedora) 7 Nuitka-Scons:INFO: The provided gcc is too old, switching to its g++ instead. Version C compiler: /usr/bin/g++ (g++).

Download from https://www.python.org/

Package Version

astropy 5.3

I can compile code that does not include Astropy.

Text of minimalTest.py:

import astropy.coordinates #this does not work
#import astropy  #this line appears to work
print('hello world')

Compiling minimal test appears to work. When running the resulting executable, I get errors. Commands to repeat my simple test:

pip3 install jplephem
pip3 install astropy
time python3 -m nuitka --standalone --include-package=astropy.coordinates --include-package=astropy.constants minimalTest.py
cp /usr/local/lib/python3.9/site-packages/astropy/CITATION /generator/tmp/minimalTest.dist/astropy
./minimalTest.dist/minimalTest.bin

The result of running the .bin is an error similar to https://github.com/astropy/astropy/issues/10361.

I think there are 2 issues: Issue 1: Nuitka does something I don't understand when importing sub-packages. I don't get an instant runtime fail when minimalTest.py calls "import astropy" I do get an instant runtime fail when minimalTest.py calls "import astropy.coordinates" I would expect either import call to work. Since the minimalTest.py does not make use of any astropy functions (it only imports it), I can't confirm that it is fully functional.

Issue 2: Removing docstrings Astropy uses a 3rd party package Ply that requires docstrings. Compiling with Nuitka seems to have some similar failures as running with python3 -OO minimalTest.py. Does Nuitka remove docstrings? Where can I find documentation related to this?

--standalone --include-package=astropy.coordinates --include-package=astropy.constants also tried with --include-package=astropy

Not working in any tested version.

kayhayen commented 1 year ago

Just a note, you might want to use the EPEL devtools like this:

yum -y install epel-release centos-release-scl;yum repolist;yum -y install devtoolset-9;

The old gcc is supposed to work, but that's going to give nicer results if that gcc is used.

Nuitka does include docstrings unless you ask it to remove it, with --python-flag options.

For data files, there are options and configuration to copy them.

I definitely don't like "error similar to read some other place", please report the actual error.

kayhayen commented 1 year ago

In the code I found this in:

def get_caller_module_dict(levels):
    f = sys._getframe(levels)

    ldict = f.f_globals.copy()
    if f.f_globals != f.f_locals:
        ldict.update(f.f_locals)
    return ldict

This call to return parsing.yacc(tabmodule="generic_parsetab", package="astropy/units") wants to find lots of unused functions and variables in this way, and instead of passing locals() along, it just does this crapy approach. I believe it merges locals() and globals() too. My Visual Code shows these as unused functions.

I did a bunch of anti-bloat to get rid of IPython and pytest somewhat, to make it more bearable. But it seems there is no easy way to make this compatible. Nuitka populates the frame locals only when an exception occurs, which didn't happen.

To add insult to injury, there is glorious more code.

        with _patch_get_caller_module_dict(yacc):
            parser = yacc.yacc(
                tabmodule=tabmodule,
                outputdir=os.path.dirname(caller_file),
                debug=False,
                optimize=True,
                write_tables=True,
            )

This context generator wraps get_caller_module_dict such that the levels that it expects it up, which is hard coded to 2 is then going to be 3, since it's make a call through another function.

This is clearly not close to good code.

The current state of factory should get you straight there. The exception chain points to yacc and the error is ERROR: No token list is defined. No more options are needed, dependencies and data files were added to Nuitka package configuration there.

MatCat776 commented 1 year ago

Thanks for the quick reply. I've never installed nuitka from factory code, so it may take a bit to test. I plan to try this today.

MatCat776 commented 1 year ago

My testing is still in progress. I stumbled across something interesting. I don't think this is the cause of my issues, but worth noting just in case.

I added the following lines to the top of my minimalTest.py. (It is quite possible that the rest of minimalTest.py is unnecessary, but I didn't test it that way.)

import sys
print(sys.flags)

When I run my script, I get different values of the optimize flag when I run nuitka vs python with the -OO flag.

Running with nuitka:

time python3 -m nuitka --standalone --python-flag=-OO minimalTest.py
./minimalTest.dist/minimalTest.bin

Running with Python python3 -OO minimalTest.py

Results of optimize flag: Python Flag - Nuitka - Python none ------------ 0 -------- 0 -O --------------- 1 -------- 1 -OO ------------- 1 -------- 2 doc+ass* ------- 1 ---------n/a

*full command: --python-flag=no_docstrings --python-flag=no_asserts

kayhayen commented 1 year ago

That's indeed very interesting. I believe making a patch to upstream, such that get_caller_module_dict is replaced by explicit passing of context should be trival. If you or anybody were to do and share it, that will be great.

For now, the result of said function is an empty dict, which triggers the error we remain seeing.

As for your flags issue, that's indeed a compatiblity bug. I wonder if people check it ever, but rather than wondering, I guess it's better to make it behave compatible.

The last of your cases is -OO spelled out.

                elif part in ("-OO",):
                    _python_flags.add("no_docstrings")
                    _python_flags.add("no_asserts")

Nuitka allows a mode that Python doesn't have there. Gradually we are going to move to allowing a scoping on these things, such that e.g. no_docstrings will become default for stdlib potentially. Or that Yaml package configuration will allow to enforce docstrings for certain modules or functions. Going to get more messy to reduce it to one value.

kayhayen commented 1 year ago

Just noticing, that the __compiled__ probably deserves to have these flags, and then maybe needs to be made module local where there are differences, or be accompanied by another variable that is not as static.

kayhayen commented 1 year ago

So for factory, astropy anti-bloat, etc. is complete from my side, should need no options at all anymore. However, an upstream change is needed. I did try to set frame locals value before the call to locals(), like so sys._getframe().f_locals.update(locals()) but it didn't yield the result I was hoping for. This was a new idea I had, but I likely need to check it in a smaller test case.

kayhayen commented 1 year ago

That's on develop now.

MatCat776 commented 1 year ago

Thanks for the update. I think the next step is for me to contact the astropy team to investigate the issues you mentioned above.

kayhayen commented 1 year ago

Yes, please keep me posted, I can also clarify if they need that. I think that need to at least make it optionally so, that the context can be explicitely passed. But let me guess, everybody forgot what that yacc is and is afraid to touch it. :)

MatCat776 commented 1 year ago

I see that your update is in develop branch. Astropy's first update will be released soon. I'm going to wait until both updates are properly released, then do a clean re-build of my environment and continue testing.

kayhayen commented 1 year ago

In our package configuration, we can check package versions, it would be nice to know what version is supported.

- module-name: 'objc'
  options:
    checks:
      - description: 'pyobjc is not supported before 9.0 or later'
        support_info: 'error'
        when: 'version("pyobjc") < (9,)'

As an example. Let me know or create a PR adding something for astropy once they enhanced that.

MatCat776 commented 1 year ago

The current up-to-date code versions of Nuitka and Astropy put together doesn't solve the problem. I'm really not sure if the problem is with Astropy, Ply or Nuitka. Can you join this thread so that we have the conversation in a single location? https://github.com/astropy/astropy/issues/15069

kayhayen commented 1 year ago

I am afraid, I cannot do that. For me it's not easy to understand interactions of other projects. I think I made clear, what the issue is from Nuitka's side. Now I need somebody else to take care of it.

MatCat776 commented 1 year ago

I agree with you that _patch_get_caller_module_dict is a bit of a mess, but I'm not convinced that is the root of my problem. It looks like Nuitka picks up the same dictionary as straight python, but in the compiled version, it gets cropped when the value 'quit' appears. Can you provide some insight one how Nuitka reads in dictionaries?

Normal python use: debug out: pdict


{'__name__': 'astropy.units.format.generic', '__doc__': '\nHandles a "generic" string format for units\n', '__package__': 'astropy.units.format', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f4fe817cc70>, '__spec__': ModuleSpec(name='astropy.units.format.generic', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f4fe817cc70>, origin='/generator/tmp/astropy/astropy/units/format/generic.py'), '__file__': '/generator/tmp/astropy/astropy/units/format/generic.py', '__cached__': '/generator/tmp/astropy/astropy/units/format/__pycache__/generic.cpython-39.pyc', '__builtins__': {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>, origin='built-in'), '__build_class__': <built-in function __build_class__>, '__import__': <built-in function __import__>, 'abs': <built-in function abs>, 'all': <built-in function all>, 'any': <built-in function any>, 'ascii': <built-in function ascii>, 'bin': <built-in function bin>, 'breakpoint': <built-in function breakpoint>, 'callable': <built-in function callable>, 'chr': <built-in function chr>, 'compile': <built-in function compile>, 'delattr': <built-in function delattr>, 'dir': <built-in function dir>, 'divmod': <built-in function divmod>, 'eval': <built-in function eval>, 'exec': <built-in function exec>, 'format': <built-in function format>, 'getattr': <built-in function getattr>, 'globals': <built-in function globals>, 'hasattr': <built-in function hasattr>, 'hash': <built-in function hash>, 'hex': <built-in function hex>, 'id': <built-in function id>, 'input': <built-in function input>, 'isinstance': <built-in function isinstance>, 'issubclass': <built-in function issubclass>, 'iter': <built-in function iter>, 'len': <built-in function len>, 'locals': <built-in function locals>, 'max': <built-in function max>, 'min': <built-in function min>, 'next': <built-in function next>, 'oct': <built-in function oct>, 'ord': <built-in function ord>, 'pow': <built-in function pow>, 'print': <built-in function print>, 'repr': <built-in function repr>, 'round': <built-in function round>, 'setattr': <built-in function setattr>, 'sorted': <built-in function sorted>, 'sum': <built-in function sum>, 'vars': <built-in function vars>, 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': <class 'bool'>, 'memoryview': <class 'memoryview'>, 'bytearray': <class 'bytearray'>, 'bytes': <class 'bytes'>, 'classmethod': <class 'classmethod'>, 'complex': <class 'complex'>, 'dict': <class 'dict'>, 'enumerate': <class 'enumerate'>, 'filter': <class 'filter'>, 'float': <class 'float'>, 'frozenset': <class 'frozenset'>, 'property': <class 'property'>, 'int': <class 'int'>, 'list': <class 'list'>, 'map': <class 'map'>, 'object': <class 'object'>, 'range': <class 'range'>, 'reversed': <class 'reversed'>, 'set': <class 'set'>, 'slice': <class 'slice'>, 'staticmethod': <class 'staticmethod'>, 'str': <class 'str'>, 'super': <class 'super'>, 'tuple': <class 'tuple'>, 'type': <class 'type'>, 'zip': <class 'zip'>, '__debug__': True, 'BaseException': <class 'BaseException'>, 'Exception': <class 'Exception'>, 'TypeError': <class 'TypeError'>, 'StopAsyncIteration': <class 'StopAsyncIteration'>, 'StopIteration': <class 'StopIteration'>, 'GeneratorExit': <class 'GeneratorExit'>, 'SystemExit': <class 'SystemExit'>, 'KeyboardInterrupt': <class 'KeyboardInterrupt'>, 'ImportError': <class 'ImportError'>, 'ModuleNotFoundError': <class 'ModuleNotFoundError'>, 'OSError': <class 'OSError'>, 'EnvironmentError': <class 'OSError'>, 'IOError': <class 'OSError'>, 'EOFError': <class 'EOFError'>, 'RuntimeError': <class 'RuntimeError'>, 'RecursionError': <class 'RecursionError'>, 'NotImplementedError': <class 'NotImplementedError'>, 'NameError': <class 'NameError'>, 'UnboundLocalError': <class 'UnboundLocalError'>, 'AttributeError': <class 'AttributeError'>, 'SyntaxError': <class 'SyntaxError'>, 'IndentationError': <class 'IndentationError'>, 'TabError': <class 'TabError'>, 'LookupError': <class 'LookupError'>, 'IndexError': <class 'IndexError'>, 'KeyError': <class 'KeyError'>, 'ValueError': <class 'ValueError'>, 'UnicodeError': <class 'UnicodeError'>, 'UnicodeEncodeError': <class 'UnicodeEncodeError'>, 'UnicodeDecodeError': <class 'UnicodeDecodeError'>, 'UnicodeTranslateError': <class 'UnicodeTranslateError'>, 'AssertionError': <class 'AssertionError'>, 'ArithmeticError': <class 'ArithmeticError'>, 'FloatingPointError': <class 'FloatingPointError'>, 'OverflowError': <class 'OverflowError'>, 'ZeroDivisionError': <class 'ZeroDivisionError'>, 'SystemError': <class 'SystemError'>, 'ReferenceError': <class 'ReferenceError'>, 'MemoryError': <class 'MemoryError'>, 'BufferError': <class 'BufferError'>, 'Warning': <class 'Warning'>, 'UserWarning': <class 'UserWarning'>, 'DeprecationWarning': <class 'DeprecationWarning'>, 'PendingDeprecationWarning': <class 'PendingDeprecationWarning'>, 'SyntaxWarning': <class 'SyntaxWarning'>, 'RuntimeWarning': <class 'RuntimeWarning'>, 'FutureWarning': <class 'FutureWarning'>, 'ImportWarning': <class 'ImportWarning'>, 'UnicodeWarning': <class 'UnicodeWarning'>, 'BytesWarning': <class 'BytesWarning'>, 'ResourceWarning': <class 'ResourceWarning'>, 'ConnectionError': <class 'ConnectionError'>, 'BlockingIOError': <class 'BlockingIOError'>, 'BrokenPipeError': <class 'BrokenPipeError'>, 'ChildProcessError': <class 'ChildProcessError'>, 'ConnectionAbortedError': <class 'ConnectionAbortedError'>, 'ConnectionRefusedError': <class 'ConnectionRefusedError'>, 'ConnectionResetError': <class 'ConnectionResetError'>, 'FileExistsError': <class 'FileExistsError'>, 'FileNotFoundError': <class 'FileNotFoundError'>, 'IsADirectoryError': <class 'IsADirectoryError'>, 'NotADirectoryError': <class 'NotADirectoryError'>, 'InterruptedError': <class 'InterruptedError'>, 'PermissionError': <class 'PermissionError'>, 'ProcessLookupError': <class 'ProcessLookupError'>, 'TimeoutError': <class 'TimeoutError'>, 'open': <built-in function open>, 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2022 Python Software Foundation.
All Rights Reserved.

Copyright (c) 2000 BeOpen.com.
All Rights Reserved.

Copyright (c) 1995-2001 Corporation for National Research Initiatives.
All Rights Reserved.

Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
All Rights Reserved., 'credits':     Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
    for supporting Python development.  See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.}, 're': <module 're' from '/usr/local/lib/python3.9/re.py'>, 'unicodedata': <module 'unicodedata' from '/usr/local/lib/python3.9/lib-dynload/unicodedata.cpython-39-x86_64-linux-gnu.so'>, 'warnings': <module 'warnings' from '/usr/local/lib/python3.9/warnings.py'>, 'Fraction': <class 'fractions.Fraction'>, 'classproperty': <class 'astropy.utils.decorators.classproperty'>, 'deprecated': <function deprecated at 0x7f5001126ee0>, 'parsing': <module 'astropy.utils.parsing' from '/generator/tmp/astropy/astropy/utils/parsing.py'>, 'did_you_mean': <function did_you_mean at 0x7f4fe8537040>, 'core': <module 'astropy.units.core' from '/generator/tmp/astropy/astropy/units/core.py'>, 'Base': <class 'astropy.units.format.base.Base'>, 'Generic': <class 'astropy.units.format.generic.Generic'>, 'Unscaled': <class 'astropy.units.format.generic.Unscaled'>, 'tokens': ('COMMA', 'DOUBLE_STAR', 'STAR', 'PERIOD', 'SOLIDUS', 'CARET', 'OPEN_PAREN', 'CLOSE_PAREN', 'FUNCNAME', 'UNIT', 'SIGN', 'UINT', 'UFLOAT'), 'p_main': <function Generic._make_parser.<locals>.p_main at 0x7f4fe80b9670>, 'p_structured_subunit': <function Generic._make_parser.<locals>.p_structured_subunit at 0x7f4fe80b9700>, 'p_structured_unit': <function Generic._make_parser.<locals>.p_structured_unit at 0x7f4fe805a670>, 'p_subunit': <function Generic._make_parser.<locals>.p_subunit at 0x7f4fe805a700>, 'p_unit': <function Generic._make_parser.<locals>.p_unit at 0x7f4fe805a790>, 'p_division_product_of_units': <function Generic._make_parser.<locals>.p_division_product_of_units at 0x7f4fe805a820>, 'p_inverse_unit': <function Generic._make_parser.<locals>.p_inverse_unit at 0x7f4fe805a8b0>, 'p_factor': <function Generic._make_parser.<locals>.p_factor at 0x7f4fe805a940>, 'p_factor_float': <function Generic._make_parser.<locals>.p_factor_float at 0x7f4fe805a9d0>, 'p_factor_int': <function Generic._make_parser.<locals>.p_factor_int at 0x7f4fe805aa60>, 'p_factor_fits': <function Generic._make_parser.<locals>.p_factor_fits at 0x7f4fe805aaf0>, 'p_product_of_units': <function Generic._make_parser.<locals>.p_product_of_units at 0x7f4fe805ab80>, 'p_unit_expression': <function Generic._make_parser.<locals>.p_unit_expression at 0x7f4fe805ac10>, 'p_unit_with_power': <function Generic._make_parser.<locals>.p_unit_with_power at 0x7f4fe805aca0>, 'p_numeric_power': <function Generic._make_parser.<locals>.p_numeric_power at 0x7f4fe805ad30>, 'p_paren_expr': <function Generic._make_parser.<locals>.p_paren_expr at 0x7f4fe805adc0>, 'p_frac': <function Generic._make_parser.<locals>.p_frac at 0x7f4fe805ae50>, 'p_sign': <function Generic._make_parser.<locals>.p_sign at 0x7f4fe805aee0>, 'p_product': <function Generic._make_parser.<locals>.p_product at 0x7f4fe805af70>, 'p_division': <function Generic._make_parser.<locals>.p_division at 0x7f4fe7a2f040>, 'p_power': <function Generic._make_parser.<locals>.p_power at 0x7f4fe7a2f0d0>, 'p_signed_int': <function Generic._make_parser.<locals>.p_signed_int at 0x7f4fe7a2f160>, 'p_signed_float': <function Generic._make_parser.<locals>.p_signed_float at 0x7f4fe7a2f1f0>, 'p_function_name': <function Generic._make_parser.<locals>.p_function_name at 0x7f4fe7a2f280>, 'p_function': <function Generic._make_parser.<locals>.p_function at 0x7f4fe7a2f310>, 'p_error': <function Generic._make_parser.<locals>.p_error at 0x7f4fe7a2f3a0>, 'cls': <class 'astropy.units.format.generic.Generic'>}

Combiled bin use: debug out: pdict

{'__name__': 'astropy.units.format.generic', '__doc__': '\nHandles a "generic" string format for units\n', '__package__': 'astropy.units.format', '__loader__': <class 'nuitka_module_loader'>, '__spec__': ModuleSpec(name='astropy.units.format.generic', loader=<class 'nuitka_module_loader'>, origin='/generator/tmp/Nuitka/minimalTest.dist/astropy/units/format/generic.py'), '__compiled__': __nuitka_version__(major=1, minor=8, micro=0, releaselevel='candidate', standalone=True, onefile=False, no_asserts=False, no_docstrings=False, no_annotations=False), '__builtins__': {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>, origin='built-in'), '__build_class__': <built-in function __build_class__>, '__import__': <built-in function __import__>, 'abs': <built-in function abs>, 'all': <built-in function all>, 'any': <built-in function any>, 'ascii': <built-in function ascii>, 'bin': <built-in function bin>, 'breakpoint': <built-in function breakpoint>, 'callable': <built-in function callable>, 'chr': <built-in function chr>, 'compile': <built-in function compile>, 'delattr': <built-in function delattr>, 'dir': <built-in function dir>, 'divmod': <built-in function divmod>, 'eval': <built-in function eval>, 'exec': <built-in function exec>, 'format': <built-in function format>, 'getattr': <built-in function getattr>, 'globals': <built-in function globals>, 'hasattr': <built-in function hasattr>, 'hash': <built-in function hash>, 'hex': <built-in function hex>, 'id': <built-in function id>, 'input': <built-in function input>, 'isinstance': <built-in function isinstance>, 'issubclass': <built-in function issubclass>, 'iter': <built-in function iter>, 'len': <built-in function len>, 'locals': <built-in function locals>, 'max': <built-in function max>, 'min': <built-in function min>, 'next': <built-in function next>, 'oct': <built-in function oct>, 'ord': <built-in function ord>, 'pow': <built-in function pow>, 'print': <built-in function print>, 'repr': <built-in function repr>, 'round': <built-in function round>, 'setattr': <built-in function setattr>, 'sorted': <built-in function sorted>, 'sum': <built-in function sum>, 'vars': <built-in function vars>, 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': <class 'bool'>, 'memoryview': <class 'memoryview'>, 'bytearray': <class 'bytearray'>, 'bytes': <class 'bytes'>, 'classmethod': <class 'classmethod'>, 'complex': <class 'complex'>, 'dict': <class 'dict'>, 'enumerate': <class 'enumerate'>, 'filter': <class 'filter'>, 'float': <class 'float'>, 'frozenset': <class 'frozenset'>, 'property': <class 'property'>, 'int': <class 'int'>, 'list': <class 'list'>, 'map': <class 'map'>, 'object': <class 'object'>, 'range': <class 'range'>, 'reversed': <class 'reversed'>, 'set': <class 'set'>, 'slice': <class 'slice'>, 'staticmethod': <class 'staticmethod'>, 'str': <class 'str'>, 'super': <class 'super'>, 'tuple': <class 'tuple'>, 'type': <class 'type'>, 'zip': <class 'zip'>, '__debug__': True, 'BaseException': <class 'BaseException'>, 'Exception': <class 'Exception'>, 'TypeError': <class 'TypeError'>, 'StopAsyncIteration': <class 'StopAsyncIteration'>, 'StopIteration': <class 'StopIteration'>, 'GeneratorExit': <class 'GeneratorExit'>, 'SystemExit': <class 'SystemExit'>, 'KeyboardInterrupt': <class 'KeyboardInterrupt'>, 'ImportError': <class 'ImportError'>, 'ModuleNotFoundError': <class 'ModuleNotFoundError'>, 'OSError': <class 'OSError'>, 'EnvironmentError': <class 'OSError'>, 'IOError': <class 'OSError'>, 'EOFError': <class 'EOFError'>, 'RuntimeError': <class 'RuntimeError'>, 'RecursionError': <class 'RecursionError'>, 'NotImplementedError': <class 'NotImplementedError'>, 'NameError': <class 'NameError'>, 'UnboundLocalError': <class 'UnboundLocalError'>, 'AttributeError': <class 'AttributeError'>, 'SyntaxError': <class 'SyntaxError'>, 'IndentationError': <class 'IndentationError'>, 'TabError': <class 'TabError'>, 'LookupError': <class 'LookupError'>, 'IndexError': <class 'IndexError'>, 'KeyError': <class 'KeyError'>, 'ValueError': <class 'ValueError'>, 'UnicodeError': <class 'UnicodeError'>, 'UnicodeEncodeError': <class 'UnicodeEncodeError'>, 'UnicodeDecodeError': <class 'UnicodeDecodeError'>, 'UnicodeTranslateError': <class 'UnicodeTranslateError'>, 'AssertionError': <class 'AssertionError'>, 'ArithmeticError': <class 'ArithmeticError'>, 'FloatingPointError': <class 'FloatingPointError'>, 'OverflowError': <class 'OverflowError'>, 'ZeroDivisionError': <class 'ZeroDivisionError'>, 'SystemError': <class 'SystemError'>, 'ReferenceError': <class 'ReferenceError'>, 'MemoryError': <class 'MemoryError'>, 'BufferError': <class 'BufferError'>, 'Warning': <class 'Warning'>, 'UserWarning': <class 'UserWarning'>, 'DeprecationWarning': <class 'DeprecationWarning'>, 'PendingDeprecationWarning': <class 'PendingDeprecationWarning'>, 'SyntaxWarning': <class 'SyntaxWarning'>, 'RuntimeWarning': <class 'RuntimeWarning'>, 'FutureWarning': <class 'FutureWarning'>, 'ImportWarning': <class 'ImportWarning'>, 'UnicodeWarning': <class 'UnicodeWarning'>, 'BytesWarning': <class 'BytesWarning'>, 'ResourceWarning': <class 'ResourceWarning'>, 'ConnectionError': <class 'ConnectionError'>, 'BlockingIOError': <class 'BlockingIOError'>, 'BrokenPipeError': <class 'BrokenPipeError'>, 'ChildProcessError': <class 'ChildProcessError'>, 'ConnectionAbortedError': <class 'ConnectionAbortedError'>, 'ConnectionRefusedError': <class 'ConnectionRefusedError'>, 'ConnectionResetError': <class 'ConnectionResetError'>, 'FileExistsError': <class 'FileExistsError'>, 'FileNotFoundError': <class 'FileNotFoundError'>, 'IsADirectoryError': <class 'IsADirectoryError'>, 'NotADirectoryError': <class 'NotADirectoryError'>, 'InterruptedError': <class 'InterruptedError'>, 'PermissionError': <class 'PermissionError'>, 'ProcessLookupError': <class 'ProcessLookupError'>, 'TimeoutError': <class 'TimeoutError'>, 'open': <built-in function open>, '__nuitka_binary_dir': '/generator/tmp/Nuitka/minimalTest.dist', '__nuitka_binary_exe': '/generator/tmp/Nuitka/minimalTest.dist/minimalTest.bin', '__nuitka_loader_type': <class 'nuitka_module_loader'>}, '__file__': '/generator/tmp/Nuitka/minimalTest.dist/astropy/units/format/generic.py', '__cached__': None, 're': <module 're' from '/generator/tmp/Nuitka/minimalTest.dist/re.py'>, 'unicodedata': <module 'unicodedata' (/generator/tmp/Nuitka/minimalTest.dist/unicodedata.so)>, 'warnings': <module 'warnings' (frozen)>, 'Fraction': <class 'fractions.Fraction'>, 'classproperty': <class 'astropy.utils.decorators.classproperty'>, 'deprecated': <compiled_function deprecated at 0x7fd38530d4f0>, 'parsing': <module 'astropy.utils.parsing' from '/generator/tmp/Nuitka/minimalTest.dist/astropy/utils/parsing.py'>, 'did_you_mean': <compiled_function did_you_mean at 0x7fd3852d3d60>, 'core': <module 'astropy.units.core' from '/generator/tmp/Nuitka/minimalTest.dist/astropy/units/core.py'>, 'Base': <class 'astropy.units.format.base.Base'>, 'Generic': <class 'astropy.units.format.generic.Generic'>, 'Unscaled': <class 'astropy.units.format.generic.Unscaled'>}

Search for 'Timeout' in both error strings. (Timeout is not significant, but it gets you to the right place in the string. You can't search for a missing term.) Notice that the first significant deviation is for the value 'quit'.

MatCat776 commented 1 year ago

After more debugging, I see that there are 2 things going on when I run the standalone compiled code:

  1. The f.f_global dictionary gets cropped starting at the value 'quit'.
  2. The f.f_locals dictionary is empty.

Debugging was in astropy/extern/ply/yacc.py line 2885+ My current theory is that there are 2 different root causes that resulted in what I thought was a single issue.

In an earlier comment, you said "Nuitka populates the frame locals only when an exception occurs, which didn't happen." Can you explain this a bit more?

kayhayen commented 1 year ago

Point 2 is exactly what I mean, it is not empty with Python I believe. However, I do not know if you need its values.

The quit is missing, because standalone nowadays does --python-flag=no_site by default. In the site module, builtins like quit, exit and help are added, which are mostly intended for the interactive prompt. Check your Python installationsite.pyfile. It is also responsible for addingsite-packagestosys.path`. Nuitka extracts those effects, but then runs without these things itself, and standalone programs too.

You can disable that behavior with --python-flag=site which then pulls in the site module. On some distributions like Ubuntu this also pulls in apport and what not, often very bloaty stuff, that can only do harm. For accelerated mode, it is the default however to load it, but it's also not included in the compilation by default of course.

kayhayen commented 1 year ago

Part of the 1.8 release I just made, I don't think Astropy works now, please open a new issue if there is more that Nuitka can do, e.g. workaround patches to apply