Skip to main content

Sage Deps - A Sage Dependency Analysis Tool

This is a SageMath dependency analysis tool used for understanding Sage's structure. It can be used to detect circular imports, upstream dependencies, and provide various dependency-graph metrics including PageRank.

Warning: This package is still in its testing phase, and may have unexpected behaviour.

Installation

Dependencies

The package requires numpy, scipy, networkx, and scikit-network.

Install from PyPi:

Run pip install sage-deps to install as a pypi package. Make sure the script sdeps.exe is added to PATH to run the sdeps command.

Manual Install

To install, simply download or clone the repository. Navigate to the root folder (where pyproject.toml lives) and run pip install ..

Additional Setup

The package requires access to the SageMath repository. By default, it assumes you have the repository cloned to the same parent directory as your sage-deps folder. You may modify this by modifying the configuration file, as shown below.

Getting started

To ensure the package is successfully installed, run sdeps. It should output a blank line by default.

The package comes with some pre-compiled resource files generated by SageMath version 10.6. To update these pre-generated files, run:

sdeps -gm -gg

To store and use local resource files, use the -m and -g flags or run:

sdeps -set-config modules_src <modules-path>
sdeps -set-config graph_src <graph-path>

Similarly, to specify a custom SageMath installation path, use the -s flag or run:

sdeps -set-config sage_path <sage-path>

Relative and absolute files are both supported.

Full options list

usage: sdeps [-h] [-s SOURCE_FILE] [-m SOURCE_FILE] [-g SOURCE_FILE] [-o OUTPUT_FILE] [-up SOURCE_CLASS DEPTH]
             [-cc SOURCE_CLASS TIMEOUT] [-cl SIZE] [-gm] [-gi] [-gd] [-gg] [-gdg SOURCE DISTANCE DIRECTION] [-f SOURCE_FILE] [-nf]
             [-view] [-set-config NAME VALUE] [--verbose]

A program top help manage SageMath dependencies.

options:
  -h, --help            show this help message and exit
  -s, --sage-source SOURCE_FILE
                        The source file of Sage.
  -m, --modules-source SOURCE_FILE
                        Specify the modules file.
  -g, --graph-source SOURCE_FILE
                        Specify the graph file.
  -o, --output-file OUTPUT_FILE
                        Specify the file to dump the output.
  -up SOURCE_CLASS DEPTH
                        Generates a breadth-first dependency tree rooted at SOURCE_CLASS, up to a given depth.
  -cc SOURCE_CLASS TIMEOUT
                        Finds cycles starting at SOURCE_CLASS with a timeout of TIMEOUT seconds.
  -cl SIZE              Finds cliques of size SIZE.
  -gm, --generate-modules
                        Generate a modules file. Will output to default location or `--modules-source`.
  -gi, --generate-imports
                        Generate an imports file.
  -gd, --generate-dependencies
                        Generate a dependencies file.
  -gg, --generate-graph
                        Generate an graph file. Will output to default location or `--graph-source`.
  -gdg, --generate-dependency-graph SOURCE DISTANCE DIRECTION
                        Generate a dependency graph rooted at a SOURCE node.
  -f, --ff SOURCE_FILE  Load a custom filter. If not, a default filter is used.
  -nf                   Disables the filter.
  -view, --view         Run a cytoscape.js instance. Specify graph source using `--graph-source`.
  -set-config NAME VALUE
                        Updates the configuration file.
  --verbose             Enable verbose output.

Note: Currently, verbose output doesn't do anything.

Example Usage

Command line examples

We can use the -up flag to compute all upwards dependencies of a particular class in SageMath.

% sdeps -up sage.rings.polynomial.polynomial\_element.Polynomial 1
{0: ['sage.rings.polynomial.polynomial_element.Polynomial'], 1: ['sage.rings.integer.Integer', 'sage.rings.rational_field.RationalField', 'sage.rings.integer_ring.IntegerRing_class', 'sage.rings.padics.padic_generic.pAdicGeneric', 'sage.rings.ideal.Ideal_generic', 'sage.rings.polynomial.polynomial_ring.PolynomialRing_generic', 'sage.rings.polynomial.multi_polynomial.MPolynomial', 'sage.rings.finite_rings.finite_field_base.FiniteField', 'sage.rings.number_field.number_field_base.NumberField', 'sage.rings.finite_rings.finite_field_constructor.FiniteFieldFactory', 'sage.rings.fraction_field.FractionField_generic']}

Similarly, we can do cycle detection. Notice that we need to set a time limit as finding cycles is, in general, NP-hard.

