Pajek read/write: store and read tabular data as attributes#295
Open
janezd wants to merge 1 commit into
Open
Conversation
8340d91 to
3151ddc
Compare
There was a problem hiding this comment.
Pull request overview
This PR extends the Pajek (.net) import/export support to preserve tabular node/edge data as key–value attributes (in a NetworkX-like style) and updates the Save/Load widgets and tests to exercise the new behavior.
Changes:
- Enhance Pajek reader/writer to parse and emit node/edge attribute key–value pairs, producing Orange
Table-backed node/edge data when present. - Update Save Network widget UI to allow choosing node/edge label variables and optionally appending remaining attributes on save.
- Add/extend tests and test fixtures for quoted labels and attribute round-tripping.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| orangecontrib/network/widgets/OWNxSave.py | Adds UI/settings for node/edge label selection and optional attribute appending when saving. |
| orangecontrib/network/widgets/OWNxFile.py | Adjusts node data output behavior when the underlying network already stores nodes as a Table. |
| orangecontrib/network/network/tests/towns.net | Quotes a multi-word edge label to match new shlex parsing behavior. |
| orangecontrib/network/network/tests/towns-2.net | New fixture covering node + edge attributes and mixed edge value/attributes cases. |
| orangecontrib/network/network/tests/test_readwrite.py | Adds tests for reading/writing attributes and helper utilities. |
| orangecontrib/network/network/readwrite.py | Implements parsing/writing of vertex/edge attributes and table conversion helpers. |
| i18n/si/msgs.jaml | Adds translation keys for newly introduced UI strings and read/write formatting strings. |
Comments suppressed due to low confidence (5)
orangecontrib/network/widgets/OWNxSave.py:112
- In
set_network, the edge-label setup usesnetwork.edges[0]without checking thatnetwork.edgesis non-empty (Pajek files can contain vertices only), which can raiseIndexErrorwhen a network has no edges.
if isinstance(network.edges[0].edge_data, Table):
self.controls.edge_variable.setEnabled(True)
orangecontrib/network/widgets/OWNxSave.py:115
domain = network.edges.domainis invalid becausenetwork.edgesis a list; this will raiseAttributeError. The domain should come from the edge data table (e.g.network.edges[0].edge_data.domain).
self.controls.edge_variable.setEnabled(True)
domain = network.edges.domain
self.edge_model.set_domain(domain)
for attr in domain.metas:
orangecontrib/network/widgets/OWNxSave.py:121
- The hint restoration logic is broken: it does
domain[self.edge_variable](whereself.edge_variableis a Variable, not a name) and then checks it againstself.edge_model. This will either error or never match; it should look updomain[self.edge_variable_hint](and also verify the variable is inself.edge_model).
if self.edge_variable_hint in domain and \
(attr := domain[self.edge_variable]) in self.edge_model:
self.edge_variable = attr
orangecontrib/network/widgets/OWNxSave.py:149
dict_rows_from_table(..., self.label_variable)/(..., self.edge_variable)passes a Variable object into theexcludeparameter, butdict_rows_from_tablecomparesattr.name != exclude(string vs Variable), so the selected label column will not be excluded and will be duplicated in the saved attributes. Pass the variable name (or extenddict_rows_from_tableto accept a Variable).
if self.append_node_data and isinstance(data := net.nodes, Table):
label_data = dict_rows_from_table(data, self.label_variable)
else:
label_data = None
if self.append_edge_data and isinstance(data := net.edges[0].edge_data, Table):
edge_data = dict_rows_from_table(data, self.edge_variable)
else:
orangecontrib/network/widgets/OWNxSave.py:117
- Default label auto-detection only looks for meta variables named
node_label/edge_label, but this PR’s Pajek reader/writer usesnode label/edge label(with spaces). This prevents the widget from auto-selecting the correct label variable for Pajek-loaded networks; consider accepting both naming variants.
for attr in domain.metas:
if attr.name == "node_label":
self.label_variable = attr
break
if self.label_variable_hint in domain and \
(attr := domain[self.label_variable_hint]) in self.label_model:
self.label_variable = domain[self.label_variable_hint]
else:
self.label_model.set_domain(None)
self.label_variable = None
self.controls.label_variable.setEnabled(False)
if isinstance(network.edges[0].edge_data, Table):
self.controls.edge_variable.setEnabled(True)
domain = network.edges.domain
self.edge_model.set_domain(domain)
for attr in domain.metas:
if attr.name == "edge_label":
self.edge_variable = attr
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
3151ddc to
0ec2e3e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue
Fixes #286. Fixes #275.
Description of changes
When saving, add data about nodes and edges. For nodes, this data is saved in the same format as in NetworkX, which is a hack of what's in Pajek. For edges, the format is the same, though unsupported by NetworkX (AFAIK).
When reading -- read the data save in this way.
The format is a mess: it allows (but doesn't require) node coordinates. Edges may have a numeric weight or a non-numeric label, but not both, to which we now add NetworkX-like key-value pairs, and so forth.
Tests for existing mess are lacking, and the new tests might not cover all possible combinations.
Includes