From 44fcee43d249d3024cf9d375ba2e276eb15b5d3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Fern=C3=A1ndez?= Date: Mon, 26 Oct 2026 11:59:28 +0100 Subject: [PATCH 1/6] Reduce install size: make ipyparallel/matplotlib optional (ipyp extra) and drop tests from wheel (#6) --- MANIFEST.in | 3 +-- bluepyopt/ipyp/bpopt_tasksdb.py | 6 +++++- pyproject.toml | 11 +++++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 0781bf4..a32931b 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -6,8 +6,7 @@ include bluepyopt/ephys/templates/acc/_json_template.jinja2 include bluepyopt/ephys/templates/acc/decor_acc_template.jinja2 include bluepyopt/ephys/templates/acc/label_dict_acc_template.jinja2 -include.txt +include README.rst include AUTHORS.txt include COPYING include COPYING.lesser -recursive-include bluepyopt/tests * diff --git a/bluepyopt/ipyp/bpopt_tasksdb.py b/bluepyopt/ipyp/bpopt_tasksdb.py index 5709209..99849c9 100644 --- a/bluepyopt/ipyp/bpopt_tasksdb.py +++ b/bluepyopt/ipyp/bpopt_tasksdb.py @@ -29,7 +29,6 @@ import itertools import numpy as np -import matplotlib.pyplot as plt def get_engine_data(tasksdb_filename): @@ -67,6 +66,8 @@ def get_engine_data(tasksdb_filename): def plot_usage(tasks, engine_number_map): """Plot usage stats""" + import matplotlib.pyplot as plt + plt.figure(figsize=(8, 8)) for engine_uuid, task_list in tasks.items(): engine_number = engine_number_map[engine_uuid] @@ -91,6 +92,8 @@ def plot_usage(tasks, engine_number_map): def plot_duration_histogram(tasks): """Plot duration histogram""" + import matplotlib.pyplot as plt + plt.figure(figsize=(8, 8)) durations = np.fromiter((t['duration'] @@ -137,6 +140,7 @@ def run(arg_list): plot_usage(tasks, engine_number_map) plot_duration_histogram(tasks) + import matplotlib.pyplot as plt plt.show() diff --git a/pyproject.toml b/pyproject.toml index addb435..4c74cbc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,8 +17,6 @@ dependencies = [ "pandas>=0.18", "deap>=1.3.3", "efel>=2.13", - "ipyparallel", - "pickleshare>=0.7.3", "Jinja2>=2.8", "Pebble>=4.6.0", "NEURON>=7.8", @@ -39,13 +37,15 @@ keywords = [ ] [project.optional-dependencies] -all = ["scoop>=0.7", "pyneuroml>=0.5.20", "libNeuroML>=0.3.1", "LFPy>=2.3", "arbor>=0.10,<0.12"] +all = ["scoop>=0.7", "pyneuroml>=0.5.20", "libNeuroML>=0.3.1", "LFPy>=2.3", "arbor>=0.10,<0.12", "ipyparallel", "pickleshare>=0.7.3", "matplotlib"] tests = ["pyneuroml>=0.5.20", "libNeuroML>=0.3.1", "LFPy>=2.3", "arbor>=0.10,<0.12"] tests-no-arbor = ["pyneuroml>=0.5.20", "libNeuroML>=0.3.1", "LFPy>=2.3"] scoop = ["scoop>=0.7"] neuroml = ["pyneuroml>=0.5.20", "libNeuroML>=0.3.1"] lfpy = ["LFPy>=2.3"] arbor = ["arbor>=0.10,<0.12"] +# Dependencies for the optional ipyparallel-based bpopt_tasksdb helper script. +ipyp = ["ipyparallel", "pickleshare>=0.7.3", "matplotlib"] [project.urls] Homepage = "https://github.com/openbraininstitute/BluePyOpt" @@ -72,7 +72,10 @@ bluepyopt = [ ] [tool.setuptools.packages.find] -exclude = ["examples*"] +exclude = ["examples*", "bluepyopt.tests*"] + +[tool.setuptools.exclude-package-data] +"*" = ["tests/*", "tests/**/*"] [tool.setuptools_scm] version_scheme = "python-simplified-semver" From 03519c0eb3197df5fd57d3200b5854aa6f875a7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Fern=C3=A1ndez?= Date: Tue, 27 Oct 2026 12:17:29 +0100 Subject: [PATCH 2/6] Fix bpopt_tasksdb console-script entry point (module:callable) --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4c74cbc..dfafa80 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,7 @@ Tracker = "https://github.com/openbraininstitute/BluePyOpt/issues" Documentation = "https://bluepyopt.readthedocs.io/en/latest" [project.scripts] -bpopt_tasksdb = "bluepyopt:ipyp.bpopt_tasksdb.main" +bpopt_tasksdb = "bluepyopt.ipyp.bpopt_tasksdb:main" [tool.setuptools] include-package-data = true From 37323eff2e47fda7c5f4fe48ce7bd842af823a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Fern=C3=A1ndez?= Date: Tue, 27 Oct 2026 12:17:32 +0100 Subject: [PATCH 3/6] Drop unused pickleshare and declare matplotlib in tests extras --- pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index dfafa80..15fe290 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,15 +37,15 @@ keywords = [ ] [project.optional-dependencies] -all = ["scoop>=0.7", "pyneuroml>=0.5.20", "libNeuroML>=0.3.1", "LFPy>=2.3", "arbor>=0.10,<0.12", "ipyparallel", "pickleshare>=0.7.3", "matplotlib"] -tests = ["pyneuroml>=0.5.20", "libNeuroML>=0.3.1", "LFPy>=2.3", "arbor>=0.10,<0.12"] -tests-no-arbor = ["pyneuroml>=0.5.20", "libNeuroML>=0.3.1", "LFPy>=2.3"] +all = ["scoop>=0.7", "pyneuroml>=0.5.20", "libNeuroML>=0.3.1", "LFPy>=2.3", "arbor>=0.10,<0.12", "ipyparallel", "matplotlib"] +tests = ["pyneuroml>=0.5.20", "libNeuroML>=0.3.1", "LFPy>=2.3", "arbor>=0.10,<0.12", "matplotlib"] +tests-no-arbor = ["pyneuroml>=0.5.20", "libNeuroML>=0.3.1", "LFPy>=2.3", "matplotlib"] scoop = ["scoop>=0.7"] neuroml = ["pyneuroml>=0.5.20", "libNeuroML>=0.3.1"] lfpy = ["LFPy>=2.3"] arbor = ["arbor>=0.10,<0.12"] # Dependencies for the optional ipyparallel-based bpopt_tasksdb helper script. -ipyp = ["ipyparallel", "pickleshare>=0.7.3", "matplotlib"] +ipyp = ["ipyparallel", "matplotlib"] [project.urls] Homepage = "https://github.com/openbraininstitute/BluePyOpt" From 96349a2a32ca7eb5d8380e32ee4497e7fe10dbbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Fern=C3=A1ndez?= Date: Tue, 27 Oct 2026 12:17:37 +0100 Subject: [PATCH 4/6] Keep tests in sdist for downstream packagers (conda-forge) --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index a32931b..238dd17 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -10,3 +10,4 @@ include README.rst include AUTHORS.txt include COPYING include COPYING.lesser +recursive-include bluepyopt/tests * From 60437a0a5a518fa85292f14c70c907db5c51ad16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Fern=C3=A1ndez?= Date: Tue, 27 Oct 2026 12:17:37 +0100 Subject: [PATCH 5/6] Guard matplotlib import in bpopt_tasksdb with helpful error --- bluepyopt/ipyp/bpopt_tasksdb.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/bluepyopt/ipyp/bpopt_tasksdb.py b/bluepyopt/ipyp/bpopt_tasksdb.py index 99849c9..5e960bc 100644 --- a/bluepyopt/ipyp/bpopt_tasksdb.py +++ b/bluepyopt/ipyp/bpopt_tasksdb.py @@ -31,6 +31,21 @@ import numpy as np +def _import_pyplot(): + """Import matplotlib.pyplot, with a helpful error if it is missing. + + matplotlib is an optional dependency of bpopt_tasksdb; install it via + ``pip install bluepyopt[ipyp]``. + """ + try: + import matplotlib.pyplot as plt + except ImportError as e: + raise ImportError( + "bpopt_tasksdb requires matplotlib: pip install bluepyopt[ipyp]" + ) from e + return plt + + def get_engine_data(tasksdb_filename): """Main""" conn = sqlite3.connect(tasksdb_filename) @@ -66,7 +81,7 @@ def get_engine_data(tasksdb_filename): def plot_usage(tasks, engine_number_map): """Plot usage stats""" - import matplotlib.pyplot as plt + plt = _import_pyplot() plt.figure(figsize=(8, 8)) for engine_uuid, task_list in tasks.items(): @@ -92,7 +107,7 @@ def plot_usage(tasks, engine_number_map): def plot_duration_histogram(tasks): """Plot duration histogram""" - import matplotlib.pyplot as plt + plt = _import_pyplot() plt.figure(figsize=(8, 8)) @@ -140,7 +155,7 @@ def run(arg_list): plot_usage(tasks, engine_number_map) plot_duration_histogram(tasks) - import matplotlib.pyplot as plt + plt = _import_pyplot() plt.show() From 35cb3fa5846d9e898fedd77f083eb66a6007abee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Fern=C3=A1ndez?= Date: Tue, 27 Oct 2026 12:17:37 +0100 Subject: [PATCH 6/6] Document that ipyparallel is now the bluepyopt[ipyp] extra --- examples/BluePyOpt-ipyparallel.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/BluePyOpt-ipyparallel.md b/examples/BluePyOpt-ipyparallel.md index ab6b04a..c7eee5e 100644 --- a/examples/BluePyOpt-ipyparallel.md +++ b/examples/BluePyOpt-ipyparallel.md @@ -12,6 +12,11 @@ The `ipcontroller` gets its work from clients that connect to it. ## Installation +> **Note:** As of recent versions, `ipyparallel` is no longer installed +> automatically with `BluePyOpt`. Install it explicitly, either on its own +> (`pip install ipyparallel`) or together with BluePyOpt via the extra: +> `pip install bluepyopt[ipyp]`. + `ipyparallel` can be installed using pip: # create and activate virtualenv