diff --git a/pyproject.toml b/pyproject.toml index af83201f..2c0f5880 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,100 @@ +# PEP 621 build info +[build-system] +requires = ["setuptools>=61", "setuptools-scm"] +build-backend = "setuptools.build_meta" + +# Project metadata +# ref: https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html +[project] +name = "jupyterhub" +version = "4.1.0.dev" +dynamic = ["readme", "dependencies"] +description = "JupyterHub: A multi-user server for Jupyter notebooks" +authors = [ + { name = "Jupyter Development Team", email = "jupyter@googlegroups.com" }, +] +keywords = ["Interactive", "Interpreter", "Shell", "Web", "Jupyter"] +license = { text = "BSD-3-Clause" } +requires-python = ">=3.7" +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: BSD License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Operating System :: POSIX", + "Framework :: Jupyter", +] + +[project.urls] +Homepage = "https://hub.jupyter.org" +Documentation = "https://jupyterhub.readthedocs.io" +Funding = "https://jupyter.org/about" +Source = "https://github.com/jupyterhub/jupyterhub" +Tracker = "https://github.com/jupyterhub/jupyterhub/issues" + +[project.optional-dependencies] +test = [ + "beautifulsoup4[html5lib]", + "coverage", + # cryptography is an optional dependency for jupyterhub that we test + # against by default + "cryptography", + "jsonschema", + "jupyterlab>=3", + "mock", + # nbclassic provides the '/tree/' handler that we tests against in + # the test test_nbclassic_control_panel. + "nbclassic", + "pytest>=3.3", + "pytest-asyncio>=0.17", + "pytest-cov", + "requests-mock", + "playwright", + "virtualenv", +] + +[project.scripts] +jupyterhub = "jupyterhub.app:main" +jupyterhub-singleuser = "jupyterhub.singleuser:main" + +[project.entry-points."jupyterhub.authenticators"] +default = "jupyterhub.auth:PAMAuthenticator" +pam = "jupyterhub.auth:PAMAuthenticator" +dummy = "jupyterhub.auth:DummyAuthenticator" +null = "jupyterhub.auth:NullAuthenticator" + +[project.entry-points."jupyterhub.proxies"] +default = "jupyterhub.proxy:ConfigurableHTTPProxy" +configurable-http-proxy = "jupyterhub.proxy:ConfigurableHTTPProxy" + +[project.entry-points."jupyterhub.spawners"] +default = "jupyterhub.spawner:LocalProcessSpawner" +localprocess = "jupyterhub.spawner:LocalProcessSpawner" +simple = "jupyterhub.spawner:SimpleLocalProcessSpawner" + +[tool.setuptools] +zip-safe = false +license-files = ["COPYING.md"] +include-package-data = true + +[tool.setuptools.packages.find] +where = [""] +include = ["jupyterhub*"] + +# dynamic sources of metadata in other files +[tool.setuptools.dynamic] +readme = { file = "README.md", content-type = "text/markdown" } +dependencies = { file = "requirements.txt" } + +# declarative data-files doesn't quite work right +# this is still in setup.py:get_data_files +# [tool.setuptools.data-files] +# "share/jupyterhub" = ["share/jupyterhub/**"] + + # autoflake is used for autoformatting Python code # # ref: https://github.com/PyCQA/autoflake#readme @@ -67,6 +164,10 @@ tag_template = "{new_version}" # section containing the path of the file, relative to the # pyproject.toml location. +[[tool.tbump.file]] +src = "pyproject.toml" +search = 'version = "{current_version}"' + [[tool.tbump.file]] src = "jupyterhub/_version.py" version_template = '({major}, {minor}, {patch}, "{pre}", "{dev}")' diff --git a/setup.py b/setup.py index 2aad1b14..d3d7b735 100755 --- a/setup.py +++ b/setup.py @@ -1,9 +1,7 @@ #!/usr/bin/env python3 # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. -# ----------------------------------------------------------------------------- -# Minimal Python version sanity check (from IPython) -# ----------------------------------------------------------------------------- + import os import shutil import sys @@ -12,6 +10,7 @@ from subprocess import check_call from setuptools import Command, setup from setuptools.command.bdist_egg import bdist_egg from setuptools.command.build_py import build_py +from setuptools.command.develop import develop from setuptools.command.sdist import sdist shell = False @@ -29,9 +28,7 @@ static = pjoin(share_jupyterhub, 'static') is_repo = os.path.exists(pjoin(here, '.git')) -# --------------------------------------------------------------------------- # Build basic package data, etc. -# --------------------------------------------------------------------------- def get_data_files(): @@ -44,113 +41,6 @@ def get_data_files(): return data_files -def get_package_data(): - """Get package data - - (mostly alembic config) - """ - package_data = {} - package_data['jupyterhub'] = [ - 'alembic.ini', - 'alembic/*', - 'alembic/versions/*', - 'event-schemas/*/*.yaml', - 'singleuser/templates/*.html', - ] - return package_data - - -ns = {} -with open(pjoin(here, 'jupyterhub', '_version.py')) as f: - exec(f.read(), {}, ns) - - -packages = [] -for d, _, _ in os.walk('jupyterhub'): - if os.path.exists(pjoin(d, '__init__.py')): - packages.append(d.replace(os.path.sep, '.')) - -with open('README.md', encoding="utf8") as f: - readme = f.read() - - -setup_args = dict( - name='jupyterhub', - packages=packages, - # dummy, so that install_data doesn't get skipped - # this will be overridden when bower is run anyway - data_files=get_data_files() or ['dummy'], - package_data=get_package_data(), - version=ns['__version__'], - description="JupyterHub: A multi-user server for Jupyter notebooks", - long_description=readme, - long_description_content_type='text/markdown', - author="Jupyter Development Team", - author_email="jupyter@googlegroups.com", - url="https://jupyter.org", - license="BSD", - platforms="Linux, Mac OS X", - keywords=['Interactive', 'Interpreter', 'Shell', 'Web'], - python_requires=">=3.7", - entry_points={ - 'jupyterhub.authenticators': [ - 'default = jupyterhub.auth:PAMAuthenticator', - 'pam = jupyterhub.auth:PAMAuthenticator', - 'dummy = jupyterhub.auth:DummyAuthenticator', - 'null = jupyterhub.auth:NullAuthenticator', - ], - 'jupyterhub.proxies': [ - 'default = jupyterhub.proxy:ConfigurableHTTPProxy', - 'configurable-http-proxy = jupyterhub.proxy:ConfigurableHTTPProxy', - ], - 'jupyterhub.spawners': [ - 'default = jupyterhub.spawner:LocalProcessSpawner', - 'localprocess = jupyterhub.spawner:LocalProcessSpawner', - 'simple = jupyterhub.spawner:SimpleLocalProcessSpawner', - ], - 'console_scripts': [ - 'jupyterhub = jupyterhub.app:main', - 'jupyterhub-singleuser = jupyterhub.singleuser:main', - ], - }, - classifiers=[ - 'Intended Audience :: Developers', - 'Intended Audience :: System Administrators', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: BSD License', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - ], - project_urls={ - 'Documentation': 'https://jupyterhub.readthedocs.io', - 'Funding': 'https://jupyter.org/about', - 'Source': 'https://github.com/jupyterhub/jupyterhub/', - 'Tracker': 'https://github.com/jupyterhub/jupyterhub/issues', - }, - extras_require={ - "test": [ - "beautifulsoup4[html5lib]", - "coverage", - # cryptography is an optional dependency for jupyterhub that we test - # against by default - "cryptography", - "jsonschema", - "jupyterlab>=3", - "mock", - # nbclassic provides the '/tree/' handler that we tests against in - # the test test_nbclassic_control_panel. - "nbclassic", - "pytest>=3.3", - "pytest-asyncio>=0.17", - "pytest-cov", - "requests-mock", - "playwright", - "virtualenv", - ], - }, -) - - def mtime(path): """shorthand for mtime""" return os.stat(path).st_mtime @@ -373,22 +263,6 @@ class bdist_egg_disabled(bdist_egg): ) -setup_args['cmdclass'] = { - 'js': NPM, - 'css': CSS, - 'jsx': JSX, - 'build_py': js_css_first(build_py, strict=is_repo), - 'sdist': js_css_first(sdist, strict=True), - 'bdist_egg': bdist_egg if 'bdist_egg' in sys.argv else bdist_egg_disabled, -} - - -# setuptools requirements - -setup_args['zip_safe'] = False -from setuptools.command.develop import develop - - class develop_js_css(develop): def run(self): if not self.uninstall: @@ -397,23 +271,24 @@ class develop_js_css(develop): super().run() -setup_args['cmdclass']['develop'] = develop_js_css -setup_args['install_requires'] = install_requires = [] +cmdclass = { + 'js': NPM, + 'css': CSS, + 'jsx': JSX, + 'build_py': js_css_first(build_py, strict=is_repo), + 'sdist': js_css_first(sdist, strict=True), + 'bdist_egg': bdist_egg if 'bdist_egg' in sys.argv else bdist_egg_disabled, + 'develop': develop_js_css, +} -with open('requirements.txt') as f: - for line in f.readlines(): - req = line.strip() - if not req or req.startswith('#') or '://' in req: - continue - install_requires.append(req) - -# --------------------------------------------------------------------------- -# setup -# --------------------------------------------------------------------------- +# run setup def main(): - setup(**setup_args) + setup( + cmdclass=cmdclass, + data_files=get_data_files(), + ) if __name__ == '__main__':