Skip to content
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

Table has public attributes we assume won't change (but can) #5303

Closed
markotoplak opened this issue Mar 1, 2021 · 2 comments
Closed

Table has public attributes we assume won't change (but can) #5303

markotoplak opened this issue Mar 1, 2021 · 2 comments
Assignees

Comments

@markotoplak
Copy link
Member

When we write widgets, we usually assume that their inputs do not change unless the widget receives a new input. If one widget modifies the table that is also an input to some other widget, we would have problems.

Orange data Tables store, among others, domain, X, Y, Z, weights, ids. All these are directly writable. We never prevent changing them, so we rely only on programmer discipline to avoid changing tables. Even within our group, we sometimes start changing tables when we should not. Who knows how bugs are in Orange because of this.

Multithreading makes changes to Tables even more dangerous: even if some widget changes its input table only for computation and restores it when done, the table is invalid in between. We just saw a bug like this today with Vesna, and luckily we saw it before the merge.

So what could we do? We could keep relying on conventions. But now that the Table seems to be getting a pandas interface #5189, whose setters set both the domain and value arrays, we could see bugs even more often.

On the other extreme, we could go nuclear and hide values behind properties and not implement any setters. Ok, we would implement them and immediately deprecate them for backward compatibility. But changing tables can sometimes be genuinely useful. I do not see a problem if someone is changing a Table when it is still private, before it is sent out. For example, I often expand a table with .transform() and then fill it in afterward. Also, if we want to facilitate users in writing code (either as widgets or as Python scripts), we should make creating tables friendlier, not harder.

We could go for something in the middle. We could put all elements behind properties and have some kind of a lock on setters. So setting elements could work at first, and then we could lock it. I do not know precisely how this locking should work, but just an idea: perhaps every time a table is sent into some other widget, its setters would get locked (of course, first with deprecation warnings). It would help us write more reliable code and would also warn Python Script users, who tend to write code like in_data.X = X+42.

What do you think we should do?

@markotoplak markotoplak added bug report Bug is reported by user, not yet confirmed by the core team needs discussion Core developers need to discuss the issue and removed bug report Bug is reported by user, not yet confirmed by the core team labels Mar 1, 2021
@janezd
Copy link
Contributor

janezd commented Apr 2, 2021

@janezd will try to implement context manager that unlocks a table.

@janezd janezd removed the needs discussion Core developers need to discuss the issue label Apr 2, 2021
@janezd janezd self-assigned this Apr 2, 2021
@janezd
Copy link
Contributor

janezd commented Oct 8, 2021

Fixed via #5381.

@janezd janezd closed this as completed Oct 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants