Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-jupyter-core for openSUSE:Factory checked in at 2023-02-06 14:15:19 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-jupyter-core (Old) and /work/SRC/openSUSE:Factory/.python-jupyter-core.new.4462 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-jupyter-core" Mon Feb 6 14:15:19 2023 rev:16 rq:1063296 version:5.2.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-jupyter-core/python-jupyter-core.changes 2023-01-24 20:32:01.288276373 +0100 +++ /work/SRC/openSUSE:Factory/.python-jupyter-core.new.4462/python-jupyter-core.changes 2023-02-06 14:15:21.140551335 +0100 @@ -1,0 +2,11 @@ +Sun Feb 5 15:58:09 UTC 2023 - Ben Greiner <c...@bnavigator.de> + +- Update to 5.2.0 + * Set up shell command-line tab-completion for jupyter and + subcommands #337 (@azjps) +- Release 5.1.5 + * Don't format logs in log call. #336 (@Carreau) +- Release 5.1.4 + * Suppress any exception in _do_i_own shortcut #335 (@minrk) + +------------------------------------------------------------------- Old: ---- jupyter_core-5.1.3.tar.gz New: ---- jupyter_core-5.2.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-jupyter-core.spec ++++++ --- /var/tmp/diff_new_pack.qIpoD6/_old 2023-02-06 14:15:21.684554046 +0100 +++ /var/tmp/diff_new_pack.qIpoD6/_new 2023-02-06 14:15:21.692554086 +0100 @@ -32,7 +32,7 @@ %endif Name: python-jupyter-core%{psuffix} -Version: 5.1.3 +Version: 5.2.0 Release: 0 Summary: Base package on which Jupyter projects rely License: BSD-3-Clause ++++++ jupyter_core-5.1.3.tar.gz -> jupyter_core-5.2.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/.pre-commit-config.yaml new/jupyter_core-5.2.0/.pre-commit-config.yaml --- old/jupyter_core-5.1.3/.pre-commit-config.yaml 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/.pre-commit-config.yaml 2020-02-02 01:00:00.000000000 +0100 @@ -35,7 +35,7 @@ - id: black - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.207 + rev: v0.0.237 hooks: - id: ruff args: ["--fix"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/CHANGELOG.md new/jupyter_core-5.2.0/CHANGELOG.md --- old/jupyter_core-5.1.3/CHANGELOG.md 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/CHANGELOG.md 2020-02-02 01:00:00.000000000 +0100 @@ -2,6 +2,54 @@ <!-- <START NEW CHANGELOG ENTRY> --> +## 5.2.0 + +([Full Changelog](https://github.com/jupyter/jupyter_core/compare/v5.1.5...98b9a1a94e79d1137246b4c1f8c16343b72b050c)) + +### Enhancements made + +- Set up shell command-line tab-completion for jupyter and subcommands [#337](https://github.com/jupyter/jupyter_core/pull/337) ([@azjps](https://github.com/azjps)) + +### Maintenance and upkeep improvements + +- Add more linting [#338](https://github.com/jupyter/jupyter_core/pull/338) ([@blink1073](https://github.com/blink1073)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyter/jupyter_core/graphs/contributors?from=2023-01-24&to=2023-01-30&type=c)) + +[@azjps](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Aazjps+updated%3A2023-01-24..2023-01-30&type=Issues) | [@blink1073](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Ablink1073+updated%3A2023-01-24..2023-01-30&type=Issues) + +<!-- <END NEW CHANGELOG ENTRY> --> + +## 5.1.5 + +([Full Changelog](https://github.com/jupyter/jupyter_core/compare/v5.1.4...269449fe4dcb8d427b54337d83bcb67bf50e87da)) + +### Maintenance and upkeep improvements + +- MAINT: Don't format logs in log call. [#336](https://github.com/jupyter/jupyter_core/pull/336) ([@Carreau](https://github.com/Carreau)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyter/jupyter_core/graphs/contributors?from=2023-01-23&to=2023-01-24&type=c)) + +[@Carreau](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3ACarreau+updated%3A2023-01-23..2023-01-24&type=Issues) + +## 5.1.4 + +([Full Changelog](https://github.com/jupyter/jupyter_core/compare/v5.1.3...c268e9133b37f710360a102f3a5d47a84e8cadc8)) + +### Bugs fixed + +- Suppress any exception in \_do_i_own shortcut [#335](https://github.com/jupyter/jupyter_core/pull/335) ([@minrk](https://github.com/minrk)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyter/jupyter_core/graphs/contributors?from=2023-01-09&to=2023-01-23&type=c)) + +[@minrk](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Aminrk+updated%3A2023-01-09..2023-01-23&type=Issues) + ## 5.1.3 ([Full Changelog](https://github.com/jupyter/jupyter_core/compare/v5.1.2...eb65690cb69a793edeb21b520c2358332933bb5d)) @@ -22,8 +70,6 @@ [@blink1073](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Ablink1073+updated%3A2023-01-02..2023-01-09&type=Issues) | [@Carreau](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3ACarreau+updated%3A2023-01-02..2023-01-09&type=Issues) | [@jasongrout](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Ajasongrout+updated%3A2023-01-02..2023-01-09&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_core+involves%3Apre-commit-ci+updated%3A2023-01-02..2023-01-09&type=Issues) -<!-- <END NEW CHANGELOG ENTRY> --> - ## 5.1.2 ([Full Changelog](https://github.com/jupyter/jupyter_core/compare/v5.1.1...4bd8ba97c99fefc416fe43411f935d40e2b7e441)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/PKG-INFO new/jupyter_core-5.2.0/PKG-INFO --- old/jupyter_core-5.1.3/PKG-INFO 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/PKG-INFO 2020-02-02 01:00:00.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: jupyter_core -Version: 5.1.3 +Version: 5.2.0 Summary: Jupyter core package. A base package on which Jupyter projects rely. Project-URL: Homepage, https://jupyter.org Project-URL: Documentation, https://jupyter-core.readthedocs.io/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/docs/conf.py new/jupyter_core-5.2.0/docs/conf.py --- old/jupyter_core-5.1.3/docs/conf.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/docs/conf.py 2020-02-02 01:00:00.000000000 +0100 @@ -15,6 +15,8 @@ import os import shutil +from jupyter_core.version import __version__, version_info + # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. @@ -61,11 +63,9 @@ # General information about the project. project = "jupyter_core" -copyright = "2015, Jupyter Development Team" +copyright = "2015, Jupyter Development Team" # noqa author = "Jupyter Development Team" -from jupyter_core.version import __version__, version_info - # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/examples/jupyter-completion.bash new/jupyter_core-5.2.0/examples/jupyter-completion.bash --- old/jupyter_core-5.1.3/examples/jupyter-completion.bash 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/examples/jupyter-completion.bash 2020-02-02 01:00:00.000000000 +0100 @@ -1,4 +1,10 @@ # load with: . jupyter-completion.bash +# +# NOTE: with traitlets>=5.8, jupyter and its subcommands now directly support +# shell command-line tab-completion using argcomplete, which has more complete +# support than this script. Simply install argcomplete and activate global +# completion by following the relevant instructions in: +# https://kislyuk.github.io/argcomplete/#activating-global-completion if [[ -n ${ZSH_VERSION-} ]]; then autoload -Uz bashcompinit && bashcompinit diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/jupyter_core/application.py new/jupyter_core-5.2.0/jupyter_core/application.py --- old/jupyter_core-5.1.3/jupyter_core/application.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/jupyter_core/application.py 2020-02-02 01:00:00.000000000 +0100 @@ -216,7 +216,7 @@ # self.raise_config_file_errors if (not suppress_errors) or self.raise_config_file_errors: raise - self.log.warning("Error loading config file: %s" % config_file_name, exc_info=True) + self.log.warning("Error loading config file: %s", config_file_name, exc_info=True) # subcommand-related def _find_subcommand(self, name): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/jupyter_core/command.py new/jupyter_core-5.2.0/jupyter_core/command.py --- old/jupyter_core-5.1.3/jupyter_core/command.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/jupyter_core/command.py 2020-02-02 01:00:00.000000000 +0100 @@ -1,3 +1,4 @@ +# PYTHON_ARGCOMPLETE_OK """The root `jupyter` command. This does nothing other than dispatch to subcommands or output path info. @@ -37,6 +38,15 @@ """Ignore epilog set in Parser.__init__""" pass + def argcomplete(self): + """Trigger auto-completion, if enabled""" + try: + import argcomplete # type: ignore[import] + + argcomplete.autocomplete(self) + except ImportError: + pass + def jupyter_parser() -> JupyterParser: """Create a jupyter parser object.""" @@ -48,7 +58,11 @@ group.add_argument( "--version", action="store_true", help="show the versions of core jupyter packages and exit" ) - group.add_argument("subcommand", type=str, nargs="?", help="the subcommand to launch") + subcommand_action = group.add_argument( + "subcommand", type=str, nargs="?", help="the subcommand to launch" + ) + # For argcomplete, supply all known subcommands + subcommand_action.completer = lambda *args, **kwargs: list_subcommands() # type: ignore[attr-defined] group.add_argument("--config-dir", action="store_true", help="show Jupyter config dir") group.add_argument("--data-dir", action="store_true", help="show Jupyter data dir") @@ -127,10 +141,12 @@ jupyter_subcommand = f"jupyter-{subcommand}" abs_path = which(jupyter_subcommand, path=search_path) if abs_path is None: - raise Exception(f"\nJupyter command `{jupyter_subcommand}` not found.") + msg = f"\nJupyter command `{jupyter_subcommand}` not found." + raise Exception(msg) if not os.access(abs_path, os.X_OK): - raise Exception(f"\nJupyter command `{jupyter_subcommand}` is not executable.") + msg = f"\nJupyter command `{jupyter_subcommand}` is not executable." + raise Exception(msg) return abs_path @@ -173,13 +189,50 @@ return path_list -def main() -> None: +def _evaluate_argcomplete(parser: JupyterParser) -> List[str]: + """If argcomplete is enabled, trigger autocomplete or return current words + + If the first word looks like a subcommand, return the current command + that is attempting to be completed so that the subcommand can evaluate it; + otherwise auto-complete using the main parser. + """ + try: + # traitlets >= 5.8 provides some argcomplete support, + # use helper methods to jump to argcomplete + from traitlets.config.argcomplete_config import ( + get_argcomplete_cwords, + increment_argcomplete_index, + ) + + cwords = get_argcomplete_cwords() + if cwords and len(cwords) > 1 and not cwords[1].startswith("-"): + # If first completion word looks like a subcommand, + # increment word from which to start handling arguments + increment_argcomplete_index() + return cwords + else: + # Otherwise no subcommand, directly autocomplete and exit + parser.argcomplete() + except ImportError: + # traitlets >= 5.8 not available, just try to complete this without + # worrying about subcommands + parser.argcomplete() + msg = "Control flow should not reach end of autocomplete()" + raise AssertionError(msg) + + +def main() -> None: # noqa """The command entry point.""" parser = jupyter_parser() - if len(sys.argv) > 1 and not sys.argv[1].startswith("-"): + argv = sys.argv + subcommand = None + if "_ARGCOMPLETE" in os.environ: + argv = _evaluate_argcomplete(parser) + subcommand = argv[1] + elif len(argv) > 1 and not argv[1].startswith("-"): # Don't parse if a subcommand is given # Avoids argparse gobbling up args passed to subcommand, such as `-h`. - subcommand = sys.argv[1] + subcommand = argv[1] else: args, opts = parser.parse_known_args() subcommand = args.subcommand @@ -343,7 +396,7 @@ sys.exit(str(e)) try: - _execvp(command, [command] + sys.argv[2:]) + _execvp(command, [command] + argv[2:]) except OSError as e: sys.exit(f"Error executing Jupyter command {subcommand!r}: {e}") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/jupyter_core/migrate.py new/jupyter_core-5.2.0/jupyter_core/migrate.py --- old/jupyter_core-5.1.3/jupyter_core/migrate.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/jupyter_core/migrate.py 2020-02-02 01:00:00.000000000 +0100 @@ -1,3 +1,4 @@ +# PYTHON_ARGCOMPLETE_OK """Migrating IPython < 4.0 to Jupyter This *copies* configuration and resources to their new locations in Jupyter @@ -26,7 +27,7 @@ import os import re import shutil -from datetime import datetime +from datetime import datetime, timezone from traitlets.config.loader import JSONFileConfigLoader, PyFileConfigLoader from traitlets.log import get_logger @@ -82,16 +83,16 @@ """Migrate a directory from src to dst""" log = get_logger() if not os.listdir(src): - log.debug("No files in %s" % src) + log.debug("No files in %s", src) return False if os.path.exists(dst): if os.listdir(dst): # already exists, non-empty - log.debug("%s already exists" % dst) + log.debug("%s already exists", dst) return False else: os.rmdir(dst) - log.info(f"Copying {src} -> {dst}") + log.info("Copying %s -> %s", src, dst) ensure_dir_exists(os.path.dirname(dst)) shutil.copytree(src, dst, symlinks=True) return True @@ -105,9 +106,9 @@ log = get_logger() if os.path.exists(dst): # already exists - log.debug("%s already exists" % dst) + log.debug("%s already exists", dst) return False - log.info(f"Copying {src} -> {dst}") + log.info("Copying %s -> %s", src, dst) ensure_dir_exists(os.path.dirname(dst)) shutil.copy(src, dst) if substitutions: @@ -131,7 +132,7 @@ elif os.path.isdir(src): return migrate_dir(src, dst) else: - log.debug("Nothing to migrate for %s" % src) + log.debug("Nothing to migrate for %s", src) return False @@ -163,9 +164,9 @@ custom_css_empty = css.startswith("/*") and css.endswith("*/") if custom_js_empty: - log.debug("Ignoring empty %s" % custom_js) + log.debug("Ignoring empty %s", custom_js) if custom_css_empty: - log.debug("Ignoring empty %s" % custom_css) + log.debug("Ignoring empty %s", custom_css) if custom_js_empty and custom_css_empty: # nothing to migrate @@ -175,12 +176,10 @@ if not custom_js_empty or not custom_css_empty: ensure_dir_exists(dst) - if not custom_js_empty: - if migrate_file(custom_js, pjoin(dst, "custom.js")): - migrated = True - if not custom_css_empty: - if migrate_file(custom_css, pjoin(dst, "custom.css")): - migrated = True + if not custom_js_empty and migrate_file(custom_js, pjoin(dst, "custom.js")): + migrated = True + if not custom_css_empty and migrate_file(custom_css, pjoin(dst, "custom.css")): + migrated = True return migrated @@ -208,7 +207,7 @@ migrated.append(src) else: # don't migrate empty config files - log.debug("Not migrating empty config file: %s" % src) + log.debug("Not migrating empty config file: %s", src) return migrated @@ -224,9 +223,8 @@ for src_t, dst_t in migrations.items(): src = src_t.format(**env) dst = dst_t.format(**env) - if os.path.exists(src): - if migrate_one(src, dst): - migrated = True + if os.path.exists(src) and migrate_one(src, dst): + migrated = True for name in config_migrations: if migrate_config(name, env): @@ -235,14 +233,13 @@ custom_src = custom_src_t.format(**env) custom_dst = custom_dst_t.format(**env) - if os.path.exists(custom_src): - if migrate_static_custom(custom_src, custom_dst): - migrated = True + if os.path.exists(custom_src) and migrate_static_custom(custom_src, custom_dst): + migrated = True # write a marker to avoid re-running migration checks ensure_dir_exists(env["jupyter_config"]) with open(os.path.join(env["jupyter_config"], "migrated"), "w", encoding="utf-8") as f: - f.write(datetime.utcnow().isoformat()) + f.write(datetime.now(tz=timezone.utc).isoformat()) return migrated diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/jupyter_core/paths.py new/jupyter_core-5.2.0/jupyter_core/paths.py --- old/jupyter_core-5.1.3/jupyter_core/paths.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/jupyter_core/paths.py 2020-02-02 01:00:00.000000000 +0100 @@ -80,8 +80,8 @@ # not always implemented or available try: return p.owner() == os.getlogin() - except (NotImplementedError, OSError): - pass + except Exception: + pass # noqa if hasattr(os, 'geteuid'): try: @@ -89,7 +89,7 @@ return st.st_uid == os.geteuid() except (NotImplementedError, OSError): # geteuid not always implemented - pass + pass # noqa # no ownership checks worked, check write access return os.access(p, os.W_OK) @@ -207,10 +207,10 @@ else: deprecation( "Jupyter is migrating its paths to use standard platformdirs\n" - + "given by the platformdirs library. To remove this warning and\n" - + "see the appropriate new directories, set the environment variable\n" - + "`JUPYTER_PLATFORM_DIRS=1` and then run `jupyter --paths`.\n" - + "The use of platformdirs will be the default in `jupyter_core` v6" + "given by the platformdirs library. To remove this warning and\n" + "see the appropriate new directories, set the environment variable\n" + "`JUPYTER_PLATFORM_DIRS=1` and then run `jupyter --paths`.\n" + "The use of platformdirs will be the default in `jupyter_core` v6" ) if os.name == "nt": programdata = os.environ.get("PROGRAMDATA", None) @@ -261,10 +261,7 @@ # Check if site.getuserbase() exists to be compatible with virtualenv, # which often does not have this method. userbase: Optional[str] - if hasattr(site, "getuserbase"): - userbase = site.getuserbase() - else: - userbase = site.USER_BASE + userbase = site.getuserbase() if hasattr(site, "getuserbase") else site.USER_BASE if userbase: userdir = os.path.join(userbase, "share", "jupyter") @@ -334,10 +331,7 @@ userbase: Optional[str] # Check if site.getuserbase() exists to be compatible with virtualenv, # which often does not have this method. - if hasattr(site, "getuserbase"): - userbase = site.getuserbase() - else: - userbase = site.USER_BASE + userbase = site.getuserbase() if hasattr(site, "getuserbase") else site.USER_BASE if userbase: userdir = os.path.join(userbase, "etc", "jupyter") @@ -439,7 +433,7 @@ raise # check that dirs can be listed - if stat.S_ISDIR(stat_res.st_mode): # type:ignore[misc] + if stat.S_ISDIR(stat_res.st_mode): # type:ignore[misc] # noqa # use x-access, not actual listing, in case of slow/large listings if not os.access(abs_path, os.X_OK | os.R_OK): return True @@ -457,7 +451,7 @@ is_file_hidden = is_file_hidden_posix -def is_hidden(abs_path: str, abs_root: str = "") -> bool: +def is_hidden(abs_path: str, abs_root: str = "") -> bool: # noqa """Is a file hidden or contained in a hidden directory? This will start with the rightmost path element and work backwards to the @@ -554,7 +548,7 @@ win32security.SetFileSecurity(fname, win32security.DACL_SECURITY_INFORMATION, sd) -def _win32_restrict_file_to_user_ctypes(fname: str) -> None: +def _win32_restrict_file_to_user_ctypes(fname: str) -> None: # noqa """Secure a windows file to read-only access for the user. Follows guidance from win32 library creator: @@ -992,16 +986,17 @@ if os.name != "nt": # Enforce that the file got the requested permissions before writing file_mode = get_file_mode(fname) - if 0o0600 != file_mode: + if file_mode != 0o0600: # noqa if allow_insecure_writes: issue_insecure_write_warning() else: - raise RuntimeError( + msg = ( "Permissions assignment failed for secure file: '{file}'." " Got '{permissions}' instead of '0o0600'.".format( file=fname, permissions=oct(file_mode) ) ) + raise RuntimeError(msg) yield f diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/jupyter_core/tests/test_command.py new/jupyter_core-5.2.0/jupyter_core/tests/test_command.py --- old/jupyter_core-5.1.3/jupyter_core/tests/test_command.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/jupyter_core/tests/test_command.py 2020-02-02 01:00:00.000000000 +0100 @@ -44,7 +44,7 @@ if not isinstance(cmd, list): cmd = [cmd] return ( - check_output([sys.executable, "-m", "jupyter_core"] + cmd, stderr=PIPE) + check_output([sys.executable, "-m", "jupyter_core", *cmd], stderr=PIPE) .decode("utf8") .strip() ) @@ -108,7 +108,7 @@ def test_paths_debug(): - vars = [ + names = [ "JUPYTER_PREFER_ENV_PATH", "JUPYTER_NO_CONFIG", "JUPYTER_CONFIG_PATH", @@ -118,12 +118,12 @@ "JUPYTER_RUNTIME_DIR", ] output = get_jupyter_output(["--paths", "--debug"]) - for v in vars: + for v in names: assert f"{v} is not set" in output - with patch.dict("os.environ", [(v, "y") for v in vars]): + with patch.dict("os.environ", [(v, "y") for v in names]): output = get_jupyter_output(["--paths", "--debug"]) - for v in vars: + for v in names: assert f"{v} is set" in output @@ -161,17 +161,16 @@ def get_path(dummy): return str(c) - with patch.object(sysconfig, "get_path", get_path): - with patch.dict("os.environ", {"PATH": path}): - subcommands = list_subcommands() - assert subcommands == [ - "babel-fish", - "baz", - "bop", - "foo", - "xyz", - "yo-eyropa-ganymyde-callysto", - ] + with patch.object(sysconfig, "get_path", get_path), patch.dict("os.environ", {"PATH": path}): + subcommands = list_subcommands() + assert subcommands == [ + "babel-fish", + "baz", + "bop", + "foo", + "xyz", + "yo-eyropa-ganymyde-callysto", + ] skip_darwin = pytest.mark.skipif(sys.platform == "darwin", reason="Fails on macos") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/jupyter_core/tests/test_paths.py new/jupyter_core-5.2.0/jupyter_core/tests/test_paths.py --- old/jupyter_core-5.1.3/jupyter_core/tests/test_paths.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/jupyter_core/tests/test_paths.py 2020-02-02 01:00:00.000000000 +0100 @@ -548,7 +548,7 @@ assert "administrators" in permissions assert permissions["administrators"] == {"f"} assert "everyone" not in permissions - assert len(permissions) == 2 + assert len(permissions) == 2 # noqa directory = tempfile.mkdtemp() fname = os.path.join(directory, "check_perms") @@ -570,16 +570,16 @@ with secure_write(fname) as f: f.write("test 1") mode = os.stat(fname).st_mode - assert 0o0600 == (stat.S_IMODE(mode) & 0o7677) # tolerate owner-execute bit + assert 0o0600 == (stat.S_IMODE(mode) & 0o7677) # noqa # tolerate owner-execute bit with open(fname, encoding="utf-8") as f: assert f.read() == "test 1" # Try changing file permissions ahead of time - os.chmod(fname, 0o755) + os.chmod(fname, 0o755) # noqa with secure_write(fname) as f: f.write("test 2") mode = os.stat(fname).st_mode - assert 0o0600 == (stat.S_IMODE(mode) & 0o7677) # tolerate owner-execute bit + assert 0o0600 == (stat.S_IMODE(mode) & 0o7677) # noqa # tolerate owner-execute bit with open(fname, encoding="utf-8") as f: assert f.read() == "test 2" finally: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/jupyter_core/troubleshoot.py new/jupyter_core-5.2.0/jupyter_core/troubleshoot.py --- old/jupyter_core-5.1.3/jupyter_core/troubleshoot.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/jupyter_core/troubleshoot.py 2020-02-02 01:00:00.000000000 +0100 @@ -45,12 +45,17 @@ return env -def main() -> None: +def main() -> None: # noqa """ print out useful info """ # pylint: disable=superfluous-parens # args = get_args() + if "_ARGCOMPLETE" in os.environ: + # No arguments to complete, the script can be slow to run to completion, + # so in case someone tries to complete jupyter troubleshoot just exit early + return + environment_data = get_data() print("$PATH:") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/jupyter_core/utils/__init__.py new/jupyter_core-5.2.0/jupyter_core/utils/__init__.py --- old/jupyter_core-5.1.3/jupyter_core/utils/__init__.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/jupyter_core/utils/__init__.py 2020-02-02 01:00:00.000000000 +0100 @@ -80,10 +80,7 @@ we know that our internal code is calling out to another library. """ _internal: List[str] - if isinstance(internal, str): - _internal = [internal] - else: - _internal = internal + _internal = [internal] if isinstance(internal, str) else internal # stack level of the first external frame from here stacklevel = _external_stacklevel(_internal) @@ -110,7 +107,7 @@ def _runner(self): loop = self.__io_loop - assert loop is not None + assert loop is not None # noqa try: loop.run_forever() finally: @@ -146,7 +143,8 @@ Whatever the coroutine-function returns. """ - assert inspect.iscoroutinefunction(coro) + if not inspect.iscoroutinefunction(coro): + raise AssertionError def wrapped(*args, **kwargs): name = threading.current_thread().name diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/jupyter_core/version.py new/jupyter_core-5.2.0/jupyter_core/version.py --- old/jupyter_core-5.1.3/jupyter_core/version.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/jupyter_core/version.py 2020-02-02 01:00:00.000000000 +0100 @@ -5,12 +5,12 @@ from typing import List # Version string must appear intact for hatch versioning -__version__ = "5.1.3" +__version__ = "5.2.0" # Build up version_info tuple for backwards compatibility pattern = r"(?P<major>\d+).(?P<minor>\d+).(?P<patch>\d+)(?P<rest>.*)" match = re.match(pattern, __version__) -assert match is not None +assert match is not None # noqa parts: List[object] = [int(match[part]) for part in ["major", "minor", "patch"]] if match["rest"]: parts.append(match["rest"]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/pyproject.toml new/jupyter_core-5.2.0/pyproject.toml --- old/jupyter_core-5.1.3/pyproject.toml 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/pyproject.toml 2020-02-02 01:00:00.000000000 +0100 @@ -93,7 +93,7 @@ test = "mypy --install-types --non-interactive {args:.}" [tool.hatch.envs.lint] -dependencies = ["black==22.12.0", "mdformat>0.7", "ruff==0.0.206"] +dependencies = ["black==22.12.0", "mdformat>0.7", "ruff==0.0.237"] detached = true [tool.hatch.envs.lint.scripts] style = [ @@ -161,38 +161,19 @@ target-version = "py38" line-length = 100 select = [ - "A", "B", "C", "E", "F", "FBT", "I", "N", "Q", "RUF", "S", "T", - "UP", "W", "YTT", + "A", "B", "C", "DTZ", "E", "EM", "F", "FBT", "I", "ICN", "ISC", "N", + "PLC", "PLE", "PLR", "PLW", "Q", "RUF", "S", "SIM", "T", "TID", "UP", + "W", "YTT", ] ignore = [ - # Allow non-abstract empty methods in abstract base classes - "B027", - # Ignore McCabe complexity - "C901", - # Allow boolean positional values in function calls, like `dict.get(... True)` - "FBT003", - # Use of `assert` detected - "S101", - # Line too long - "E501", - # Relative imports are banned - "TID252", - # Boolean ... in function definition - "FBT001", "FBT002", - # Module level import not at top of file - "E402", - # A001/A002/A003 .. is shadowing a python builtin - "A001", "A002", "A003", - # Possible hardcoded password - "S105", "S106", # Q000 Single quotes found but double quotes preferred "Q000", - # N806 Variable `B` in function should be lowercase - "N806", - # T201 `print` found - "T201", - # N802 Function name `CreateWellKnownSid` should be lowercase - "N802", "N803" + # FBT001 Boolean positional arg in function definition + "FBT001", "FBT002", "FBT003", + # E501 Line too long (158 > 100 characters) + "E501", + # SIM105 Use `contextlib.suppress(...)` + "SIM105", ] unfixable = [ # Don't touch print statements @@ -209,9 +190,18 @@ # T201 `print` found # B007 Loop control variable `i` not used within the loop body. # N802 Function name `assertIn` should be lowercase -"tests/*" = ["B011", "F841", "C408", "E402", "T201", "B007", "N802"] +# S101 Use of `assert` detected +# S108 Probable insecure usage of temporary file or directory: "/tmp" +# PLR2004 Magic value used in comparison, consider replacing b'WITNESS A' with a constant variable +"jupyter_core/tests/*" = ["B011", "F841", "C408", "E402", "T201", "B007", "N802", "S101", "S108", "PLR2004"] # F821 Undefined name `get_config` "jupyter_core/tests/**/profile_default/*_config.py" = ["F821"] +# T201 `print` found +"jupyter_core/application.py" = ["T201"] +"jupyter_core/command.py" = ["T201"] +"jupyter_core/troubleshoot.py" = ["T201"] +# N802 Function name `SetFileSecurity` should be lowercase +"jupyter_core/paths.py" = ["N802", "N803", "N806"] [tool.interrogate] ignore-init-module=true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_core-5.1.3/scripts/jupyter-migrate new/jupyter_core-5.2.0/scripts/jupyter-migrate --- old/jupyter_core-5.1.3/scripts/jupyter-migrate 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_core-5.2.0/scripts/jupyter-migrate 2020-02-02 01:00:00.000000000 +0100 @@ -1,4 +1,5 @@ #!/usr/bin/env python +# PYTHON_ARGCOMPLETE_OK """Migrate Jupyter config from IPython < 4.0""" from jupyter_core.migrate import main