From dc1c71bc04ecb6646fc1270e6243c2bbb3067eff Mon Sep 17 00:00:00 2001 From: Dou Du Date: Sun, 30 Oct 2022 10:30:41 +0100 Subject: [PATCH 1/8] use the new template for ipywidgets v8.x --- css/widget.css | 3 +- docs/source/conf.py | 4 +- docs/source/index.rst | 2 +- package.json | 17 ++-- pyproject.toml | 113 ++++++++++++++++++++- setup.py | 124 +----------------------- src/__tests__/utils.ts | 3 +- src/plugin.ts | 4 +- widget_code_input/_frontend.py | 2 +- widget_code_input/_version.py | 2 +- widget_code_input/tests/test_example.py | 41 ++------ 11 files changed, 139 insertions(+), 176 deletions(-) diff --git a/css/widget.css b/css/widget.css index 98542ce..f7abb3f 100644 --- a/css/widget.css +++ b/css/widget.css @@ -1,3 +1,4 @@ .custom-widget { - background-color: blue; + background-color: lightseagreen; + padding: 0px 2px; } diff --git a/docs/source/conf.py b/docs/source/conf.py index dd7b567..a847020 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -88,7 +88,7 @@ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = "en" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -175,7 +175,7 @@ 'widget_code_input Documentation', author, 'widget_code_input', - 'A Jupyter widget to allow input of a python function, with syntax highlighting.', + 'A widget to allow input of a python function, with syntax highlighting.', 'Miscellaneous'), ] diff --git a/docs/source/index.rst b/docs/source/index.rst index 84e03cb..10f35a1 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -4,7 +4,7 @@ widget_code_input Version: |release| -A Jupyter widget to allow input of a python function, with syntax highlighting. +A widget to allow input of a python function, with syntax highlighting. Quickstart diff --git a/package.json b/package.json index 5b44648..7b774f3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "widget-code-input", - "version": "3.0.0", - "description": "A Jupyter widget to allow input of a python function, with syntax highlighting.", + "version": "3.5.0", + "description": "A widget to allow input of a python function, with syntax highlighting.", "keywords": [ "jupyter", "jupyterlab", @@ -19,7 +19,7 @@ }, "license": "BSD-3-Clause", "author": { - "name": "Dou Du", + "name": "Dou Du and Giovanni Pizzi", "email": "dou.du@epfl.ch" }, "main": "lib/index.js", @@ -49,15 +49,16 @@ "watch:labextension": "jupyter labextension watch ." }, "dependencies": { - "@jupyter-widgets/base": "^1.1.10 || ^2.0.0 || ^3.0.0 || ^4.0.0", - "codemirror": "5.58.2" + "@jupyter-widgets/base": "^1.1.10 || ^2 || ^3 || ^4 || ^5 || ^6", + "codemirror": "5.65.9" }, "devDependencies": { "@babel/core": "^7.5.0", "@babel/preset-env": "^7.5.0", + "@jupyter-widgets/base-manager": "^1.0.2", "@jupyterlab/builder": "^3.0.0", - "@phosphor/application": "^1.6.0", - "@phosphor/widgets": "^1.6.0", + "@lumino/application": "^1.6.0", + "@lumino/widgets": "^1.6.0", "@types/jest": "^26.0.0", "@types/webpack-env": "^1.13.6", "@typescript-eslint/eslint-plugin": "^3.6.0", @@ -79,7 +80,7 @@ "ts-jest": "^26.0.0", "ts-loader": "^8.0.0", "typescript": "~4.1.3", - "webpack": "^5.0.0", + "webpack": "^5.61.0", "webpack-cli": "^4.0.0", "underscore": "^1.13.2", "@types/codemirror": "^0.0.76" diff --git a/pyproject.toml b/pyproject.toml index 498df1e..cd0a9b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,112 @@ [build-system] -requires = ["jupyter_packaging==0.7.9", "jupyterlab==3.*", "setuptools>=40.8.0", "wheel"] -build-backend = "setuptools.build_meta" +requires = [ + "hatchling>=1.3.1", + "jupyterlab==3.*", +] +build-backend = "hatchling.build" + +[project] +name = "widget_code_input" +description = "A widget to allow input of a python function, with syntax highlighting." +readme = "README.md" +license = { file = "LICENSE.txt" } +requires-python = ">=3.7" +authors = [ + { name = "Dou Du", email = "dou.du@epfl.ch" }, +] +keywords = [ + "IPython", + "Jupyter", + "Widgets", +] +classifiers = [ + "Framework :: Jupyter", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: BSD License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", +] +dependencies = [ + "ipywidgets>=7.0.0", +] +version = "0.1.0.dev0" + +[project.optional-dependencies] +docs = [ + "jupyter_sphinx", + "nbsphinx", + "nbsphinx-link", + "pypandoc", + "pytest_check_links", + "recommonmark", + "sphinx>=1.5", + "sphinx_rtd_theme", +] +examples = [] +test = [ + "nbval", + "pytest-cov", + "pytest>=6.0", +] + +[project.urls] +Homepage = "https://github.com/osscar-org/widget-code-input" + +[tool.hatch.build] +artifacts = [ + "widget_code_input/nbextension/index.*", + "widget_code_input/labextension/*.tgz", + "widget_code_input/labextension", +] + +[tool.hatch.build.targets.wheel.shared-data] +"widget_code_input/nbextension" = "share/jupyter/nbextensions/widget_code_input" +"widget_code_input/labextension" = "share/jupyter/labextensions/widget_code_input" +"./install.json" = "share/jupyter/labextensions/widget_code_input/install.json" +"./widget_code_input.json" = "etc/jupyter/nbconfig/notebook.d/widget_code_input.json" + +[tool.hatch.build.targets.sdist] +exclude = [ + ".github", +] + +[tool.hatch.build.hooks.jupyter-builder] +build-function = "hatch_jupyter_builder.npm_builder" +ensured-targets = [ + "widget_code_input/nbextension/index.js", + "widget_code_input/labextension/package.json", +] +skip-if-exists = [ + "widget_code_input/nbextension/index.js", + "widget_code_input/labextension/package.json", +] +dependencies = [ + "hatch-jupyter-builder>=0.5.0", +] + +[tool.hatch.build.hooks.jupyter-builder.build-kwargs] +path = "." +build_cmd = "build:prod" + +[tool.tbump] +field = [ + { name = "channel", default = "" }, + { name = "release", default = "" }, +] +file = [ + { src = "pyproject.toml", version_template = "version = \"{major}.{minor}.{patch}{channel}{release}\"" }, + { src = "widget_code_input/_version.py" }, +] + +[tool.tbump.version] +current = "0.1.0.dev0" +regex = "(?P\\d+)\\.(?P\\d+)\\.(?P\\d+)((?Pa|b|rc|.dev)(?P\\d+))?" + +[tool.tbump.git] +message_template = "Bump to {new_version}" +tag_template = "v{new_version}" diff --git a/setup.py b/setup.py index 3a6817c..b6c6681 100644 --- a/setup.py +++ b/setup.py @@ -1,122 +1,2 @@ -#!/usr/bin/env python -# coding: utf-8 - -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -from __future__ import print_function -from glob import glob -import os -from os.path import join as pjoin -from setuptools import setup, find_packages - - -from jupyter_packaging import ( - create_cmdclass, - install_npm, - ensure_targets, - combine_commands, - get_version, - skip_if_exists -) - -HERE = os.path.dirname(os.path.abspath(__file__)) - - - - -# The name of the project -name = 'widget_code_input' - -# Get the version -version = get_version(pjoin(name, '_version.py')) - - -# Representative files that should exist after a successful build -jstargets = [ - pjoin(HERE, name, 'nbextension', 'index.js'), - pjoin(HERE, name, 'labextension', 'package.json'), -] - - -package_data_spec = { - name: [ - 'nbextension/**js*', - 'labextension/**' - ] -} - - -data_files_spec = [ - ('share/jupyter/nbextensions/widget_code_input', 'widget_code_input/nbextension', '**'), - ('share/jupyter/labextensions/widget-code-input', 'widget_code_input/labextension', '**'), - ('share/jupyter/labextensions/widget-code-input', '.', 'install.json'), - ('etc/jupyter/nbconfig/notebook.d', '.', 'widget_code_input.json'), -] - - -cmdclass = create_cmdclass('jsdeps', package_data_spec=package_data_spec, - data_files_spec=data_files_spec) -npm_install = combine_commands( - install_npm(HERE, build_cmd='build:prod'), - ensure_targets(jstargets), -) -cmdclass['jsdeps'] = skip_if_exists(jstargets, npm_install) - - -setup_args = dict( - name = name, - description = 'A Jupyter widget to allow input of a python function, with syntax highlighting.', - version = version, - scripts = glob(pjoin('scripts', '*')), - cmdclass = cmdclass, - packages = find_packages(), - author = 'Dou Du', - author_email = 'dou.du@epfl.ch', - url = 'https://github.com/osscar-org/widget-code-input', - license = 'BSD', - platforms = "Linux, Mac OS X, Windows", - keywords = ['Jupyter', 'Widgets', 'IPython'], - classifiers = [ - 'Intended Audience :: Developers', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: BSD License', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Framework :: Jupyter', - ], - include_package_data = True, - python_requires=">=3.6", - install_requires = [ - 'ipywidgets>=7.0.0', - ], - extras_require = { - 'test': [ - 'pytest>=4.6', - 'pytest-cov', - 'nbval', - ], - 'examples': [ - # Any requirements for the examples to run - ], - 'docs': [ - 'jupyter_sphinx', - 'nbsphinx', - 'nbsphinx-link', - 'pytest_check_links', - 'pypandoc', - 'recommonmark', - 'sphinx>=1.5', - 'sphinx_rtd_theme', - ], - }, - entry_points = { - }, -) - -if __name__ == '__main__': - setup(**setup_args) +# setup.py shim for use with applications that require it. +__import__("setuptools").setup() diff --git a/src/__tests__/utils.ts b/src/__tests__/utils.ts index 945b912..0a61d63 100644 --- a/src/__tests__/utils.ts +++ b/src/__tests__/utils.ts @@ -2,6 +2,7 @@ // Distributed under the terms of the Modified BSD License. import * as widgets from '@jupyter-widgets/base'; +import * as baseManager from '@jupyter-widgets/base-manager'; import * as services from '@jupyterlab/services'; let numComms = 0; @@ -44,7 +45,7 @@ export class MockComm implements widgets.IClassicComm { _on_close: ((x?: any) => void) | null = null; } -export class DummyManager extends widgets.ManagerBase { +export class DummyManager extends baseManager.ManagerBase { constructor() { super(); this.el = window.document.createElement('div'); diff --git a/src/plugin.ts b/src/plugin.ts index 0ed26c1..c8ed238 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -1,9 +1,9 @@ // Copyright (c) Dou Du // Distributed under the terms of the Modified BSD License. -import { Application, IPlugin } from '@phosphor/application'; +import { Application, IPlugin } from '@lumino/application'; -import { Widget } from '@phosphor/widgets'; +import { Widget } from '@lumino/widgets'; import { IJupyterWidgetRegistry } from '@jupyter-widgets/base'; diff --git a/widget_code_input/_frontend.py b/widget_code_input/_frontend.py index 947ce20..ebc21e3 100644 --- a/widget_code_input/_frontend.py +++ b/widget_code_input/_frontend.py @@ -9,4 +9,4 @@ """ module_name = "widget-code-input" -module_version = "^3.0.0" +module_version = "^3.5.0" diff --git a/widget_code_input/_version.py b/widget_code_input/_version.py index e680689..2b2304e 100644 --- a/widget_code_input/_version.py +++ b/widget_code_input/_version.py @@ -4,5 +4,5 @@ # Copyright (c) Dou Du. # Distributed under the terms of the Modified BSD License. -version_info = (3, 1, 0) +version_info = (0, 1, 0, 'dev') __version__ = ".".join(map(str, version_info)) diff --git a/widget_code_input/tests/test_example.py b/widget_code_input/tests/test_example.py index 06593c4..a173e76 100644 --- a/widget_code_input/tests/test_example.py +++ b/widget_code_input/tests/test_example.py @@ -1,43 +1,14 @@ #!/usr/bin/env python # coding: utf-8 -# Copyright (c) Giovanni Pizzi and Dou Du. +# Copyright (c) Dou Du. # Distributed under the terms of the Modified BSD License. -from widget_code_input import WidgetCodeInput +import pytest +from ..example import ExampleWidget -def test_example_creation(): - w = WidgetCodeInput( - function_name="my_f", - function_parameters="a, b=1", - docstring="some\nmultiline", - function_body="c = a+b\nreturn c", - ) - assert w.function_body == "c = a+b\nreturn c" - - expected_body = f'''def my_f(a, b=1): - """some - multiline""" - c = a+b - return c -''' - assert w.full_function_code == expected_body - - -def test_example_running(): - function_name = "my_f" - function_parameters = "a, b=1" - docstring = "some\nmultiline" - function_body = "c = a+b\nreturn c" - - w = WidgetCodeInput( - function_name=function_name, - function_parameters=function_parameters, - docstring=docstring, - function_body=function_body, - ) - - f = w.get_function_object() - assert f(1, 2) == 3 +def test_example_creation_blank(): + w = ExampleWidget() + assert w.value == 'Hello World' From 2b1770da76382e63e4904ba65190c8944c823e41 Mon Sep 17 00:00:00 2001 From: Dou Du Date: Sun, 30 Oct 2022 11:11:00 +0100 Subject: [PATCH 2/8] fix the eslint test for _this --- .eslintrc.js | 6 +++++- tsconfig.json | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 9fb27ea..40889cc 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -21,8 +21,12 @@ module.exports = { 'single', { avoidEscape: true, allowTemplateLiterals: false } ], + '@typescript-eslint/no-this-alias': [ + 'error', + { "allowDestructuring": true, "allowedNames": ["_this"] } + ], curly: ['error', 'all'], eqeqeq: 'error', 'prefer-arrow-callback': 'error' } -}; \ No newline at end of file +}; diff --git a/tsconfig.json b/tsconfig.json index f143a55..877823a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,7 @@ }, "include": [ "src/**/*.ts", - "src/**/*.tsx", + "src/**/*.tsx" ], "exclude": ["src/**/__tests__"] } From ab9dae0c1f2e349edd9f0fe47a0e6d9adbe70eb7 Mon Sep 17 00:00:00 2001 From: Dou Du Date: Sun, 30 Oct 2022 11:29:21 +0100 Subject: [PATCH 3/8] turn of the eslint check for rest params --- .eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc.js b/.eslintrc.js index 40889cc..6633094 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,6 +15,7 @@ module.exports = { '@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }], '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-namespace': 'off', + 'prefer-rest-params': 'off', '@typescript-eslint/no-use-before-define': 'off', '@typescript-eslint/quotes': [ 'error', From 21903052c4ff95ff9d05d2a1c0fad469f6cc41d9 Mon Sep 17 00:00:00 2001 From: Dou Du Date: Sun, 30 Oct 2022 11:37:00 +0100 Subject: [PATCH 4/8] update tests example --- widget_code_input/tests/test_example.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widget_code_input/tests/test_example.py b/widget_code_input/tests/test_example.py index a173e76..d979e92 100644 --- a/widget_code_input/tests/test_example.py +++ b/widget_code_input/tests/test_example.py @@ -6,9 +6,9 @@ import pytest -from ..example import ExampleWidget +from ..widget_code_input import WidgetCodeInput def test_example_creation_blank(): - w = ExampleWidget() + w = WidgetCodeInput() assert w.value == 'Hello World' From 4b4bdf91ccac4447f7a3cf53267f4b04128dec3c Mon Sep 17 00:00:00 2001 From: Dou Du Date: Sun, 30 Oct 2022 11:47:26 +0100 Subject: [PATCH 5/8] add function_name to the test --- widget_code_input/tests/test_example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget_code_input/tests/test_example.py b/widget_code_input/tests/test_example.py index d979e92..aba57f5 100644 --- a/widget_code_input/tests/test_example.py +++ b/widget_code_input/tests/test_example.py @@ -10,5 +10,5 @@ def test_example_creation_blank(): - w = WidgetCodeInput() + w = WidgetCodeInput(function_name = 'my_function') assert w.value == 'Hello World' From 325f564b7e1c8d140c9677ccde6d7ca7aa7bac60 Mon Sep 17 00:00:00 2001 From: Dou Du Date: Sun, 30 Oct 2022 11:55:58 +0100 Subject: [PATCH 6/8] fix the value bug --- widget_code_input/tests/test_example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget_code_input/tests/test_example.py b/widget_code_input/tests/test_example.py index aba57f5..fe09afa 100644 --- a/widget_code_input/tests/test_example.py +++ b/widget_code_input/tests/test_example.py @@ -11,4 +11,4 @@ def test_example_creation_blank(): w = WidgetCodeInput(function_name = 'my_function') - assert w.value == 'Hello World' + assert w.function_name == 'my_function' From cd0fd9e13a50a4fe911a67b7224fdd0bd2a997fe Mon Sep 17 00:00:00 2001 From: Dou Du Date: Sun, 30 Oct 2022 12:02:51 +0100 Subject: [PATCH 7/8] fix the index.spec.ts test fails --- src/__tests__/index.spec.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/__tests__/index.spec.ts b/src/__tests__/index.spec.ts index 407f930..243c449 100644 --- a/src/__tests__/index.spec.ts +++ b/src/__tests__/index.spec.ts @@ -6,20 +6,20 @@ import { createTestModel } from './utils'; -import { ExampleModel } from '..'; +import { WidgetCodeModel } from '..'; describe('Example', () => { - describe('ExampleModel', () => { + describe('WidgetCodeModel', () => { it('should be createable', () => { - const model = createTestModel(ExampleModel); - expect(model).toBeInstanceOf(ExampleModel); + const model = createTestModel(WidgetCodeModel); + expect(model).toBeInstanceOf(WidgetCodeModel); expect(model.get('value')).toEqual('Hello World'); }); it('should be createable with a value', () => { const state = { value: 'Foo Bar!' }; - const model = createTestModel(ExampleModel, state); - expect(model).toBeInstanceOf(ExampleModel); + const model = createTestModel(WidgetCodeModel, state); + expect(model).toBeInstanceOf(WidgetCodeModel); expect(model.get('value')).toEqual('Foo Bar!'); }); }); From ab2b3bd55d4f3e507c095469fe1189e8f79af4f5 Mon Sep 17 00:00:00 2001 From: Dou Du Date: Sun, 30 Oct 2022 12:12:01 +0100 Subject: [PATCH 8/8] make PyPi version number 0.3.5 --- widget_code_input/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget_code_input/_version.py b/widget_code_input/_version.py index 2b2304e..675e34b 100644 --- a/widget_code_input/_version.py +++ b/widget_code_input/_version.py @@ -4,5 +4,5 @@ # Copyright (c) Dou Du. # Distributed under the terms of the Modified BSD License. -version_info = (0, 1, 0, 'dev') +version_info = (3, 5, 0, 'dev') __version__ = ".".join(map(str, version_info))