sugarlabs / sugar

Sugar GTK shell
GNU General Public License v3.0
253 stars 241 forks source link

Fixed Python3 TypeError #911

Closed shaansubbaiah closed 4 years ago

shaansubbaiah commented 4 years ago

For TypeError: ord() expected string of length 1, but int found In Python3 indexing a bytes object returns an integer, ord() is not required. stream_id = ord(message.data[0]) -> stream_id = message.data[0]

For TypeError: must be str, not bytes file_object.write(data[1:]) -> file_object.write(data[1:].decode("utf-8"))

srevinsaju commented 4 years ago

@shaansubbaiah it would be nice if you could refrain from uploadin to google drive. You can alternatively use MEGA.nz which is open source, or rather attach it here in github comment assets. Thanks, maybe this will make it helpful for other mentors to review work too.

quozl commented 4 years ago

@shaansubbaiah, I confirm by analysis with tcpdump and wireshark that you have captured some of the data exchanged between Sugar and the activity over the apisocket/gwebsocket connection. Thanks.

The packet trace is not complete in the temporal domain; there are no SYN, SYN ACK, FIN, or FIN ACK packets. You can fix that by starting the tcpdump before the activity is started, and keeping tcpdump running until the activity has finished.

I agree with @srevinsaju that attaching this tcpdump, which was 5114 bytes, to a GitHub comment would be more efficient for us than using Google Drive. (Google Drive's supporting HTML and JavaScript exceeds the size of the file by orders of magnitude). However, I don't foresee you having to do it much, as I expect you to analyse the data yourself and to cite any relevant sections.

Data in the packet trace is certainly recognisable as WebSocket protocol. It looks like what I saw when I was finishing up the port of gwebsockets. Wireshark contains a WebSocket protocol dissector, but I've not figured out how to use it yet. Maybe you will. Here are the references that I found;

Getting back to the problem at hand; "how a JavaScript activity that writes to the journal twice doesn't succeed in doing so. So I suggested testing to see if this is a Python 3 porting regression."

You have proof from logs that the activity writes to the Journal twice. As far as I know, and unless someone can tell me otherwise, there's nothing wrong with an activity doing that, and if it doesn't work then something somewhere should be fixed. Not just fixed so that we don't get an error, but fixed so that the data is properly stored and can be recalled.

You can use the packet trace to confirm that the activity writes to the Journal twice.

You may already have this proof from the activity source code, I don't know.

You already proved that the Python 2 build of Sugar and gwebsockets didn't properly handle writing to the Journal twice. So the problem is latent before porting, and so your pull request commits are suggesting a change that may not be correct.

shaansubbaiah commented 4 years ago

@srevinsaju thanks for the tip! I wasn't aware that I could attach non image files to GitHub comments.

@quozl there are two issues:

1] Web activities calling the datastore functions multiple times to load/store activity data. 2] The Type errors due to Python 2 and 3's difference in indexing a bytes buffer.

The 2 issues are independent of each other. I was facing the web activity issue before applying the changes in the PR. As you said, the web activity issue doesn't break anything, only causes those extra errors when data in the instance directory has already moved.

The Type Errors however prevent activities like the Gears activity from loading data stored in the Journal Create gears in activity -> Close -> Open activity -> Data doesn't load, no gears present Comparing the 'type' of data between the Live Build v117 running Python3 and OLPC 18.04 running Python 2:

Live Build v117, stream_id type = int

1586440656.674570 DEBUG PY3-VM: message.data[0] of type:
1586440656.674726 DEBUG PY3-VM: <class 'int'>

OLPC 18.04, stream_id type = str

1586441221.329491 DEBUG PY2-OLPC: Type of streamid:
1586441221.329558 DEBUG PY2-OLPC: <type 'str'>

1586441221.329618 DEBUG PY2-OLPC: Ord(stream_id) type:
1586441221.329673 DEBUG PY2-OLPC: <type 'int'>

stream_id is supposed to be an Int and ord() is not required as explained in the commit.

and the data loaded at DATASTOREAPI.save.on_data : Live Build v117, data of type = bytes

1586441759.834844 DEBUG PY3-VM: DATASTOREAPI.save.on_data(data), data of type:
1586441759.834897 DEBUG PY3-VM: <class 'bytes'>

1586441759.834958 DEBUG PY3-VM: data[1:].decode('utf-8') of type:
1586441759.835013 DEBUG PY3-VM: <class 'str'>

OLPC 18.04, data of type = str

1586441868.168910 DEBUG PY2-OLPC: DATASTOREAPI.save.on_data(data), data of type:
1586441868.168946 DEBUG PY2-OLPC: <type 'str'>

write() function requires parameter of type str. In python 2 the bytes type is the same as the str type. So write() had not issues earlier.

The commit fixes these and data from the Journal loads properly. The rest of the apisocket file seems to function without issues, the files open in text mode, data in activities can be saved and resumed. There are no issues logged, not sure how else to check that there are no errors.

quozl commented 4 years ago

@shaansubbaiah, thanks, great explanation. Please amend your commit and add some of your explanation there. Sugar is a critical repository, so see making commits and [https://github.com/sugarlabs/sugar-docs/blob/master/src/contributing.md#guide-for-reviewers](guide for reviewers).

You have confirmed Gears is able to save and load data.

I've gone back through the pull request to check for unresolved questions.

About 25 days ago, I observed;

For the change to DatastoreAPI.load.on_data, your fix is to decode the bytes into utf-8, [...] . The error happened when the file is created and written to. I don't see a corresponding change to when the file is read. Are you sure the file is read and sent back to the client intact? How did you test that? Might it be better to change the file open mode (in the two places) to binary?

Another test is whether you can resume a web activity from the journal and have the previously saved data properly loaded, even if it is binary. You may have to look for a web activity that does that. I can't remember which ones do.

Looking at apisocket.py, the file is not opened in binary mode, and this suggests that while binary data might have been supported by Python 2, it is certainly not supported by Python 3.

I speculate that this was not considered in the port to Python 3, instead 2to3 was run followed by some testing without measured coverage. What do you think?

chimosky commented 4 years ago

I speculate that this was not considered in the port to Python 3, instead 2to3 was run followed by some testing without measured coverage. What do you think?

I agree, I was looking at the changes made to the datastore and they're things we should do differently for compatibility for both python3 and python2 activities.

shaansubbaiah commented 4 years ago

@quozl agree, like @chimosky mentioned, in the porting process I feel care must have been taken where binary type data was used, as it was used interchangeably with the str type in Python2.

Might it be better to change the file open mode (in the two places) to binary?

As to my knowledge, data in the datastore is stored as text/string, so the current way of opening as text mode is correct. The APIClient passes messages of binary type to the APIServer which calls the Datastore API, Activity API and open_stream, close_stream functions.

The ord() was used only when the message is of binary type. I don't think this will cause issues later.

321    def _message_received_cb(self, session, message, client):
 322        if message.message_type == Message.TYPE_BINARY:
 323            stream_id = ord(message.data[0]) // ord() removed in PR

Updated the commit message

quozl commented 4 years ago

As to my knowledge, data in the datastore is stored as text/string,

Since the start, datastore is for binary data. Interpretation of the data is left to the activities. A content type is kept for reference and to associate with activities.

@shaansubbaiah, which web activities did you survey to ensure they stored data as text/string?

@llaske, doesn't the Sugarizer datastore support binary too?

shaansubbaiah commented 4 years ago

@quozl I might have called the wrong location the datastore. There are files in the 1]~/.sugar/default/datastore/, 2]~/.sugar/default/dataand some sort of temporary storage at 3]~/.sugar/default/<activity_name>/

