layout: modularity_weighted_layout silently DELETES edges with a dangling endpoint (inner merge), KeyErrors on an edge column named like _node, and emits no positions
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 48/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Ít trao đổi
- Lĩnh vực
- data-visualization
Hướng nghiên cứu
Start in graphistry/layout/modularity_weighted/modularity_weighted.py, especially the merges at lines 101–104 and edge assignments at 107–116; compare sibling layout validation behavior. Reproduce the dangling-endpoint and edge-column collision cases in tests, and check the documented position contract in docs/source/gfql/spec/llm_guide.md. Done means the edge cases and layout contract are handled consistently, with tests covering the behavior.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Found by the 2026-08 layouts/viz amplification probe. Repros on master @ 42b4f7f7d, pandas 2.3.3 / py3.12.
modularity_weighted_layout() rewrites the caller's edge frame through two unqualified .merge() calls. Because merge defaults to how='inner', edges are silently deleted; because the merge keys are not disambiguated, a benign column name in the edge frame turns into a KeyError.
graphistry/layout/modularity_weighted/modularity_weighted.py:101-104:
101: edges = (g._edges
102: .merge(g._nodes[[community_col, g._node]], left_on=g._source, right_on=g._node)
.rename(columns={community_col: 'source_community'}).drop(columns=[g._node])
103: .merge(g._nodes[[community_col, g._node]], left_on=g._destination, right_on=g._node)
.rename(columns={community_col: 'destination_community'}).drop(columns=[g._node])
104: )
and the result is bound as the graph's edges at :116.
Defect 1 (silent-wrong): edges whose endpoint is missing from _nodes are deleted without a word
import pandas as pd, graphistry
e = pd.DataFrame({'s': ['a','b','z'], 'd': ['b','a','a']}) # 'z' is not in _nodes
n = pd.DataFrame({'id': ['a','b'], 'comm': [0, 1]})
out = graphistry.edges(e,'s','d').nodes(n,'id').modularity_weighted_layout(community_col='comm')
print(len(e), '->', len(out._edges))
Observed: 3 -> 2 — the z->a edge is gone, no warning, no error.
Expected: either all 3 edges preserved (with a null/cross_community_weight community), or a typed decline naming the dangling endpoint.
This is the mirror image of the #1944 shape: there a node survived while its edges were dropped; here an edge is dropped while both frames look fine. Note the sibling layouts do reject the same graph loudly — layout_igraph('fr') and group_in_a_box_layout() both raise ValueError: Some vertices in the edge DataFrame are missing from vertices DataFrame. So this is also a surface divergence: three layouts, same input, one silently mutilates it.
The inverse also holds and is untested: duplicate ids in _nodes make the same inner merge fan out each edge into multiple rows.
Defect 2 (bare-crash): an edge column that shares the node-id column name
import pandas as pd, graphistry
e = pd.DataFrame({'s': ['a','b'], 'd': ['b','a'], 'id': [10, 11]}) # edges carry their own 'id'
n = pd.DataFrame({'id': ['a','b'], 'comm': [0, 1]})
graphistry.edges(e,'s','d').nodes(n,'id').modularity_weighted_layout(community_col='comm')
Observed: KeyError: "['id'] not found in axis" — the merge emitted id_x/id_y, so drop(columns=[g._node]) at :102 cannot find id.
Expected: a suffix-safe merge, or a typed error naming the collision.
An id column on edges is entirely ordinary (it is what g.edges(df, 's', 'd', 'id') binds), so this is a routine input.
Defect 3 (contract): the "layout" produces no positions
Despite the name and its listing under Layouts in docs/source/gfql/spec/llm_guide.md:548, the function only sets layout_settings(edge_influence=...) and an edge weight column (:96, :107-116). It emits no x/y at all:
out = g.modularity_weighted_layout()
'x' in out._nodes # False
Every other entry in that list writes x/y. Either the docs/schema_effects should say "edge weights + settings only, positions come from the server", or the function should produce positions. As it stands, g.modularity_weighted_layout() followed by a local position read silently yields nothing.
Defect 4 (minor): silent overwrites and bare asserts on user data
:107-113assign(weight=..., same_community=...)overwrites an existing userweightcolumn and injects a permanentsame_communityboolean into the caller's edge table;:116rebindsedge_weight='weight'.:98-99assert 'source_community' not in g._edges/'destination_community'— a user edge frame that already has either column gets a bareAssertionError(and underpython -Othe check vanishes and:102-103then produce duplicate column names).:91raise ValueError(f'Unsupported engine: {engine}')prints the abstract argument rather thanengine_concrete, soengine='auto'reportsUnsupported engine: EngineAbstract.AUTO.
Category
Defect 1: silent-wrong + surface-divergence. Defect 2: bare-crash on valid input. Defect 3: docs/contract divergence. Defect 4: bare asserts on user data.
Not exercised
cuDF arm not run (cugraph not installed here). By inspection :106-108 same_community.map({True: ..., False: ...}) is a pandas-dict-map form that cuDF handles unreliably for booleans and polars does not have at all — INDICATIVE, static only. Polars is covered separately in the engine-parity report.
- Ngôn ngữ chính
- Python
- Star
- 2.6k
- Fork
- 229
- Merge trung bình
- 1 ngày 5 giờ
- Pull request đã merge (30 ngày)
- 99
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của graphistry/pygraphistry
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
graphistry/pygraphistry#2171 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
graphistry/pygraphistry#1965 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
graphistry/pygraphistry#1208 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
graphistry/pygraphistry#966 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
graphistry/pygraphistry#824 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của graphistry/pygraphistry
Issue tương tự
-
[MOVIE]: Airport '77 (1977)Đang mởrequest-theme
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 78/100
LizardByte/ThemerrDB#9883 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
Project-MONAI/MONAI#9258 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
catalog:deprecation
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
surendranb/free-inference#31 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
fritzprix/libr-agent#2612 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
needs-triage presubmit-gate
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
gke-labs/kube-agents#5001 ·
Maintainer thường phản hồi trong vòng 1 ngày