Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 28, 2025

The mode parameter defaults are inconsistent across analysis functions. distances() defaults to "all" (ignoring edge directions) while shortest_paths() defaults to "out" (respecting directions). For directed graphs, "out" is the more intuitive default.

Changes

  • Added deprecation warnings to 9 functions when mode is not explicitly specified on directed graphs:

    • Path/distance functions: distances(), eccentricity(), radius(), graph_center()
    • Neighborhood functions: ego(), ego_size(), make_ego_graph()
    • Degree functions: degree(), strength()
  • Implementation: Used lifecycle::deprecate_soft() with missing(mode) detection. Warnings only fire for directed graphs.

  • Test updates: Fixed internal code and tests to explicitly specify mode where the old "all" behavior is intended.

  • Documentation: Added breaking change notice to NEWS.md.

Example

library(igraph)
g <- make_star(10, mode = "out")

# Now warns:
distances(g)
#> Warning: The default value of `mode` will change from "all" to "out" 
#> in a future version. Please specify `mode` explicitly.

# No warning:
distances(g, mode = "all")

This implements step 2 of the migration plan: warn users before changing defaults in a future release.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • cran.rstudio.com
    • Triggering command: /opt/R/4.5.1/lib/R/bin/exec/R --no-restore --no-echo --args nextArgigraph_2.2.1.9002.tar.gznextArg--as-crannextArg--timingsnextArg--no-manual (dns block)
  • packagemanager.posit.co
    • Triggering command: /opt/R/4.5.1/lib/R/bin/exec/R --no-restore --no-echo --args nextArgigraph_2.2.1.9002.tar.gznextArg--as-crannextArg--timingsnextArg--no-manual (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Inconsistent defaults for the 'mode' parameter</issue_title>
<issue_description>Describe the bug

The default value of the common mode parameter differs from function to function. In some functions it's out, in others it's all. This is a usability bug, as it makes igraph unpredictable.

To reproduce

In shortest_paths(), the default is out. In the closely related distances(), the default is all.

You can use a grep line such as rg 'mode *= *c\\(.*?\\)' to see many of the defaults.

Grep output
scan.R
106:                       weighted = FALSE, mode = c("out", "in", "all"),

iterators.R
514:  .nei <- function(v, mode = c("all", "in", "out", "total")) {
539:  .innei <- function(v, mode = c("in", "all", "out", "total")) {
546:  .outnei <- function(v, mode = c("out", "all", "in", "total")) {

structural.properties.R
200:                   mode = c("all", "out", "in", "total"), loops = TRUE,
418:                      mode = c("all", "out", "in"),
506:                           mode = c("out", "all", "in"),
602:                               mode = c("out", "all", "in"),
675:subcomponent <- function(graph, v, mode = c("all", "out", "in")) {
1048:                        mode = c("default", "ratio")) {
1114:                     mode = c("all", "out", "in"), mindist = 0) {
1204:                mode = c("all", "out", "in"), mindist = 0) {
1234:                           mode = c("all", "out", "in"), mindist = 0) {
1292:coreness <- function(graph, mode = c("all", "out", "in")) {
1342:topo_sort <- function(graph, mode = c("out", "all", "in")) {
1615:bfs <- function(graph, root, mode = c("out", "in", "all", "total"),
1780:dfs <- function(graph, root, mode = c("out", "in", "all", "total"),
1889:components <- function(graph, mode = c("weak", "strong")) {
1950:unfold_tree <- function(graph, mode = c("all", "out", "in", "total"), roots) {

paths.R
58:                             mode = c("out", "in", "all", "total"),

interface.R
272:neighbors <- function(graph, v, mode = c("out", "in", "all", "total")) {
314:incident <- function(graph, v, mode = c("all", "out", "in", "total")) {
512:                              mode = c("out", "in", "all", "total")) {
555:                           mode = c("out", "in", "all", "total")) {

flow.R
546:dominator_tree <- function(graph, root, mode = c("out", "in", "all", "total")) {

rewire.R
131:each_edge <- function(prob, loops = FALSE, multiple = FALSE, mode = c("all", "out", "in", "total")) {

components.R
27:count_components <- function(graph, mode = c("weak", "strong")) {
101:decompose <- function(graph, mode = c("weak", "strong"), max.comps = NA,

layout.R
432:                           rootlevel = numeric(), mode = c("out", "in", "all"),

conversion.R
362:as.undirected <- function(graph, mode = c("collapse", "each", "mutual"), edge.attr.comb = igraph_opt("edge.attr.comb")) {
423:                        mode = c("all", "out", "in", "total"),
463:                             mode = c("all", "out", "in", "total"),

centrality.R
257:                      mode = c("out", "in", "all", "total"), weights = NULL,
295:estimate_closeness <- function(graph, vids = V(graph), mode = c("out", "in", "all", "total"), cutoff, weights = NULL, normalized = FALSE) {

incidence.R
198:                                        mode = c("all", "out", "in", "total"),

centralization.R
150:centr_degree_tmax <- function(graph = NULL, nodes = 0, mode = c("all", "out", "in", "total"), loops = FALSE) {

aaa-auto.R
35:graph_from_adj_list <- function(adjlist, mode=c("out", "in", "all", "total"), duplicate=TRUE) {
346:harmonic_centrality <- function(graph, vids=V(graph), mode=c("out", "in", "all", "total"), weights=NULL, normalized=FALSE, cutoff=-1) {
683:knn <- function(graph, vids=V(graph), mode=c("all", "out", "in", "total"), neighbor.degree.mode=c("all", "out", "in", "total"), weights=NULL) {
708:strength <- function(graph, vids=V(graph), mode=c("all", "out", "in", "total"), loops=TRUE, weights=NULL) {
748:centr_degree <- function(graph, mode=c("all", "out", "in", "total"), loops=TRUE, normalized=TRUE) {
791:centr_clo <- function(graph, mode=c("out", "in", "all", "total"), normalized=TRUE) {
805:centr_clo_tmax <- function(graph=NULL, nodes=0, mode=c("out", "in", "all", "total")) {
906:eccentricity <- function(graph, vids=V(graph), mode=c("all", "out", "in", "total")) {
922:radius <- function(graph, mode=c("all", "out", "in", "total")) {
958:random_walk <- function(graph, start, steps, mode=c("out", "in", "all", "total"), stuck=c("return", "error")) {
979:random_edge_walk <- function(graph, start, steps, weights=NULL, mode=c("out", "in", "all", "total"), stuck=c("return", "error")) {
1029:local_efficiency <- function(graph, vids=V(graph), weights=NULL, directed=TRUE, mode=c("all",...

</details>

- Fixes igraph/rigraph#622

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

Copilot AI self-assigned this Oct 28, 2025
Copilot AI changed the title [WIP] Fix inconsistent defaults for the 'mode' parameter fix: Add deprecation warnings for inconsistent mode parameter defaults Oct 28, 2025
Copilot AI requested a review from krlmlr October 28, 2025 23:21
Copilot finished work on behalf of krlmlr October 28, 2025 23:21
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