1

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,#
  • how do you make your python code into .app, pyinstaller, py2app or other – KetZoomer Apr 03 '21 at 01:44
  • @KetZoomer As mentioned in my question, I'm using py2app. – Lenka Čížková Apr 03 '21 at 01:51
  • sorry, didn't see that, try using pyinstaller, might be a bug with py2app – KetZoomer Apr 03 '21 at 01:51
  • We had a lot of problems with PyInstaller (related to missing libraries / unable to find dylibs under Big Sur), that's why we ended up using py2app. I just don't see how is it possible that the .app has problems with just this one action (it has many more functions including GUI and dealing with online data, reading/writing files in various formats etc and everything else works well, just this one specific function under specific occasions not) while the binary inside the .app works well in all cases (if it would be due to a bug in packaging, it shouldn't work either, should it?) – Lenka Čížková Apr 03 '21 at 01:58
  • I've put a bounty (offer my rep) on this, hope it attracts some attention, as this is a interesting question I'd love to see and answer for – KetZoomer Apr 03 '21 at 02:15
  • Thank you! I've also posted it to the Apple Developer Forum about 2 weeks ago but got no reaction so far. – Lenka Čížková Apr 03 '21 at 02:18

1 Answers1

2

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

Philippe
  • 20,025
  • 2
  • 23
  • 32
  • Thank you for your answer. Does it make any difference between (in Finder) double-clicking `my_app.app` vs. double-clicking the binary inside it (`my_app.app/Contents/MacOS/my_app`)? I'll try it as soon as I'm on my work computer. – Lenka Čížková Apr 03 '21 at 21:39
  • It behaves the same way. – Philippe Apr 03 '21 at 21:56
  • Then it cannot be a solution to my problem, unfortunately. Because the binary inside our .app works well when double-clicked, just the .app doesn't. – Lenka Čížková Apr 03 '21 at 22:00
  • What I mean is that with my change, it should work in both situations. – Philippe Apr 03 '21 at 22:02
  • I will try. Could you please let me know what means 'C' in `locale.setlocale`? I understand that it should be a country code but haven't found any with 'C'. – Lenka Čížková Apr 03 '21 at 22:06
  • @lenka_cizkova please tell me if if this works so I can award the bounty – KetZoomer Apr 04 '21 at 16:25
  • Yes! Thank you very much for this answer @Philippe, and for your support @KetZoomer. I've tested it with texts coming from various websites and it seems to work perfectly! Before adding this code snippet, I've checked current settings using `locale.setlocale(locale.LC_ALL, None)` and got from PyCharm: `C/UTF-8/C/C/C/C`, from terminal: `C/UTF-8/C/C/C/C`, from my_app.app: `en_US.UTF-8/C/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8` and from my_app.app/Contents/MacOS/my_app: `en_US.UTF-8/UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8`. While with that code snippet, just `en_US.UTF-8`. – Lenka Čížková Apr 05 '21 at 00:17