diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e8f6663e..67297a8e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: reorder-python-imports - repo: https://github.com/psf/black - rev: 19.10b0 + rev: 20.8b1 hooks: - id: black - repo: https://github.com/pre-commit/pre-commit-hooks diff --git a/jupyterhub/apihandlers/hub.py b/jupyterhub/apihandlers/hub.py index 155ddf92..dbfbece0 100644 --- a/jupyterhub/apihandlers/hub.py +++ b/jupyterhub/apihandlers/hub.py @@ -16,9 +16,9 @@ class ShutdownAPIHandler(APIHandler): @admin_only def post(self): """POST /api/shutdown triggers a clean shutdown - + POST (JSON) parameters: - + - servers: specify whether single-user servers should be terminated - proxy: specify whether the proxy should be terminated """ @@ -57,7 +57,7 @@ class RootAPIHandler(APIHandler): """GET /api/ returns info about the Hub and its API. It is not an authenticated endpoint. - + For now, it just returns the version of JupyterHub itself. """ data = {'version': __version__} @@ -70,7 +70,7 @@ class InfoAPIHandler(APIHandler): """GET /api/info returns detailed info about the Hub and its API. It is not an authenticated endpoint. - + For now, it just returns the version of JupyterHub itself. """ diff --git a/jupyterhub/auth.py b/jupyterhub/auth.py index bc9c1ef8..33a00bef 100644 --- a/jupyterhub/auth.py +++ b/jupyterhub/auth.py @@ -101,7 +101,10 @@ class Authenticator(LoggingConfigurable): """ ).tag(config=True) - whitelist = Set(help="Deprecated, use `Authenticator.allowed_users`", config=True,) + whitelist = Set( + help="Deprecated, use `Authenticator.allowed_users`", + config=True, + ) allowed_users = Set( help=""" @@ -715,7 +718,9 @@ for _old_name, _new_name, _version in [ ("check_blacklist", "check_blocked_users", "1.2"), ]: setattr( - Authenticator, _old_name, _deprecated_method(_old_name, _new_name, _version), + Authenticator, + _old_name, + _deprecated_method(_old_name, _new_name, _version), ) @@ -778,7 +783,9 @@ class LocalAuthenticator(Authenticator): """ ).tag(config=True) - group_whitelist = Set(help="""DEPRECATED: use allowed_groups""",).tag(config=True) + group_whitelist = Set( + help="""DEPRECATED: use allowed_groups""", + ).tag(config=True) allowed_groups = Set( help=""" diff --git a/jupyterhub/handlers/base.py b/jupyterhub/handlers/base.py index bb03fad6..e5764f3b 100644 --- a/jupyterhub/handlers/base.py +++ b/jupyterhub/handlers/base.py @@ -489,7 +489,7 @@ class BaseHandler(RequestHandler): self.clear_cookie( 'jupyterhub-services', path=url_path_join(self.base_url, 'services'), - **kwargs + **kwargs, ) # Reset _jupyterhub_user self._jupyterhub_user = None @@ -1485,10 +1485,14 @@ class UserUrlHandler(BaseHandler): # if request is expecting JSON, assume it's an API request and fail with 503 # because it won't like the redirect to the pending page - if get_accepted_mimetype( - self.request.headers.get('Accept', ''), - choices=['application/json', 'text/html'], - ) == 'application/json' or 'api' in user_path.split('/'): + if ( + get_accepted_mimetype( + self.request.headers.get('Accept', ''), + choices=['application/json', 'text/html'], + ) + == 'application/json' + or 'api' in user_path.split('/') + ): self._fail_api_request(user_name, server_name) return diff --git a/jupyterhub/handlers/static.py b/jupyterhub/handlers/static.py index 662af997..e9c54199 100644 --- a/jupyterhub/handlers/static.py +++ b/jupyterhub/handlers/static.py @@ -7,7 +7,7 @@ from tornado.web import StaticFileHandler class CacheControlStaticFilesHandler(StaticFileHandler): """StaticFileHandler subclass that sets Cache-Control: no-cache without `?v=` - + rather than relying on default browser cache behavior. """ diff --git a/jupyterhub/oauth/provider.py b/jupyterhub/oauth/provider.py index 7649f1ad..ea275a45 100644 --- a/jupyterhub/oauth/provider.py +++ b/jupyterhub/oauth/provider.py @@ -256,7 +256,7 @@ class JupyterHubRequestValidator(RequestValidator): self.db.commit() def get_authorization_code_scopes(self, client_id, code, redirect_uri, request): - """ Extracts scopes from saved authorization code. + """Extracts scopes from saved authorization code. The scopes returned by this method is used to route token requests based on scopes passed to Authorization Code requests. With that the token endpoint knows when to include OpenIDConnect diff --git a/jupyterhub/pagination.py b/jupyterhub/pagination.py index 8d4b912d..dc315e7e 100644 --- a/jupyterhub/pagination.py +++ b/jupyterhub/pagination.py @@ -107,14 +107,14 @@ class Pagination(Configurable): def calculate_pages_window(self): """Calculates the set of pages to render later in links() method. - It returns the list of pages to render via links for the pagination - By default, as we've observed in other applications, we're going to render - only a finite and predefined number of pages, avoiding visual fatigue related - to a long list of pages. By default, we render 7 pages plus some inactive links with the characters '...' - to point out that there are other pages that aren't explicitly rendered. - The primary way of work is to provide current webpage and 5 next pages, the last 2 ones - (in case the current page + 5 does not overflow the total lenght of pages) and the first one for reference. - """ + It returns the list of pages to render via links for the pagination + By default, as we've observed in other applications, we're going to render + only a finite and predefined number of pages, avoiding visual fatigue related + to a long list of pages. By default, we render 7 pages plus some inactive links with the characters '...' + to point out that there are other pages that aren't explicitly rendered. + The primary way of work is to provide current webpage and 5 next pages, the last 2 ones + (in case the current page + 5 does not overflow the total lenght of pages) and the first one for reference. + """ before_page = 2 after_page = 2 @@ -158,9 +158,9 @@ class Pagination(Configurable): @property def links(self): """Get the links for the pagination. - Getting the input from calculate_pages_window(), generates the HTML code - for the pages to render, plus the arrows to go onwards and backwards (if needed). - """ + Getting the input from calculate_pages_window(), generates the HTML code + for the pages to render, plus the arrows to go onwards and backwards (if needed). + """ if self.total_pages == 1: return [] diff --git a/jupyterhub/services/auth.py b/jupyterhub/services/auth.py index 2818b7df..6eaa4caa 100644 --- a/jupyterhub/services/auth.py +++ b/jupyterhub/services/auth.py @@ -287,7 +287,7 @@ class HubAuth(SingletonConfigurable): def _check_hub_authorization(self, url, cache_key=None, use_cache=True): """Identify a user with the Hub - + Args: url (str): The API URL to check the Hub for authorization (e.g. http://127.0.0.1:8081/hub/api/authorizations/token/abc-def) @@ -603,10 +603,10 @@ class HubOAuth(HubAuth): def token_for_code(self, code): """Get token for OAuth temporary code - + This is the last step of OAuth login. Should be called in OAuth Callback handler. - + Args: code (str): oauth code for finishing OAuth login Returns: diff --git a/jupyterhub/tests/conftest.py b/jupyterhub/tests/conftest.py index 34c94e4f..db033e84 100644 --- a/jupyterhub/tests/conftest.py +++ b/jupyterhub/tests/conftest.py @@ -216,7 +216,7 @@ def admin_user(app, username): class MockServiceSpawner(jupyterhub.services.service._ServiceSpawner): """mock services for testing. - Shorter intervals, etc. + Shorter intervals, etc. """ poll_interval = 1 diff --git a/jupyterhub/tests/mockservice.py b/jupyterhub/tests/mockservice.py index 6194d844..415f512f 100644 --- a/jupyterhub/tests/mockservice.py +++ b/jupyterhub/tests/mockservice.py @@ -60,7 +60,7 @@ class APIHandler(web.RequestHandler): class WhoAmIHandler(HubAuthenticated, web.RequestHandler): """Reply with the name of the user who made the request. - + Uses "deprecated" cookie login """ @@ -71,7 +71,7 @@ class WhoAmIHandler(HubAuthenticated, web.RequestHandler): class OWhoAmIHandler(HubOAuthenticated, web.RequestHandler): """Reply with the name of the user who made the request. - + Uses OAuth login flow """ diff --git a/jupyterhub/tests/test_api.py b/jupyterhub/tests/test_api.py index 9afad86a..4750afda 100644 --- a/jupyterhub/tests/test_api.py +++ b/jupyterhub/tests/test_api.py @@ -182,7 +182,8 @@ async def test_get_users(app): @mark.user @mark.parametrize( - "state", ("inactive", "active", "ready", "invalid"), + "state", + ("inactive", "active", "ready", "invalid"), ) async def test_get_users_state_filter(app, state): db = app.db diff --git a/jupyterhub/tests/test_pages.py b/jupyterhub/tests/test_pages.py index 59fa7a19..7140b823 100644 --- a/jupyterhub/tests/test_pages.py +++ b/jupyterhub/tests/test_pages.py @@ -265,7 +265,8 @@ async def test_spawn_with_query_arguments(app): next_url = ujoin(app.base_url, 'user/jones/tree') r = await async_requests.get( url_concat( - ujoin(base_url, 'spawn'), {'next': next_url, 'energy': '510keV'}, + ujoin(base_url, 'spawn'), + {'next': next_url, 'energy': '510keV'}, ), cookies=cookies, ) diff --git a/jupyterhub/tests/test_spawner.py b/jupyterhub/tests/test_spawner.py index e728081d..7a37cc58 100644 --- a/jupyterhub/tests/test_spawner.py +++ b/jupyterhub/tests/test_spawner.py @@ -258,8 +258,7 @@ async def test_shell_cmd(db, tmpdir, request): def test_inherit_overwrite(): - """On 3.6+ we check things are overwritten at import time - """ + """On 3.6+ we check things are overwritten at import time""" if sys.version_info >= (3, 6): with pytest.raises(NotImplementedError): diff --git a/jupyterhub/utils.py b/jupyterhub/utils.py index 1f3e163c..8fcf7bc6 100644 --- a/jupyterhub/utils.py +++ b/jupyterhub/utils.py @@ -75,8 +75,7 @@ def can_connect(ip, port): def make_ssl_context(keyfile, certfile, cafile=None, verify=True, check_hostname=True): - """Setup context for starting an https server or making requests over ssl. - """ + """Setup context for starting an https server or making requests over ssl.""" if not keyfile or not certfile: return None purpose = ssl.Purpose.SERVER_AUTH if verify else ssl.Purpose.CLIENT_AUTH @@ -96,7 +95,7 @@ async def exponential_backoff( timeout=10, timeout_tolerance=0.1, *args, - **kwargs + **kwargs, ): """ Exponentially backoff until `pass_func` is true. diff --git a/pyproject.toml b/pyproject.toml index 0097e9f6..a7630d48 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,2 +1,7 @@ [tool.black] skip-string-normalization = true +target_version = [ + "py36", + "py37", + "py38", +] diff --git a/tools/tasks.py b/tools/tasks.py index dbbc89f4..c9648e04 100644 --- a/tools/tasks.py +++ b/tools/tasks.py @@ -142,7 +142,7 @@ def untag(vs, push=False): def make_env(*packages): """Make a virtualenv - + Assumes `which python` has the `virtualenv` package """ if not os.path.exists(env_root): @@ -167,7 +167,7 @@ def make_env(*packages): def build_sdist(py): """Build sdists - + Returns the path to the tarball """ with cd(repo_root):