Christos Hayward
Christos Hayward

Reputation: 5993

Why is Python concatenating strings in a list rather than iterating over them?

In a Python CGI script, I have lists of strings which are keys to a hash:

APPENDIX_WEBSITES = ['CJSHayward']
MAIN_WEBSITES = ['Alfresco',
  'Bible',
  'Fathers',
  'MyCollab',
  'Koha',
  'MediaWiki',
  'Moodle',
  'RequestTracker',
  'SuiteCRM',
  'TikiWiki',
  'Wordpress']
# The variable "data" is populated with a hash containing all above entries as keys.
sys.stderr.write(repr(MAIN_WEBSITES) + '\n')
sys.stderr.write(repr(APPENDIX_WEBSITES) + '\n')
sys.stderr.write(repr(MAIN_WEBSITES + APPENDIX_WEBSITES) + '\n')
for website in MAIN_WEBSITES + APPENDIX_WEBSITES:
    sys.stderr.write(website)

The Apache log faithfully records:

[Tue Aug 08 16:25:34.266769 2017] [cgi:error] [pid 16429] [client 127.0.0.1:40600] AH01215: ['Alfresco', 'Bible', 'Fathers', 'MyCollab', 'Koha', 'MediaWiki', 'Moodle', 'RequestTracker', 'SuiteCRM', 'TikiWiki', 'Wordpress']: /usr/local/websites/home/www/configure/index.cgi, referer: http://localhost/
[Tue Aug 08 16:25:34.267050 2017] [cgi:error] [pid 16429] [client 127.0.0.1:40600] AH01215: ['CJSHayward']: /usr/local/websites/home/www/configure/index.cgi, referer: http://localhost/
[Tue Aug 08 16:25:34.267268 2017] [cgi:error] [pid 16429] [client 127.0.0.1:40600] AH01215: ['Alfresco', 'Bible', 'Fathers', 'MyCollab', 'Koha', 'MediaWiki', 'Moodle', 'RequestTracker', 'SuiteCRM', 'TikiWiki', 'Wordpress', 'CJSHayward']: /usr/local/websites/home/www/configure/index.cgi, referer: http://localhost/
[Tue Aug 08 16:25:34.267490 2017] [cgi:error] [pid 16429] [client 127.0.0.1:40600] AH01215: AlfrescoAlfrescoBibleBibleFathersFathersMyCollabMyCollabKohaKohaMediaWikiMediaWikiMoodleMoodleRequestTrackerRequestTrackerSuiteCRMSuiteCRMTikiWikiTikiWiki: /usr/local/websites/home/www/configure/index.cgi, referer: http://localhost/

I am surprised that it seems to be iterating once over a single string (a redundant concatenation of the list), instead of iterating over what repr seems to recognize as a list of strings, which is what I intended.

How can I get the loop to iterate over 'Alfresco', 'Bible', etc. up through 'CJSHayward'?

Upvotes: 4

Views: 145

Answers (1)

andrew
andrew

Reputation: 2574

As commenters have indicated, you must append a newline character (\n) to website in order for each website to appear on it's own line in the Apache log.

for website in MAIN_WEBSITES + APPENDIX_WEBSITES:
    sys.stderr.write(website + '\n')

That is will resolve your issue. However, it may interest you to know why this resolves the issue.

It's not crazy to expect that each call to sys.stderr.write would result its own line in the log. The reason this is not the case is because sys.stderr is a stream. A stream is an abstraction for data being sent somewhere. In this case, sys.stderr.write writes to the standard error stream, and your Apache log reads from the standard error stream. The Apache log does not know how many times you have called sys.stderr.write. It only knows what it can see in the stream. For example, it is impossible for the Apache log to know the difference between

sys.stderr('HelloWorld')

and

sys.stderr('Hello')
sys.stderr('World')

In both cases, Apache log (and other applications that read from standard error) just see the stream of characters 'HelloWorld'. For this reason, Apache log must use the newline character (\n) to divide the standard error stream into separate lines.

Upvotes: 1

Related Questions