For example the Gears Activity temporarily stores data in the instance folder eg /home/shaan/.sugar/default/org.sugarlabs.GearsActivity/instance/1586609408 some file is created by DatastoreAPI._create_file() which creates the file in text mode.

Activity data is kept in an object in plaintext with the metadata at /home/shaan/.sugar/default/datastore/63/634fc302-4b74-4b13-b82e-30ab18e13e08/ containing data, metadata [634fc....e08] -> activity uid.

There's also Activity data stored with the uid in the same object in plaintext format at ~/.sugar/default/<activity_name>/ with the uid as filename.

Similarly, the Find Words Activity stores data at 1] , 3] the Moon Activity stores data at 1] , 2] , 3]

The wiki does state that the instance directory is temp storage but I'm not very clear on the other 2 locations- Data/ and Datastore/

llaske commented 4 years ago

@quozl Sugarizer datastore content is stored as string. It's usually serialized Javascript object used to save activity context. It supports binary (images and even LZ compressed content) encoded as base64. Locally the datastore was initially stored in browser localStorage but it's now in a IndexedDB database of the browser. On the server, the content is stored in a MongoDB database.

quozl commented 4 years ago

Thanks both.

I've reviewed bus.js, datastore.js, and activity.js in sugar-web. First time. I don't fully understand them, but I agree that they seem to support text without supporting unencoded binary.

I know that Sugar Python activities can store binary data; such as PNG, JPEG, OGG, and other formats.

I've searched for use of datastoreObject in https://github.com/sugarlabs and found 63 matches, and reviewed use of the datastore API among the Sugar Web activity collection. None of them seem to store binary data. I didn't look at Sugarizer activities, as @llaske has answered on that, and GitHub didn't give any matches for forks(!).

Data on the API socket arrives and leaves as Python object type bytes. What I'm still not clear on is whether that data should be converted to str for writing to a file opened in text mode (the default, and present state of the code), or whether it should be written unconverted to a file opened in binary mode. Both would be functionally identical as far as an activity is concerned, but the conversion method would require extra CPU resources and the activity to always submit data in a supported character set. At the moment, a conversion does occur. Why do we need to do this conversion only for Python to undo it?

shaansubbaiah commented 4 years ago

I agree that data stored as bytes prevents the conversions every time the API is called but storing as text makes it very easy to view, modify data directly, especially while debugging. Some activities may want to use string functions on the data (then again it could have been decoded to str if required). Currently data is stored using the default Linux encoding-utf-8.

Text files are also less prone to corruption and compressed text files are generally smaller than binary files. I don't think the CPU overhead is significant enough to outweigh the simplicity the text files provides.

I would prefer that the data be stored as text, what are the organization's views on this?

quozl commented 4 years ago

Thanks for thinking about this, but you're wrong in several respects.

Regardless of whether Python opens the file as text or binary, there's no difference to the bit stream in the file. There will be no impact on viewing, modifying, or debugging. What activities do with the data has nothing to do with how it is stored by the API socket class.

I don't believe text files are less prone to corruption. We don't compress the files, but as the bit stream in the files would be no different, compression would equally be no different.

Demonstration of no difference;

#!/usr/bin/python3

# an original text string
d0 = 'Regardless of whether Python opens the file as text or binary'

# convert to bytes for transmission through a socket
d1 = d0.encode()

# imagine the transmission

# option 1, the long way around

# convert to string
d2 = d1.decode()

# write to a text file
open('/tmp/data-text', 'w').write(d2)

# option 2, the short method

# write to a binary file
open('/tmp/data-binary', 'wb').write(d1)

# test that the files are the same
import subprocess

subprocess.call(['/usr/bin/md5sum', '/tmp/data-text', '/tmp/data-binary'])
rc = subprocess.call(['/usr/bin/cmp', '/tmp/data-text', '/tmp/data-binary'])
if rc == 0:
    print("same")
shaansubbaiah commented 4 years ago

