-
Notifications
You must be signed in to change notification settings - Fork 105
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
agi.verbose("string") bug #19
Comments
What is the variable (data) you are passing into it? Is it possible you are passing an object reference ? |
you are trying to join together string and byte objects. Oops, you've just dropped the python3 support.
did you ever test your own patches? |
Eill, Asterisk AGI works by standard in/out. And this stdin/out is expected to be plain text. The previous code converted everything passed to it to text str(). This had the side effect of if you passed a string that contained string encodings, as shown below, that the data would not be translated r = '\xc2\xae' # The ® trademark symbol. Because python can not determine the actual encoding used on the string, this can not be converted. Furthermore it can cause your asterisk application to crash. Enter Python 3. The issue comes from python3 when it performs the encoding it returns a byte string, and in python 2 it returns an ascii string. Finally, if you care to look at the first line of the agi.py file. this module is designed to work with python2 not python3. I am happy to review alternative methods, if you present them. BUT do keep in mind that things should remain compatible with python2. As to your question "did you ever test your own patches?", yes, obviously I have. Under the conditions that the script is designed to work, using the correct python interpreter, this functions correctly. Is PyST2 compatible with Python3? No. Not fully. It's getting there. Can you submit a test condition and code to be reviewed? Absolutely, and I would be happy to run tests against it. Keep in mind the code should remain backward compatible with python2 installations. |
that's wrong, I've added python3 support a year ago (and the module works with python3 fine). Yes, I forgot to change the shebang, but it does not matter here (you almost never directly execute the agi.py file but import it). for all, could you tell me what's the purpose of function _quote? Let's see the code (I've omitted the isinstance checks for clarity):
if you want to dispose of exceptions (according to your commit cef87f4 comment) you've done it wrong, because exceptions are still here. so code needs to be rewritten here. |
ok, I've read again your comment and I see that you just want not to pass the unicode strings to asterisk. I wish I finally understood your logic and I'll try to rewrite this code as soon as possible. |
The purpose of _quote() is to prevent illegal characters are passed back over AGI.
string here can not be encoded to 'ascii' because the string is encoded. You would need to decode this first.
Passing the decoded string to _quote functions correctly.
Python 2 automatically provides the output of string as the escaped characters. While Python3 does not.
The old code would have taken executed the above returning escaped characters under Python2 and a utf-8 (or whatever encoded character) under Python3. There is also no .decode() method on the string in python3 which adds to the problem. Under python2 converting of values such as '®' do not have an ascii equivalent and therefore are ignored. It would be considered reasonable to expect that a user would not want '\xc2\xae' to be the data returned to asterisk. The problem becomes more interesting when add things like JSON. Take for example the following under python3
and under python2
No shock here as python transforms each as expected. But note what happens when it is stored as JSON. We get yet another encoding. \u00ae So lets assume for example that your AGI application has made a call to some web service, or maybe a DB that is returning a JSON payload, something that is a rather common task. If the data contains our sample string, it would have been converted, to the cryptic \u00ae value. The new code change will ignore this char.
While the older code, converting all values to strings would have crashed.
This is what the code change is intended to prevent. Moving Forward Admittedly I did not do a lot of testing on python3, as python2 is still the default on distributions. (I am at least not aware of a python3 as default on any distro). I think the only way to make this work is to do some additional condition checking.
Okay I hope that gave enough examples and use case to help paint a better picture. |
Just wondering if there were any more thoughts on this? Given that Python 3 is almost a decade old now... also this is the subject of several issues and pull requests, eg: In my case, I just ended up doing this:
So far, it SEEMS to be OK. What might bite me here? In fact, I even tried a little test, pushing some weird characters back from pyst2 to Asterisk.
|
This indeed works but better make sure the other types are converted:
Or better !isinstance(string, str) which will fail in cases, where casting will not make sense. |
File "/opt/agi/unknow", line 13, in
agi.verbose("python agi started")
File "/usr/local/lib/python3.4/dist-packages/pyst2-0.4.7-py3.4.egg/asterisk/agi.py", line 606, in verbose
self.execute('VERBOSE', self._quote(message), level)
File "/usr/local/lib/python3.4/dist-packages/pyst2-0.4.7-py3.4.egg/asterisk/agi.py", line 121, in _quote
return ''.join(['"', string.encode('ascii', 'ignore'), '"'])
TypeError: sequence item 1: expected str instance, bytes found
The text was updated successfully, but these errors were encountered: