Skip to content

Upgrading jupyterlab 3 to 4

Breaking3.6.8 → 4.6.5Security1Platform1Deprecated1New80Changed18Fixed43

Fetching 163 releases from GitHub…4 / 163
BreakingUpgrade verdict

A platform requirement change and a security fix.

  • Update to python 3.14, remove python 3.9 (@jasongrout, @brichet, @krassowski).
  • Fix CVE-2025-13465 in lodash and lodash-es (@ktaletsk, @jtpio, @krassowski).
  • Drives: Deprecate the notion of defaultContentProvider (@martinRenou, @brichet, @jasongrout, @jtpio, @krassowski).
3 items need code or config changes

Python requirement changed in 4.6.0a1: >=3.7 → >=3.10.

Adds async-lru >=1.0.0, httpx <1,>=0.25.0, ipykernel !=6.30.0,>=6.5.0, jupyter-builder >=1.0.2, jupyter-lsp >=2.0.0, notebook-shim >=0.2, traitlets.

Drops ipython, jupyter-server-ydoc, jupyter-ydoc, nbclassic, notebook.

Installs 81 packages in all (was 86).

Also installs h11, httpcore, nest-asyncio2.

No longer installs aiofiles, aiosqlite, entrypoints, ipython-genutils, jupyter-server-fileid, nest-asyncio, y-py, ypy-websocket.

Moves ipykernel 6.29.5 → 7.4.0, jupyter-client 7.4.9 → 8.10.0. Your build may pick other versions.

Security1
Fix CVE-2025-13465 in lodash and lodash-es (@ktaletsk, @jtpio, @krassowski).
lodashlodash-es
Platform1
Update to python 3.14, remove python 3.9 (@jasongrout, @brichet, @krassowski).
Deprecated1
Drives: Deprecate the notion of defaultContentProvider (@martinRenou, @brichet, @jasongrout, @jtpio, @krassowski).