@quozl I was wrong, storing characters in either file mode yields the same result, both can be viewed like normal text files. I had got confused with how it worked in C with .bin files. Turns out after testing in C, it works similarly. Might have stored and viewed non string files earlier that led to this confusion.

Thank you for the correction, I now see that the conversion is unnecessary.

shaansubbaiah commented 4 years ago

I've made some progress towards making it read, write as binary files. It needs more testing, have only tested with the Gears activity as of now (Saving and Resuming works properly). I'll try out other activities for proper coverage.

Some changes being: 1] Read, write files in binary mode (rb, wb) 2] Remove the part where data is decoded to UTF format 3] stream_id is an integer as mentioned earlier, function send_binary() used to send a string (concatenating stream_id and data). Now that data is bytes, made stream_id as bytes.

quozl commented 4 years ago

Thanks. Reviewed changes. Looks okay.

Another review by interpreting the change relative to the Python 2 source;

git diff 69e3a01545eee18ced09c4b1505ecbe8bbebd934..HEAD -- src/jarabe/apisocket.py

Looks okay.

Another review using;

Looks okay.

This extends and seeks to complete the aa18879e9717dfe2d30f249549e9a43d6dd6da4f ("Port to Python 3") for apisocket.py, so that's what the commit message should eventually become.

Last thing I've noted as open;

shaansubbaiah commented 4 years ago

Thanks for reviewing the current progress. I didn't quite catch what you meant by 'instead of converting the exception into something the client can be given.' Could you please explain in detail?

quozl commented 4 years ago

Sure. At the moment in apisocket.py when a D-Bus exception occurs, the error handler is called with an argument which contains the exception. This cannot be translated using json, and so cannot be sent to the client. However, the client should be informed in some way that the API call failed, and if possible why it failed. You might need to look at sugar-web JavaScript to figure out what is expected when a call fails.

shaansubbaiah commented 4 years ago

Regarding the DBUSException error not being handled properly,

Error generated at self._client.send_error(info["close_request"], error):

TypeError: Object of type DBusException is not JSON serializable at self._session.send_message(json.dumps(response)) where response is an object with error as a parameter (should be JSON or string, here it is of type DBusException)

Where: error. (type dbus.exceptions.DBusException)

        org.freedesktop.DBus.Python.ValueError: Traceback (most recent call last):
        File "/usr/lib/python3/dist-packages/dbus/service.py", line 707, in _message_cb
            retval = candidate_method(self, *args, **keywords)
        File "/usr/lib/python3.7/dist-packages/carquinyol/datastore.py", line 373, in update
            lambda * args: self._update_completion_cb(async_cb,
        File "/usr/lib/python3.7/dist-packages/carquinyol/filestore.py", line 49, in store
            raise ValueError('No file at %r' % file_path)
        ValueError: No file at dbus.String('/home/shaan/.sugar/default/org.sugarlabs.FindWords/instance/1587569354')

info["close_request"]. (type JSON)

{'method': 'close_stream', 'id': 21, 'params': [1], 'jsonrpc': '2.0'}```

---
TEMPORARY FIX
Making error a `string` with the Name and Traceback of the Exception (https://dbus.freedesktop.org/doc/dbus-python/dbus.exceptions.html):
    if(type(error) == dbus.exceptions.DBusException):
        dbus_error = error.get_dbus_name() + " " + error.get_dbus_message()
        error = dbus_error

---

The error generated before fix (Live Build v117)
```Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/dbus/connection.py", line 607, in msg_reply_handler
    *message.get_args_list()))
  File "/usr/lib/python3.7/dist-packages/jarabe/apisocket.py", line 252, in error_handler
    self._client.send_error(info["close_request"], error)
  File "/usr/lib/python3.7/dist-packages/jarabe/apisocket.py", line 328, in send_error
    self._session.send_message(json.dumps(response))
  File "/usr/lib/python3.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python3.7/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type DBusException is not JSON serializable

Output after (Error only in the second line as the first call was able to access the data at the /instance folder)

