diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index cb2c87e3..fc3122fa 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -9,8 +9,8 @@ Summary of approach. ### To-Do - [ ] Clean up commit history - -* [ ] Add entry to the [release notes](https://github.com/libp2p/py-libp2p/blob/main/newsfragments/README.md) +- [ ] Add or update documentation related to these changes +- [ ] Add entry to the [release notes](https://github.com/libp2p/py-libp2p/blob/main/newsfragments/README.md) #### Cute Animal Picture diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index b84d4cd1..fa8c42b9 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -4,7 +4,7 @@ on: pull_request: push: branches: - - master + - main - github-actions defaults: @@ -16,10 +16,10 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python: ['3.8', '3.9', '3.10', '3.11', '3.12'] + python: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] toxenv: [core, lint, wheel] include: - - python: '3.9' + - python: '3.10' toxenv: docs fail-fast: false steps: diff --git a/.gitignore b/.gitignore index 33f68437..192718c6 100644 --- a/.gitignore +++ b/.gitignore @@ -95,31 +95,8 @@ logs # vs-code .vscode -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff: -.idea/workspace.xml -.idea/tasks.xml -.idea/dictionaries -.idea/vcs.xml -.idea/jsLibraryMappings.xml - -# Sensitive or high-churn files: -.idea/dataSources.ids -.idea/dataSources.xml -.idea/dataSources.local.xml -.idea/sqlDataSources.xml -.idea/dynamic.xml -.idea/uiDesigner.xml - -# Gradle: -.idea/gradle.xml -.idea/libraries - -# Mongo Explorer plugin: -.idea/mongoSettings.xml +# jupyter notebook files +*.ipynb # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm # For a more precise, explicit template, see: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 093599b1..0ddba122 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -exclude: '.project-template|docs/conf.py|.bumpversion.cfg|.*pb2\..*' +exclude: '.project-template|docs/conf.py|.*pb2\..*' repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 1d04e5cf..6ae9548a 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -3,7 +3,7 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.9" + python: "3.10" sphinx: configuration: docs/conf.py diff --git a/Makefile b/Makefile index 2fac0807..d78b722f 100644 --- a/Makefile +++ b/Makefile @@ -6,16 +6,18 @@ help: @echo "clean-build - remove build artifacts" @echo "clean-pyc - remove Python file artifacts" @echo "clean - run clean-build and clean-pyc" + @echo "dist - build package and cat contents of the dist directory" @echo "lint - fix linting issues with pre-commit" @echo "test - run tests quickly with the default Python" @echo "docs - generate docs and open in browser (linux-docs for version on linux)" - @echo "notes - consume towncrier newsfragments/ and update release notes in docs/" - @echo "release - package and upload a release (does not run notes target)" - @echo "dist - package" + @echo "package-test - build package and install it in a venv for manual testing" + @echo "notes - consume towncrier newsfragments and update release notes in docs - requires bump to be set" + @echo "release - package and upload a release (does not run notes target) - requires bump to be set" clean-build: rm -fr build/ rm -fr dist/ + rm -fr *.egg-info clean-pyc: find . -name '*.pyc' -exec rm -f {} + @@ -25,6 +27,10 @@ clean-pyc: clean: clean-build clean-pyc +dist: clean + python -m build + ls -l dist + lint: @pre-commit run --all-files --show-diff-on-failure || ( \ echo "\n\n\n * pre-commit should have fixed the errors above. Running again to make sure everything is good..." \ @@ -32,7 +38,7 @@ lint: ) test: - pytest tests + python -m pytest tests # protobufs management @@ -73,13 +79,11 @@ validate-newsfragments: check-docs: build-docs validate-newsfragments build-docs: - sphinx-apidoc -o docs/ . setup.py "*conftest*" "libp2p/tools/interop*" + sphinx-apidoc -o docs/ . setup.py "*conftest*" $(MAKE) -C docs clean $(MAKE) -C docs html $(MAKE) -C docs doctest -# docs helpers for CI, which requires extra dependencies - check-docs-ci: build-docs build-docs-ci validate-newsfragments build-docs-ci: @@ -93,14 +97,14 @@ package-test: clean notes: check-bump validate-newsfragments # Let UPCOMING_VERSION be the version that is used for the current bump - $(eval UPCOMING_VERSION=$(shell bump-my-version show --increment $(bump) new_version)) + $(eval UPCOMING_VERSION=$(shell bump-my-version bump --dry-run $(bump) -v | awk -F"'" '/New version will be / {print $$2}')) # Now generate the release notes to have them included in the release commit towncrier build --yes --version $(UPCOMING_VERSION) # Before we bump the version, make sure that the towncrier-generated docs will build make build-docs git commit -m "Compile release notes for v$(UPCOMING_VERSION)" -release: check-bump clean +release: check-bump check-git clean # verify that notes command ran correctly ./newsfragments/validate_files.py is-empty CURRENT_SIGN_SETTING=$(git config commit.gpgSign) @@ -115,15 +119,10 @@ release: check-bump clean check-bump: ifndef bump - $(error bump must be one of: major, minor, patch, stage, or devnum) + $(error bump must be set, typically: major, minor, patch, or devnum) endif check-git: - # require that you be on a branch that's linked to upstream/main - @if ! git status -s -b | head -1 | grep -q "\.\.upstream/main"; then \ - echo "Error: You must be on a branch that's linked to upstream/main"; \ - exit 1; \ - fi # require that upstream is configured for ethereum/py-libp2p @if ! git remote -v | grep "upstream[[:space:]]git@github.com:ethereum/py-libp2p.git (push)\|upstream[[:space:]]https://github.com/ethereum/py-libp2p (push)"; then \ echo "Error: You must have a remote named 'upstream' that points to 'py-libp2p'"; \ diff --git a/docs/conf.py b/docs/conf.py index f0bd6191..8a9af857 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# # py-libp2p documentation build configuration file, created by # sphinx-quickstart on Thu Oct 16 20:43:24 2014. # @@ -19,7 +17,7 @@ import os -DIR = os.path.dirname("__file__") +DIR = os.path.dirname(__file__) with open(os.path.join(DIR, "../setup.py"), "r") as f: for line in f: if "version=" in line: @@ -200,6 +198,8 @@ htmlhelp_basename = "libp2pdocs" # -- Options for LaTeX output --------------------------------------------- +latex_engine = "xelatex" + latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', diff --git a/docs/contributing.rst b/docs/contributing.rst index 6a7c3603..d760d02c 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -1,8 +1,12 @@ Contributing ------------ -Development -~~~~~~~~~~~ +Thank you for your interest in contributing! We welcome all contributions no matter +their size. Please read along to learn how to get started. If you get stuck, feel free +to ask for help in `Ethereum Python Discord server `_. + +Setting the stage +~~~~~~~~~~~~~~~~~ To get started, fork the repository to your own github account, then clone it to your development machine: @@ -11,8 +15,7 @@ development machine: git clone git@github.com:your-github-username/py-libp2p.git - -then install the development dependencies. We recommend using a virtual environment, +Next, install the development dependencies. We recommend using a virtual environment, such as `virtualenv `_. .. code:: sh @@ -43,12 +46,16 @@ Requirements The protobuf description in this repository was generated by ``protoc`` at version ``27.2``. -Testing -~~~~~~~ +Running the tests +~~~~~~~~~~~~~~~~~ -Running that tests is a great way to explore the codebase. +A great way to explore the code base is to run the tests. -You can run all the tests with ``pytest tests``. +We can run all tests with: + +.. code:: sh + + make test At this time, the interop tests are not passing. You can run just the internal tests with ``pytest tests/core``. @@ -57,20 +64,47 @@ with ``pytest tests/core``. Code Style ~~~~~~~~~~ -We use `pre-commit `_ to maintain consistent code style. Once -installed, it will run automatically with every commit. You can also run it manually -with: +We use `pre-commit `_ to enforce a consistent code style across +the library. This tool runs automatically with every commit, but you can also run it +manually with: .. code:: sh make lint -If you need to make a commit that skips the pre-commit checks, you can do so with +If you need to make a commit that skips the ``pre-commit`` checks, you can do so with ``git commit --no-verify``. -This project uses ``mypy`` for static type checking, though it is not yet complete. -All new code should be fully typed, and we are working to add types to the existing -codebase. +This library uses type hints, which are enforced by the ``mypy`` tool (part of the +``pre-commit`` checks). All new code is required to land with type hints, with the +exception of code within the ``tests`` directory. + +Documentation +~~~~~~~~~~~~~ + +Good documentation will lead to quicker adoption and happier users. Please check out our +guide on +`how to create documentation for the Python Ethereum ecosystem `_. + +Pull Requests +~~~~~~~~~~~~~ + +It's a good idea to make pull requests early on. A pull request represents the start of +a discussion, and doesn't necessarily need to be the final, finished submission. + +GitHub's documentation for working on pull requests is +`available here `_. + +Once you've made a pull request, take a look at the Circle CI build status in the +GitHub interface and make sure all tests are passing. In general pull requests that +do not pass the CI build yet won't get reviewed unless explicitly requested. + +If the pull request introduces changes that should be reflected in the release notes, +please add a `newsfragment` file as explained +`here `_. + +If possible, the change to the release notes file should be included in the commit that +introduces the feature or bugfix. Releasing ~~~~~~~~~ @@ -87,10 +121,8 @@ Before releasing a new version, build and test the package that will be released .. code:: sh git checkout main && git pull - make package-test - This will build the package and install it in a temporary virtual environment. Follow the instructions to activate the venv and test whatever you think is important. @@ -100,7 +132,6 @@ You can also preview the release notes: towncrier --draft - Build the release notes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -112,7 +143,6 @@ release notes. make notes bump=$$VERSION_PART_TO_BUMP$$ - If there are any errors, be sure to re-run make notes until it works. Push the release to github & pypi @@ -124,7 +154,6 @@ After confirming that the release package looks okay, release a new version: make release bump=$$VERSION_PART_TO_BUMP$$ - This command will: - Bump the version number as specified in ``.pyproject.toml`` and ``setup.py``. diff --git a/docs/index.rst b/docs/index.rst index 392e435b..35d38247 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,8 +3,13 @@ py-libp2p The Python implementation of the libp2p networking stack -Contents --------- +Installation +------------ + +.. code-block:: bash + + python -m pip install py-libp2p + .. toctree:: :maxdepth: 1 @@ -14,6 +19,9 @@ Contents quickstart release_notes +.. toctree:: + :maxdepth: 1 + :caption: Community .. toctree:: :maxdepth: 1 diff --git a/newsfragments/496.feature.rst b/newsfragments/496.feature.rst new file mode 100644 index 00000000..535e107e --- /dev/null +++ b/newsfragments/496.feature.rst @@ -0,0 +1 @@ +Merge template, adding python 3.13 to CI checks. diff --git a/pyproject.toml b/pyproject.toml index 40638063..27d20ac0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,11 +7,14 @@ combine_as_imports = false extra_standard_library = "pytest" force_grid_wrap = 1 force_sort_within_sections = true +force_to_top = "pytest" +honor_noqa = true known_first_party = "libp2p" known_third_party = "anyio,factory,lru,p2pclient,pytest,noise" multi_line_output = 3 profile = "black" skip_glob= "*_pb2*.py, *.pyi" +use_parentheses = true [tool.mypy] check_untyped_defs = true diff --git a/scripts/release/test_package.py b/scripts/release/test_package.py index e8221c1d..2f23898e 100644 --- a/scripts/release/test_package.py +++ b/scripts/release/test_package.py @@ -5,9 +5,6 @@ import subprocess from tempfile import ( TemporaryDirectory, ) -from typing import ( - Tuple, -) import venv @@ -25,23 +22,16 @@ def find_wheel(project_path: Path) -> Path: if len(wheels) != 1: raise Exception( - f"Expected one wheel. Instead found: {wheels} in project " - f"{project_path.absolute()}" + f"Expected one wheel. Instead found: {wheels} " + f"in project {project_path.absolute()}" ) return wheels[0] -def install_wheel( - venv_path: Path, wheel_path: Path, extras: Tuple[str, ...] = () -) -> None: - if extras: - extra_suffix = f"[{','.join(extras)}]" - else: - extra_suffix = "" - +def install_wheel(venv_path: Path, wheel_path: Path) -> None: subprocess.run( - [venv_path / "bin" / "pip", "install", f"{wheel_path}{extra_suffix}"], + [venv_path / "bin" / "pip", "install", f"{wheel_path}"], check=True, ) diff --git a/setup.py b/setup.py index 59edb2af..1aa753b9 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ from setuptools import ( extras_require = { "dev": [ "build>=0.9.0", - "bump-my-version>=0.5.3", + "bump_my_version>=0.19.0", "ipython", "mypy==1.10.0", "pre-commit>=3.4.0", @@ -20,7 +20,7 @@ extras_require = { "docs": [ "sphinx>=6.0.0", "sphinx_rtd_theme>=1.0.0", - "towncrier>=21,<22", + "towncrier>=24,<25", ], "test": [ "pytest>=7.0.0", @@ -79,7 +79,7 @@ if not readthedocs_is_building: setup( name="libp2p", - # *IMPORTANT*: Don't manually change the version here. Use `make bump`, as described in readme + # *IMPORTANT*: Don't manually change the version here. See Contributing docs for the release process. version="0.2.1", description="""libp2p: The Python implementation of the libp2p networking stack""", long_description=long_description, @@ -109,6 +109,7 @@ setup( "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ], platforms=["unix", "linux", "osx"], entry_points={ diff --git a/tests/core/network/test_swarm.py b/tests/core/network/test_swarm.py index ae2b46d0..d3d6a7f8 100644 --- a/tests/core/network/test_swarm.py +++ b/tests/core/network/test_swarm.py @@ -1,7 +1,7 @@ +import pytest from multiaddr import ( Multiaddr, ) -import pytest import trio from trio.testing import ( wait_all_tasks_blocked, diff --git a/tests/core/peer/test_peerinfo.py b/tests/core/peer/test_peerinfo.py index cc3f79a0..497060c0 100644 --- a/tests/core/peer/test_peerinfo.py +++ b/tests/core/peer/test_peerinfo.py @@ -1,7 +1,7 @@ import random -import multiaddr import pytest +import multiaddr from libp2p.peer.id import ( ID, diff --git a/tests/core/test_libp2p/test_libp2p.py b/tests/core/test_libp2p/test_libp2p.py index 7fa7bbdc..235cd119 100644 --- a/tests/core/test_libp2p/test_libp2p.py +++ b/tests/core/test_libp2p/test_libp2p.py @@ -1,5 +1,5 @@ -import multiaddr import pytest +import multiaddr from libp2p.network.stream.exceptions import ( StreamError, diff --git a/tests/core/transport/test_tcp.py b/tests/core/transport/test_tcp.py index 8d011f4f..0a77a78d 100644 --- a/tests/core/transport/test_tcp.py +++ b/tests/core/transport/test_tcp.py @@ -1,7 +1,7 @@ +import pytest from multiaddr import ( Multiaddr, ) -import pytest import trio from libp2p.network.connection.raw_connection import ( diff --git a/tests/interop/conftest.py b/tests/interop/conftest.py index 80785fce..39efbe31 100644 --- a/tests/interop/conftest.py +++ b/tests/interop/conftest.py @@ -2,6 +2,7 @@ from contextlib import ( AsyncExitStack, ) +import pytest import anyio from p2pclient.datastructures import ( StreamInfo, @@ -9,7 +10,6 @@ from p2pclient.datastructures import ( from p2pclient.utils import ( get_unused_tcp_port, ) -import pytest import trio from libp2p.io.abc import ( diff --git a/tests/interop/test_echo.py b/tests/interop/test_echo.py index 623b4085..00a990f6 100644 --- a/tests/interop/test_echo.py +++ b/tests/interop/test_echo.py @@ -1,12 +1,12 @@ import re +import pytest from multiaddr import ( Multiaddr, ) from p2pclient.utils import ( get_unused_tcp_port, ) -import pytest import trio from libp2p.peer.peerinfo import ( diff --git a/tests/interop/test_pubsub.py b/tests/interop/test_pubsub.py index 471f0dea..1132831d 100644 --- a/tests/interop/test_pubsub.py +++ b/tests/interop/test_pubsub.py @@ -1,10 +1,10 @@ import functools import math +import pytest from p2pclient.pb import ( p2pd_pb2, ) -import pytest import trio from libp2p.io.trio import ( diff --git a/tox.ini b/tox.ini index 0b27b621..f345cd7e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,9 @@ [tox] envlist= - py{38,39,310,311,312}-core - py{38,39,310,311,312}-lint - py{38,39,310,311,312}-wheel - py{38,39,310,311,312}-interop + py{38,39,310,311,312,313}-core + py{38,39,310,311,312,313}-lint + py{38,39,310,311,312,313}-wheel + py{38,39,310,311,312,313}-interop windows-wheel docs @@ -13,6 +13,9 @@ extend-ignore=E203 max-line-length=88 per-file-ignores=__init__.py:F401 +[blocklint] +max_issue_threshold=1 + [testenv] usedevelop=True commands= @@ -27,12 +30,13 @@ basepython= py310: python3.10 py311: python3.11 py312: python3.12 + py313: python3.13 extras= test docs allowlist_externals=make,pre-commit -[testenv:py{38,39,310,311,312}-lint] +[testenv:py{38,39,310,311,312,313}-lint] deps=pre-commit extras= dev @@ -40,7 +44,7 @@ commands= pre-commit install pre-commit run --all-files --show-diff-on-failure -[testenv:py{38,39,310,311,312}-wheel] +[testenv:py{38,39,310,311,312,313}-wheel] deps= wheel build[virtualenv]