Generated by DepDelta from published Python source. Not mixed with prose notes.

  • removed: function load_jupyter_server_extension(serverapp)
  • changed: class LogErrorHandler(logging.Handler) → class LogErrorHandler(logging.StreamHandler)
  • removed: variable WEBPACK_EXPECT
  • added: class LockStatus
  • added: field AppOptions.verbose
  • added: field LockStatus.entire_extension_locked: bool
  • added: field LockStatus.locked_plugins: frozenset[str] | None
  • added: function lock_extension(extension, app_options=…, level=…)
  • added: function unlock_extension(extension, app_options=…, level=…)
  • added: variable HERE
  • added: variable RSPACK_EXPECT
  • added: variable HERE
  • added: export ActionResult
  • added: export ExtensionManager
  • added: export ExtensionPackage
  • added: export PyPIExtensionManager
  • added: export ReadOnlyExtensionManager
  • added: function get_pypi_manager(app_options: dict | None=…, ext_options: dict | None=…, parent: Configurable | None=…) -> ExtensionManager
  • added: function get_readonly_manager(app_options: dict | None=…, ext_options: dict | None=…, parent: Configurable | None=…) -> ExtensionManager
  • added: variable MANAGERS
  • added: async method ExtensionManager.get_latest_version(extension: str) -> str | None
  • added: async method ExtensionManager.install(extension: str, version: str | None=…) -> ActionResult
  • added: async method ExtensionManager.is_install_allowed(name: str, _version: str | None=…) -> bool
  • added: async method ExtensionManager.is_uninstall_allowed(_name: str) -> bool
  • added: async method ExtensionManager.list_extensions(query: str | None=…, page: int=…, per_page: int=…) -> tuple[list[ExtensionPackage], int | None]
  • added: async method ExtensionManager.list_packages(query: str, page: int, per_page: int) -> tuple[dict[str, ExtensionPackage], int | None]
  • added: async method ExtensionManager.refresh(query: str | None, page: int, per_page: int) -> None
  • added: async method ExtensionManager.uninstall(extension: str) -> ActionResult
  • added: async method PluginManager.disable(plugins: str | list[str]) -> ActionResult
  • added: async method PluginManager.enable(plugins: str | list[str]) -> ActionResult
  • added: async method PluginManager.plugin_locks() -> dict
  • added: class ActionResult
  • added: class ExtensionManager(PluginManager)
  • added: class ExtensionManagerMetadata
  • added: class ExtensionManagerOptions(PluginManagerOptions)
  • added: class ExtensionPackage
  • added: class ExtensionsCache
  • added: class PluginManager(LoggingConfigurable)
  • added: class PluginManagerOptions
  • added: constructor ExtensionManager(app_options: dict | None=…, ext_options: dict | None=…, parent: Configurable | None=…) -> None
  • added: constructor PluginManager(app_options: dict | None=…, ext_options: dict | None=…, parent: Configurable | None=…) -> None
  • added: field ActionResult.message: str | None
  • added: field ActionResult.needs_restart: list[str]
  • added: field ActionResult.status: str
  • added: field ExtensionManagerMetadata.can_install: bool
  • added: field ExtensionManagerMetadata.install_path: str | None
  • added: field ExtensionManagerMetadata.name: str
  • added: field ExtensionManagerOptions.allowed_extensions_uris: set[str]
  • added: field ExtensionManagerOptions.blocked_extensions_uris: set[str]
  • added: field ExtensionManagerOptions.listings_refresh_seconds: int
  • added: field ExtensionManagerOptions.listings_tornado_options: dict
  • added: field ExtensionPackage.allowed: bool
  • added: field ExtensionPackage.approved: bool
  • added: field ExtensionPackage.author: str | None
  • added: field ExtensionPackage.bug_tracker_url: str | None
  • added: field ExtensionPackage.companion: str | None
  • added: field ExtensionPackage.core: bool
  • added: field ExtensionPackage.description: str
  • added: field ExtensionPackage.documentation_url: str | None
  • added: field ExtensionPackage.enabled: bool
  • added: field ExtensionPackage.homepage_url: str
  • added: field ExtensionPackage.install: dict | None
  • added: field ExtensionPackage.installed: bool | None
  • added: field ExtensionPackage.installed_version: str
  • added: field ExtensionPackage.latest_version: str
  • added: field ExtensionPackage.license: str | None
  • added: field ExtensionPackage.name: str
  • added: field ExtensionPackage.package_manager_url: str | None
  • added: field ExtensionPackage.pkg_type: str
  • added: field ExtensionPackage.repository_url: str | None
  • added: field ExtensionPackage.status: str
  • added: field ExtensionsCache.cache: dict[int, dict[str, ExtensionPackage] | None]
  • added: field ExtensionsCache.last_page: int
  • added: field PluginManager.level
  • added: field PluginManagerOptions.lock_all: bool
  • added: field PluginManagerOptions.lock_rules: frozenset[str]
  • added: method ExtensionManager.get_normalized_name(extension: ExtensionPackage) -> str
  • added: property ExtensionManager.metadata -> ExtensionManagerMetadata
  • added: static method ExtensionManager.get_semver_version(version: str) -> str
  • added: variable PYTHON_TO_SEMVER
  • added: async method PyPIExtensionManager.get_latest_version(pkg: str) -> str | None
  • added: async method PyPIExtensionManager.install(name: str, version: Optional[str]=…) -> ActionResult
  • added: async method PyPIExtensionManager.is_install_allowed(name: str, version: str | None=…) -> bool
  • added: async method PyPIExtensionManager.is_uninstall_allowed(name: str) -> bool
  • added: async method PyPIExtensionManager.list_packages(query: str, page: int, per_page: int) -> tuple[dict[str, ExtensionPackage], int | None]
  • added: async method PyPIExtensionManager.uninstall(extension: str) -> ActionResult
  • added: class ProxiedTransport(xmlrpc.client.Transport)
  • added: class PyPIExtensionManager(ExtensionManager)
  • added: constructor PyPIExtensionManager(app_options: dict | None=…, ext_options: dict | None=…, parent: config.Configurable | None=…) -> None
  • added: field PyPIExtensionManager.base_url
  • added: field PyPIExtensionManager.cache_timeout
  • added: field PyPIExtensionManager.package_metadata_cache_size
  • added: field PyPIExtensionManager.rpc_request_throttling
  • added: method ProxiedTransport.make_connection(host)
  • added: method ProxiedTransport.set_proxy(host, port=…, headers=…)
  • added: method PyPIExtensionManager.get_normalized_name(extension: ExtensionPackage) -> str
  • added: property PyPIExtensionManager.metadata -> ExtensionManagerMetadata
  • added: variable LANGUAGE_PACKS
  • added: variable all_proxy_url
  • added: variable http_proxy
  • added: variable http_proxy_url
  • added: variable https_proxy_url
  • added: variable proxy_host
  • added: variable proxy_port
  • added: variable xmlrpc_transport_override
  • added: async method ReadOnlyExtensionManager.get_latest_version(pkg: str) -> str | None
  • added: async method ReadOnlyExtensionManager.install(extension: str, version: str | None=…) -> ActionResult
  • added: async method ReadOnlyExtensionManager.is_install_allowed(name: str, version: str | None=…) -> bool
  • added: async method ReadOnlyExtensionManager.list_packages(query: str, page: int, per_page: int) -> tuple[dict[str, ExtensionPackage], int | None]
  • added: async method ReadOnlyExtensionManager.uninstall(extension: str) -> ActionResult
  • added: class ReadOnlyExtensionManager(ExtensionManager)
  • added: property ReadOnlyExtensionManager.metadata -> ExtensionManagerMetadata
  • removed: variable DEPRECATED_ARGUMENT
  • removed: variable HERE
  • changed: function build_labextension(path, logger=…, development=…, static_url=…, source_map=…, core_path=…) → function build_labextension(*args, **kwargs)
  • changed: function develop_labextension(path, symlink=…, overwrite=…, user=…, labextensions_dir=…, destination=…, logger=…, sys_prefix=…) → function develop_labextension(*args, **kwargs)
  • changed: function develop_labextension_py(module, user=…, sys_prefix=…, overwrite=…, symlink=…, labextensions_dir=…, logger=…) → function develop_labextension_py(*args, **kwargs)
  • changed: function watch_labextension(path, labextensions_path, logger=…, development=…, source_map=…, core_path=…) → function watch_labextension(*args, **kwargs)
  • added: function configure_jupyter_server(c)
  • changed: field Notification.link: Tuple[str, str] → field Notification.link: tuple[str, str]
  • changed: method CheckForUpdateHandler.initialize(update_checker: Optional[CheckForUpdate]=…) -> None → method CheckForUpdateHandler.initialize(update_checker: CheckForUpdate | None=…) -> None
  • changed: method NewsHandler.initialize(news_url: Optional[str]=…) -> None → method NewsHandler.initialize(news_url: str | None=…) -> None
  • changed: class Builder(object) → class Builder
  • removed: class ExtensionManager(object)
  • removed: constructor ExtensionManager(app_options=…)
  • removed: field ExtensionManager.executor
  • removed: method ExtensionManager.disable(extension)
  • removed: method ExtensionManager.enable(extension)
  • removed: method ExtensionManager.install(extension)
  • removed: method ExtensionManager.list_extensions()
  • removed: method ExtensionManager.refresh_outdated()
  • removed: method ExtensionManager.uninstall(extension)
  • changed: class ExtensionHandler(ExtensionHandlerMixin, APIHandler) → class ExtensionHandler(APIHandler)
  • changed: method ExtensionHandler.get() → async method ExtensionHandler.get()
  • changed: method ExtensionHandler.initialize(manager=…, name=…) → method ExtensionHandler.initialize(manager: ExtensionManager)
  • changed: method ExtensionHandler.post() → async method ExtensionHandler.post()
  • added: async method PluginHandler.get()
  • added: async method PluginHandler.post()
  • added: class PluginHandler(APIHandler)
  • added: method PluginHandler.initialize(manager: PluginManager)
  • added: variable plugins_handler_path
  • removed: function execvp(cmd, argv)
  • removed: function main(argv=…)
  • removed: variable HERE
  • removed: variable YARN_PATH
  • removed: field LabApp.future_skip_styles_for_disabled
  • removed: method LabApp.initialize_settings()
  • removed: variable buildFailureMsg
  • changed: class LabApp(NBClassicConfigShimMixin, LabServerApp) → class LabApp(NotebookConfigShimMixin, LabServerApp)
  • added: field LabApp.custom_css
  • added: field LabApp.extension_manager
  • added: field LabApp.lock_all_plugins
  • added: field LabApp.skip_dev_build
  • added: variable build_failure_msg
  • removed: class BuildLabExtensionApp(BaseExtensionApp)
  • removed: class DevelopLabExtensionApp(BaseExtensionApp)
  • removed: class WatchLabExtensionApp(BaseExtensionApp)
  • removed: field BuildLabExtensionApp.aliases
  • removed: field BuildLabExtensionApp.core_path
  • removed: field BuildLabExtensionApp.description
  • removed: field BuildLabExtensionApp.development
  • removed: field BuildLabExtensionApp.source_map
  • removed: field BuildLabExtensionApp.static_url
  • removed: field DevelopLabExtensionApp.description
  • removed: field DevelopLabExtensionApp.flags
  • removed: field DevelopLabExtensionApp.labextensions_dir
  • removed: field DevelopLabExtensionApp.overwrite
  • removed: field DevelopLabExtensionApp.symlink
  • removed: field DevelopLabExtensionApp.sys_prefix
  • removed: field DevelopLabExtensionApp.user
  • removed: field WatchLabExtensionApp.aliases
  • removed: field WatchLabExtensionApp.core_path
  • removed: field WatchLabExtensionApp.description
  • removed: field WatchLabExtensionApp.development
  • removed: field WatchLabExtensionApp.source_map
  • removed: method BuildLabExtensionApp.run_task()
  • removed: method DevelopLabExtensionApp.run_task()
  • removed: method WatchLabExtensionApp.run_task()
  • removed: variable HERE
  • added: class BuildLabExtensionAlias(BaseExtensionApp)
  • added: class DevelopLabExtensionAlias(BaseExtensionApp)
  • added: class LockLabExtensionsApp(BaseExtensionApp)
  • added: class UnlockLabExtensionsApp(BaseExtensionApp)
  • added: class WatchLabExtensionAlias(BaseExtensionApp)
  • added: field BuildLabExtensionAlias.description
  • added: field DevelopLabExtensionAlias.description
  • added: field ListLabExtensionsApp.flags
  • added: field ListLabExtensionsApp.verbose
  • added: field LockLabExtensionsApp.aliases
  • added: field LockLabExtensionsApp.description
  • added: field LockLabExtensionsApp.level
  • added: field UnlockLabExtensionsApp.aliases
  • added: field UnlockLabExtensionsApp.description
  • added: field UnlockLabExtensionsApp.level
  • added: field WatchLabExtensionAlias.description
  • added: method BuildLabExtensionAlias.parse_command_line(argv=…)
  • added: method BuildLabExtensionAlias.start()
  • added: method DevelopLabExtensionAlias.parse_command_line(argv=…)
  • added: method DevelopLabExtensionAlias.start()
  • added: method LockLabExtensionsApp.run_task()
  • added: method UnlockLabExtensionsApp.run_task()
  • added: method WatchLabExtensionAlias.parse_command_line(argv=…)
  • added: method WatchLabExtensionAlias.start()
  • added: variable list_flags
  • added: variable lock_aliases
  • added: variable unlock_aliases
  • added: variable error_msg
  • added: variable is_venv
  • added: variable venv_info
  • added: variable venv_type
  • removed: class Comparator(object)
  • removed: class Extendlist(list)
  • removed: class Range(object)
  • removed: class SemVer(object)
  • removed: constructor Comparator(comp, loose)
  • removed: constructor Range(range_, loose)
  • removed: constructor SemVer(version, loose)
  • removed: field Comparator.semver
  • removed: function clean(version, loose)
  • removed: function cmp(a, op, b, loose)
  • removed: function comparator(comp, loose)
  • removed: function compare(a, b, loose)
  • removed: function compare_identifiers(a, b)
  • removed: function compare_loose(a, b)
  • removed: function eq(a, b, loose)
  • removed: function gt(a, b, loose)
  • removed: function gte(a, b, loose)
  • removed: function hyphen_replace(mob)
  • removed: function inc(version, release, loose, identifier=…)
  • removed: function is_x(id)
  • removed: function list_get(xs, i)
  • removed: function lt(a, b, loose)
  • removed: function lte(a, b, loose)
  • removed: function ltr(version, range_, loose)
  • removed: function make_key_function(loose)
  • removed: function make_range(range_, loose)
  • removed: function max_satisfying(versions, range_, loose=…)
  • removed: function neq(a, b, loose)
  • removed: function outside(version, range_, hilo, loose)
  • removed: function parse(version, loose)
  • removed: function parse_comparator(comp, loose)
  • removed: function rcompare(a, b, loose)
  • removed: function rcompare_identifiers(a, b)
  • removed: function replace_caret(comp, loose)
  • removed: function replace_carets(comp, loose)
  • removed: function replace_stars(comp, loose)
  • removed: function replace_tilde(comp, loose)
  • removed: function replace_tildes(comp, loose)
  • removed: function replace_xrange(comp, loose)
  • removed: function replace_xranges(comp, loose)
  • removed: function rsort(list, loose)
  • removed: function rtr(version, range_, loose)
  • removed: function satisfies(version, range_, loose=…)
  • removed: function semver(version, loose)
  • removed: function sort(list, loose)
  • removed: function test_set(set_, version)
  • removed: function to_comparators(range_, loose)
  • removed: function valid(version, loose)
  • removed: function valid_range(range_, loose)
  • removed: method Comparator.parse(comp)
  • removed: method Comparator.test(version)
  • removed: method Range.format()
  • removed: method Range.parse_range(range_)
  • removed: method Range.test(version)
  • removed: method SemVer.compare(other)
  • removed: method SemVer.compare_main(other)
  • removed: method SemVer.compare_pre(other)
  • removed: method SemVer.format()
  • removed: method SemVer.inc(release, identifier=…)
  • removed: variable ANY
  • removed: variable BUILD
  • removed: variable BUILDIDENTIFIER
  • removed: variable CARET
  • removed: variable CARETLOOSE
  • removed: variable CARETTRIM
  • removed: variable COMPARATOR
  • removed: variable COMPARATORLOOSE
  • removed: variable COMPARATORTRIM
  • removed: variable FULL
  • removed: variable FULLPLAIN
  • removed: variable GTLT
  • removed: variable HYPHENRANGE
  • removed: variable HYPHENRANGELOOSE
  • removed: variable LONECARET
  • removed: variable LONETILDE
  • removed: variable LOOSE
  • removed: variable LOOSEPLAIN
  • removed: variable MAINVERSION
  • removed: variable MAINVERSIONLOOSE
  • removed: variable NONNUMERICIDENTIFIER
  • removed: variable NUMERIC
  • removed: variable NUMERICIDENTIFIER
  • removed: variable NUMERICIDENTIFIERLOOSE
  • removed: variable PRERELEASE
  • removed: variable PRERELEASEIDENTIFIER
  • removed: variable PRERELEASEIDENTIFIERLOOSE
  • removed: variable PRERELEASELOOSE
  • removed: variable R
  • removed: variable RECOVERYVERSIONNAME
  • removed: variable SEMVER_SPEC_VERSION
  • removed: variable STAR
  • removed: variable TILDE
  • removed: variable TILDELOOSE
  • removed: variable TILDETRIM
  • removed: variable XRANGE
  • removed: variable XRANGEIDENTIFIER
  • removed: variable XRANGEIDENTIFIERLOOSE
  • removed: variable XRANGELOOSE
  • removed: variable XRANGEPLAIN
  • removed: variable XRANGEPLAINLOOSE
  • removed: variable caretTrimReplace
  • removed: variable comparatorTrimReplace
  • removed: variable full_key_function
  • removed: variable logger
  • removed: variable loose_key_function
  • removed: variable make_comparator
  • removed: variable make_semver
  • removed: variable regexp
  • removed: variable src
  • removed: variable string_type
  • removed: variable tildeTrimReplace
  • removed: variable DEFAULT_COOKIECUTTER_BRANCH
  • changed: function update_extension(target, branch=…, interactive=…) → function update_extension(target: str, vcs_ref: str | None=…, interactive: bool=…) -> None
  • added: variable JUPYTER_SERVER_REQUIREMENT
  • added: variable RECOMMENDED_TO_OVERRIDE
  • added: variable answer_file
  • added: variable msg
  • changed: class deprecated(object) → class deprecated