DEBUG gwebsockets: Sending text message {"result": [], "error": null, "id": 13}
DEBUG gwebsockets: Sending text message {"result": null, "error": "org.freedesktop.DBus.Python.ValueError Traceback (most recent call last):\n  File \"/usr/lib/python3/dist-packages/dbus/service.py\", line 707, in _message_cb\n    retval = candidate_method(self, *args, **keywords)\n  File \"/usr/lib/python3.7/dist-packages/carquinyol/datastore.py\", line 373, in update\n    lambda * args: self._update_completion_cb(async_cb,\n  File \"/usr/lib/python3.7/dist-packages/carquinyol/filestore.py\", line 49, in store\n    raise ValueError('No file at %r' % file_path)\nValueError: No file at dbus.String('/home/shaan/.sugar/default/org.sugarlabs.FindWords/instance/1587574588')\n", "id": 14}

The error could have been converted at DatastoreAPI.save().error_handler(error) but I wasn't sure if DBUSExceptions could occur elsewhere. Putting it within APIClient.send_error() will check every error sent from the client.

Right now the error passed is a string containing the error name and traceback. It's very long and appears in a single line so it is slightly difficult to read.

I'm not sure of the exact format of the errors passed by Sugar. I went through the sugar-web repo and didn't find anything. Only found that the functions pass the error in the callback like https://github.com/sugarlabs/sugar-web/blob/cef6655e7230759aadc23f4c9641b285f845f17c/bus.js#L209 .

Edit: The FindWords Activity was able to successfully resume after the previous fix (switch to binary data in datastore)

quozl commented 4 years ago

Thanks, well done. What does the client do with it?

shaansubbaiah commented 4 years ago

Went through sugar-web again, self._session.send_message(json.dumps(response)) calls gwebsockets send_message() and on the client side upon receiving a message with an error it should throw a new error with the contents of the sent error.

sugar-web/bus.js

client.onMessage(){
.
.
.
                if (parsed.error === null) {
                    callback(null, parsed.result);
                } else {
                    callback(new Error(parsed.error), null);
                } 
.
}

Right now the error is sent as a message but it does not throw it in shell.log edit: there's also nothing reported in the activity log

quozl commented 4 years ago

Is the error shown to the user?

shaansubbaiah commented 4 years ago

It is not shown to the user explicitly, just gets logged in shell.log as a gwebsockets message (when logging is enabled in debug settings)

FindWords Activity DEBUG gwebsockets: Sending text message {"result": null, "error": "org.freedesktop.DBus.Python.ValueError Traceback (most recent call last):\n File \"/usr/lib/python3/dist-packages/dbus/service.py\", line 707, in _message_cb\n retval = candidate_method(self, *args, **keywords)\n File \"/usr/lib/python3.7/dist-packages/carquinyol/datastore.py\", line 373, in update\n lambda * args: self._update_completion_cb(async_cb,\n File \"/usr/lib/python3.7/dist-packages/carquinyol/filestore.py\", line 49, in store\n raise ValueError('No file at %r' % file_path)\nValueError: No file at dbus.String('/home/shaan/.sugar/default/org.sugarlabs.FindWords/instance/1587574588')\n", "id": 14}

Moon Activity

DEBUG gwebsockets: Sending text message {"result": [], "error": null, "id": 13}
DEBUG gwebsockets: Sending text message {"result": null, "error": "org.freedesktop.DBus.Python.ValueError Traceback (most recent call last):\n  File \"/usr/lib/python3/dist-packages/dbus/service.py\", line 707, in _message_cb\n    retval = candidate_method(self, *args, **keywords)\n  File \"/usr/lib/python3.7/dist-packages/carquinyol/datastore.py\", line 373, in update\n    lambda * args: self._update_completion_cb(async_cb,\n  File \"/usr/lib/python3.7/dist-packages/carquinyol/filestore.py\", line 49, in store\n    raise ValueError('No file at %r' % file_path)\nValueError: No file at dbus.String('/home/shaan/.sugar/default/com.garycmartin.Moon/instance/1587713909')\n", "id": 14}

