From 7fbaa767c71302cc756bdf1fb11fcbf1b3768dcc Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 16 Mar 2022 15:32:09 -0500 Subject: [PATCH] More CI Cleanup (#742) --- .github/workflows/python-linux.yml | 2 +- .mailmap | 2 +- .pre-commit-config.yaml | 10 ++++++++- docs/Makefile | 2 +- docs/autogen_config.py | 2 +- docs/source/conf.py | 11 ---------- examples/simple/jupyter_server_config.py | 2 +- examples/simple/pytest.ini | 2 +- examples/simple/simple_ext11/application.py | 2 +- jupyter_server/auth/login.py | 4 ++-- jupyter_server/auth/logout.py | 2 +- jupyter_server/auth/security.py | 4 ++-- jupyter_server/base/handlers.py | 2 +- jupyter_server/extension/application.py | 4 ++-- jupyter_server/extension/manager.py | 2 +- jupyter_server/extension/serverextension.py | 2 +- jupyter_server/extension/utils.py | 4 ++-- jupyter_server/gateway/managers.py | 8 ++++--- jupyter_server/i18n/__init__.py | 2 +- jupyter_server/i18n/babel_nbui.cfg | 2 +- jupyter_server/nbconvert/handlers.py | 2 +- jupyter_server/serverapp.py | 22 ++++++++----------- jupyter_server/services/contents/fileio.py | 6 ++--- .../services/contents/filemanager.py | 4 ++-- jupyter_server/services/contents/manager.py | 2 +- jupyter_server/services/kernels/handlers.py | 10 ++++----- .../services/kernels/kernelmanager.py | 6 ++--- .../services/sessions/sessionmanager.py | 2 +- jupyter_server/terminal/terminalmanager.py | 2 +- jupyter_server/traittypes.py | 8 +++---- jupyter_server/utils.py | 1 + setup.cfg | 11 +++++++++- tests/auth/test_authorizer.py | 4 ++-- tests/auth/test_security.py | 4 +--- tests/extension/mockextensions/app.py | 2 ++ tests/extension/mockextensions/mock1.py | 2 ++ tests/extension/mockextensions/mock2.py | 2 ++ .../extension/mockextensions/mockext_both.py | 2 ++ tests/extension/mockextensions/mockext_py.py | 2 ++ tests/extension/mockextensions/mockext_sys.py | 2 ++ .../extension/mockextensions/mockext_user.py | 2 ++ tests/extension/test_launch.py | 4 +++- tests/services/contents/test_manager.py | 4 ++-- tests/services/kernels/test_api.py | 4 ++-- tests/services/nbconvert/test_api.py | 2 +- tests/services/sessions/test_api.py | 7 +++--- tests/test_gateway.py | 2 +- tests/test_terminal.py | 2 +- tests/unix_sockets/test_api.py | 8 +++---- 49 files changed, 111 insertions(+), 91 deletions(-) diff --git a/.github/workflows/python-linux.yml b/.github/workflows/python-linux.yml index b178640653..5b96aea3bb 100644 --- a/.github/workflows/python-linux.yml +++ b/.github/workflows/python-linux.yml @@ -54,7 +54,7 @@ jobs: - name: Run the tests if: ${{ matrix.python-version != 'pypy-3.7' }} run: | - pytest -vv --cov jupyter_server --cov-branch --cov-report term-missing:skip-covered || pytest -vv --cov jupyter_server --cov-branch --cov-report term-missing:skip-covered --lf + pytest -vv --cov jupyter_server --cov-branch --cov-report term-missing:skip-covered --cov-fail-under 70 || pytest -vv --cov jupyter_server --cov-branch --cov-report term-missing:skip-covered --cov-fail-under 70 --lf - name: Run the tests on pypy if: ${{ matrix.python-version == 'pypy-3.7' }} run: | diff --git a/.mailmap b/.mailmap index bd6544e25c..e39230250a 100644 --- a/.mailmap +++ b/.mailmap @@ -26,7 +26,7 @@ David Hirschfeld dhirschfeld David P. Sanders David Warde-Farley David Warde-Farley <> Doug Blank Doug Blank -Eugene Van den Bulke Eugene Van den Bulke +Eugene Van den Bulke Eugene Van den Bulke Evan Patterson Evan Patterson Evan Patterson diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b221b5ba6d..5f3e2ebe23 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,10 +15,16 @@ repos: hooks: - id: prettier - - repo: https://gitlab.com/pycqa/flake8 + - repo: https://github.com/pycqa/flake8 rev: 4.0.1 hooks: - id: flake8 + additional_dependencies: + [ + "flake8-bugbear==20.1.4", + "flake8-logging-format==0.6.0", + "flake8-implicit-str-concat==0.2.0", + ] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.1.0 @@ -33,6 +39,8 @@ repos: - id: check-yaml - id: debug-statements - id: forbid-new-submodules + - id: check-builtin-literals + - id: trailing-whitespace - repo: https://github.com/pre-commit/mirrors-eslint rev: v8.8.0 diff --git a/docs/Makefile b/docs/Makefile index 02cb617a36..1765c64af3 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -176,7 +176,7 @@ linkcheck: @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." - + spelling: $(SPHINXBUILD) -b spelling $(ALLSPHINXOPTS) $(BUILDDIR)/spelling @echo "Spell check complete; look for any errors in the above output " \ diff --git a/docs/autogen_config.py b/docs/autogen_config.py index 2892dfebe9..7f4ec15db0 100644 --- a/docs/autogen_config.py +++ b/docs/autogen_config.py @@ -37,7 +37,7 @@ """ try: destination = os.path.join(os.path.dirname(__file__), "source/other/full-config.rst") -except: +except BaseException: destination = os.path.join(os.getcwd(), "full-config.rst") with open(destination, "w") as f: diff --git a/docs/source/conf.py b/docs/source/conf.py index 23369d43f1..ad8eb1bf15 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -279,17 +279,6 @@ # -- Options for LaTeX output --------------------------------------------- -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - #'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - #'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - #'preamble': '', - # Latex figure (float) alignment - #'figure_align': 'htbp', -} - # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). diff --git a/examples/simple/jupyter_server_config.py b/examples/simple/jupyter_server_config.py index b994a7140c..723d6cdadb 100644 --- a/examples/simple/jupyter_server_config.py +++ b/examples/simple/jupyter_server_config.py @@ -2,5 +2,5 @@ # ------------------------------------------------------------------------------ # Application(SingletonConfigurable) configuration # ------------------------------------------------------------------------------ -## The date format used by logging formatters for %(asctime)s +# The date format used by logging formatters for %(asctime)s c.Application.log_datefmt = "%Y-%m-%d %H:%M:%S Simple_Extensions_Example" diff --git a/examples/simple/pytest.ini b/examples/simple/pytest.ini index 31e2592bf3..83dd817a2b 100644 --- a/examples/simple/pytest.ini +++ b/examples/simple/pytest.ini @@ -1,3 +1,3 @@ [pytest] # Disable any upper exclusion. -norecursedirs = +norecursedirs = diff --git a/examples/simple/simple_ext11/application.py b/examples/simple/simple_ext11/application.py index 82411dd0a6..81416ebdf6 100644 --- a/examples/simple/simple_ext11/application.py +++ b/examples/simple/simple_ext11/application.py @@ -57,7 +57,7 @@ def simple11_dir_formatted(self): def initialize_settings(self): self.log.info("hello: {}".format(self.hello)) - if self.hello == True: + if self.hello is True: self.log.info( "Hello Simple11: You have launched with --hello flag or defined 'c.SimpleApp1.hello == True' in your config file" ) diff --git a/jupyter_server/auth/login.py b/jupyter_server/auth/login.py index fb245f7854..efae3d60ed 100644 --- a/jupyter_server/auth/login.py +++ b/jupyter_server/auth/login.py @@ -229,10 +229,10 @@ def validate_security(cls, app, ssl_options=None): if not app.ip: warning = "WARNING: The Jupyter server is listening on all IP addresses" if ssl_options is None: - app.log.warning(warning + " and not using encryption. This " "is not recommended.") + app.log.warning(f"{warning} and not using encryption. This is not recommended.") if not app.password and not app.token: app.log.warning( - warning + " and not using authentication. " + f"{warning} and not using authentication. " "This is highly insecure and not recommended." ) else: diff --git a/jupyter_server/auth/logout.py b/jupyter_server/auth/logout.py index 1704967ea8..abe23425c9 100644 --- a/jupyter_server/auth/logout.py +++ b/jupyter_server/auth/logout.py @@ -11,7 +11,7 @@ def get(self): if self.login_available: message = {"info": "Successfully logged out."} else: - message = {"warning": "Cannot log out. Jupyter Server authentication " "is disabled."} + message = {"warning": "Cannot log out. Jupyter Server authentication is disabled."} self.write(self.render_template("logout.html", message=message)) diff --git a/jupyter_server/auth/security.py b/jupyter_server/auth/security.py index 5744e264e6..d6edd80246 100644 --- a/jupyter_server/auth/security.py +++ b/jupyter_server/auth/security.py @@ -48,7 +48,7 @@ def passwd(passphrase=None, algorithm="argon2"): """ if passphrase is None: - for i in range(3): + for _ in range(3): p0 = getpass.getpass("Enter password: ") p1 = getpass.getpass("Verify password: ") if p0 == p1: @@ -161,7 +161,7 @@ def persist_config(config_file=None, mode=0o600): try: os.chmod(config_file, mode) - except Exception as e: + except Exception: tb = traceback.format_exc() warnings.warn("Failed to set permissions on %s:\n%s" % (config_file, tb), RuntimeWarning) diff --git a/jupyter_server/base/handlers.py b/jupyter_server/base/handlers.py index 067235ab70..d305977059 100644 --- a/jupyter_server/base/handlers.py +++ b/jupyter_server/base/handlers.py @@ -454,7 +454,7 @@ def check_xsrf_cookie(self): return try: return super(JupyterHandler, self).check_xsrf_cookie() - except web.HTTPError as e: + except web.HTTPError: if self.request.method in {"GET", "HEAD"}: # Consider Referer a sufficient cross-origin check for GET requests if not self.check_referer(): diff --git a/jupyter_server/extension/application.py b/jupyter_server/extension/application.py index 4bae58f6e9..abcb64f8d7 100644 --- a/jupyter_server/extension/application.py +++ b/jupyter_server/extension/application.py @@ -543,7 +543,7 @@ def load_classic_server_extension(cls, serverapp): extension.initialize() @classmethod - def initialize_server(cls, argv=[], load_other_extensions=True, **kwargs): + def initialize_server(cls, argv=None, load_other_extensions=True, **kwargs): """Creates an instance of ServerApp and explicitly sets this extension to enabled=True (i.e. superceding disabling found in other config from files). @@ -560,7 +560,7 @@ def initialize_server(cls, argv=[], load_other_extensions=True, **kwargs): serverapp = ServerApp.instance(jpserver_extensions=jpserver_extensions, **kwargs) serverapp.aliases.update(cls.aliases) serverapp.initialize( - argv=argv, + argv=argv or [], starter_extension=cls.name, find_extensions=find_extensions, ) diff --git a/jupyter_server/extension/manager.py b/jupyter_server/extension/manager.py index 2f92e7856c..c0cc4ac390 100644 --- a/jupyter_server/extension/manager.py +++ b/jupyter_server/extension/manager.py @@ -39,7 +39,7 @@ def _valid_metadata(self, proposed): self._module_name = metadata["module"] except KeyError: raise ExtensionMetadataError( - "There is no 'module' key in the extension's " "metadata packet." + "There is no 'module' key in the extension's metadata packet." ) try: diff --git a/jupyter_server/extension/serverextension.py b/jupyter_server/extension/serverextension.py index bfc398a547..22b52bb670 100644 --- a/jupyter_server/extension/serverextension.py +++ b/jupyter_server/extension/serverextension.py @@ -337,7 +337,7 @@ def list_server_extensions(self): version = extension.version self.log.info(" {} {} {}".format(name, version, GREEN_OK)) except Exception as err: - self.log.warn(" {} {}".format(RED_X, err)) + self.log.warning(" {} {}".format(RED_X, err)) # Add a blank line between paths. self.log.info("") diff --git a/jupyter_server/extension/utils.py b/jupyter_server/extension/utils.py index afca32203c..a8c93a0580 100644 --- a/jupyter_server/extension/utils.py +++ b/jupyter_server/extension/utils.py @@ -26,9 +26,9 @@ def get_loader(obj, logger=None): underscore prefix. """ try: - func = getattr(obj, "_load_jupyter_server_extension") + func = getattr(obj, "_load_jupyter_server_extension") # noqa B009 except AttributeError: - func = getattr(obj, "load_jupyter_server_extension") + func = getattr(obj, "load_jupyter_server_extension", None) warnings.warn( "A `_load_jupyter_server_extension` function was not " "found in {name!s}. Instead, a `load_jupyter_server_extension` " diff --git a/jupyter_server/gateway/managers.py b/jupyter_server/gateway/managers.py index 9462229b41..2a9fe451fe 100644 --- a/jupyter_server/gateway/managers.py +++ b/jupyter_server/gateway/managers.py @@ -125,9 +125,11 @@ async def list_kernels(self, **kwargs): # Remove any of our kernels that may have been culled on the gateway server our_kernels = self._kernels.copy() culled_ids = [] - for kid, km in our_kernels.items(): + for kid, _ in our_kernels.items(): if kid not in kernel_models: - self.log.warn(f"Kernel {kid} no longer active - probably culled on Gateway server.") + self.log.warning( + f"Kernel {kid} no longer active - probably culled on Gateway server." + ) self._kernels.pop(kid, None) culled_ids.append(kid) # TODO: Figure out what do with these. return list(kernel_models.values()) @@ -606,7 +608,7 @@ async def start_channels(self, shell=True, iopub=True, stdin=True, hb=True, cont "channels", ) # Gather cert info in case where ssl is desired... - ssl_options = dict() + ssl_options = {} ssl_options["ca_certs"] = GatewayClient.instance().ca_certs ssl_options["certfile"] = GatewayClient.instance().client_cert ssl_options["keyfile"] = GatewayClient.instance().client_key diff --git a/jupyter_server/i18n/__init__.py b/jupyter_server/i18n/__init__.py index 2ffa7ad392..b292368fc3 100644 --- a/jupyter_server/i18n/__init__.py +++ b/jupyter_server/i18n/__init__.py @@ -52,7 +52,7 @@ def parse_accept_lang_header(accept_lang): by_q[qvalue].append(lang) res = [] - for qvalue, langs in sorted(by_q.items()): + for _, langs in sorted(by_q.items()): res.extend(sorted(langs)) return res diff --git a/jupyter_server/i18n/babel_nbui.cfg b/jupyter_server/i18n/babel_nbui.cfg index 271554a8aa..5f05ba0d7a 100644 --- a/jupyter_server/i18n/babel_nbui.cfg +++ b/jupyter_server/i18n/babel_nbui.cfg @@ -1,4 +1,4 @@ [jinja2: notebook/templates/**.html] encoding = utf-8 -[extractors] +[extractors] jinja2 = jinja2.ext:babel_extract diff --git a/jupyter_server/nbconvert/handlers.py b/jupyter_server/nbconvert/handlers.py index 8adbda2f6c..e7b1da8c2e 100644 --- a/jupyter_server/nbconvert/handlers.py +++ b/jupyter_server/nbconvert/handlers.py @@ -30,7 +30,7 @@ def find_resource_files(output_files_dir): files = [] - for dirpath, dirnames, filenames in os.walk(output_files_dir): + for dirpath, _, filenames in os.walk(output_files_dir): files.extend([os.path.join(dirpath, f) for f in filenames]) return files diff --git a/jupyter_server/serverapp.py b/jupyter_server/serverapp.py index 422f4ffb13..acab9a7869 100644 --- a/jupyter_server/serverapp.py +++ b/jupyter_server/serverapp.py @@ -132,7 +132,6 @@ url_path_join, check_pid, url_escape, - pathname2url, unix_socket_in_use, urlencode_unix_socket_path, fetch, @@ -198,7 +197,7 @@ def random_ports(port, n): """ for i in range(min(5, n)): yield port + i - for i in range(n - 5): + for _ in range(n - 5): yield max(1, port + random.randint(-2 * n, 2 * n)) @@ -292,11 +291,7 @@ def init_settings( ) sys_info = get_sys_info() - # If the user is running the server in a git directory, make the assumption - # that this is a dev install and suggest to the developer `npm run build:watch`. base_dir = os.path.realpath(os.path.join(__file__, "..", "..")) - dev_mode = os.path.exists(os.path.join(base_dir, ".git")) - nbui = gettext.translation( "nbui", localedir=os.path.join(base_dir, "jupyter_server/i18n"), @@ -423,7 +418,7 @@ def init_handlers(self, default_services, settings): # for each handler required for gateway, locate its pattern # in the current list and replace that entry... gateway_handlers = load_handlers("jupyter_server.gateway.handlers") - for i, gwh in enumerate(gateway_handlers): + for _, gwh in enumerate(gateway_handlers): for j, h in enumerate(handlers): if gwh[0] == h[0]: handlers[j] = (gwh[0], gwh[1]) @@ -517,7 +512,7 @@ def shutdown_server(server_info, timeout=5, log=None): if log: log.debug("POST request to %sapi/shutdown", url) - r = fetch(url, method="POST", headers={"Authorization": "token " + server_info["token"]}) + fetch(url, method="POST", headers={"Authorization": "token " + server_info["token"]}) # Poll to see if it shut down. for _ in range(timeout * 10): if not check_pid(pid): @@ -581,7 +576,7 @@ def _shutdown_or_exit(self, target_endpoint, server): def _maybe_remove_unix_socket(socket_path): try: os.unlink(socket_path) - except (OSError, IOError): + except OSError: pass def start(self): @@ -1293,7 +1288,7 @@ def _default_allow_remote(self): tornado_settings = Dict( config=True, help=_i18n( - "Supply overrides for the tornado.web.Application that the " "Jupyter server uses." + "Supply overrides for the tornado.web.Application that the Jupyter server uses." ), ) @@ -1948,7 +1943,6 @@ def init_webapp(self): ) if self.ssl_options.get("ca_certs", False): self.ssl_options.setdefault("cert_reqs", ssl.CERT_REQUIRED) - ssl_options = self.ssl_options self.login_handler_class.validate_security(self, ssl_options=self.ssl_options) @@ -2655,8 +2649,10 @@ def launch_browser(self): assembled_url, _ = self._prepare_browser_open() - b = lambda: browser.open(assembled_url, new=self.webbrowser_open_new) - threading.Thread(target=b).start() + def target(): + browser.open(assembled_url, new=self.webbrowser_open_new) + + threading.Thread(target=target).start() def start_app(self): super(ServerApp, self).start() diff --git a/jupyter_server/services/contents/fileio.py b/jupyter_server/services/contents/fileio.py index 41d86b5f51..4ef4f95811 100644 --- a/jupyter_server/services/contents/fileio.py +++ b/jupyter_server/services/contents/fileio.py @@ -113,7 +113,7 @@ def atomic_writing(path, text=True, encoding="utf-8", log=None, **kwargs): try: yield fileobj - except: + except BaseException: # Failed! Move the backup file back to the real path to avoid corruption fileobj.close() replace_file(tmp_path, path) @@ -161,7 +161,7 @@ def _simple_writing(path, text=True, encoding="utf-8", log=None, **kwargs): try: yield fileobj - except: + except BaseException: fileobj.close() raise @@ -219,7 +219,7 @@ def perm_to_403(self, os_path=""): """context manager for turning permission errors into 403.""" try: yield - except (OSError, IOError) as e: + except OSError as e: if e.errno in {errno.EPERM, errno.EACCES}: # make 403 error message without root prefix # this may not work perfectly on unicode paths on Python 2, diff --git a/jupyter_server/services/contents/filemanager.py b/jupyter_server/services/contents/filemanager.py index 33d8f80116..0a53e4e01b 100644 --- a/jupyter_server/services/contents/filemanager.py +++ b/jupyter_server/services/contents/filemanager.py @@ -500,7 +500,7 @@ def is_non_empty_dir(os_path): return else: self.log.warning( - "Skipping trash for %s, on different device " "to home directory", + "Skipping trash for %s, on different device to home directory", os_path, ) @@ -833,7 +833,7 @@ async def is_non_empty_dir(os_path): return else: self.log.warning( - "Skipping trash for %s, on different device " "to home directory", + "Skipping trash for %s, on different device to home directory", os_path, ) diff --git a/jupyter_server/services/contents/manager.py b/jupyter_server/services/contents/manager.py index 2c34daf0fe..cd4ce80fbf 100644 --- a/jupyter_server/services/contents/manager.py +++ b/jupyter_server/services/contents/manager.py @@ -505,7 +505,7 @@ def validate_notebook_model(self, model, validation_error=None): validate_nb(model["content"]) except ValidationError as e: model["message"] = "Notebook validation failed: {}:\n{}".format( - e.message, + str(e), json.dumps(e.instance, indent=1, default=lambda obj: ""), ) return model diff --git a/jupyter_server/services/kernels/handlers.py b/jupyter_server/services/kernels/handlers.py index 76b8ecaedd..80762d0dd4 100644 --- a/jupyter_server/services/kernels/handlers.py +++ b/jupyter_server/services/kernels/handlers.py @@ -177,7 +177,7 @@ def nudge(self): # before connections are opened, # plus it is *very* unlikely that a busy kernel will not finish # establishing its zmq subscriptions before processing the next request. - if getattr(kernel, "execution_state") == "busy": + if getattr(kernel, "execution_state", None) == "busy": self.log.debug("Nudge: not nudging busy kernel %s", self.kernel_id) f = Future() f.set_result(None) @@ -315,7 +315,7 @@ def _handle_kernel_info_reply(self, msg): idents, msg = self.session.feed_identities(msg) try: msg = self.session.deserialize(msg) - except: + except BaseException: self.log.error("Bad kernel_info reply", exc_info=True) self._kernel_info_future.set_result({}) return @@ -468,7 +468,7 @@ def replay(value): pass # WebSockets don't respond to traditional error codes so we # close the connection. - for channel, stream in self.channels.items(): + for _, stream in self.channels.items(): if not stream.closed(): stream.close() self.close() @@ -478,7 +478,7 @@ def replay(value): km.add_restart_callback(self.kernel_id, self.on_restart_failed, "dead") def subscribe(value): - for channel, stream in self.channels.items(): + for _, stream in self.channels.items(): stream.on_recv_stream(self._on_zmq_reply) connected.add_done_callback(subscribe) @@ -727,7 +727,7 @@ def on_close(self): # This method can be called twice, once by self.kernel_died and once # from the WebSocket close event. If the WebSocket connection is # closed before the ZMQ streams are setup, they could be None. - for channel, stream in self.channels.items(): + for _, stream in self.channels.items(): if stream is not None and not stream.closed(): stream.on_recv(None) stream.close() diff --git a/jupyter_server/services/kernels/kernelmanager.py b/jupyter_server/services/kernels/kernelmanager.py index 7cd890a522..65582844cb 100644 --- a/jupyter_server/services/kernels/kernelmanager.py +++ b/jupyter_server/services/kernels/kernelmanager.py @@ -303,7 +303,7 @@ def start_buffering(self, kernel_id, session_key, channels): """ if not self.buffer_offline_messages: - for channel, stream in channels.items(): + for _, stream in channels.items(): stream.close() return @@ -545,7 +545,7 @@ def initialize_culler(self): """ if not self._initialized_culler and self.cull_idle_timeout > 0: if self._culler_callback is None: - loop = IOLoop.current() + _ = IOLoop.current() if self.cull_interval <= 0: # handle case where user set invalid value self.log.warning( "Invalid value for 'cull_interval' detected (%s) - using default value (%s).", @@ -589,7 +589,7 @@ async def cull_kernels(self): async def cull_kernel_if_idle(self, kernel_id): kernel = self._kernels[kernel_id] - if getattr(kernel, "execution_state") == "dead": + if getattr(kernel, "execution_state", None) == "dead": self.log.warning( "Culling '%s' dead kernel '%s' (%s).", kernel.execution_state, diff --git a/jupyter_server/services/sessions/sessionmanager.py b/jupyter_server/services/sessions/sessionmanager.py index 6a2a4547a1..5cfe9186bc 100644 --- a/jupyter_server/services/sessions/sessionmanager.py +++ b/jupyter_server/services/sessions/sessionmanager.py @@ -275,7 +275,7 @@ async def row_to_model(self, row, tolerate_culled=False): ) ) if tolerate_culled: - self.log.warning(msg + " Continuing...") + self.log.warning(f"{msg} Continuing...") return raise KeyError(msg) diff --git a/jupyter_server/terminal/terminalmanager.py b/jupyter_server/terminal/terminalmanager.py index 1db545e4a4..7806173731 100644 --- a/jupyter_server/terminal/terminalmanager.py +++ b/jupyter_server/terminal/terminalmanager.py @@ -110,7 +110,7 @@ def _initialize_culler(self): """ if not self._initialized_culler and self.cull_inactive_timeout > 0: if self._culler_callback is None: - loop = IOLoop.current() + _ = IOLoop.current() if self.cull_interval <= 0: # handle case where user set invalid value self.log.warning( "Invalid value for 'cull_interval' detected (%s) - using default value (%s).", diff --git a/jupyter_server/traittypes.py b/jupyter_server/traittypes.py index 5c6ede5c3f..0f835b4a45 100644 --- a/jupyter_server/traittypes.py +++ b/jupyter_server/traittypes.py @@ -85,7 +85,7 @@ def info(self): klass = klass.__module__ + "." + klass.__name__ result += f"{klass} or " # Strip the last "or" - result = result.strip(" or ") + result = result.strip(" or ") # noqa B005 if self.allow_none: return result + " or None" return result @@ -103,7 +103,7 @@ def _resolve_classes(self): try: klass = self._resolve_string(klass) self.importable_klasses.append(klass) - except: + except Exception: pass else: self.importable_klasses.append(klass) @@ -189,7 +189,7 @@ def info(self): else: result += describe("a", klass) result += " or " - result = result.strip(" or ") + result = result.strip(" or ") # noqa B005 if self.allow_none: result += " or None" return result @@ -207,7 +207,7 @@ def _resolve_classes(self): try: klass = self._resolve_string(klass) self.importable_klasses.append(klass) - except: + except Exception: pass else: self.importable_klasses.append(klass) diff --git a/jupyter_server/utils.py b/jupyter_server/utils.py index aa23aa2c70..dfbe8e37fc 100644 --- a/jupyter_server/utils.py +++ b/jupyter_server/utils.py @@ -217,6 +217,7 @@ def run_sync(maybe_async): # that was not something async, just return it return maybe_async # it is async, we need to run it in an event loop + def wrapped(): create_new_event_loop = False try: diff --git a/setup.cfg b/setup.cfg index 94ae0aefc2..08774d3fb1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -70,10 +70,19 @@ exclude = tests.* [flake8] -ignore = E, C, W, F403, F811, F841, E402, I100, I101, D400 +ignore = E501, W503, E402 builtins = c, get_config exclude = .cache, .github, docs, setup.py +enable-extensions = G +extend-ignore = + G001, G002, G004, G200, G201, G202, + # black adds spaces around ':' + E203, +per-file-ignores = + # B011: Do not call assert False since python -O removes these calls + # F841 local variable 'foo' is assigned to but never used + tests/*: B011, F841 diff --git a/tests/auth/test_authorizer.py b/tests/auth/test_authorizer.py index a0453200e0..5e36976888 100644 --- a/tests/auth/test_authorizer.py +++ b/tests/auth/test_authorizer.py @@ -211,7 +211,7 @@ async def test_authorized_requests( body, allowed, ): - ### Setup stuff for the Contents API + # Setup stuff for the Contents API # Add a notebook on disk contents_dir = tmp_path / jp_serverapp.root_dir p = contents_dir / "dir_for_testing" @@ -222,7 +222,7 @@ async def test_authorized_requests( nbname = p.joinpath("nb_for_testing.ipynb") nbname.write_text(nb, encoding="utf-8") - ### Setup + # Setup nbpath = "dir_for_testing/nb_for_testing.ipynb" kernelspec = NATIVE_KERNEL_NAME km = jp_serverapp.kernel_manager diff --git a/tests/auth/test_security.py b/tests/auth/test_security.py index 1a3f172a2d..0f8a385dc8 100644 --- a/tests/auth/test_security.py +++ b/tests/auth/test_security.py @@ -25,7 +25,5 @@ def test_passwd_check_unicode(): # GH issue #4524 phash = "sha1:23862bc21dd3:7a415a95ae4580582e314072143d9c382c491e4f" assert passwd_check(phash, "łe¶ŧ←↓→") - phash = ( - "argon2:$argon2id$v=19$m=10240,t=10,p=8$" "qjjDiZUofUVVnrVYxacnbA$l5pQq1bJ8zglGT2uXP6iOg" - ) + phash = "argon2:$argon2id$v=19$m=10240,t=10,p=8$qjjDiZUofUVVnrVYxacnbA$l5pQq1bJ8zglGT2uXP6iOg" assert passwd_check(phash, "łe¶ŧ←↓→") diff --git a/tests/extension/mockextensions/app.py b/tests/extension/mockextensions/app.py index 3e86f4fc36..4c50a6e9c9 100644 --- a/tests/extension/mockextensions/app.py +++ b/tests/extension/mockextensions/app.py @@ -13,6 +13,8 @@ # Function that makes these extensions discoverable # by the test functions. + + def _jupyter_server_extension_points(): return [{"module": __name__, "app": MockExtensionApp}] diff --git a/tests/extension/mockextensions/mock1.py b/tests/extension/mockextensions/mock1.py index 9d2a3cce69..92e7637d63 100644 --- a/tests/extension/mockextensions/mock1.py +++ b/tests/extension/mockextensions/mock1.py @@ -1,6 +1,8 @@ """A mock extension named `mock1` for testing purposes. """ # by the test functions. + + def _jupyter_server_extension_paths(): return [{"module": "tests.extension.mockextensions.mock1"}] diff --git a/tests/extension/mockextensions/mock2.py b/tests/extension/mockextensions/mock2.py index 97cce4c776..9f3b7449f4 100644 --- a/tests/extension/mockextensions/mock2.py +++ b/tests/extension/mockextensions/mock2.py @@ -1,6 +1,8 @@ """A mock extension named `mock2` for testing purposes. """ # by the test functions. + + def _jupyter_server_extension_paths(): return [{"module": "tests.extension.mockextensions.mock2"}] diff --git a/tests/extension/mockextensions/mockext_both.py b/tests/extension/mockextensions/mockext_both.py index 7df390f7cf..5e24c7c6ff 100644 --- a/tests/extension/mockextensions/mockext_both.py +++ b/tests/extension/mockextensions/mockext_both.py @@ -2,6 +2,8 @@ """ # Function that makes these extensions discoverable # by the test functions. + + def _jupyter_server_extension_paths(): return [{"module": "tests.extension.mockextensions.mockext_both"}] diff --git a/tests/extension/mockextensions/mockext_py.py b/tests/extension/mockextensions/mockext_py.py index bef4b6be52..f5b467b1fa 100644 --- a/tests/extension/mockextensions/mockext_py.py +++ b/tests/extension/mockextensions/mockext_py.py @@ -2,6 +2,8 @@ """ # Function that makes these extensions discoverable # by the test functions. + + def _jupyter_server_extension_paths(): return [{"module": "tests.extension.mockextensions.mockext_py"}] diff --git a/tests/extension/mockextensions/mockext_sys.py b/tests/extension/mockextensions/mockext_sys.py index f06aa4e973..dfaf4e3546 100644 --- a/tests/extension/mockextensions/mockext_sys.py +++ b/tests/extension/mockextensions/mockext_sys.py @@ -2,6 +2,8 @@ """ # Function that makes these extensions discoverable # by the test functions. + + def _jupyter_server_extension_paths(): return [{"module": "tests.extension.mockextensions.mockext_sys"}] diff --git a/tests/extension/mockextensions/mockext_user.py b/tests/extension/mockextensions/mockext_user.py index c9ba107cb5..d925ad29b3 100644 --- a/tests/extension/mockextensions/mockext_user.py +++ b/tests/extension/mockextensions/mockext_user.py @@ -2,6 +2,8 @@ """ # Function that makes these extensions discoverable # by the test functions. + + def _jupyter_server_extension_paths(): return [{"module": "tests.extension.mockextensions.mockext_user"}] diff --git a/tests/extension/test_launch.py b/tests/extension/test_launch.py index c0969356fe..5cefcdbffb 100644 --- a/tests/extension/test_launch.py +++ b/tests/extension/test_launch.py @@ -45,7 +45,9 @@ def wait_up(url, interval=0.1, check=None): @pytest.fixture def launch_instance(request, port, token): - def _run_in_subprocess(argv=[], add_token=True): + def _run_in_subprocess(argv=None, add_token=True): + argv = argv or [] + def _kill_extension_app(): try: process.terminate() diff --git a/tests/services/contents/test_manager.py b/tests/services/contents/test_manager.py index 6ed6ac7b3c..04608dc6e1 100644 --- a/tests/services/contents/test_manager.py +++ b/tests/services/contents/test_manager.py @@ -442,7 +442,7 @@ async def test_get(jp_contents_manager): elif entry["path"] == file_model_no_content["path"]: assert entry == file_model_no_content else: - assert False, "Unexpected directory entry: %s" % entry() + raise AssertionError("Unexpected directory entry: %s" % entry()) with pytest.raises(HTTPError): await ensure_async(cm.get("foo", type="file")) @@ -579,7 +579,7 @@ async def test_delete_non_empty_folder(delete_to_trash, always_delete, error, jp await ensure_async(cm.delete_file(dir)) else: await ensure_async(cm.delete_file(dir)) - assert await ensure_async(cm.dir_exists(dir)) == False + assert await ensure_async(cm.dir_exists(dir)) is False async def test_rename(jp_contents_manager): diff --git a/tests/services/kernels/test_api.py b/tests/services/kernels/test_api.py index d0fed006db..6630e2059c 100644 --- a/tests/services/kernels/test_api.py +++ b/tests/services/kernels/test_api.py @@ -21,7 +21,7 @@ async def _(kernel_id): km = jp_serverapp.kernel_manager if getattr(km, "use_pending_kernels", False): kernel = km.get_kernel(kernel_id) - if getattr(kernel, "ready"): + if getattr(kernel, "ready", None): await kernel.ready return _ @@ -263,7 +263,7 @@ async def test_connection( # Close websocket ws.close() # give it some time to close on the other side: - for i in range(10): + for _ in range(10): r = await jp_fetch("api", "kernels", kid, method="GET") model = json.loads(r.body.decode()) if model["connections"] > 0: diff --git a/tests/services/nbconvert/test_api.py b/tests/services/nbconvert/test_api.py index ae028dd2db..5a6fca5186 100644 --- a/tests/services/nbconvert/test_api.py +++ b/tests/services/nbconvert/test_api.py @@ -9,6 +9,6 @@ async def test_list_formats(jp_fetch): # Verify that all returned formats have an # output mimetype defined. required_keys_present = [] - for name, data in formats.items(): + for _, data in formats.items(): required_keys_present.append("output_mimetype" in data) assert all(required_keys_present), "All returned formats must have a `output_mimetype` key." diff --git a/tests/services/sessions/test_api.py b/tests/services/sessions/test_api.py index 1711a50b28..2fe9f7b7a1 100644 --- a/tests/services/sessions/test_api.py +++ b/tests/services/sessions/test_api.py @@ -20,7 +20,8 @@ TEST_TIMEOUT = 60 -j = lambda r: json.loads(r.body.decode()) +def j(r): + return json.loads(r.body.decode()) class NewPortsKernelManager(AsyncIOLoopKernelManager): @@ -160,7 +161,7 @@ async def _(session_id): session = await sm.get_session(session_id=session_id) kernel_id = session["kernel"]["id"] kernel = mkm.get_kernel(kernel_id) - if getattr(kernel, "ready"): + if getattr(kernel, "ready", None): await kernel.ready return _ @@ -577,7 +578,7 @@ async def test_restart_kernel( # Close/open websocket ws.close() # give it some time to close on the other side: - for i in range(10): + for _ in range(10): r = await jp_fetch("api", "kernels", kid, method="GET") model = json.loads(r.body.decode()) if model["connections"] > 0: diff --git a/tests/test_gateway.py b/tests/test_gateway.py index ec279f300e..f935d61e0c 100644 --- a/tests/test_gateway.py +++ b/tests/test_gateway.py @@ -44,7 +44,7 @@ def generate_kernelspec(name): # maintain a dictionary of expected running kernels. Key = kernel_id, Value = model. -running_kernels = dict() +running_kernels = {} def generate_model(name): diff --git a/tests/test_terminal.py b/tests/test_terminal.py index b9754e1784..a12ad2ef52 100644 --- a/tests/test_terminal.py +++ b/tests/test_terminal.py @@ -159,7 +159,7 @@ async def test_culling(jp_server_config, jp_fetch, jp_cleanup_subprocesses): last_activity = term["last_activity"] culled = False - for i in range(CULL_TIMEOUT + CULL_INTERVAL): + for _ in range(CULL_TIMEOUT + CULL_INTERVAL): try: resp = await jp_fetch( "api", diff --git a/tests/unix_sockets/test_api.py b/tests/unix_sockets/test_api.py index 1653a90749..ac5abb9706 100644 --- a/tests/unix_sockets/test_api.py +++ b/tests/unix_sockets/test_api.py @@ -40,13 +40,13 @@ def http_server_port(jp_unix_socket_file, jp_process_id): def jp_unix_socket_fetch(jp_unix_socket_file, jp_auth_header, jp_base_url, http_server, io_loop): """A fetch fixture for Jupyter Server tests that use the unix_serverapp fixture""" - async def client(*parts, headers={}, params={}, **kwargs): + async def client(*parts, headers=None, params=None, **kwargs): # Handle URL strings host_url = urlencode_unix_socket(jp_unix_socket_file) path_url = url_path_join(jp_base_url, *parts) - params_url = urllib.parse.urlencode(params) + params_url = urllib.parse.urlencode(params or {}) url = url_path_join(host_url, path_url + "?" + params_url) - r = await async_fetch(url, headers=headers, io_loop=io_loop, **kwargs) + r = await async_fetch(url, headers=headers or {}, io_loop=io_loop, **kwargs) return r return client @@ -59,7 +59,7 @@ async def test_get_spec(jp_unix_socket_fetch): # Make request and verify it succeeds.' response = await jp_unix_socket_fetch(*parts) assert response.code == 200 - assert response.body != None + assert response.body is not None async def test_list_running_servers(jp_unix_socket_file, http_server):