Skip to content

Commit

Permalink
Move files to gb.core for better tab-completion (python-graphblas#289)
Browse files Browse the repository at this point in the history
* Move files to `gb.core` for better tab-completion

* Don't need to skip `core/__init__.py` anymore

* oops

* oops

* last one?

* Move ffi, lib, and NULL to `gb.core`

* sometimes autoload for lib, ffi, NULL

* Fix notebooks

* More cleanup
  • Loading branch information
eriknw authored Oct 19, 2022
1 parent 5fc34d7 commit 171c092
Show file tree
Hide file tree
Showing 78 changed files with 18,214 additions and 3,501 deletions.
10 changes: 7 additions & 3 deletions .github/workflows/test_and_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,17 @@ jobs:
# Test (and cover) lazy module loader
echo "from graphblas.agg import count" > script.py
coverage run -a --branch script.py
echo "from graphblas import agg, _agg" > script.py
echo "from graphblas import agg" > script.py # Does this still cover?
echo "from graphblas.core import agg" >> script.py
coverage run -a --branch script.py
# Tests lazy loading of lib, ffi, and NULL in gb.core
echo "from graphblas.core import base" > script.py
coverage run -a --branch script.py
rm script.py
- name: Auto-generated code check
run: |
coverage run -a --branch -m graphblas._automethods
coverage run -a --branch -m graphblas._infixmethods
coverage run -a --branch -m graphblas.core.automethods
coverage run -a --branch -m graphblas.core.infixmethods
git diff --exit-code
- name: Coverage
# if: (! contains(matrix.cfg.testopts, 'pygraphblas')) || (matrix.cfg.pyver != 3.9)
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,13 @@ Python-graphblas requires `numba` which enables compiling user-defined Python fu
Example customized UnaryOp:
```python
from graphblas import unary
from graphblas.operator import UnaryOp

def force_odd_func(x):
if x % 2 == 0:
return x + 1
return x

UnaryOp.register_new('force_odd', force_odd_func)
unary.register_new('force_odd', force_odd_func)

v = Vector.from_values([0, 1, 3], [1, 2, 3])
w = v.apply(unary.force_odd).new()
Expand Down
34 changes: 12 additions & 22 deletions graphblas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,35 +45,19 @@ def get_config():
"Recorder",
"Scalar",
"Vector",
"_agg",
"_ss",
"agg",
"base",
"binary",
"descriptor",
"core",
"dtypes",
"exceptions",
"expr",
"ffi",
"formatting",
"indexunary",
"infix",
"io",
"lib",
"mask",
"matrix",
"monoid",
"op",
"operator",
"recorder",
"scalar",
"select",
"semiring",
"ss",
"tests",
"unary",
"utils",
"vector",
"viz",
}

Expand All @@ -89,6 +73,9 @@ def __getattr__(name):
else:
_load(name)
return globals()[name]
elif name == "_autoinit":
if _init_params is None:
_init("suitesparse", None, automatic=True)
else:
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

Expand All @@ -111,7 +98,7 @@ def init(backend="suitesparse", blocking=False):


def _init(backend_arg, blocking, automatic=False):
global _init_params, backend, lib, ffi
global _init_params, backend

passed_params = {"backend": backend_arg, "blocking": blocking, "automatic": automatic}
if _init_params is not None:
Expand Down Expand Up @@ -154,17 +141,20 @@ def _init(backend_arg, blocking, automatic=False):
raise ValueError(f'Bad backend name. Must be "suitesparse". Got: {backend}')
_init_params = passed_params

from . import core

core.ffi = ffi
core.lib = lib
core.NULL = ffi.NULL


# Ideally this is in operator.py, but lives here to avoid circular references
_STANDARD_OPERATOR_NAMES = set()


def _load(name):
if name in {"Matrix", "Vector", "Scalar", "Recorder"}:
module_name = name.lower()
if module_name not in globals():
_load(module_name)
module = globals()[module_name]
module = _import_module(f".core.{name.lower()}", __name__)
globals()[name] = getattr(module, name)
else:
# Everything else is a module
Expand Down
7 changes: 3 additions & 4 deletions graphblas/agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,8 @@
# - bxnor monoid: even bits
# - bnor monoid: odd bits
"""
# All items are dynamically added by classes in _agg.py
# All items are dynamically added by classes in core/agg.py
# This module acts as a container of Aggregator instances
from . import operator
from .core import agg

del operator
from . import _agg # noqa isort:skip
del agg
2 changes: 1 addition & 1 deletion graphblas/binary/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def __getattr__(key):
raise AttributeError(f"module {__name__!r} has no attribute {key!r}")


from .. import operator # noqa isort:skip
from ..core import operator # noqa isort:skip
from . import numpy # noqa isort:skip

del operator
4 changes: 2 additions & 2 deletions graphblas/binary/numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def __getattr__(name):
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
if _config.get("mapnumpy") and name in _numpy_to_graphblas:
if name == "float_power":
from .. import operator
from ..core import operator

new_op = operator.BinaryOp(f"numpy.{name}")
builtin_op = _binary.pow
Expand All @@ -166,7 +166,7 @@ def __getattr__(name):
else:
globals()[name] = getattr(_binary, _numpy_to_graphblas[name])
else:
from .. import operator
from ..core import operator

numpy_func = getattr(_np, name)

Expand Down
7 changes: 7 additions & 0 deletions graphblas/core/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
def __getattr__(name):
if name in {"ffi", "lib", "NULL"}:
from .. import _autoinit # noqa

return globals()[name]
else:
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
4 changes: 2 additions & 2 deletions graphblas/_agg.py → graphblas/core/agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

import numpy as np

from . import agg, binary, monoid, semiring, unary
from .dtypes import INT64, lookup_dtype
from .. import agg, binary, monoid, semiring, unary
from ..dtypes import INT64, lookup_dtype
from .utils import output_type


Expand Down
26 changes: 13 additions & 13 deletions graphblas/_automethods.py → graphblas/core/automethods.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
To automatically create the functions, run:
$ python -m graphblas._automethods
$ python -m graphblas.core.automethods
"""
from . import config
from .. import config


def _get_value(self, attr=None, default=None):
Expand Down Expand Up @@ -446,11 +446,11 @@ def _main():

# Copy to scalar.py and infix.py
lines = []
lines.append(" _get_value = _automethods._get_value")
lines.append(" _get_value = automethods._get_value")
for name in sorted(common | scalar):
lines.append(f" {name} = wrapdoc(Scalar.{name})(property(_automethods.{name}))")
lines.append(f" {name} = wrapdoc(Scalar.{name})(property(automethods.{name}))")
if name == "name":
lines.append(" name = name.setter(_automethods._set_name)")
lines.append(" name = name.setter(automethods._set_name)")
lines.append(" # These raise exceptions")
for name in sorted(common_raises | scalar_raises):
lines.append(f" {name} = Scalar.{name}")
Expand All @@ -468,16 +468,16 @@ def get_name(line):

# Copy to vector.py and infix.py
lines = []
lines.append(" _get_value = _automethods._get_value")
lines.append(" _get_value = automethods._get_value")
for name in sorted(common | vector_matrix | vector):
lines.append(f" {name} = wrapdoc(Vector.{name})(property(_automethods.{name}))")
lines.append(f" {name} = wrapdoc(Vector.{name})(property(automethods.{name}))")
if name == "name":
lines.append(" name = name.setter(_automethods._set_name)")
lines.append(" name = name.setter(automethods._set_name)")
lines.append(" # These raise exceptions")
for name in sorted(common_raises | vector_matrix_raises):
lines.append(f" {name} = Vector.{name}")
for name in sorted(bad_sugar):
lines.append(f" {name} = _automethods.{name}")
lines.append(f" {name} = automethods.{name}")

text = "\n".join(lines) + "\n "
_autogenerate_code(os.path.join(thisdir, "vector.py"), text, "Vector")
Expand All @@ -486,16 +486,16 @@ def get_name(line):

# Copy to matrix.py and infix.py
lines = []
lines.append(" _get_value = _automethods._get_value")
lines.append(" _get_value = automethods._get_value")
for name in sorted(common | vector_matrix | matrix):
lines.append(f" {name} = wrapdoc(Matrix.{name})(property(_automethods.{name}))")
lines.append(f" {name} = wrapdoc(Matrix.{name})(property(automethods.{name}))")
if name == "name":
lines.append(" name = name.setter(_automethods._set_name)")
lines.append(" name = name.setter(automethods._set_name)")
lines.append(" # These raise exceptions")
for name in sorted(common_raises | vector_matrix_raises):
lines.append(f" {name} = Matrix.{name}")
for name in sorted(bad_sugar):
lines.append(f" {name} = _automethods.{name}")
lines.append(f" {name} = automethods.{name}")

text = "\n".join(lines) + "\n "
_autogenerate_code(os.path.join(thisdir, "matrix.py"), text, "Matrix")
Expand Down
10 changes: 5 additions & 5 deletions graphblas/base.py → graphblas/core/base.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
from contextvars import ContextVar

from . import config, ffi
from . import replace as replace_singleton
from .. import config
from .. import replace as replace_singleton
from ..dtypes import BOOL
from ..exceptions import check_status
from . import NULL, ffi
from .descriptor import lookup as descriptor_lookup
from .dtypes import BOOL
from .exceptions import check_status
from .expr import AmbiguousAssignOrExtract, Updater
from .mask import Mask
from .operator import UNKNOWN_OPCLASS, binary_from_string, find_opclass, get_typed_op
from .utils import _Pointer, libget, output_type

NULL = ffi.NULL
CData = ffi.CData
_recorder = ContextVar("recorder")
_prev_recorder = None
Expand Down
6 changes: 2 additions & 4 deletions graphblas/descriptor.py → graphblas/core/descriptor.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from . import ffi, lib
from .exceptions import check_status_carg

NULL = ffi.NULL
from ..exceptions import check_status_carg
from . import NULL, ffi, lib


class Descriptor:
Expand Down
6 changes: 3 additions & 3 deletions graphblas/expr.py → graphblas/core/expr.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import numpy as np

from ..dtypes import _INDEX
from . import lib, utils
from .dtypes import _INDEX
from .utils import _CArray, output_type


Expand Down Expand Up @@ -58,7 +58,7 @@ def _py_index(self):
return self.index.value
if self.index is _ALL_INDICES:
return slice(None)
from ._slice import gxb_backwards, gxb_range, gxb_stride
from .slice import gxb_backwards, gxb_range, gxb_stride

if self.cscalar is gxb_backwards:
start, stop, step = self.index.array.tolist()
Expand Down Expand Up @@ -183,7 +183,7 @@ def parse_index(self, index, typ, size):
if typ is list:
pass
elif typ is slice:
from ._slice import slice_to_index
from .slice import slice_to_index

return slice_to_index(index, size)

Expand Down
6 changes: 3 additions & 3 deletions graphblas/formatting.py → graphblas/core/formatting.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import numpy as np

from . import config, monoid, unary
from .dtypes import BOOL
from .exceptions import OutOfMemory
from .. import config, monoid, unary
from ..dtypes import BOOL
from ..exceptions import OutOfMemory
from .matrix import Matrix, TransposedMatrix
from .vector import Vector

Expand Down
Loading

0 comments on commit 171c092

Please sign in to comment.