Would it be better to 1] Print the error in the log properly (like how other errors display, showing traceback with proper formatting eg.

1587714611.466397 DEBUG root: _Account.__set_current_activity_cb
/usr/lib/python3/dist-packages/gi/overrides/Gtk.py:1641: Warning: g_value_transform: assertion 'G_IS_VALUE (src_value)' failed
  return _Gtk_main(*args, **kwargs)
/usr/lib/python3/dist-packages/gi/overrides/Gtk.py:1641: Warning: unable to set property 'buddy' of type 'PyObject' from value of type '(null)'
  return _Gtk_main(*args, **kwargs)
1587714616.034032 DEBUG root: launch bundle_id=org.sug.......

2] Leave it as is, show the error in the message as we are not planning to fix the error?

I had expected the change made in the DBUSException handling commit to function like [1] but unfortunately it doesn't. Perhaps the format of the error is wrong? Is there a way of throwing some known error in apisocket so I could inspect its format? I couldn't find anything helpful in the gwebsockets and sugar-web repos.

quozl commented 4 years ago

I'm getting a bit lost, sorry. My recent replies have been regarding the general handling of errors; how they are logged, or how they are displayed. Goal is software that does the right thing, or the expected thing, and people expect to be told if something isn't done because of either (a) a flaw in the activity, or (b) some failure relating to the filesystem, such as corruption or read-only remounts.

For problems involving loss of user data, reporting this directly and instantly to the user is needed. Logs can contain additional detail, but people don't look at logs unless they are told there is a problem.

So assuming a web activity runs, and a datastore exception occurs, how is the user informed?

shaansubbaiah commented 4 years ago

There is an issue where multiple datastore (store, load) calls by an activity are made, where some of them fail because data has already moved by a previous call. We were unable to find the cause of the issue and concluded that since it didn't affect the working of the activity it wasn't very important.

However, every time the issue occurred, it generated a DBUSException which could not be passed as an error to the APISocket error handling function. The temporary fix here only converts the DBUSException to string so that is sent to the error handler function and the error can be viewed in the logs.

I do not think this issue needs to be reported to the user as it doesn't affect the activity's working and occurs quite frequently.

What I understood by your earlier message was that there should be a method to report corruption/read-only issues directly to the user. I think this will require creating some sort of popup in the activity displaying the error so the user gets to know when it occurs. Regarding this, I am still not very sure how the errors are handled to come up with such a fix at the moment.

quozl commented 4 years ago

Thanks for summarising the problems. This is exactly the sort of thing that should be in commit messages.

There is an issue where multiple datastore (store, load) calls by an activity are made, where some of them fail because data has already moved by a previous call. We were unable to find the cause of the issue and concluded that since it didn't affect the working of the activity it wasn't very important.

We need to fix this issue. I don't see why multiple datastore calls aren't allowed. Is this because the calls occur within the same clock second? "%i" % time.time() seems to be remarkably non-unique as a filename. "%s" % time.time() is likely to be more unique, but still, on faster and faster systems or where clock values are cached, this method of creating a temporary file name seems unwise. There's a whole module tempfile for the knotty problem of creating unique temporary files. Or just a sequence number would be fine?

However, every time the issue occurred, it generated a DBUSException which could not be passed as an error to the APISocket error handling function. The temporary fix here only converts the DBUSException to string so that is sent to the error handler function and the error can be viewed in the logs.

I do not think this issue needs to be reported to the user as it doesn't affect the activity's working and occurs quite frequently.

It will result in data loss. If the activity saves to the datastore, then changes the data, then saves again, it is not clear what is saved, and there is no message to the user.

What I understood by your earlier message was that there should be a method to report corruption/read-only issues directly to the user. I think this will require creating some sort of popup in the activity displaying the error so the user gets to know when it occurs. Regarding this, I am still not very sure how the errors are handled to come up with such a fix at the moment.

