diff --git a/.github/workflows/downstream.yml b/.github/workflows/downstream.yml index 1cd5c5a069..a92d24f2bb 100644 --- a/.github/workflows/downstream.yml +++ b/.github/workflows/downstream.yml @@ -2,9 +2,7 @@ name: Test downstream projects on: push: - branches: "*" pull_request: - branches: "*" jobs: tests: diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index ad780b71a1..3ce3622289 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -1,16 +1,16 @@ name: Jupyter Server Integration Tests [Linux] on: push: - branches: "main" + branches: ["main"] pull_request: - branches: "*" + branches: ["*"] jobs: build: - runs-on: ${{ matrix.os }}-latest + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - os: [ubuntu] + os: [ubuntu-latest] python-version: ["3.7", "3.8", "3.9", "3.10", "pypy-3.7"] steps: - name: Checkout diff --git a/.github/workflows/python-linux.yml b/.github/workflows/python-linux.yml index 2b01149006..8a6bfb4cfc 100644 --- a/.github/workflows/python-linux.yml +++ b/.github/workflows/python-linux.yml @@ -1,9 +1,9 @@ name: Jupyter Server Tests [Linux] on: push: - branches: "main" + branches: ["main"] pull_request: - branches: "*" + branches: ["*"] jobs: # Run "pre-commit run --all-files" pre-commit: @@ -30,11 +30,11 @@ jobs: echo " pre-commit run --all-files" build: - runs-on: ${{ matrix.os }}-latest + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - os: [ubuntu] + os: [ubuntu-latest] python-version: ["3.7", "3.8", "3.9", "3.10", "pypy-3.7"] steps: - name: Checkout diff --git a/.github/workflows/python-macos.yml b/.github/workflows/python-macos.yml index 78ab08f491..595c586d79 100644 --- a/.github/workflows/python-macos.yml +++ b/.github/workflows/python-macos.yml @@ -1,16 +1,16 @@ name: Jupyter Server Tests [Mac OS] on: push: - branches: "main" + branches: ["main"] pull_request: - branches: "*" + branches: ["*"] jobs: build: - runs-on: ${{ matrix.os }}-latest + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - os: [macos] + os: [macos-latest] python-version: ["3.7", "3.8", "3.9", "3.10", "pypy-3.7"] steps: - name: Checkout diff --git a/.github/workflows/python-windows.yml b/.github/workflows/python-windows.yml index 5d41cc3b6d..31123e92d2 100644 --- a/.github/workflows/python-windows.yml +++ b/.github/workflows/python-windows.yml @@ -1,16 +1,16 @@ name: Jupyter Server Tests [Windows] on: push: - branches: "main" + branches: ["main"] pull_request: - branches: "*" + branches: ["*"] jobs: build: - runs-on: ${{ matrix.os }}-latest + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - os: [windows] + os: [windows-latest] python-version: ["3.7", "3.8", "3.9", "3.10"] steps: - name: Checkout diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1df95b667b..b221b5ba6d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,29 +1,49 @@ repos: - repo: https://github.com/asottile/reorder_python_imports - rev: v1.9.0 + rev: v2.7.1 hooks: - id: reorder-python-imports + - repo: https://github.com/psf/black - rev: 20.8b1 + rev: 22.1.0 hooks: - id: black args: ["--line-length", "100"] + - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.2.1 + rev: v2.5.1 hooks: - id: prettier + - repo: https://gitlab.com/pycqa/flake8 - rev: "3.8.4" + rev: 4.0.1 hooks: - id: flake8 + - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.4.0 + rev: v4.1.0 hooks: - id: end-of-file-fixer - id: check-case-conflict - id: check-executables-have-shebangs - id: requirements-txt-fixer + - id: check-added-large-files + - id: check-case-conflict + - id: check-toml + - id: check-yaml + - id: debug-statements + - id: forbid-new-submodules + - repo: https://github.com/pre-commit/mirrors-eslint - rev: v7.32.0 + rev: v8.8.0 hooks: - id: eslint + + - repo: https://github.com/sirosen/check-jsonschema + rev: 0.10.2 + hooks: + - id: check-jsonschema + name: "Check GitHub Workflows" + files: ^\.github/workflows/ + types: [yaml] + args: ["--schemafile", "https://json.schemastore.org/github-workflow"] diff --git a/examples/simple/simple_ext1/handlers.py b/examples/simple/simple_ext1/handlers.py index b63d84811a..1f412e8500 100644 --- a/examples/simple/simple_ext1/handlers.py +++ b/examples/simple/simple_ext1/handlers.py @@ -42,7 +42,7 @@ def get(self): class TemplateHandler(BaseTemplateHandler): def get(self, path): - """ Optionaly, you can print(self.get_template('simple1.html'))""" + """Optionaly, you can print(self.get_template('simple1.html'))""" self.write(self.render_template("simple1.html", path=path)) diff --git a/examples/simple/simple_ext1/static/bundle.js b/examples/simple/simple_ext1/static/bundle.js index 9590862ded..9017d3883d 100644 --- a/examples/simple/simple_ext1/static/bundle.js +++ b/examples/simple/simple_ext1/static/bundle.js @@ -57,37 +57,35 @@ /******/ }; // create a fake namespace object // mode & 1: value is a module id, require it // mode & 2: merge all properties of value into the ns // mode & 4: return value when already ns object // mode & 8|1: behave like require /******/ - /******/ /******/ /******/ /******/ /******/ /******/ __webpack_require__.t = function ( - value, - mode - ) { - /******/ if (mode & 1) value = __webpack_require__(value); - /******/ if (mode & 8) return value; - /******/ if ( - mode & 4 && - typeof value === "object" && - value && - value.__esModule - ) - return value; - /******/ var ns = Object.create(null); - /******/ __webpack_require__.r(ns); - /******/ Object.defineProperty(ns, "default", { - enumerable: true, - value: value, - }); - /******/ if (mode & 2 && typeof value != "string") - for (var key in value) - __webpack_require__.d( - ns, - key, - function (key) { - return value[key]; - }.bind(null, key) - ); - /******/ return ns; - /******/ - }; // getDefaultExport function for compatibility with non-harmony modules + /******/ /******/ /******/ /******/ /******/ /******/ __webpack_require__.t = + function (value, mode) { + /******/ if (mode & 1) value = __webpack_require__(value); + /******/ if (mode & 8) return value; + /******/ if ( + mode & 4 && + typeof value === "object" && + value && + value.__esModule + ) + return value; + /******/ var ns = Object.create(null); + /******/ __webpack_require__.r(ns); + /******/ Object.defineProperty(ns, "default", { + enumerable: true, + value: value, + }); + /******/ if (mode & 2 && typeof value != "string") + for (var key in value) + __webpack_require__.d( + ns, + key, + function (key) { + return value[key]; + }.bind(null, key) + ); + /******/ return ns; + /******/ + }; // getDefaultExport function for compatibility with non-harmony modules /******/ /******/ /******/ __webpack_require__.n = function (module) { /******/ var getter = diff --git a/jupyter_server/_sysinfo.py b/jupyter_server/_sysinfo.py index 1f1cbf2251..6dbc9f788c 100644 --- a/jupyter_server/_sysinfo.py +++ b/jupyter_server/_sysinfo.py @@ -56,10 +56,10 @@ def pkg_commit_hash(pkg_path): if repo_commit: return "repository", repo_commit.strip().decode("ascii") else: - return u"", u"" + return "", "" par_path = p.dirname(par_path) - return u"", u"" + return "", "" def pkg_info(pkg_path): diff --git a/jupyter_server/auth/login.py b/jupyter_server/auth/login.py index 84bd22a86b..fb245f7854 100644 --- a/jupyter_server/auth/login.py +++ b/jupyter_server/auth/login.py @@ -75,8 +75,8 @@ def passwd_check(self, a, b): return passwd_check(a, b) def post(self): - typed_password = self.get_argument("password", default=u"") - new_password = self.get_argument("new_password", default=u"") + typed_password = self.get_argument("password", default="") + new_password = self.get_argument("new_password", default="") if self.get_login_available(self.settings): if self.passwd_check(self.hashed_password, typed_password) and not new_password: @@ -248,7 +248,7 @@ def password_from_settings(cls, settings): If there is no configured password, an empty string will be returned. """ - return settings.get("password", u"") + return settings.get("password", "") @classmethod def get_login_available(cls, settings): diff --git a/jupyter_server/base/handlers.py b/jupyter_server/base/handlers.py index 7de52f4e04..0361b12d3a 100644 --- a/jupyter_server/base/handlers.py +++ b/jupyter_server/base/handlers.py @@ -553,13 +553,13 @@ def get_json_body(self): if not self.request.body: return None # Do we need to call body.decode('utf-8') here? - body = self.request.body.strip().decode(u"utf-8") + body = self.request.body.strip().decode("utf-8") try: model = json.loads(body) except Exception as e: self.log.debug("Bad JSON: %r", body) self.log.error("Couldn't parse JSON", exc_info=True) - raise web.HTTPError(400, u"Invalid JSON in body of request") from e + raise web.HTTPError(400, "Invalid JSON in body of request") from e return model def write_error(self, status_code, **kwargs): diff --git a/jupyter_server/extension/application.py b/jupyter_server/extension/application.py index ac990b8d22..ea18d687d4 100644 --- a/jupyter_server/extension/application.py +++ b/jupyter_server/extension/application.py @@ -211,7 +211,9 @@ def _default_log_level(self): @default("log_format") def _default_log_format(self): """override default log format to include date & time""" - return u"%(color)s[%(levelname)1.1s %(asctime)s.%(msecs).03d %(name)s]%(end_color)s %(message)s" + return ( + "%(color)s[%(levelname)1.1s %(asctime)s.%(msecs).03d %(name)s]%(end_color)s %(message)s" + ) static_url_prefix = Unicode( help="""Url where the static assets for the extension are served.""" diff --git a/jupyter_server/extension/serverextension.py b/jupyter_server/extension/serverextension.py index 202d75e127..bfc398a547 100644 --- a/jupyter_server/extension/serverextension.py +++ b/jupyter_server/extension/serverextension.py @@ -329,7 +329,7 @@ def list_server_extensions(self): for name, extension in ext_manager.extensions.items(): enabled = extension.enabled # Attempt to get extension metadata - self.log.info(u" {} {}".format(name, GREEN_ENABLED if enabled else RED_DISABLED)) + self.log.info(" {} {}".format(name, GREEN_ENABLED if enabled else RED_DISABLED)) try: self.log.info(" - Validating {}...".format(name)) if not extension.validate(): diff --git a/jupyter_server/gateway/gateway_client.py b/jupyter_server/gateway/gateway_client.py index ec7b52f8d8..4efbd2e18f 100644 --- a/jupyter_server/gateway/gateway_client.py +++ b/jupyter_server/gateway/gateway_client.py @@ -400,7 +400,7 @@ def load_connection_args(self, **kwargs): async def gateway_request(endpoint, **kwargs): - """Make an async request to kernel gateway endpoint, returns a response """ + """Make an async request to kernel gateway endpoint, returns a response""" client = AsyncHTTPClient() kwargs = GatewayClient.instance().load_connection_args(**kwargs) try: diff --git a/jupyter_server/gateway/handlers.py b/jupyter_server/gateway/handlers.py index 274d5a7084..3e86cbec32 100644 --- a/jupyter_server/gateway/handlers.py +++ b/jupyter_server/gateway/handlers.py @@ -81,7 +81,7 @@ def send_ping(self): self.ping(b"") def open(self, kernel_id, *args, **kwargs): - """Handle web socket connection open to notebook server and delegate to gateway web socket handler """ + """Handle web socket connection open to notebook server and delegate to gateway web socket handler""" self.ping_callback = PeriodicCallback(self.send_ping, GATEWAY_WS_PING_INTERVAL_SECS * 1000) self.ping_callback.start() @@ -221,7 +221,7 @@ async def _read_messages(self, callback): jitter = random.randint(10, 100) * 0.01 retry_interval = ( min( - GatewayClient.instance().gateway_retry_interval * (2 ** self.retry), + GatewayClient.instance().gateway_retry_interval * (2**self.retry), GatewayClient.instance().gateway_retry_interval_max, ) + jitter diff --git a/jupyter_server/gateway/managers.py b/jupyter_server/gateway/managers.py index 6b50ecdb46..9462229b41 100644 --- a/jupyter_server/gateway/managers.py +++ b/jupyter_server/gateway/managers.py @@ -54,7 +54,7 @@ def __init__(self, **kwargs): ) def remove_kernel(self, kernel_id): - """Complete override since we want to be more tolerant of missing keys """ + """Complete override since we want to be more tolerant of missing keys""" try: return self._kernels.pop(kernel_id) except KeyError: @@ -178,7 +178,7 @@ async def shutdown_all(self, now=False): self.remove_kernel(kernel_id) async def cull_kernels(self): - """Override cull_kernels so we can be sure their state is current. """ + """Override cull_kernels so we can be sure their state is current.""" await self.list_kernels() await super().cull_kernels() @@ -301,7 +301,7 @@ class GatewaySessionManager(SessionManager): kernel_manager = Instance("jupyter_server.gateway.managers.GatewayMappingKernelManager") async def kernel_culled(self, kernel_id): - """Checks if the kernel is still considered alive and returns true if its not found. """ + """Checks if the kernel is still considered alive and returns true if its not found.""" kernel = None try: km = self.kernel_manager.get_kernel(kernel_id) @@ -315,7 +315,7 @@ async def kernel_culled(self, kernel_id): class GatewayKernelManager(AsyncKernelManager): - """Manages a single kernel remotely via a Gateway Server. """ + """Manages a single kernel remotely via a Gateway Server.""" kernel_id = None kernel = None @@ -451,7 +451,7 @@ async def start_kernel(self, **kwargs): self.kernel_url = url_path_join(self.kernels_url, url_escape(str(self.kernel_id))) async def shutdown_kernel(self, now=False, restart=False): - """Attempts to stop the kernel process cleanly via HTTP. """ + """Attempts to stop the kernel process cleanly via HTTP.""" if self.has_kernel: self.log.debug("Request shutdown kernel at: %s", self.kernel_url) @@ -459,7 +459,7 @@ async def shutdown_kernel(self, now=False, restart=False): self.log.debug("Shutdown kernel response: %d %s", response.code, response.reason) async def restart_kernel(self, **kw): - """Restarts a kernel via HTTP. """ + """Restarts a kernel via HTTP.""" if self.has_kernel: kernel_url = self.kernel_url + "/restart" self.log.debug("Request restart kernel at: %s", kernel_url) @@ -467,7 +467,7 @@ async def restart_kernel(self, **kw): self.log.debug("Restart kernel response: %d %s", response.code, response.reason) async def interrupt_kernel(self): - """Interrupts the kernel via an HTTP request. """ + """Interrupts the kernel via an HTTP request.""" if self.has_kernel: kernel_url = self.kernel_url + "/interrupt" self.log.debug("Request interrupt kernel at: %s", kernel_url) diff --git a/jupyter_server/kernelspecs/handlers.py b/jupyter_server/kernelspecs/handlers.py index f78a57181c..437670d90a 100644 --- a/jupyter_server/kernelspecs/handlers.py +++ b/jupyter_server/kernelspecs/handlers.py @@ -22,7 +22,7 @@ def get(self, kernel_name, path, include_body=True): try: self.root = ksm.get_kernel_spec(kernel_name).resource_dir except KeyError as e: - raise web.HTTPError(404, u"Kernel spec %s not found" % kernel_name) from e + raise web.HTTPError(404, "Kernel spec %s not found" % kernel_name) from e self.log.debug("Serving kernel resource from: %s", self.root) return web.StaticFileHandler.get(self, path, include_body=include_body) diff --git a/jupyter_server/nbconvert/handlers.py b/jupyter_server/nbconvert/handlers.py index e4ba4bb851..84efaabc03 100644 --- a/jupyter_server/nbconvert/handlers.py +++ b/jupyter_server/nbconvert/handlers.py @@ -71,7 +71,7 @@ def get_exporter(format, **kwargs): Exporter = get_exporter(format) except KeyError as e: # should this be 400? - raise web.HTTPError(404, u"No exporter for format: %s" % format) from e + raise web.HTTPError(404, "No exporter for format: %s" % format) from e try: return Exporter(**kwargs) diff --git a/jupyter_server/pytest_plugin.py b/jupyter_server/pytest_plugin.py index acf93b25b4..45f3f73f26 100644 --- a/jupyter_server/pytest_plugin.py +++ b/jupyter_server/pytest_plugin.py @@ -109,7 +109,7 @@ def jp_environ( jp_env_jupyter_path, jp_env_config_path, ): - """Configures a temporary environment based on Jupyter-specific environment variables. """ + """Configures a temporary environment based on Jupyter-specific environment variables.""" monkeypatch.setenv("HOME", str(jp_home_dir)) monkeypatch.setenv("PYTHONPATH", os.pathsep.join(sys.path)) # monkeypatch.setenv("JUPYTER_NO_CONFIG", "1") @@ -127,7 +127,7 @@ def jp_environ( @pytest.fixture def jp_server_config(): - """Allows tests to setup their specific configuration values. """ + """Allows tests to setup their specific configuration values.""" return {} @@ -145,7 +145,7 @@ def jp_template_dir(tmp_path): @pytest.fixture def jp_argv(): - """Allows tests to setup specific argv values. """ + """Allows tests to setup specific argv values.""" return [] @@ -157,7 +157,7 @@ def jp_extension_environ(jp_env_config_path, monkeypatch): @pytest.fixture def jp_http_port(http_server_port): - """Returns the port value from the http_server_port fixture. """ + """Returns the port value from the http_server_port fixture.""" return http_server_port[-1] @@ -406,7 +406,7 @@ def client_fetch(*parts, headers=None, params=None, **kwargs): return client_fetch -some_resource = u"The very model of a modern major general" +some_resource = "The very model of a modern major general" sample_kernel_json = { "argv": ["cat", "{connection_file}"], "display_name": "Test kernel", diff --git a/jupyter_server/serverapp.py b/jupyter_server/serverapp.py index 0630037dbe..028344f7d9 100644 --- a/jupyter_server/serverapp.py +++ b/jupyter_server/serverapp.py @@ -559,7 +559,7 @@ class JupyterServerStopApp(JupyterApp): help="Port of the server to be killed. Default %s" % DEFAULT_JUPYTER_SERVER_PORT, ) - sock = Unicode(u"", config=True, help="UNIX socket of the server to be killed.") + sock = Unicode("", config=True, help="UNIX socket of the server to be killed.") def parse_command_line(self, argv=None): super(JupyterServerStopApp, self).parse_command_line(argv) @@ -795,7 +795,9 @@ def _default_log_level(self): @default("log_format") def _default_log_format(self): """override default log format to include date & time""" - return u"%(color)s[%(levelname)1.1s %(asctime)s.%(msecs).03d %(name)s]%(end_color)s %(message)s" + return ( + "%(color)s[%(levelname)1.1s %(asctime)s.%(msecs).03d %(name)s]%(end_color)s %(message)s" + ) # file to be opened in the Jupyter server file_to_run = Unicode("", help="Open the named file when the application is launched.").tag( @@ -880,12 +882,12 @@ def _default_ip(self): @validate("ip") def _validate_ip(self, proposal): value = proposal["value"] - if value == u"*": - value = u"" + if value == "*": + value = "" return value custom_display_url = Unicode( - u"", + "", config=True, help=_i18n( """Override URL shown to users. @@ -928,7 +930,7 @@ def port_default(self): def port_retries_default(self): return int(os.getenv(self.port_retries_env, self.port_retries_default_value)) - sock = Unicode(u"", config=True, help="The UNIX socket the Jupyter server will listen on.") + sock = Unicode("", config=True, help="The UNIX socket the Jupyter server will listen on.") sock_mode = Unicode( "0600", @@ -947,7 +949,7 @@ def _validate_sock_mode(self, proposal): bool(converted_value & stat.S_IRUSR), bool(converted_value & stat.S_IWUSR), # And isn't out of bounds. - converted_value <= 2 ** 12, + converted_value <= 2**12, ) ) except ValueError: @@ -959,19 +961,19 @@ def _validate_sock_mode(self, proposal): return value certfile = Unicode( - u"", + "", config=True, help=_i18n("""The full path to an SSL/TLS certificate file."""), ) keyfile = Unicode( - u"", + "", config=True, help=_i18n("""The full path to a private key file for usage with SSL/TLS."""), ) client_ca = Unicode( - u"", + "", config=True, help=_i18n( """The full path to a certificate authority certificate for SSL/TLS client authentication.""" @@ -1053,7 +1055,7 @@ def _token_default(self): if self.password: # no token if password is enabled self._token_generated = False - return u"" + return "" else: self._token_generated = True return binascii.hexlify(os.urandom(24)).decode("ascii") @@ -1116,7 +1118,7 @@ def _token_changed(self, change): self._token_generated = False password = Unicode( - u"", + "", config=True, help="""Hashed password to use for web authentication. @@ -1261,7 +1263,7 @@ def _default_allow_remote(self): ) browser = Unicode( - u"", + "", config=True, help="""Specify what command to use to invoke a web browser when starting the server. If not specified, the diff --git a/jupyter_server/services/contents/checkpoints.py b/jupyter_server/services/contents/checkpoints.py index a3a3356b4e..7a5fa2eeeb 100644 --- a/jupyter_server/services/contents/checkpoints.py +++ b/jupyter_server/services/contents/checkpoints.py @@ -88,7 +88,7 @@ def create_checkpoint(self, contents_mgr, path): path, ) else: - raise HTTPError(500, u"Unexpected type %s" % type) + raise HTTPError(500, "Unexpected type %s" % type) def restore_checkpoint(self, contents_mgr, checkpoint_id, path): """Restore a checkpoint.""" @@ -98,7 +98,7 @@ def restore_checkpoint(self, contents_mgr, checkpoint_id, path): elif type == "file": model = self.get_file_checkpoint(checkpoint_id, path) else: - raise HTTPError(500, u"Unexpected type %s" % type) + raise HTTPError(500, "Unexpected type %s" % type) contents_mgr.save(model, path) # Required Methods @@ -197,7 +197,7 @@ async def create_checkpoint(self, contents_mgr, path): path, ) else: - raise HTTPError(500, u"Unexpected type %s" % type) + raise HTTPError(500, "Unexpected type %s" % type) async def restore_checkpoint(self, contents_mgr, checkpoint_id, path): """Restore a checkpoint.""" @@ -207,7 +207,7 @@ async def restore_checkpoint(self, contents_mgr, checkpoint_id, path): elif type == "file": model = await self.get_file_checkpoint(checkpoint_id, path) else: - raise HTTPError(500, u"Unexpected type %s" % type) + raise HTTPError(500, "Unexpected type %s" % type) await contents_mgr.save(model, path) # Required Methods diff --git a/jupyter_server/services/contents/filecheckpoints.py b/jupyter_server/services/contents/filecheckpoints.py index 0deb3998f3..b4c89f73a0 100644 --- a/jupyter_server/services/contents/filecheckpoints.py +++ b/jupyter_server/services/contents/filecheckpoints.py @@ -49,7 +49,7 @@ def _root_dir_default(self): # ContentsManager-dependent checkpoint API def create_checkpoint(self, contents_mgr, path): """Create a checkpoint.""" - checkpoint_id = u"checkpoint" + checkpoint_id = "checkpoint" src_path = contents_mgr._get_os_path(path) dest_path = self.checkpoint_path(checkpoint_id, path) self._copy(src_path, dest_path) @@ -106,7 +106,7 @@ def checkpoint_path(self, checkpoint_id, path): parent, name = ("/" + path).rsplit("/", 1) parent = parent.strip("/") basename, ext = os.path.splitext(name) - filename = u"{name}-{checkpoint_id}{ext}".format( + filename = "{name}-{checkpoint_id}{ext}".format( name=basename, checkpoint_id=checkpoint_id, ext=ext, @@ -130,13 +130,13 @@ def checkpoint_model(self, checkpoint_id, os_path): # Error Handling def no_such_checkpoint(self, path, checkpoint_id): - raise HTTPError(404, u"Checkpoint does not exist: %s@%s" % (path, checkpoint_id)) + raise HTTPError(404, "Checkpoint does not exist: %s@%s" % (path, checkpoint_id)) class AsyncFileCheckpoints(FileCheckpoints, AsyncFileManagerMixin, AsyncCheckpoints): async def create_checkpoint(self, contents_mgr, path): """Create a checkpoint.""" - checkpoint_id = u"checkpoint" + checkpoint_id = "checkpoint" src_path = contents_mgr._get_os_path(path) dest_path = self.checkpoint_path(checkpoint_id, path) await self._copy(src_path, dest_path) @@ -207,7 +207,7 @@ def create_file_checkpoint(self, content, format, path): """Create a checkpoint from the current content of a file.""" path = path.strip("/") # only the one checkpoint ID: - checkpoint_id = u"checkpoint" + checkpoint_id = "checkpoint" os_checkpoint_path = self.checkpoint_path(checkpoint_id, path) self.log.debug("creating checkpoint for %s", path) with self.perm_to_403(): @@ -220,7 +220,7 @@ def create_notebook_checkpoint(self, nb, path): """Create a checkpoint from the current content of a notebook.""" path = path.strip("/") # only the one checkpoint ID: - checkpoint_id = u"checkpoint" + checkpoint_id = "checkpoint" os_checkpoint_path = self.checkpoint_path(checkpoint_id, path) self.log.debug("creating checkpoint for %s", path) with self.perm_to_403(): @@ -273,7 +273,7 @@ async def create_file_checkpoint(self, content, format, path): """Create a checkpoint from the current content of a file.""" path = path.strip("/") # only the one checkpoint ID: - checkpoint_id = u"checkpoint" + checkpoint_id = "checkpoint" os_checkpoint_path = self.checkpoint_path(checkpoint_id, path) self.log.debug("creating checkpoint for %s", path) with self.perm_to_403(): @@ -286,7 +286,7 @@ async def create_notebook_checkpoint(self, nb, path): """Create a checkpoint from the current content of a notebook.""" path = path.strip("/") # only the one checkpoint ID: - checkpoint_id = u"checkpoint" + checkpoint_id = "checkpoint" os_checkpoint_path = self.checkpoint_path(checkpoint_id, path) self.log.debug("creating checkpoint for %s", path) with self.perm_to_403(): diff --git a/jupyter_server/services/contents/fileio.py b/jupyter_server/services/contents/fileio.py index 8421339c90..49104332e3 100644 --- a/jupyter_server/services/contents/fileio.py +++ b/jupyter_server/services/contents/fileio.py @@ -227,7 +227,7 @@ def perm_to_403(self, os_path=""): if not os_path: os_path = e.filename or "unknown file" path = to_api_path(os_path, root=self.root_dir) - raise HTTPError(403, u"Permission denied: %s" % path) from e + raise HTTPError(403, "Permission denied: %s" % path) from e else: raise @@ -277,7 +277,7 @@ def _read_notebook(self, os_path, as_version=4): if not self.use_atomic_writing or not os.path.exists(tmp_path): raise HTTPError( 400, - u"Unreadable Notebook: %s %r" % (os_path, e_orig), + "Unreadable Notebook: %s %r" % (os_path, e_orig), ) # Move the bad file aside, restore the intermediate, and try again. @@ -334,7 +334,7 @@ def _save_file(self, os_path, content, format): b64_bytes = content.encode("ascii") bcontent = decodebytes(b64_bytes) except Exception as e: - raise HTTPError(400, u"Encoding error saving %s: %s" % (os_path, e)) from e + raise HTTPError(400, "Encoding error saving %s: %s" % (os_path, e)) from e with self.atomic_writing(os_path, text=False) as f: f.write(bcontent) @@ -368,7 +368,7 @@ async def _read_notebook(self, os_path, as_version=4): if not self.use_atomic_writing or not os.path.exists(tmp_path): raise HTTPError( 400, - u"Unreadable Notebook: %s %r" % (os_path, e_orig), + "Unreadable Notebook: %s %r" % (os_path, e_orig), ) # Move the bad file aside, restore the intermediate, and try again. @@ -425,7 +425,7 @@ async def _save_file(self, os_path, content, format): b64_bytes = content.encode("ascii") bcontent = decodebytes(b64_bytes) except Exception as e: - raise HTTPError(400, u"Encoding error saving %s: %s" % (os_path, e)) from e + raise HTTPError(400, "Encoding error saving %s: %s" % (os_path, e)) from e with self.atomic_writing(os_path, text=False) as f: await run_sync(f.write, bcontent) diff --git a/jupyter_server/services/contents/filemanager.py b/jupyter_server/services/contents/filemanager.py index cb6f4f0932..554087579a 100644 --- a/jupyter_server/services/contents/filemanager.py +++ b/jupyter_server/services/contents/filemanager.py @@ -93,7 +93,7 @@ def run_post_save_hook(self, model, os_path): except Exception as e: self.log.error("Post-save hook failed o-n %s", os_path, exc_info=True) raise web.HTTPError( - 500, u"Unexpected error while running post hook save: %s" % e + 500, "Unexpected error while running post hook save: %s" % e ) from e @validate("root_dir") @@ -284,7 +284,7 @@ def _dir_model(self, path, content=True): """ os_path = self._get_os_path(path) - four_o_four = u"directory does not exist: %r" % path + four_o_four = "directory does not exist: %r" % path if not os.path.isdir(os_path): raise web.HTTPError(404, four_o_four) @@ -416,14 +416,14 @@ def get(self, path, content=True, type=None, format=None): path = path.strip("/") if not self.exists(path): - raise web.HTTPError(404, u"No such file or directory: %s" % path) + raise web.HTTPError(404, "No such file or directory: %s" % path) os_path = self._get_os_path(path) if os.path.isdir(os_path): if type not in (None, "directory"): raise web.HTTPError( 400, - u"%s is a directory, not a %s" % (path, type), + "%s is a directory, not a %s" % (path, type), reason="bad type", ) model = self._dir_model(path, content=content) @@ -431,19 +431,19 @@ def get(self, path, content=True, type=None, format=None): model = self._notebook_model(path, content=content) else: if type == "directory": - raise web.HTTPError(400, u"%s is not a directory" % path, reason="bad type") + raise web.HTTPError(400, "%s is not a directory" % path, reason="bad type") model = self._file_model(path, content=content, format=format) return model def _save_directory(self, os_path, model, path=""): """create a directory""" if is_hidden(os_path, self.root_dir) and not self.allow_hidden: - raise web.HTTPError(400, u"Cannot create hidden directory %r" % os_path) + raise web.HTTPError(400, "Cannot create hidden directory %r" % os_path) if not os.path.exists(os_path): with self.perm_to_403(): os.mkdir(os_path) elif not os.path.isdir(os_path): - raise web.HTTPError(400, u"Not a directory: %s" % (os_path)) + raise web.HTTPError(400, "Not a directory: %s" % (os_path)) else: self.log.debug("Directory %r already exists", os_path) @@ -454,9 +454,9 @@ def save(self, model, path=""): self.run_pre_save_hook(model=model, path=path) if "type" not in model: - raise web.HTTPError(400, u"No file type provided") + raise web.HTTPError(400, "No file type provided") if "content" not in model and model["type"] != "directory": - raise web.HTTPError(400, u"No file content provided") + raise web.HTTPError(400, "No file content provided") os_path = self._get_os_path(path) self.log.debug("Saving %s", os_path) @@ -479,10 +479,8 @@ def save(self, model, path=""): except web.HTTPError: raise except Exception as e: - self.log.error(u"Error while saving file: %s %s", path, e, exc_info=True) - raise web.HTTPError( - 500, u"Unexpected error while saving file: %s %s" % (path, e) - ) from e + self.log.error("Error while saving file: %s %s", path, e, exc_info=True) + raise web.HTTPError(500, "Unexpected error while saving file: %s %s" % (path, e)) from e validation_message = None if model["type"] == "notebook": @@ -503,7 +501,7 @@ def delete_file(self, path): os_path = self._get_os_path(path) rm = os.unlink if not os.path.exists(os_path): - raise web.HTTPError(404, u"File or directory does not exist: %s" % os_path) + raise web.HTTPError(404, "File or directory does not exist: %s" % os_path) def _check_trash(os_path): if sys.platform in {"win32", "darwin"}: @@ -530,13 +528,13 @@ def is_non_empty_dir(os_path): if not self.always_delete_dir and sys.platform == "win32" and is_non_empty_dir(os_path): # send2trash can really delete files on Windows, so disallow # deleting non-empty files. See Github issue 3631. - raise web.HTTPError(400, u"Directory %s not empty" % os_path) + raise web.HTTPError(400, "Directory %s not empty" % os_path) if _check_trash(os_path): # Looking at the code in send2trash, I don't think the errors it # raises let us distinguish permission errors from other errors in # code. So for now, the "look before you leap" approach is used. if not self.is_writable(path): - raise web.HTTPError(403, u"Permission denied: %s" % path) + raise web.HTTPError(403, "Permission denied: %s" % path) self.log.debug("Sending %s to trash", os_path) send2trash(os_path) return @@ -549,7 +547,7 @@ def is_non_empty_dir(os_path): if os.path.isdir(os_path): # Don't permanently delete non-empty directories. if not self.always_delete_dir and is_non_empty_dir(os_path): - raise web.HTTPError(400, u"Directory %s not empty" % os_path) + raise web.HTTPError(400, "Directory %s not empty" % os_path) self.log.debug("Removing directory %s", os_path) with self.perm_to_403(): shutil.rmtree(os_path) @@ -570,7 +568,7 @@ def rename_file(self, old_path, new_path): # Should we proceed with the move? if os.path.exists(new_os_path) and not samefile(old_os_path, new_os_path): - raise web.HTTPError(409, u"File already exists: %s" % new_path) + raise web.HTTPError(409, "File already exists: %s" % new_path) # Move the file try: @@ -579,7 +577,7 @@ def rename_file(self, old_path, new_path): except web.HTTPError: raise except Exception as e: - raise web.HTTPError(500, u"Unknown error renaming file: %s %s" % (old_path, e)) from e + raise web.HTTPError(500, "Unknown error renaming file: %s %s" % (old_path, e)) from e def info_string(self): return _i18n("Serving notebooks from local directory: %s") % self.root_dir @@ -607,7 +605,7 @@ async def _dir_model(self, path, content=True): """ os_path = self._get_os_path(path) - four_o_four = u"directory does not exist: %r" % path + four_o_four = "directory does not exist: %r" % path if not os.path.isdir(os_path): raise web.HTTPError(404, four_o_four) @@ -742,14 +740,14 @@ async def get(self, path, content=True, type=None, format=None): path = path.strip("/") if not self.exists(path): - raise web.HTTPError(404, u"No such file or directory: %s" % path) + raise web.HTTPError(404, "No such file or directory: %s" % path) os_path = self._get_os_path(path) if os.path.isdir(os_path): if type not in (None, "directory"): raise web.HTTPError( 400, - u"%s is a directory, not a %s" % (path, type), + "%s is a directory, not a %s" % (path, type), reason="bad type", ) model = await self._dir_model(path, content=content) @@ -757,19 +755,19 @@ async def get(self, path, content=True, type=None, format=None): model = await self._notebook_model(path, content=content) else: if type == "directory": - raise web.HTTPError(400, u"%s is not a directory" % path, reason="bad type") + raise web.HTTPError(400, "%s is not a directory" % path, reason="bad type") model = await self._file_model(path, content=content, format=format) return model async def _save_directory(self, os_path, model, path=""): """create a directory""" if is_hidden(os_path, self.root_dir) and not self.allow_hidden: - raise web.HTTPError(400, u"Cannot create hidden directory %r" % os_path) + raise web.HTTPError(400, "Cannot create hidden directory %r" % os_path) if not os.path.exists(os_path): with self.perm_to_403(): await run_sync(os.mkdir, os_path) elif not os.path.isdir(os_path): - raise web.HTTPError(400, u"Not a directory: %s" % (os_path)) + raise web.HTTPError(400, "Not a directory: %s" % (os_path)) else: self.log.debug("Directory %r already exists", os_path) @@ -782,9 +780,9 @@ async def save(self, model, path=""): self.run_pre_save_hook(model=model, path=path) if "type" not in model: - raise web.HTTPError(400, u"No file type provided") + raise web.HTTPError(400, "No file type provided") if "content" not in model and model["type"] != "directory": - raise web.HTTPError(400, u"No file content provided") + raise web.HTTPError(400, "No file content provided") try: if model["type"] == "notebook": @@ -804,10 +802,8 @@ async def save(self, model, path=""): except web.HTTPError: raise except Exception as e: - self.log.error(u"Error while saving file: %s %s", path, e, exc_info=True) - raise web.HTTPError( - 500, u"Unexpected error while saving file: %s %s" % (path, e) - ) from e + self.log.error("Error while saving file: %s %s", path, e, exc_info=True) + raise web.HTTPError(500, "Unexpected error while saving file: %s %s" % (path, e)) from e validation_message = None if model["type"] == "notebook": @@ -828,7 +824,7 @@ async def delete_file(self, path): os_path = self._get_os_path(path) rm = os.unlink if not os.path.exists(os_path): - raise web.HTTPError(404, u"File or directory does not exist: %s" % os_path) + raise web.HTTPError(404, "File or directory does not exist: %s" % os_path) async def _check_trash(os_path): if sys.platform in {"win32", "darwin"}: @@ -860,13 +856,13 @@ async def is_non_empty_dir(os_path): ): # send2trash can really delete files on Windows, so disallow # deleting non-empty files. See Github issue 3631. - raise web.HTTPError(400, u"Directory %s not empty" % os_path) + raise web.HTTPError(400, "Directory %s not empty" % os_path) if await _check_trash(os_path): # Looking at the code in send2trash, I don't think the errors it # raises let us distinguish permission errors from other errors in # code. So for now, the "look before you leap" approach is used. if not self.is_writable(path): - raise web.HTTPError(403, u"Permission denied: %s" % path) + raise web.HTTPError(403, "Permission denied: %s" % path) self.log.debug("Sending %s to trash", os_path) send2trash(os_path) return @@ -879,7 +875,7 @@ async def is_non_empty_dir(os_path): if os.path.isdir(os_path): # Don't permanently delete non-empty directories. if not self.always_delete_dir and await is_non_empty_dir(os_path): - raise web.HTTPError(400, u"Directory %s not empty" % os_path) + raise web.HTTPError(400, "Directory %s not empty" % os_path) self.log.debug("Removing directory %s", os_path) with self.perm_to_403(): await run_sync(shutil.rmtree, os_path) @@ -900,7 +896,7 @@ async def rename_file(self, old_path, new_path): # Should we proceed with the move? if os.path.exists(new_os_path) and not samefile(old_os_path, new_os_path): - raise web.HTTPError(409, u"File already exists: %s" % new_path) + raise web.HTTPError(409, "File already exists: %s" % new_path) # Move the file try: @@ -909,4 +905,4 @@ async def rename_file(self, old_path, new_path): except web.HTTPError: raise except Exception as e: - raise web.HTTPError(500, u"Unknown error renaming file: %s %s" % (old_path, e)) from e + raise web.HTTPError(500, "Unknown error renaming file: %s %s" % (old_path, e)) from e diff --git a/jupyter_server/services/contents/handlers.py b/jupyter_server/services/contents/handlers.py index e4e97bb59e..83db1f99ee 100644 --- a/jupyter_server/services/contents/handlers.py +++ b/jupyter_server/services/contents/handlers.py @@ -46,7 +46,7 @@ def validate_model(model, expect_content): if missing: raise web.HTTPError( 500, - u"Missing Model Keys: {missing}".format(missing=missing), + "Missing Model Keys: {missing}".format(missing=missing), ) maybe_none_keys = ["content", "format"] @@ -55,14 +55,14 @@ def validate_model(model, expect_content): if errors: raise web.HTTPError( 500, - u"Keys unexpectedly None: {keys}".format(keys=errors), + "Keys unexpectedly None: {keys}".format(keys=errors), ) else: errors = {key: model[key] for key in maybe_none_keys if model[key] is not None} if errors: raise web.HTTPError( 500, - u"Keys unexpectedly not None: {keys}".format(keys=errors), + "Keys unexpectedly not None: {keys}".format(keys=errors), ) @@ -101,14 +101,14 @@ async def get(self, path=""): path = path or "" type = self.get_query_argument("type", default=None) if type not in {None, "directory", "file", "notebook"}: - raise web.HTTPError(400, u"Type %r is invalid" % type) + raise web.HTTPError(400, "Type %r is invalid" % type) format = self.get_query_argument("format", default=None) if format not in {None, "text", "base64"}: - raise web.HTTPError(400, u"Format %r is invalid" % format) + raise web.HTTPError(400, "Format %r is invalid" % format) content = self.get_query_argument("content", default="1") if content not in {"0", "1"}: - raise web.HTTPError(400, u"Content %r is invalid" % content) + raise web.HTTPError(400, "Content %r is invalid" % content) content = int(content) model = await ensure_async( @@ -129,7 +129,7 @@ async def patch(self, path=""): cm = self.contents_manager model = self.get_json_body() if model is None: - raise web.HTTPError(400, u"JSON body missing") + raise web.HTTPError(400, "JSON body missing") model = await ensure_async(cm.update(model, path)) validate_model(model, expect_content=False) self._finish_model(model) @@ -137,7 +137,7 @@ async def patch(self, path=""): async def _copy(self, copy_from, copy_to=None): """Copy a file, optionally specifying a target directory.""" self.log.info( - u"Copying {copy_from} to {copy_to}".format( + "Copying {copy_from} to {copy_to}".format( copy_from=copy_from, copy_to=copy_to or "", ) @@ -149,7 +149,7 @@ async def _copy(self, copy_from, copy_to=None): async def _upload(self, model, path): """Handle upload of a new file to path""" - self.log.info(u"Uploading file to %s", path) + self.log.info("Uploading file to %s", path) model = await ensure_async(self.contents_manager.new(model, path)) self.set_status(201) validate_model(model, expect_content=False) @@ -157,7 +157,7 @@ async def _upload(self, model, path): async def _new_untitled(self, path, type="", ext=""): """Create a new, empty untitled entity""" - self.log.info(u"Creating new %s in %s", type or "file", path) + self.log.info("Creating new %s in %s", type or "file", path) model = await ensure_async( self.contents_manager.new_untitled(path=path, type=type, ext=ext) ) @@ -169,7 +169,7 @@ async def _save(self, model, path): """Save an existing file.""" chunk = model.get("chunk", None) if not chunk or chunk == -1: # Avoid tedious log information - self.log.info(u"Saving file at %s", path) + self.log.info("Saving file at %s", path) model = await ensure_async(self.contents_manager.save(model, path)) validate_model(model, expect_content=False) self._finish_model(model) @@ -309,7 +309,7 @@ def get(self, path): class TrustNotebooksHandler(JupyterHandler): - """ Handles trust/signing of notebooks """ + """Handles trust/signing of notebooks""" @web.authenticated @authorized(resource=AUTH_RESOURCE) diff --git a/jupyter_server/services/contents/largefilemanager.py b/jupyter_server/services/contents/largefilemanager.py index 28c3ffce50..3b404abf9f 100644 --- a/jupyter_server/services/contents/largefilemanager.py +++ b/jupyter_server/services/contents/largefilemanager.py @@ -21,16 +21,14 @@ def save(self, model, path=""): self.run_pre_save_hook(model=model, path=path) if "type" not in model: - raise web.HTTPError(400, u"No file type provided") + raise web.HTTPError(400, "No file type provided") if model["type"] != "file": raise web.HTTPError( 400, - u'File type "{}" is not supported for large file transfer'.format( - model["type"] - ), + 'File type "{}" is not supported for large file transfer'.format(model["type"]), ) if "content" not in model and model["type"] != "directory": - raise web.HTTPError(400, u"No file content provided") + raise web.HTTPError(400, "No file content provided") os_path = self._get_os_path(path) self.log.debug("Saving %s", os_path) @@ -45,9 +43,9 @@ def save(self, model, path=""): except web.HTTPError: raise except Exception as e: - self.log.error(u"Error while saving file: %s %s", path, e, exc_info=True) + self.log.error("Error while saving file: %s %s", path, e, exc_info=True) raise web.HTTPError( - 500, u"Unexpected error while saving file: %s %s" % (path, e) + 500, "Unexpected error while saving file: %s %s" % (path, e) ) from e model = self.get(path, content=False) @@ -73,7 +71,7 @@ def _save_large_file(self, os_path, content, format): b64_bytes = content.encode("ascii") bcontent = base64.b64decode(b64_bytes) except Exception as e: - raise web.HTTPError(400, u"Encoding error saving %s: %s" % (os_path, e)) from e + raise web.HTTPError(400, "Encoding error saving %s: %s" % (os_path, e)) from e with self.perm_to_403(os_path): if os.path.islink(os_path): @@ -96,16 +94,14 @@ async def save(self, model, path=""): self.run_pre_save_hook(model=model, path=path) if "type" not in model: - raise web.HTTPError(400, u"No file type provided") + raise web.HTTPError(400, "No file type provided") if model["type"] != "file": raise web.HTTPError( 400, - u'File type "{}" is not supported for large file transfer'.format( - model["type"] - ), + 'File type "{}" is not supported for large file transfer'.format(model["type"]), ) if "content" not in model and model["type"] != "directory": - raise web.HTTPError(400, u"No file content provided") + raise web.HTTPError(400, "No file content provided") try: if chunk == 1: @@ -117,9 +113,9 @@ async def save(self, model, path=""): except web.HTTPError: raise except Exception as e: - self.log.error(u"Error while saving file: %s %s", path, e, exc_info=True) + self.log.error("Error while saving file: %s %s", path, e, exc_info=True) raise web.HTTPError( - 500, u"Unexpected error while saving file: %s %s" % (path, e) + 500, "Unexpected error while saving file: %s %s" % (path, e) ) from e model = await self.get(path, content=False) @@ -145,7 +141,7 @@ async def _save_large_file(self, os_path, content, format): b64_bytes = content.encode("ascii") bcontent = base64.b64decode(b64_bytes) except Exception as e: - raise web.HTTPError(400, u"Encoding error saving %s: %s" % (os_path, e)) from e + raise web.HTTPError(400, "Encoding error saving %s: %s" % (os_path, e)) from e with self.perm_to_403(os_path): if os.path.islink(os_path): diff --git a/jupyter_server/services/contents/manager.py b/jupyter_server/services/contents/manager.py index d5c728cb17..3e47a637af 100644 --- a/jupyter_server/services/contents/manager.py +++ b/jupyter_server/services/contents/manager.py @@ -66,7 +66,7 @@ def _notary_default(self): hide_globs = List( Unicode(), [ - u"__pycache__", + "__pycache__", "*.pyc", "*.pyo", ".DS_Store", @@ -365,10 +365,10 @@ def increment_filename(self, filename, path="", insert=""): insert_i = "{}{}".format(insert, i) else: insert_i = "" - name = u"{basename}{insert}{suffix}".format( + name = "{basename}{insert}{suffix}".format( basename=basename, insert=insert_i, suffix=suffix ) - if not self.exists(u"{}/{}".format(path, name)): + if not self.exists("{}/{}".format(path, name)): break return name @@ -377,7 +377,7 @@ def validate_notebook_model(self, model): try: validate_nb(model["content"]) except ValidationError as e: - model["message"] = u"Notebook validation failed: {}:\n{}".format( + model["message"] = "Notebook validation failed: {}:\n{}".format( e.message, json.dumps(e.instance, indent=1, default=lambda obj: ""), ) @@ -418,7 +418,7 @@ def new_untitled(self, path="", type="", ext=""): raise HTTPError(400, "Unexpected model type: %r" % model["type"]) name = self.increment_filename(untitled + ext, path, insert=insert) - path = u"{0}/{1}".format(path, name) + path = "{0}/{1}".format(path, name) return self.new(model, path) def new(self, model=None, path=""): @@ -477,9 +477,9 @@ def copy(self, from_path, to_path=None): if to_path is None: to_path = from_dir if self.dir_exists(to_path): - name = copy_pat.sub(u".", from_name) + name = copy_pat.sub(".", from_name) to_name = self.increment_filename(name, to_path, insert="-Copy") - to_path = u"{0}/{1}".format(to_path, to_name) + to_path = "{0}/{1}".format(to_path, to_name) model = self.save(model, to_path) return model @@ -734,10 +734,10 @@ async def increment_filename(self, filename, path="", insert=""): insert_i = "{}{}".format(insert, i) else: insert_i = "" - name = u"{basename}{insert}{suffix}".format( + name = "{basename}{insert}{suffix}".format( basename=basename, insert=insert_i, suffix=suffix ) - file_exists = await ensure_async(self.exists(u"{}/{}".format(path, name))) + file_exists = await ensure_async(self.exists("{}/{}".format(path, name))) if not file_exists: break return name @@ -778,7 +778,7 @@ async def new_untitled(self, path="", type="", ext=""): raise HTTPError(400, "Unexpected model type: %r" % model["type"]) name = await self.increment_filename(untitled + ext, path, insert=insert) - path = u"{0}/{1}".format(path, name) + path = "{0}/{1}".format(path, name) return await self.new(model, path) async def new(self, model=None, path=""): @@ -836,9 +836,9 @@ async def copy(self, from_path, to_path=None): if to_path is None: to_path = from_dir if await ensure_async(self.dir_exists(to_path)): - name = copy_pat.sub(u".", from_name) + name = copy_pat.sub(".", from_name) to_name = await self.increment_filename(name, to_path, insert="-Copy") - to_path = u"{0}/{1}".format(to_path, to_name) + to_path = "{0}/{1}".format(to_path, to_name) model = await self.save(model, to_path) return model diff --git a/jupyter_server/services/kernelspecs/handlers.py b/jupyter_server/services/kernelspecs/handlers.py index f00cfcc999..89bb4e4592 100644 --- a/jupyter_server/services/kernelspecs/handlers.py +++ b/jupyter_server/services/kernelspecs/handlers.py @@ -90,7 +90,7 @@ async def get(self, kernel_name): try: spec = await ensure_async(ksm.get_kernel_spec(kernel_name)) except KeyError as e: - raise web.HTTPError(404, u"Kernel spec %s not found" % kernel_name) from e + raise web.HTTPError(404, "Kernel spec %s not found" % kernel_name) from e if is_kernelspec_model(spec): model = spec else: diff --git a/jupyter_server/services/sessions/sessionmanager.py b/jupyter_server/services/sessions/sessionmanager.py index 968f3f34e0..6a2a4547a1 100644 --- a/jupyter_server/services/sessions/sessionmanager.py +++ b/jupyter_server/services/sessions/sessionmanager.py @@ -215,12 +215,12 @@ async def get_session(self, **kwargs): for key, value in kwargs.items(): q.append("%s=%r" % (key, value)) - raise web.HTTPError(404, u"Session not found: %s" % (", ".join(q))) + raise web.HTTPError(404, "Session not found: %s" % (", ".join(q))) try: model = await self.row_to_model(row) except KeyError as e: - raise web.HTTPError(404, u"Session not found: %s" % str(e)) + raise web.HTTPError(404, "Session not found: %s" % str(e)) return model async def update_session(self, session_id, **kwargs): @@ -253,7 +253,7 @@ async def update_session(self, session_id, **kwargs): self.cursor.execute(query, list(kwargs.values()) + [session_id]) def kernel_culled(self, kernel_id): - """Checks if the kernel is still considered alive and returns true if its not found. """ + """Checks if the kernel is still considered alive and returns true if its not found.""" return kernel_id not in self.kernel_manager async def row_to_model(self, row, tolerate_culled=False): diff --git a/jupyter_server/terminal/terminalmanager.py b/jupyter_server/terminal/terminalmanager.py index 4e8ddcaca1..1db545e4a4 100644 --- a/jupyter_server/terminal/terminalmanager.py +++ b/jupyter_server/terminal/terminalmanager.py @@ -19,7 +19,7 @@ class TerminalManager(LoggingConfigurable, terminado.NamedTermManager): - """ """ + """ """ _culler_callback = None @@ -102,7 +102,7 @@ def get_terminal_model(self, name): def _check_terminal(self, name): """Check a that terminal 'name' exists and raise 404 if not.""" if name not in self.terminals: - raise web.HTTPError(404, u"Terminal not found: %s" % name) + raise web.HTTPError(404, "Terminal not found: %s" % name) def _initialize_culler(self): """Start culler if 'cull_inactive_timeout' is greater than zero. diff --git a/jupyter_server/tests/auth/test_security.py b/jupyter_server/tests/auth/test_security.py index ed6d62a5cc..1a3f172a2d 100644 --- a/jupyter_server/tests/auth/test_security.py +++ b/jupyter_server/tests/auth/test_security.py @@ -23,9 +23,9 @@ def test_bad(): def test_passwd_check_unicode(): # GH issue #4524 - phash = u"sha1:23862bc21dd3:7a415a95ae4580582e314072143d9c382c491e4f" - assert passwd_check(phash, u"łe¶ŧ←↓→") + phash = "sha1:23862bc21dd3:7a415a95ae4580582e314072143d9c382c491e4f" + assert passwd_check(phash, "łe¶ŧ←↓→") phash = ( - u"argon2:$argon2id$v=19$m=10240,t=10,p=8$" u"qjjDiZUofUVVnrVYxacnbA$l5pQq1bJ8zglGT2uXP6iOg" + "argon2:$argon2id$v=19$m=10240,t=10,p=8$" "qjjDiZUofUVVnrVYxacnbA$l5pQq1bJ8zglGT2uXP6iOg" ) - assert passwd_check(phash, u"łe¶ŧ←↓→") + assert passwd_check(phash, "łe¶ŧ←↓→") diff --git a/jupyter_server/tests/nbconvert/test_handlers.py b/jupyter_server/tests/nbconvert/test_handlers.py index d3769a5dae..75d2372c65 100644 --- a/jupyter_server/tests/nbconvert/test_handlers.py +++ b/jupyter_server/tests/nbconvert/test_handlers.py @@ -30,9 +30,9 @@ def notebook(jp_root_dir): # Build a notebook programmatically. nb = new_notebook() - nb.cells.append(new_markdown_cell(u"Created by test ³")) - cc1 = new_code_cell(source=u"print(2*6)") - cc1.outputs.append(new_output(output_type="stream", text=u"12")) + nb.cells.append(new_markdown_cell("Created by test ³")) + cc1 = new_code_cell(source="print(2*6)") + cc1.outputs.append(new_output(output_type="stream", text="12")) cc1.outputs.append( new_output( output_type="execute_result", @@ -134,7 +134,7 @@ async def test_from_post(jp_fetch, notebook): r = await jp_fetch("nbconvert", "python", method="POST", body=json.dumps(nbmodel)) assert r.code == 200 - assert u"text/x-python" in r.headers["Content-Type"] + assert "text/x-python" in r.headers["Content-Type"] assert "print(2*6)" in r.body.decode() diff --git a/jupyter_server/tests/services/contents/test_api.py b/jupyter_server/tests/services/contents/test_api.py index 668a815248..2d15cc2291 100644 --- a/jupyter_server/tests/services/contents/test_api.py +++ b/jupyter_server/tests/services/contents/test_api.py @@ -27,16 +27,16 @@ def dirs_only(dir_model): dirs = [ ("", "inroot"), ("Directory with spaces in", "inspace"), - (u"unicodé", "innonascii"), + ("unicodé", "innonascii"), ("foo", "a"), ("foo", "b"), ("foo", "name with spaces"), - ("foo", u"unicodé"), + ("foo", "unicodé"), ("foo/bar", "baz"), ("ordering", "A"), ("ordering", "b"), ("ordering", "C"), - (u"å b", u"ç d"), + ("å b", "ç d"), ] @@ -173,7 +173,7 @@ async def test_get_nb_invalid(contents_dir, jp_fetch, contents): } ], } - nbpath = u"å b/Validate tést.ipynb" + nbpath = "å b/Validate tést.ipynb" (contents_dir / nbpath).write_text(json.dumps(nb)) r = await jp_fetch( "api", diff --git a/jupyter_server/tests/services/contents/test_fileio.py b/jupyter_server/tests/services/contents/test_fileio.py index e837be717e..98f3a31e9a 100644 --- a/jupyter_server/tests/services/contents/test_fileio.py +++ b/jupyter_server/tests/services/contents/test_fileio.py @@ -67,7 +67,7 @@ class CustomExc(Exception): if have_symlink: # Check that writing over a file preserves a symlink with atomic_writing(str(f2)) as f: - f.write(u"written from symlink") + f.write("written from symlink") with io.open(str(f1), "r") as f: assert f.read() == "written from symlink" @@ -105,9 +105,9 @@ def test_atomic_writing_umask(handle_umask, tmp_path): def test_atomic_writing_newlines(tmp_path): path = str(tmp_path / "testfile") - lf = u"a\nb\nc\n" - plat = lf.replace(u"\n", os.linesep) - crlf = lf.replace(u"\n", u"\r\n") + lf = "a\nb\nc\n" + plat = lf.replace("\n", os.linesep) + crlf = lf.replace("\n", "\r\n") # test default with io.open(path, "w") as f: @@ -131,7 +131,7 @@ def test_atomic_writing_newlines(tmp_path): assert read == crlf # test newline=no convert - text = u"crlf\r\ncr\rlf\n" + text = "crlf\r\ncr\rlf\n" with atomic_writing(str(path), newline="") as f: f.write(text) with io.open(path, "r", newline="") as f: diff --git a/jupyter_server/tests/services/contents/test_largefilemanager.py b/jupyter_server/tests/services/contents/test_largefilemanager.py index 46b91edb48..a53ae66693 100644 --- a/jupyter_server/tests/services/contents/test_largefilemanager.py +++ b/jupyter_server/tests/services/contents/test_largefilemanager.py @@ -52,7 +52,7 @@ async def test_save(jp_large_contents_manager): "path": "test", "chunk": 2, "type": "file", - "content": u"test", + "content": "test", "format": "json", }, "HTTP 400: Bad Request (Must specify format of file contents as 'text' or 'base64')", @@ -71,7 +71,7 @@ async def test_saving_different_chunks(jp_large_contents_manager): "name": "test", "path": "test", "type": "file", - "content": u"test==", + "content": "test==", "format": "text", } name = model["name"] diff --git a/jupyter_server/tests/services/contents/test_manager.py b/jupyter_server/tests/services/contents/test_manager.py index 3475b5f3d1..4da26d369d 100644 --- a/jupyter_server/tests/services/contents/test_manager.py +++ b/jupyter_server/tests/services/contents/test_manager.py @@ -229,7 +229,7 @@ async def test_403(jp_file_contents_manager_class, tmp_path): os.chmod(os_path, 0o400) try: with cm.open(os_path, "w") as f: - f.write(u"don't care") + f.write("don't care") except HTTPError as e: assert e.status_code == 403 @@ -264,7 +264,7 @@ async def test_escape_root(jp_file_contents_manager_class, tmp_path): cm.save( model={ "type": "file", - "content": u"", + "content": "", "format": "text", }, path="../foo", @@ -375,12 +375,12 @@ async def test_get(jp_contents_manager): file_model_path = (await ensure_async(cm.new_untitled(path=sub_dir, ext=".txt")))["path"] file_model = await ensure_async(cm.get(file_model_path)) expected_model = { - "content": u"", - "format": u"text", - "mimetype": u"text/plain", - "name": u"untitled.txt", - "path": u"foo/untitled.txt", - "type": u"file", + "content": "", + "format": "text", + "mimetype": "text/plain", + "name": "untitled.txt", + "path": "foo/untitled.txt", + "type": "file", "writable": True, } # Assert expected model is in file_model @@ -402,7 +402,7 @@ async def test_get(jp_contents_manager): # Directory contents should match the contents of each individual entry # when requested with content=False. model2_no_content = await ensure_async(cm.get(sub_dir + name, content=False)) - file_model_no_content = await ensure_async(cm.get(u"foo/untitled.txt", content=False)) + file_model_no_content = await ensure_async(cm.get("foo/untitled.txt", content=False)) sub_sub_dir_no_content = await ensure_async(cm.get("foo/bar", content=False)) assert sub_sub_dir_no_content["path"] == "foo/bar" assert sub_sub_dir_no_content["name"] == "bar" @@ -618,9 +618,9 @@ async def test_delete_root(jp_contents_manager): async def test_copy(jp_contents_manager): cm = jp_contents_manager - parent = u"å b" - name = u"nb √.ipynb" - path = u"{0}/{1}".format(parent, name) + parent = "å b" + name = "nb √.ipynb" + path = "{0}/{1}".format(parent, name) _make_dir(cm, parent) orig = await ensure_async(cm.new(path=path)) @@ -629,11 +629,11 @@ async def test_copy(jp_contents_manager): assert copy["name"] == orig["name"].replace(".ipynb", "-Copy1.ipynb") # copy with specified name - copy2 = await ensure_async(cm.copy(path, u"å b/copy 2.ipynb")) - assert copy2["name"] == u"copy 2.ipynb" - assert copy2["path"] == u"å b/copy 2.ipynb" + copy2 = await ensure_async(cm.copy(path, "å b/copy 2.ipynb")) + assert copy2["name"] == "copy 2.ipynb" + assert copy2["path"] == "å b/copy 2.ipynb" # copy with specified path - copy2 = await ensure_async(cm.copy(path, u"/")) + copy2 = await ensure_async(cm.copy(path, "/")) assert copy2["name"] == name assert copy2["path"] == name diff --git a/jupyter_server/tests/services/sessions/test_manager.py b/jupyter_server/tests/services/sessions/test_manager.py index 9a3ca01905..f0142be42b 100644 --- a/jupyter_server/tests/services/sessions/test_manager.py +++ b/jupyter_server/tests/services/sessions/test_manager.py @@ -23,7 +23,7 @@ class DummyMKM(MappingKernelManager): def __init__(self, *args, **kwargs): super(DummyMKM, self).__init__(*args, **kwargs) - self.id_letters = iter(u"ABCDEFGHIJK") + self.id_letters = iter("ABCDEFGHIJK") def _new_id(self): return next(self.id_letters) @@ -62,8 +62,8 @@ async def test_get_session(session_manager): model = await session_manager.get_session(session_id=session_id) expected = { "id": session_id, - "path": u"/path/to/test.ipynb", - "notebook": {"path": u"/path/to/test.ipynb", "name": None}, + "path": "/path/to/test.ipynb", + "notebook": {"path": "/path/to/test.ipynb", "name": None}, "type": "notebook", "name": None, "kernel": { @@ -109,9 +109,9 @@ async def test_list_session(session_manager): expected = [ { "id": sessions[0]["id"], - "path": u"/path/to/1/test1.ipynb", + "path": "/path/to/1/test1.ipynb", "type": "notebook", - "notebook": {"path": u"/path/to/1/test1.ipynb", "name": None}, + "notebook": {"path": "/path/to/1/test1.ipynb", "name": None}, "name": None, "kernel": { "id": "A", @@ -123,7 +123,7 @@ async def test_list_session(session_manager): }, { "id": sessions[1]["id"], - "path": u"/path/to/2/test2.py", + "path": "/path/to/2/test2.py", "type": "file", "name": None, "kernel": { @@ -136,7 +136,7 @@ async def test_list_session(session_manager): }, { "id": sessions[2]["id"], - "path": u"/path/to/3", + "path": "/path/to/3", "type": "console", "name": "foo", "kernel": { @@ -163,10 +163,10 @@ async def test_list_sessions_dead_kernel(session_manager): expected = [ { "id": sessions[1]["id"], - "path": u"/path/to/2/test2.ipynb", + "path": "/path/to/2/test2.ipynb", "type": "notebook", "name": None, - "notebook": {"path": u"/path/to/2/test2.ipynb", "name": None}, + "notebook": {"path": "/path/to/2/test2.ipynb", "name": None}, "kernel": { "id": "B", "name": "python", @@ -188,10 +188,10 @@ async def test_update_session(session_manager): model = await session_manager.get_session(session_id=session_id) expected = { "id": session_id, - "path": u"/path/to/new_name.ipynb", + "path": "/path/to/new_name.ipynb", "type": "notebook", "name": None, - "notebook": {"path": u"/path/to/new_name.ipynb", "name": None}, + "notebook": {"path": "/path/to/new_name.ipynb", "name": None}, "kernel": { "id": "A", "name": "julia", @@ -227,10 +227,10 @@ async def test_delete_session(session_manager): expected = [ { "id": sessions[0]["id"], - "path": u"/path/to/1/test1.ipynb", + "path": "/path/to/1/test1.ipynb", "type": "notebook", "name": None, - "notebook": {"path": u"/path/to/1/test1.ipynb", "name": None}, + "notebook": {"path": "/path/to/1/test1.ipynb", "name": None}, "kernel": { "id": "A", "name": "python", @@ -242,7 +242,7 @@ async def test_delete_session(session_manager): { "id": sessions[2]["id"], "type": "console", - "path": u"/path/to/3", + "path": "/path/to/3", "name": "foo", "kernel": { "id": "C", diff --git a/jupyter_server/tests/test_files.py b/jupyter_server/tests/test_files.py index ccbbaf4fdd..c592d89fa5 100644 --- a/jupyter_server/tests/test_files.py +++ b/jupyter_server/tests/test_files.py @@ -61,7 +61,7 @@ async def test_contents_manager(jp_fetch, jp_serverapp, jp_root_dir): """make sure ContentsManager returns right files (ipynb, bin, txt).""" nb = new_notebook( cells=[ - new_markdown_cell(u"Created by test ³"), + new_markdown_cell("Created by test ³"), new_code_cell( "print(2*6)", outputs=[ diff --git a/jupyter_server/tests/test_gateway.py b/jupyter_server/tests/test_gateway.py index ba66568e72..ec279f300e 100644 --- a/jupyter_server/tests/test_gateway.py +++ b/jupyter_server/tests/test_gateway.py @@ -157,7 +157,7 @@ async def mock_gateway_request(url, **kwargs): @pytest.fixture def init_gateway(monkeypatch): - """Initializes the server for use as a gateway client. """ + """Initializes the server for use as a gateway client.""" # Clear the singleton first since previous tests may not have used a gateway. GatewayClient.clear_instance() monkeypatch.setenv("JUPYTER_GATEWAY_URL", mock_gateway_url) diff --git a/jupyter_server/tests/utils.py b/jupyter_server/tests/utils.py index c2d6181d62..6e6649af42 100644 --- a/jupyter_server/tests/utils.py +++ b/jupyter_server/tests/utils.py @@ -2,7 +2,7 @@ import tornado -some_resource = u"The very model of a modern major general" +some_resource = "The very model of a modern major general" sample_kernel_json = { "argv": ["cat", "{connection_file}"], diff --git a/jupyter_server/view/handlers.py b/jupyter_server/view/handlers.py index 6bd2f32258..a7d50f2768 100644 --- a/jupyter_server/view/handlers.py +++ b/jupyter_server/view/handlers.py @@ -25,7 +25,7 @@ class ViewHandler(JupyterHandler): async def get(self, path): path = path.strip("/") if not await ensure_async(self.contents_manager.file_exists(path)): - raise web.HTTPError(404, u"File does not exist: %s" % path) + raise web.HTTPError(404, "File does not exist: %s" % path) basename = path.rsplit("/", 1)[-1] file_url = url_path_join(self.base_url, "files", url_escape(path))