Skip to content

feat: add __repr__, __copy__, __deepcopy__ to core classes#693

Open
leotrs wants to merge 10 commits intodevfrom
dunder-method-parity
Open

feat: add __repr__, __copy__, __deepcopy__ to core classes#693
leotrs wants to merge 10 commits intodevfrom
dunder-method-parity

Conversation

@leotrs
Copy link
Collaborator

@leotrs leotrs commented Mar 5, 2026

Summary

  • Add __repr__ to Hypergraph and DiHypergraph (inherited by SimplicialComplex) showing a constructor-like representation
  • Add __copy__ and __deepcopy__ to both classes, delegating to the existing .copy() method
  • Fix rng.choice doctest in random_edge_shuffle (numpy scalars → Python types)
>>> H = xgi.Hypergraph([[1, 2, 3], [3, 4]])
>>> repr(H)
"Hypergraph([{1, 2, 3}, {3, 4}])"

>>> from copy import copy, deepcopy
>>> copy(H) == H
True
>>> deepcopy(H) == H
True

Test plan

  • All 392 tests pass
  • All 112 doctests pass
  • copy(), deepcopy(), and repr() verified on Hypergraph, DiHypergraph, and SimplicialComplex

🤖 Generated with Claude Code

@codecov
Copy link

codecov bot commented Mar 5, 2026

Codecov Report

❌ Patch coverage is 60.00000% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.58%. Comparing base (6e7fe50) to head (872a155).
⚠️ Report is 19 commits behind head on dev.

Files with missing lines Patch % Lines
xgi/core/dihypergraph.py 42.85% 4 Missing ⚠️
xgi/core/hypergraph.py 75.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev     #693      +/-   ##
==========================================
- Coverage   93.59%   93.58%   -0.01%     
==========================================
  Files          66       66              
  Lines        5120     5131      +11     
==========================================
+ Hits         4792     4802      +10     
- Misses        328      329       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

leotrs and others added 9 commits March 5, 2026 22:13
scipy's diags_array now warns (FutureWarning) when int64 input is
silently cast to float64 output, and will change this behavior in a
future release. This would silently alter numerical results.

Ensure degree and weight arrays are explicitly float before passing
to diags_array in both laplacian() and normalized_hypergraph_laplacian().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two changes to make exception usage consistent:

1. IDNotFound now inherits from (XGIException, KeyError) instead of
   just KeyError. This means all XGI exceptions can be caught uniformly
   with `except XGIException`, while preserving backwards compat for
   code that catches KeyError.

2. Standardize XGIError vs ValueError: use ValueError for pure input
   validation (bad argument values like "probability not in [0,1]"),
   reserve XGIError for domain-specific errors (disconnected graph,
   wrong network type, frozen network). Changes affect:
   - generators/uniform.py: all input validation raises
   - generators/lattice.py: invalid k value
   - generators/simple.py: invalid edge/core size
   - algorithms/assortativity.py: invalid kind argument

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add explicit __all__ lists to every subpackage (core, algorithms,
communities, convert, drawing, dynamics, generators, linalg, readwrite,
utils) and aggregate them in the top-level xgi/__init__.py. This locks
down the public API surface to 169 names, preventing internal modules
from leaking through wildcard imports.

Also fixes tests that accessed xgi.utilities.dual_dict (an internal
module path that was only reachable via leaked wildcard imports) to use
the correct public path xgi.dual_dict.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove read_json/write_json from readwrite __all__ (deprecated)
- Remove IDDict, Trie, crest_r from utils __all__ (internal)
- Update test imports to use direct module paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…stances (#689)

* feat: add seed parameter to unseeded stochastic functions

Add seed parameter to h_eigenvector_centrality, degree_assortativity,
simulate_kuramoto, and random_edge_shuffle for reproducibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: update doctest for pandas dtype='str' change

Pandas now uses dtype='str' instead of dtype='object' for string Index
columns. Compare as list to avoid version-dependent repr.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: make spectral clustering test deterministic and fix pandas doctest

Seed numpy before eigsh in spectral_clustering so ARPACK produces
consistent results. Seed random data in kmeans tests. Update pandas
dtype doctest to compare as list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add floating point tolerance to Laplacian eigenvalue test

eigvalsh can return eigenvalues like -1.3e-17 for a positive
semi-definite matrix due to floating point arithmetic. Use -1e-12
tolerance instead of strict >= 0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: make spectral clustering deterministic across platforms

Pass explicit v0 to eigsh when seed is provided, making ARPACK
initialization deterministic. Relax test assertion to check core
community membership rather than exact partition, since boundary
nodes can be assigned differently across LAPACK implementations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: migrate from global random state to local RNG instances

Replace all np.random.seed()/random.seed() + global function calls with
np.random.default_rng(seed) and local Generator instances. This eliminates
global state pollution, is thread-safe, and follows Scientific Python best
practices. All functions now accept int | np.random.Generator | None for
the seed parameter. Removed all stdlib random usage from xgi source.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: update doctest expected value in largest_connected_hypergraph

The new RNG stream produces a different random hypergraph, changing the
size of the largest connected component from 6 to 8.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: update tutorial seed for changed random stream

The fast_random_hypergraph with seed=2 now produces a different number
of dyads due to the RNG migration, causing a color array length mismatch
in the multilayer drawing tutorial. Changed to seed=8 which produces 10
dyads matching the hardcoded color lists.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address PR review comments on seed/RNG migration

- Simplify rng.choice calls (remove unnecessary np.array conversion,
  use direct list selection for edge_list)
- Standardize seed docstrings to "int, numpy.random.Generator, or None"
  for all functions using np.random.default_rng(seed)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: simplify rng.choice to select directly from list

Address review suggestion to pass the list directly to rng.choice
instead of sampling indices.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Add __repr__ to Hypergraph, DiHypergraph (inherited by
SimplicialComplex) showing a constructor-like representation.
Add __copy__ and __deepcopy__ delegating to the existing .copy()
method. Also fix rng.choice doctest in random_edge_shuffle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@leotrs leotrs force-pushed the dunder-method-parity branch from 872a155 to 50dfeb4 Compare March 5, 2026 21:15
@review-notebook-app
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

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

Successfully merging this pull request may close these issues.

2 participants