We need to be able to focus on everything at once, not one repository at a time. The investigation into these exceptions has revealed severe deficiencies in the API and sugar-web. If an activity is asked to save data by the user, but cannot do so, then it must tell the user. I don't know how yet.

aperezbios commented 4 years ago

@shaansubbaiah , how close do you think you are to addressing the remaining changes @quozl has requested? This is an important fix, and I'd love to see it committed.

shaansubbaiah commented 4 years ago

@aperezbios Sorry I've been a little busy with tests and submissions this week, I still haven't figured out a way to communicate issues to the user.

@quozl you were right regarding the issue occuring due to the calls at the same clock second. Just switching the "%i" % time.time() to a random 10 digit number while testing has removed the DBUS Errors.

Before:

DEBUG gwebsockets: Received text message b'{"method":"close_stream","id":20,"params":[0],"jsonrpc":"2.0"}'
DEBUG gwebsockets: Got data, length 174
DEBUG gwebsockets: Received binary message, length 166
DEBUG gwebsockets: Got data, length 68
DEBUG gwebsockets: Received text message b'{"method":"close_stream","id":21,"params":[1],"jsonrpc":"2.0"}'
DEBUG gwebsockets: Got data, length 242
DEBUG gwebsockets: Received binary message, length 166
DEBUG gwebsockets: Received text message b'{"method":"close_stream","id":22,"params":[2],"jsonrpc":"2.0"}'
DEBUG gwebsockets: Sending text message {"result": [], "error": null, "id": 20}
DEBUG gwebsockets: Sending text message {"result": null, "error": "org.freedesktop.DBus.Python.ValueError", "id": 21}
DEBUG gwebsockets: Sending text message {"result": null, "error": "org.freedesktop.DBus.Python.ValueError", "id": 22}

After:

DEBUG gwebsockets: Received binary message, length 180
DEBUG gwebsockets: Received text message b'{"method":"close_stream","id":20,"params":[0],"jsonrpc":"2.0"}'
DEBUG gwebsockets: Got data, length 256
DEBUG gwebsockets: Received binary message, length 180
DEBUG gwebsockets: Received text message b'{"method":"close_stream","id":21,"params":[1],"jsonrpc":"2.0"}'
DEBUG gwebsockets: Got data, length 256
DEBUG gwebsockets: Received binary message, length 180
DEBUG gwebsockets: Received text message b'{"method":"close_stream","id":22,"params":[2],"jsonrpc":"2.0"}'
DEBUG gwebsockets: Sending text message {"result": [], "error": null, "id": 20}
DEBUG gwebsockets: Sending text message {"result": [], "error": null, "id": 21}
DEBUG gwebsockets: Sending text message {"result": [], "error": null, "id": 22}
quozl commented 4 years ago

@aperezbios, thanks for your interest. Port to Python 3 is not yet finished for Sugar, in turn because of too few developers. Lots of bugs expected and not yet detected. You are better off using Python 2 if you want good results with children. We're working on it, and we have a project idea for GSoC to continue the work. We will learn on 4th May if we have that project approved.

@shaansubbaiah, re 0421cef8759993c51072e19491bf0287d8f7b0f6;

Re: using time.time or large random number. Thanks for testing the alternative.

Re: ef26a9f649a962e22012022377b65adcf58019df and 08a46a9ae4dc48035c7881751018da5df6e8f0e7.

I've looked through apisocket.py while imagining port to Python 3, and haven't come up with anything else to change.

I've pushed to master branch after testing Sugar with Gears and Moon on Ubuntu 19.04. Please test master branch. I'll close this pull request; it seems everything is done with it.

shaansubbaiah commented 4 years ago

Thanks, tested master branch with Moon, Find-Words, Gears Web Activities, found no issue :)

quozl commented 4 years ago

Thanks for testing.