pythonmacosmacos-big-sur.app

Different behaviour of my_app.app (terminating) and my_app.app/Contents/MacOS/my_app (working perfectly)


I have a function test() as shown below, downloading a txt-file containing emoji's and other unicode special characters. The downloaded content is saved to a .txt file and then, per line, with line numbers added, to a .csv file.

When I build test.app (using py2app) and run it, it does save the .txt file (showing the same content as the original) but when saving .csv, it stops at the first special character (with error message test Error: Open console / Terminate; system.log shows 'Service exited with abnormal code: 255').

On the other hand, when running test.app/Contents/MacOS/test, it works properly and saves the whole content to .csv without any problems.

I have tested it with a pure Python version as well as cythonized, and also code-signed. In all cases, .app doesn't work while .app/Contents/MacOS/test works properly.

I would like to know why is it different (I've only started with Mac 3 months ago and definitely don't know everything about it) and what should I change to get my test.app working properly.

def test():
    url = 'https://unicode.org/Public/emoji/1.0/emoji-data.txt'
    log_filename = 'emoji-data.log'
    globals.log_file = open(log_filename, 'w', buffering=1)

    output_txt = 'test.txt'
    output_csv = 'test.csv'
    keys = ('row_nr', 'row')
    with open(output_csv, 'w') as outfile:
        writer = csv.writer(outfile, delimiter=',')
        writer.writerow(keys)

    logging.info(f'going to download...')
    with requests.get(url, timeout=5) as resp:
        with open(str(output_txt), 'wb') as f:
            for chunk in resp.iter_content(chunk_size=8192):
                f.write(chunk)

    encoding = resp.encoding
    if encoding is None:
        logging.info('Unknown encoding!')
        encoding = 'utf-8'
    logging.info(f'encoding = {encoding}')
    resp = resp.content.decode(encoding)
    logging.info('decoded resp')

    for i, row in enumerate(resp.split('\n')):
        logging.info(f'row {i}: {row}')

        with open(output_csv, 'a') as outfile:
            writer = csv.writer(outfile, delimiter=',')
            writer.writerow((i, row))
            
    logging.info('... done')

    # closing:
    if log_file:
        log_file.close()
    return

test()

emoji-data.log:

going to download...
encoding = utf-8
decoded resp
row 0: # Emoji Data for UTR #51
row 1: #
row 2: # File:    emoji-data.txt
row 3: # Version: 1.0
row 4: # Date:    2015-08-04
row 5: #
row 6: # Copyright (c) 2015 Unicode, Inc.
row 7: # For terms of use, see http://www.unicode.org/terms_of_use.html
row 8: # For documentation and usage, see http://www.unicode.org/reports/tr51/
row 9: #
row 10: # Format: Code ; Default_Emoji_Style ; Emoji_Level ; Emoji_Modifier_Status ; Emoji_Sources # Comment
row 11: #

test.csv:

row_nr,row
0,# Emoji Data for UTR #51
1,#
2,# File:    emoji-data.txt
3,# Version: 1.0
4,# Date:    2015-08-04
5,#
6,"# Copyright (c) 2015 Unicode, Inc."
7,"# For terms of use, see http://www.unicode.org/terms_of_use.html"
8,"# For documentation and usage, see http://www.unicode.org/reports/tr51/"
9,#
10,# Format: Code ; Default_Emoji_Style ; Emoji_Level ; Emoji_Modifier_Status ; Emoji_Sources # Comment
11,#

Solution

  • app runs with a different locale from the one when you run directly on the command line.

    Try to put in your .py :

    import locale
    locale.setlocale(locale.LC_ALL, ('C', 'UTF-8'))
    

    For explanation of C locale, see https://docs.oracle.com/cd/E23824_01/html/E26033/glmbx.html