% sdeps -cc sage.rings.integer.Integer 120
[['sage.rings.integer.Integer', 'sage.rings.rational.Rational', 'sage.rings.integer_ring.IntegerRing_class', 'sage.rings.ring.CommutativeRing', 'sage.rings.polynomial.polynomial_element.Polynomial', 'sage.rings.rational_field.RationalField', 'sage.rings.number_field.number_field_base.NumberField', 'sage.rings.qqbar.AlgebraicRealField', 'sage.rings.qqbar.AlgebraicField_common', 'sage.rings.qqbar.AlgebraicNumberPowQQAction', 'sage.rings.real_mpfi.RealIntervalFieldElement', 'sage.rings.integer.Integer'], 
...
]

As a package

There is more freedom of use when treated as a package. An example workflow is shown below.

# Import relevant files
from sagedeps.main import *
from sagedeps.deps.loader import Loader
from sagedeps.deps.data import *
from sagedeps.deps.model.dependency import *
from sagedeps.deps.filter import *
from sagedeps.analysis import *

# Load from resources
Loader.initialize(scorer=DefaultScorer())

# Get classes and directories
filter = EmptyFilter()
classes = Data.get_classes_filtered(
    filter
)
dirs = Data.get_modules_filtered(
    filter
)
print(len(dirs))
print(len(classes))

# Count number of outdegrees over all classes to get an average
total_deg = 0
for sc in classes:
    total_deg += sc.out_degree(
        relations=[Relation.INHERITANCE, Relation.CLASS_ATTRIBUTE, Relation.DECLARED_SUB_IMPORT, Relation.DECLARED_TOP_IMPORT]
    )

print(total_deg/len(classes))

# Analyze for cliques of size 3
analyzer = CliquesAnalyzer(
    filter=EmptyFilter(),
    size=3,
    edge_types=[Relation.INHERITANCE, Relation.CLASS_ATTRIBUTE, Relation.DECLARED_SUB_IMPORT, Relation.DECLARED_TOP_IMPORT]
)

# Analyze PageRank
analyzer = PageRankAnalyzer(
    filter=EmptyFilter(),
    edge_types=[Relation.INHERITANCE, Relation.CLASS_ATTRIBUTE, Relation.DECLARED_SUB_IMPORT, Relation.DECLARED_TOP_IMPORT],
    weights=[1,1,1,1]
)
res = analyzer.run()
print(res[:15])
print(len(res))

The above snippet outputs

3202
5854
3.3659036556200888
[('sage.structure.sage_object.SageObject', np.float64(0.037002533039364974)), ('sage.rings.integer.Integer', np.float64(0.02290838092408753)), ('sage.rings.integer_ring.IntegerRing_class', np.float64(0.02273003398295342)), ('sage.structure.element.Element', np.float64(0.02090351208515615)), ('sage.structure.parent.Parent', np.float64(0.01437274473122256)), ('sage.categories.category.Category', np.float64(0.011457959949590773)), ('sage.categories.category_singleton.Category_singleton', np.float64(0.010601666149250333)), ('sage.typeset.character_art.CharacterArt', np.float64(0.010176442750443552)), ('sage.misc.lazy_attribute.lazy_attribute', np.float64(0.008751776770612866)), ('sage.categories.category_with_axiom.CategoryWithAxiom', np.float64(0.008289012215276066)), ('sage.structure.element.ModuleElement', np.float64(0.008201175230707807)), ('sage.rings.rational_field.RationalField', np.float64(0.008088172337409227)), ('sage.misc.lazy_attribute._lazy_attribute', np.float64(0.008085176090604891)), ('sage.categories.objects.Objects', np.float64(0.007503707995711554)), ('sage.structure.unique_representation.UniqueRepresentation', np.float64(0.007267035285008635))]
5854

Metadata

Release files for sage-deps 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sage-deps 0.1.2
File Size Uploaded Provenance Actions
sage_deps-0.1.2.tar.gz 27.0 kB Without provenance Details for sage_deps-0.1.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for sage-deps 0.1.2
File Interpreter ABI Platform Actions
sage_deps-0.1.2-py3-none-any.whl Python 3 none any Details for sage_deps-0.1.2-py3-none-any.whl

Total release size: 65.8 kB

Release files / sage_deps-0.1.2.tar.gz

Download URL sage_deps-0.1.2.tar.gz
Size 27.0 kB
Tags Source
SHA-256 checksum
How to use checksums
611150539ea8fb6b777a528721a5a38362db6feca550dd3bb205e1c97ddea547
BLAKE2b-256 checksum
How to use checksums
d39463ab59374e6f1045ff316266d664787f4bb08c00d43380c6039bb518c5c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.9

Release files / sage_deps-0.1.2-py3-none-any.whl

Download URL sage_deps-0.1.2-py3-none-any.whl
Size 38.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1db20bba8cd5fb492e00b79cde1fe911bc7c3d9647874206a4f32a56e1d81a32
BLAKE2b-256 checksum
How to use checksums
0711565851efa37aaf26df38c1460b0c1ad10ff00c56052435111d23955b2107
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.9

Security for sage-deps 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page