Skip to content

Commit 49b5330

Browse files
authored
Replace pylint with ruff for repository linting, modernize packaging, and update CI for Python 3.10+ (#23)
1 parent 03421f6 commit 49b5330

File tree

17 files changed

+1501
-109
lines changed

17 files changed

+1501
-109
lines changed

.github/workflows/doc.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ jobs:
99
docs:
1010
runs-on: ubuntu-latest
1111
steps:
12-
- uses: actions/checkout@v3
13-
- uses: actions/setup-python@v3
12+
- uses: actions/checkout@v4
13+
- uses: actions/setup-python@v4
14+
with:
15+
python-version: '3.10'
1416
- name: Install dependencies
1517
run: |
1618
pip install sphinx sphinx_rtd_theme myst_parser

.github/workflows/release.yml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,22 @@ jobs:
1010
runs-on: ubuntu-latest
1111

1212
steps:
13-
- uses: actions/checkout@v2
13+
- uses: actions/checkout@v4
14+
15+
- name: Set up Python
16+
uses: actions/setup-python@v4
17+
with:
18+
python-version: '3.10'
1419

1520
- name: Install dependencies
16-
run: pip3 install --upgrade setuptools wheel twine
21+
run: pip3 install --upgrade build twine
22+
23+
- name: Build package
24+
run: python -m build
1725

18-
- name: Build and publish
26+
- name: Publish to PyPI
1927
env:
2028
TWINE_USERNAME: __token__
2129
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
2230
run: |
23-
python3 setup.py sdist bdist_wheel
2431
twine upload --repository pypi dist/*

.github/workflows/status.yml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@ jobs:
99
runs-on: ubuntu-latest
1010

1111
steps:
12-
- uses: actions/checkout@v1
12+
- uses: actions/checkout@v4
1313

14-
- name: Update pylint
15-
run: pip3 install -U pylint
14+
- name: Set up Python
15+
uses: actions/setup-python@v4
16+
with:
17+
python-version: '3.10'
1618

17-
- name: Check pylint
18-
run: pylint -rn --rcfile pylintrc nbtools
19+
- name: Install ruff
20+
run: pip3 install -U ruff
21+
22+
- name: Check ruff
23+
run: ruff check nbtools

.github/workflows/test-install.yml

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ jobs:
1616
fail-fast: false
1717
matrix:
1818
os: [ubuntu-latest, macos-latest, windows-latest]
19-
python-version: [3.8, 3.9, '3.10', 3.11]
19+
python-version: ['3.10', '3.11', '3.12']
2020

2121
runs-on: ${{ matrix.os }}
2222

2323
steps:
2424
- uses: actions/checkout@v4
2525

2626
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
27-
uses: actions/setup-python@v2
27+
uses: actions/setup-python@v4
2828
with:
2929
python-version: ${{ matrix.python-version }}
3030

@@ -47,13 +47,13 @@ jobs:
4747
fail-fast: false
4848
matrix:
4949
os: [ubuntu-latest, macos-latest, windows-latest]
50-
python-version: [3.8, 3.9, '3.10', 3.11]
50+
python-version: ['3.10', '3.11', '3.12']
5151

5252
runs-on: ${{ matrix.os }}
5353

5454
steps:
5555
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
56-
uses: actions/setup-python@v2
56+
uses: actions/setup-python@v4
5757
with:
5858
python-version: ${{ matrix.python-version }}
5959

@@ -65,3 +65,42 @@ jobs:
6565
6666
- name: Run 'import nbtools'
6767
run: python -c 'import nbtools'
68+
69+
70+
# -----------------------------------------
71+
# Install with uv
72+
# -----------------------------------------
73+
install_with_uv:
74+
75+
strategy:
76+
fail-fast: false
77+
matrix:
78+
os: [ubuntu-latest, macos-latest, windows-latest]
79+
python-version: ['3.10', '3.11', '3.12']
80+
81+
runs-on: ${{ matrix.os }}
82+
83+
steps:
84+
- uses: actions/checkout@v4
85+
86+
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
87+
uses: actions/setup-python@v4
88+
with:
89+
python-version: ${{ matrix.python-version }}
90+
91+
- name: Install uv
92+
uses: astral-sh/setup-uv@v2
93+
94+
- name: Install with uv
95+
run: uv sync
96+
97+
- name: Test import with uv
98+
run: uv run python -c 'import nbtools; print("nbtools version:", nbtools.__version__)'
99+
100+
- name: Test console scripts with uv
101+
run: uv run nbstat --help
102+
103+
- name: Test optional dependencies with uv
104+
run: |
105+
uv sync --extra dev --extra nbrun
106+
uv run python -c 'import ruff; print("ruff available")'

nbtools/__init__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
""" Init file. """
2-
#pylint: disable=wildcard-import
2+
from importlib.metadata import PackageNotFoundError, version
3+
34
from .core import *
45
from .exec_notebook import exec_notebook, run_notebook
56
from .pylint_notebook import pylint_notebook
67

7-
__version__ = '0.9.14'
8+
try:
9+
__version__ = version("py-nbtools")
10+
except PackageNotFoundError:
11+
__version__ = "0.0.0" # e.g., running from a source tree

nbtools/core.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
""" Core utility functions to work with Jupyter Notebooks. """
2-
#pylint: disable=import-outside-toplevel
32
import os
43
import sys
54
import re
@@ -34,7 +33,6 @@ def get_notebook_path():
3433
3534
If run outside Jupyter notebook, returns None.
3635
"""
37-
#pylint: disable=missing-timeout
3836
if not in_notebook():
3937
return None
4038

@@ -74,7 +72,7 @@ def get_notebook_name():
7472

7573
def notebook_to_script(path_script, path_notebook=None, ignore_markdown=True, return_info=False):
7674
""" Convert a notebook to a script. """
77-
import nbformat #pylint: disable=import-outside-toplevel
75+
import nbformat
7876
path_notebook = path_notebook or get_notebook_path()
7977
if path_notebook is None:
8078
raise ValueError('Provide path to Jupyter Notebook or run `notebook_to_script` inside of it!')
@@ -267,7 +265,6 @@ def set_gpus(n=1, min_free_memory=0.9, max_processes=2, verbose=False, raise_err
267265
devices : list
268266
Indices of selected and reserved GPUs.
269267
"""
270-
#pylint: disable=consider-iterating-dictionary
271268
if 'CUDA_VISIBLE_DEVICES' in os.environ.keys():
272269
str_devices = os.environ["CUDA_VISIBLE_DEVICES"]
273270
warnings.warn(f'`CUDA_VISIBLE_DEVICES` is already set to "{str_devices}"!')

nbtools/exec_notebook.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
""" Functions for running Jupyter Notebooks programmatically."""
2-
#pylint: disable=import-outside-toplevel
32
import os
43
import time
54
import json
@@ -10,7 +9,7 @@
109
import psutil
1110

1211

13-
TMP_DIR = '/tmp/nbtools_exec_notebook'
12+
TMP_DIR = '/tmp/nbtools_exec_notebook' # noqa: S108
1413
os.makedirs(TMP_DIR, exist_ok=True)
1514

1615

@@ -19,7 +18,6 @@ def run_in_process(func):
1918
""" Decorator to run the ``func`` in a separate process for terminating all related processes properly. """
2019
@wraps(func)
2120
def _wrapper(*args, **kwargs):
22-
# pylint: disable=broad-exception-caught, broad-exception-raised
2321
_output_queue = Queue()
2422
kwargs = {**kwargs, '_output_queue': _output_queue}
2523

@@ -39,7 +37,7 @@ def _wrapper(*args, **kwargs):
3937

4038
output = _output_queue.get()
4139
process.join()
42-
except (KeyboardInterrupt, Exception) as e:
40+
except (KeyboardInterrupt, Exception) as e: # noqa: BLE001
4341
output = {'failed': True, 'traceback': e}
4442

4543
# Terminate all relevant processes when something went wrong, e.g. Keyboard Interrupt
@@ -245,7 +243,6 @@ def exec_notebook(path, inputs=None, outputs=None, inputs_pos=1, replace_inputs_
245243
- ``'notebook'`` : :class:`nbformat.notebooknode.NotebookNode`, optional
246244
Executed notebook object. Note that this output is provided only if ``return_notebook`` is ``True``.
247245
"""
248-
# pylint: disable=bare-except, lost-exception, return-in-finally
249246
import nbformat
250247
from jupyter_client.manager import KernelManager
251248
from nbconvert.preprocessors import ExecutePreprocessor
@@ -321,7 +318,7 @@ def exec_notebook(path, inputs=None, outputs=None, inputs_pos=1, replace_inputs_
321318
exec_failed = False
322319
try:
323320
executor.preprocess(notebook, {'metadata': {'path': working_dir}}, km=kernel_manager)
324-
except:
321+
except: # noqa: E722
325322
exec_failed = True
326323

327324
# Save notebook outputs in the shelve db
@@ -359,7 +356,7 @@ def exec_notebook(path, inputs=None, outputs=None, inputs_pos=1, replace_inputs_
359356
# Re-raise exception if needed
360357
if raise_exception:
361358
_output_queue.put(exec_res)
362-
return None
359+
return None # noqa: RET501
363360
else:
364361
exec_res = {'failed': failed, 'failed cell number': None, 'traceback': ''}
365362

@@ -397,7 +394,7 @@ def exec_notebook(path, inputs=None, outputs=None, inputs_pos=1, replace_inputs_
397394
exec_res['notebook'] = notebook
398395

399396
_output_queue.put(exec_res) # return for parent process
400-
return None
397+
return None # noqa: RET501
401398

402399
# Functions for database operations cells masking
403400
def _display_inputs_reading(notebook, pos):

nbtools/nbstat/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
""" NBstat module: monitoring running Python processes and Notebooks. """
2-
#pylint: disable=wildcard-import
32
from .resource import Resource
43
from .resource_entry import ResourceEntry
54
from .resource_table import ResourceTable

nbtools/nbstat/cli.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
""" Command line interface of `nbstat`.
22
Also provides `nbwatch`, `devicestat` and `devicewatch` functions.
33
"""
4-
#pylint: disable=redefined-outer-name, too-many-nested-blocks
54
import sys
65
import traceback
76
from inspect import cleandoc
@@ -21,9 +20,9 @@ def main(name, interval=None):
2120
""" Run command `name`. If `interval` is given, continuously output it to a terminal in fullscreen mode. """
2221
# Attach SIGPIPE handler to properly handle broken pipe
2322
try: # sigpipe not available under windows. just ignore in this case
24-
import signal # pylint: disable=import-outside-toplevel
23+
import signal # noqa: E402
2524
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
26-
except Exception: # pylint: disable=broad-except
25+
except Exception: # noqa: BLE001, S110
2726
pass
2827

2928
# Make parameters for requested view
@@ -54,15 +53,14 @@ def output_once(inspector, name, formatter, view_args):
5453
try:
5554
view = inspector.get_view(name=name, formatter=formatter, **view_args)
5655
print(view)
57-
except Exception as e: # pylint: disable=broad-except
56+
except Exception as e:
5857
_ = e
5958
print('Error on getting system information!' + str(e))
6059
raise e
6160

6261
def output_looped(inspector, name, formatter, view_args,
6362
other_name, other_formatter, other_view_args, interval=0.5):
6463
""" Output visualization to a stdout once each `interval` seconds in a fullscreen mode. """
65-
#pylint: disable=too-many-statements
6664
terminal = Terminal()
6765

6866
initial_view_args = dict(view_args)
@@ -194,7 +192,7 @@ def output_looped(inspector, name, formatter, view_args,
194192
else:
195193
print(f'\nUnrecognized key={inkey}, code={inkey.code}.')
196194

197-
except Exception as e: # pylint: disable=broad-except
195+
except Exception as e: # noqa: BLE001
198196
sys.stderr.write(traceback.format_exc())
199197
sys.stderr.write('Error on getting system information!')
200198
sys.stderr.write(str(e))

nbtools/nbstat/resource_entry.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ def to_format_data(self, resource, terminal, **kwargs):
3939
kwargs : dict
4040
Other parameters for string creation like memory format, width, etc.
4141
"""
42-
#pylint: disable=too-many-statements
4342
resource = Resource.parse_alias(resource)
4443
default_string = '-'
4544
style, string = None, None

0 commit comments

Comments
 (0)