From a7955a560ea8f8c10694ecdd57a6b189086f1e9c Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 24 Jan 2018 16:00:28 -0800 Subject: [PATCH 001/159] init --- .bumpversion.cfg | 23 ++++ .gitignore | 107 ++++++++++++++++ .travis.yml | 31 +++++ LICENSE | 21 ++++ Makefile | 54 ++++++++ README.md | 84 +++++++++++++ docs/conf.py | 274 +++++++++++++++++++++++++++++++++++++++++ docs/releases.rst | 7 ++ fill_template_vars.sh | 35 ++++++ pytest.ini | 7 ++ setup.py | 64 ++++++++++ tests/core/conftest.py | 0 tox.ini | 35 ++++++ 13 files changed, 742 insertions(+) create mode 100644 .bumpversion.cfg create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 docs/conf.py create mode 100644 docs/releases.rst create mode 100755 fill_template_vars.sh create mode 100644 pytest.ini create mode 100644 setup.py create mode 100644 tests/core/conftest.py create mode 100644 tox.ini diff --git a/.bumpversion.cfg b/.bumpversion.cfg new file mode 100644 index 0000000..eefe4ad --- /dev/null +++ b/.bumpversion.cfg @@ -0,0 +1,23 @@ +[bumpversion] +current_version = 0.1.0-alpha.0 +commit = True +tag = True +parse = (?P\d+)\.(?P\d+)\.(?P\d+)(-(?P[^.]*)\.(?P\d+))? +serialize = + {major}.{minor}.{patch}-{stage}.{devnum} + {major}.{minor}.{patch} + +[bumpversion:part:stage] +optional_value = stable +first_value = stable +values = + alpha + beta + stable + +[bumpversion:part:devnum] + +[bumpversion:file:setup.py] +search = version='{current_version}', +replace = version='{new_version}', + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c380203 --- /dev/null +++ b/.gitignore @@ -0,0 +1,107 @@ +*.py[cod] + +# C extensions +*.so + +# Packages +*.egg +*.egg-info +dist +build +eggs +.eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 +venv* + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox +nosetests.xml + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# Complexity +output/*.html +output/*/index.html + +# Sphinx +docs/_build +docs/modules.rst +docs/web3.* + +# Blockchain +chains + +# Hypothese Property base testing +.hypothesis + +# tox/pytest cache +.cache + +# Test output logs +logs +### 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 + +# VIM temp files +*.swp + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..72be81d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,31 @@ +sudo: false +language: python +dist: trusty +matrix: + include: + # + # Python 3.5 testing + # + # lint + - python: "3.5" + env: TOX_POSARGS="-e lint" + # core + - python: "3.5" + env: TOX_POSARGS="-e py35-core" + # + # Python 3.6 testing + # + # core + - python: "3.6" + env: TOX_POSARGS="-e py36-core" +cache: + - pip: true +install: + - travis_retry pip install pip setuptools --upgrade + - travis_retry pip install tox +before_script: + - python --version + - pip --version + - pip freeze +script: + - tox $TOX_POSARGS diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1b7a2b5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Jason Carver + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b842465 --- /dev/null +++ b/Makefile @@ -0,0 +1,54 @@ +.PHONY: clean-pyc clean-build docs + +help: + @echo "clean-build - remove build artifacts" + @echo "clean-pyc - remove Python file artifacts" + @echo "lint - check style with flake8" + @echo "test - run tests quickly with the default Python" + @echo "testall - run tests on every Python version with tox" + @echo "release - package and upload a release" + @echo "dist - package" + +clean: clean-build clean-pyc + +clean-build: + rm -fr build/ + rm -fr dist/ + rm -fr *.egg-info + +clean-pyc: + find . -name '*.pyc' -exec rm -f {} + + find . -name '*.pyo' -exec rm -f {} + + find . -name '*~' -exec rm -f {} + + +lint: + tox -elint + +test: + py.test tests + +test-all: + tox + +build-docs: + sphinx-apidoc -o docs/ . setup.py "*conftest*" + $(MAKE) -C docs clean + $(MAKE) -C docs html + +docs: build-docs + open docs/_build/html/index.html + +linux-docs: build-docs + xdg-open docs/_build/html/index.html + +release: clean + CURRENT_SIGN_SETTING=$(git config commit.gpgSign) + git config commit.gpgSign true + bumpversion $(bump) + git push && git push --tags + python setup.py sdist bdist_wheel upload + git config commit.gpgSign "$(CURRENT_SIGN_SETTING)" + +dist: clean + python setup.py sdist bdist_wheel + ls -l dist diff --git a/README.md b/README.md new file mode 100644 index 0000000..e29c4d9 --- /dev/null +++ b/README.md @@ -0,0 +1,84 @@ +# + +[![Join the chat at https://gitter.im/ethereum/](https://badges.gitter.im/ethereum/.svg)](https://gitter.im/ethereum/?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +[![Build Status](https://travis-ci.org/ethereum/.png)](https://travis-ci.org/ethereum/) + + + + +* Python 3.5+ support + +Read more in the [documentation on ReadTheDocs](http://.readthedocs.io/). [View the change log on Github](docs/releases.rst). + +## Quickstart + +```sh +pip install +``` + +## Developer setup + +If you would like to hack on , set up your dev environment with: + +```sh + +git clone git@github.com:ethereum/.git +cd +virtualenv -p python3 venv +. venv/bin/activate +pip install -e .[dev] +``` + +### Testing Setup + +During development, you might like to have tests run on every file save. + +Show flake8 errors on file change: + +```sh +# Test flake8 +when-changed -v -s -r -1 / tests/ -c "clear; flake8 tests && echo 'flake8 success' || echo 'error'" +``` + +Run multi-process tests in one command, but without color: + +```sh +# in the project root: +pytest --numprocesses=4 --looponfail --maxfail=1 +# the same thing, succinctly: +pytest -n 4 -f --maxfail=1 +``` + +Run in one thread, with color and desktop notifications: + +```sh +cd venv +ptw --onfail "notify-send -t 5000 'Test failure ⚠⚠⚠⚠⚠' 'python 3 test on failed'" ../tests ../ +``` + +### Release setup + +For Debian-like systems: +``` +apt install pandoc +``` + +To release a new version: + +```sh +make release bump=$$VERSION_PART_TO_BUMP$$ +``` + +#### How to bumpversion + +The version format for this repo is `{major}.{minor}.{patch}` for stable, and +`{major}.{minor}.{patch}-{stage}.{devnum}` for unstable (`stage` can be alpha or beta). + +To issue the next version in line, specify which part to bump, +like `make release bump=minor` or `make release bump=devnum`. + +If you are in a beta version, `make release bump=stage` will switch to a stable. + +To issue an unstable version when the current version is stable, specify the +new version explicitly, like `make release bump="--new-version 4.0.0-alpha.1 devnum"` diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..77bcb7e --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,274 @@ +# -*- coding: utf-8 -*- +# +# documentation build configuration file, created by +# sphinx-quickstart on Thu Oct 16 20:43:24 2014. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +import os + +DIR = os.path.dirname('__file__') +with open (os.path.join(DIR, '../setup.py'), 'r') as f: + for line in f: + if 'version=' in line: + setup_version = line.split('\'')[1] + break + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = '' +copyright = '2018, Jason Carver, Piper Merriam' + +__version__ = setup_version +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '.'.join(__version__.split('.')[:2]) +# The full version, including alpha/beta/rc tags. +release = __version__ + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [ + '_build', + '.rst', + 'modules.rst', +] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'doc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', '.tex', ' Documentation', + 'Jason Carver', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', '', ' Documentation', + ['Jason Carver'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', '', ' Documentation', + 'Jason Carver', '', '', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + +# -- Intersphinx configuration ------------------------------------------------ + +intersphinx_mapping = { + 'python': ('https://docs.python.org/3.5', None), +} diff --git a/docs/releases.rst b/docs/releases.rst new file mode 100644 index 0000000..ec4804d --- /dev/null +++ b/docs/releases.rst @@ -0,0 +1,7 @@ +Release Notes +============= + +v0.1.0-alpha.1 +------------- + +- Launched repository, claimed names for pip, RTD, github, etc diff --git a/fill_template_vars.sh b/fill_template_vars.sh new file mode 100755 index 0000000..ecbdcb0 --- /dev/null +++ b/fill_template_vars.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +# List of all non-executable files +TEMPLATE_FILES=$(find . ! -perm -u=x -type f) + +echo "What is your python module name?" +read MODULE_NAME + +echo "What is your pypi package name? (default: $MODULE_NAME)" +read PYPI_INPUT +PYPI_NAME=${PYPI_INPUT:-$MODULE_NAME} + +echo "What is your github project name? (default: $PYPI_NAME)" +read REPO_INPUT +REPO_NAME=${REPO_INPUT:-$PYPI_NAME} + +echo "What is your readthedocs.org project name? (default: $PYPI_NAME)" +read RTD_INPUT +RTD_NAME=${RTD_INPUT:-$PYPI_NAME} + +echo "What is your project name (ex: at the top of the README)? (default: $REPO_NAME)" +read PROJECT_INPUT +PROJECT_NAME=${PROJECT_INPUT:-$REPO_NAME} + +echo "What is a one-liner describing the project?" +read SHORT_DESCRIPTION + +sed -i "s//$MODULE_NAME/g" $TEMPLATE_FILES +sed -i "s//$PYPI_NAME/g" $TEMPLATE_FILES +sed -i "s//$REPO_NAME/g" $TEMPLATE_FILES +sed -i "s//$SHORT_DESCRIPTION/g" $TEMPLATE_FILES diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..d53de3a --- /dev/null +++ b/pytest.ini @@ -0,0 +1,7 @@ +[pytest] +addopts= -v --showlocals --durations 10 +python_paths= . +xfail_strict=true + +[pytest-watch] +runner= py.test --failed-first --maxfail=1 --no-success-flaky-report diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..4882a64 --- /dev/null +++ b/setup.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from setuptools import ( + setup, + find_packages, +) + +extras_require={ + 'test': [ + "pytest==3.3.2", + "tox>=2.9.1,<3", + ], + 'lint': [ + "flake8==3.4.1", + "isort>=4.2.15,<5", + ], + 'document': [ + "Sphinx>=1.6.5,<2", + "sphinx_rtd_theme>=0.1.9", + ], + 'dev': [ + "bumpversion>=0.5.3,<1", + "pytest-xdist", + "wheel", + ], +} + +extras_require['dev'] = ( + extras_require['dev'] + + extras_require['test'] + + extras_require['lint'] + + extras_require['document'] +) + +setup( + name='', + # *IMPORTANT*: Don't manually change the version here. Use `make bump`, as described in readme + version='0.1.0-alpha.1', + description=""": """, + long_description_markdown_filename='README.md', + author='Jason Carver', + author_email='ethcalibur+pip@gmail.com', + url='https://github.com/ethereum/', + include_package_data=True, + install_requires=[ + "eth-utils>=0.7.4,<1.0.0", + ], + setup_requires=['setuptools-markdown'], + extras_require=extras_require, + py_modules=[''], + license="MIT", + zip_safe=False, + keywords='ethereum', + packages=find_packages(exclude=["tests", "tests.*"]), + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Natural Language :: English', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + ], +) diff --git a/tests/core/conftest.py b/tests/core/conftest.py new file mode 100644 index 0000000..e69de29 diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..0277275 --- /dev/null +++ b/tox.ini @@ -0,0 +1,35 @@ +[tox] +envlist= + py{35,36}-core + lint + +[isort] +combine_as_imports=True +force_sort_within_sections=True +include_trailing_comma=True +known_standard_library=pytest +known_first_party= +line_length=21 +multi_line_output=3 +use_parentheses=True + +[flake8] +max-line-length= 100 +exclude= venv*,.tox,docs,build +ignore= + +[testenv] +usedevelop=True +commands= + core: py.test {posargs:tests/core} +basepython = + py35: python3.5 + py36: python3.6 +extras=test + +[testenv:lint] +basepython=python +extras=lint +commands= + flake8 {toxinidir}/ {toxinidir}/tests + isort --recursive --check-only --diff {toxinidir}/ {toxinidir}/tests From 3d87ff715396b8a9cdfc9d8f13b71c4e0dd2dace Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 24 Jan 2018 16:24:08 -0800 Subject: [PATCH 002/159] Replace all template vars --- fill_template_vars.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fill_template_vars.sh b/fill_template_vars.sh index ecbdcb0..236733a 100755 --- a/fill_template_vars.sh +++ b/fill_template_vars.sh @@ -32,4 +32,6 @@ read SHORT_DESCRIPTION sed -i "s//$MODULE_NAME/g" $TEMPLATE_FILES sed -i "s//$PYPI_NAME/g" $TEMPLATE_FILES sed -i "s//$REPO_NAME/g" $TEMPLATE_FILES +sed -i "s//$RTD_NAME/g" $TEMPLATE_FILES +sed -i "s//$PROJECT_NAME/g" $TEMPLATE_FILES sed -i "s//$SHORT_DESCRIPTION/g" $TEMPLATE_FILES From cdba56a29525ba9c4ba5e82dcb7901cdc3bccd9a Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 24 Jan 2018 16:24:31 -0800 Subject: [PATCH 003/159] skip replacing variables inside .git/* files --- fill_template_vars.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fill_template_vars.sh b/fill_template_vars.sh index 236733a..d4dba88 100755 --- a/fill_template_vars.sh +++ b/fill_template_vars.sh @@ -5,7 +5,7 @@ set -o nounset set -o pipefail # List of all non-executable files -TEMPLATE_FILES=$(find . ! -perm -u=x -type f) +TEMPLATE_FILES=$(find . ! -perm -u=x -type f | grep -v "\.git") echo "What is your python module name?" read MODULE_NAME From 9cdfd649d581c20939f90cb549c28c6b7e03dae8 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 24 Jan 2018 16:31:02 -0800 Subject: [PATCH 004/159] create empty module with supplied name --- fill_template_vars.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fill_template_vars.sh b/fill_template_vars.sh index d4dba88..a0f9b90 100755 --- a/fill_template_vars.sh +++ b/fill_template_vars.sh @@ -35,3 +35,6 @@ sed -i "s//$REPO_NAME/g" $TEMPLATE_FILES sed -i "s//$RTD_NAME/g" $TEMPLATE_FILES sed -i "s//$PROJECT_NAME/g" $TEMPLATE_FILES sed -i "s//$SHORT_DESCRIPTION/g" $TEMPLATE_FILES + +mkdir $MODULE_NAME +touch $MODULE_NAME/__init__.py From 4a8b7b06afca9a9d0d533e76ba1cca24788244b7 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 24 Jan 2018 16:33:03 -0800 Subject: [PATCH 005/159] shorten extra name for documentation install --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 4882a64..181033e 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ "flake8==3.4.1", "isort>=4.2.15,<5", ], - 'document': [ + 'doc': [ "Sphinx>=1.6.5,<2", "sphinx_rtd_theme>=0.1.9", ], @@ -29,7 +29,7 @@ extras_require['dev'] + extras_require['test'] + extras_require['lint'] - + extras_require['document'] + + extras_require['doc'] ) setup( From ca670f43a4be6b2d6f326e07419c6b07c2167db1 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 24 Jan 2018 16:35:36 -0800 Subject: [PATCH 006/159] start at devnum 0 so the first bump goes to 1 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 181033e..fbef344 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ setup( name='', # *IMPORTANT*: Don't manually change the version here. Use `make bump`, as described in readme - version='0.1.0-alpha.1', + version='0.1.0-alpha.0', description=""": """, long_description_markdown_filename='README.md', author='Jason Carver', From 1d4e19d929e6e2845a4da76d3bb2114d9abe932e Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 24 Jan 2018 17:04:52 -0800 Subject: [PATCH 007/159] add docs index --- docs/index.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 docs/index.rst diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..bddbdbe --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,20 @@ + +======= + + + +Contents +-------- + +.. toctree:: + :maxdepth: 1 + + releases + + +Indices and tables +------------------ + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` From 3290919ff1cd31aa1c6c491f347335ffc7d93f73 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 25 Jan 2018 15:51:14 -0800 Subject: [PATCH 008/159] add github templates for issues and pull requests --- .github/ISSUE_TEMPLATE.md | 38 ++++++++++++++++++++++++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 11 +++++++++ 2 files changed, 49 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..5ff4880 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,38 @@ + _If this is a bug report, please fill in the following sections. +If this is a feature request, delete and describe what you would like with examples._ + +## What was wrong? + +### Code that produced the error + +```py +CODE_TO_REPRODUCE +``` + +### Full error output + +```sh +ERROR_HERE +``` + +### Expected Result + +_This section may be deleted if the expectation is "don't crash"._ + +```sh +EXPECTED_RESULT +``` + +### Environment + +```sh +# run this: +$ python -m eth_utils + +# then copy the output here: +OUTPUT_HERE +``` + +## How can it be fixed? + +Fill this section in if you know how this could or should be fixed. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..76ef5ac --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,11 @@ +## What was wrong? + +Issue # + +## How was it fixed? + +Summary of approach. + +#### Cute Animal Picture + +![put a cute animal picture link inside the parentheses]() From 2938497f022a90e44d7589f19f5d960c5d1fa4c9 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 25 Jan 2018 17:21:42 -0800 Subject: [PATCH 009/159] Link to dev tactical manual --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e29c4d9..709130c 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,18 @@ pip install ## Developer setup -If you would like to hack on , set up your dev environment with: +If you would like to hack on , please check out the +[Ethereum Development Tactical Manual](https://github.com/pipermerriam/ethereum-dev-tactical-manual) +for information on how we do: + +- Testing +- Pull Requests +- Code Style +- Documentation + +### Development Environment Setup + +You can set up your dev environment with: ```sh From 76bfefa66c987ffb8004c234190aebda1d145065 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Fri, 26 Jan 2018 19:01:36 -0800 Subject: [PATCH 010/159] add `make lint-roll` to locally auto de-lint --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index b842465..1a7f8c6 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,9 @@ clean-pyc: lint: tox -elint +lint-roll: lint + isort --recursive tests + test: py.test tests From 195249cdabb2f097baed392c0ed37e0aca549768 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 30 Jan 2018 10:46:34 -0800 Subject: [PATCH 011/159] docs cleanup: Makefile, conf, warnings --- docs/Makefile | 177 ++++++++++++++++++++ docs/_static/.suppress-sphinx-build-warning | 0 docs/conf.py | 1 - docs/index.rst | 6 +- docs/releases.rst | 2 +- 5 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 docs/Makefile create mode 100644 docs/_static/.suppress-sphinx-build-warning diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..3280093 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,177 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/web3.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/web3.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/web3" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/web3" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docs/_static/.suppress-sphinx-build-warning b/docs/_static/.suppress-sphinx-build-warning new file mode 100644 index 0000000..e69de29 diff --git a/docs/conf.py b/docs/conf.py index 77bcb7e..d2294f7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -76,7 +76,6 @@ # directories to ignore when looking for source files. exclude_patterns = [ '_build', - '.rst', 'modules.rst', ] diff --git a/docs/index.rst b/docs/index.rst index bddbdbe..b3598a4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,5 +1,5 @@ -======= +============================== @@ -7,8 +7,9 @@ Contents -------- .. toctree:: - :maxdepth: 1 + :maxdepth: 3 + releases @@ -17,4 +18,3 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` -* :ref:`search` diff --git a/docs/releases.rst b/docs/releases.rst index ec4804d..6fdd6c9 100644 --- a/docs/releases.rst +++ b/docs/releases.rst @@ -2,6 +2,6 @@ Release Notes ============= v0.1.0-alpha.1 -------------- +-------------- - Launched repository, claimed names for pip, RTD, github, etc From 109a0866ed06f97e2f7b34d1090e36dd6cbf499a Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 30 Jan 2018 15:17:03 -0800 Subject: [PATCH 012/159] requirements.txt: best way to build on readthedocs --- requirements-docs.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 requirements-docs.txt diff --git a/requirements-docs.txt b/requirements-docs.txt new file mode 100644 index 0000000..1b49b74 --- /dev/null +++ b/requirements-docs.txt @@ -0,0 +1 @@ +[doc] From 96a371705b810bd036817ac33c1aed8c045644d1 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 30 Jan 2018 15:17:50 -0800 Subject: [PATCH 013/159] bugfix: run tox -elint *after* isort otherwise tox fails, and the auto-lint never runs --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1a7f8c6..97eab7c 100644 --- a/Makefile +++ b/Makefile @@ -24,8 +24,9 @@ clean-pyc: lint: tox -elint -lint-roll: lint +lint-roll: isort --recursive tests + $(make) lint test: py.test tests From 0e57d8e262a1c46d5191e7fd31fd17026bdf3e2c Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 30 Jan 2018 15:18:59 -0800 Subject: [PATCH 014/159] when do you not want ipython in local dev? never --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index fbef344..518ee26 100644 --- a/setup.py +++ b/setup.py @@ -22,6 +22,7 @@ "bumpversion>=0.5.3,<1", "pytest-xdist", "wheel", + "ipython", ], } From 9a7d72a816dc5352ace5916a4b3ea3991e146b1c Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 30 Jan 2018 15:37:40 -0800 Subject: [PATCH 015/159] pytest default settings, plus pytest-watch --- pytest.ini | 1 - setup.py | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/pytest.ini b/pytest.ini index d53de3a..9cc5a18 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,7 +1,6 @@ [pytest] addopts= -v --showlocals --durations 10 python_paths= . -xfail_strict=true [pytest-watch] runner= py.test --failed-first --maxfail=1 --no-success-flaky-report diff --git a/setup.py b/setup.py index 518ee26..a89f4ac 100644 --- a/setup.py +++ b/setup.py @@ -21,6 +21,7 @@ 'dev': [ "bumpversion>=0.5.3,<1", "pytest-xdist", + "pytest-watch>=4.1.0,<5", "wheel", "ipython", ], From cb71fb443028771e35370a4dd0bfbe848e694dda Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 1 Feb 2018 09:42:48 -0800 Subject: [PATCH 016/159] add circle ci config --- .circleci/config.yml | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..7384eab --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,51 @@ +version: 2.0 + +# heavily inspired by https://raw.githubusercontent.com/pinax/pinax-wiki/6bd2a99ab6f702e300d708532a6d1d9aa638b9f8/.circleci/config.yml + +common: &common + working_directory: ~/repo + steps: + - checkout + - restore_cache: + keys: + - cache-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} + - run: + name: install dependencies + command: pip install --user tox + - run: + name: run tox + command: ~/.local/bin/tox + - save_cache: + paths: + - .tox + - ~/.cache/pip + - ~/.local + - ./eggs + key: cache-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} + +jobs: + lint: + <<: *common + docker: + - image: circleci/python:3.5 + environment: + TOXENV: lint + py35-core: + <<: *common + docker: + - image: circleci/python:3.5 + environment: + TOXENV: py35-core + py36-core: + <<: *common + docker: + - image: circleci/python:3.6 + environment: + TOXENV: py36-core +workflows: + version: 2 + test: + jobs: + - lint + - py35-core + - py36-core From f7b0f07b45798548550a3dd90444b350b9b95ff7 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 1 Feb 2018 13:07:33 -0800 Subject: [PATCH 017/159] fixups: rm template filler, xfail strict, make bug --- Makefile | 2 +- fill_template_vars.sh | 3 +++ pytest.ini | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 97eab7c..3bf2403 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ lint: lint-roll: isort --recursive tests - $(make) lint + $(MAKE) lint test: py.test tests diff --git a/fill_template_vars.sh b/fill_template_vars.sh index a0f9b90..17f2503 100755 --- a/fill_template_vars.sh +++ b/fill_template_vars.sh @@ -38,3 +38,6 @@ sed -i "s//$SHORT_DESCRIPTION/g" $TEMPLATE_FILES mkdir $MODULE_NAME touch $MODULE_NAME/__init__.py + +# template filler is no longer needed, delete it +rm "$0" diff --git a/pytest.ini b/pytest.ini index 9cc5a18..d53de3a 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,6 +1,7 @@ [pytest] addopts= -v --showlocals --durations 10 python_paths= . +xfail_strict=true [pytest-watch] runner= py.test --failed-first --maxfail=1 --no-success-flaky-report From 4bb4f720db893c4e3f44c22d4693869ed934ef6d Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 6 Feb 2018 15:33:04 -0800 Subject: [PATCH 018/159] add badges: pypi version and pythons supported --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 709130c..228615f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # [![Join the chat at https://gitter.im/ethereum/](https://badges.gitter.im/ethereum/.svg)](https://gitter.im/ethereum/?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - [![Build Status](https://travis-ci.org/ethereum/.png)](https://travis-ci.org/ethereum/) +[![PyPI version](https://badge.fury.io/py/.svg)](https://badge.fury.io/py/) +[![Python versions](https://img.shields.io/pypi/pyversions/.svg)](https://pypi.python.org/pypi/) From b825c36defd58715d02a0dd8b5eb47f52c2795d9 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 6 Feb 2018 15:42:21 -0800 Subject: [PATCH 019/159] docs: show badge, link to release notes --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 228615f..d478ded 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,14 @@ [![Build Status](https://travis-ci.org/ethereum/.png)](https://travis-ci.org/ethereum/) [![PyPI version](https://badge.fury.io/py/.svg)](https://badge.fury.io/py/) [![Python versions](https://img.shields.io/pypi/pyversions/.svg)](https://pypi.python.org/pypi/) +[![Docs build](https://readthedocs.org/projects//badge/?version=latest)](http://.readthedocs.io/en/latest/?badge=latest) * Python 3.5+ support -Read more in the [documentation on ReadTheDocs](http://.readthedocs.io/). [View the change log on Github](docs/releases.rst). +Read more in the [documentation on ReadTheDocs](http://.readthedocs.io/). [View the change log](http://.readthedocs.io/en/latest/releases.html). ## Quickstart From 7bfa2ac5d45d274ac7e4a50415cf02eee140cdd3 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 6 Feb 2018 15:52:41 -0800 Subject: [PATCH 020/159] add pypy3 as a supported environment, by default --- .travis.yml | 6 ++++++ setup.py | 1 + tox.ini | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 72be81d..42b63c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,12 @@ matrix: # core - python: "3.6" env: TOX_POSARGS="-e py36-core" + # + # pypy3 testing + # + # core + - python: "pypy3" + env: TOX_POSARGS="-e pypy3-core" cache: - pip: true install: diff --git a/setup.py b/setup.py index a89f4ac..a59d9ee 100644 --- a/setup.py +++ b/setup.py @@ -62,5 +62,6 @@ 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: Implementation :: PyPy3', ], ) diff --git a/tox.ini b/tox.ini index 0277275..9b1727e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist= - py{35,36}-core + py{35,36,py3}-core lint [isort] @@ -25,6 +25,7 @@ commands= basepython = py35: python3.5 py36: python3.6 + pypy3: pypy3 extras=test [testenv:lint] From 6abf0667793022b1b077f6eea69c4e706cc3513d Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 6 Feb 2018 15:56:11 -0800 Subject: [PATCH 021/159] add module import test --- tests/core/test_import.py | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tests/core/test_import.py diff --git a/tests/core/test_import.py b/tests/core/test_import.py new file mode 100644 index 0000000..2243d05 --- /dev/null +++ b/tests/core/test_import.py @@ -0,0 +1,4 @@ + + +def test_import(): + import From 1695a3b3262f183dbee81229a7cbd326edc5c210 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 6 Feb 2018 16:04:41 -0800 Subject: [PATCH 022/159] bugfix: setuptools reference to pypy --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a59d9ee..4eeb8d7 100644 --- a/setup.py +++ b/setup.py @@ -62,6 +62,6 @@ 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: Implementation :: PyPy3', + 'Programming Language :: Python :: Implementation :: PyPy', ], ) From beb1b10ee893ee68b188048dba8210ebcbd0506c Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 6 Feb 2018 16:10:25 -0800 Subject: [PATCH 023/159] silence flake8 error during module import test --- tests/core/test_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/test_import.py b/tests/core/test_import.py index 2243d05..f146ae7 100644 --- a/tests/core/test_import.py +++ b/tests/core/test_import.py @@ -1,4 +1,4 @@ def test_import(): - import + import # noqa: F401 From a9d9fec258284bc01524cd59d6d18629cca523cd Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 7 Feb 2018 11:14:11 -0800 Subject: [PATCH 024/159] add doctest by default --- Makefile | 1 + docs/conf.py | 17 ++++++++++++++++- tox.ini | 6 +++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 3bf2403..bb5c6a0 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,7 @@ build-docs: sphinx-apidoc -o docs/ . setup.py "*conftest*" $(MAKE) -C docs clean $(MAKE) -C docs html + $(MAKE) -C docs doctest docs: build-docs open docs/_build/html/index.html diff --git a/docs/conf.py b/docs/conf.py index d2294f7..a74a977 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -34,7 +34,11 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx'] +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + 'sphinx.ext.intersphinx', +] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -271,3 +275,14 @@ intersphinx_mapping = { 'python': ('https://docs.python.org/3.5', None), } + +# -- Doctest configuration ---------------------------------------- + +import doctest + +doctest_default_flags = (0 + | doctest.DONT_ACCEPT_TRUE_FOR_1 + | doctest.ELLIPSIS + | doctest.IGNORE_EXCEPTION_DETAIL + | doctest.NORMALIZE_WHITESPACE +) diff --git a/tox.ini b/tox.ini index 9b1727e..162657f 100644 --- a/tox.ini +++ b/tox.ini @@ -2,6 +2,7 @@ envlist= py{35,36,py3}-core lint + doctest [isort] combine_as_imports=True @@ -22,11 +23,14 @@ ignore= usedevelop=True commands= core: py.test {posargs:tests/core} + doctest: make -C {toxinidir}/docs doctest basepython = py35: python3.5 py36: python3.6 pypy3: pypy3 -extras=test +extras= + test + doctest: doc [testenv:lint] basepython=python From a1ba89ed413b1f6ea2691f14948d0ef3cc03fbf0 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 7 Feb 2018 11:18:47 -0800 Subject: [PATCH 025/159] every tox environment should have a basic python --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 162657f..f28e277 100644 --- a/tox.ini +++ b/tox.ini @@ -25,6 +25,7 @@ commands= core: py.test {posargs:tests/core} doctest: make -C {toxinidir}/docs doctest basepython = + python py35: python3.5 py36: python3.6 pypy3: pypy3 @@ -33,7 +34,6 @@ extras= doctest: doc [testenv:lint] -basepython=python extras=lint commands= flake8 {toxinidir}/ {toxinidir}/tests From 37d978c5b3c1de029e624b1335a7d0a3df96c045 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 7 Feb 2018 11:24:37 -0800 Subject: [PATCH 026/159] squash warning about using make inside tox --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index f28e277..8328bc5 100644 --- a/tox.ini +++ b/tox.ini @@ -32,6 +32,7 @@ basepython = extras= test doctest: doc +whitelest_externals=make [testenv:lint] extras=lint From ecb3731cbe45acfc762443ff9e702e040b642b08 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 7 Feb 2018 11:26:47 -0800 Subject: [PATCH 027/159] can't override python that way in tox --- tox.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 8328bc5..e7e9713 100644 --- a/tox.ini +++ b/tox.ini @@ -25,7 +25,7 @@ commands= core: py.test {posargs:tests/core} doctest: make -C {toxinidir}/docs doctest basepython = - python + doctest: python py35: python3.5 py36: python3.6 pypy3: pypy3 @@ -35,6 +35,7 @@ extras= whitelest_externals=make [testenv:lint] +basepython=python extras=lint commands= flake8 {toxinidir}/ {toxinidir}/tests From 60b026e3edfc75d696ffb896312f9d35f4e8ab17 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 7 Feb 2018 11:40:35 -0800 Subject: [PATCH 028/159] add doctest run to travis --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 42b63c9..5600ec0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,9 @@ matrix: # lint - python: "3.5" env: TOX_POSARGS="-e lint" + # doctest + - python: "3.5" + env: TOX_POSARGS="-e doctest" # core - python: "3.5" env: TOX_POSARGS="-e py35-core" From 58902032c755c9a61ec1a32f574a9a655db68490 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 7 Feb 2018 14:37:30 -0800 Subject: [PATCH 029/159] add doctest run to circle-ci --- .circleci/config.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7384eab..2ba8898 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,6 +24,12 @@ common: &common key: cache-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} jobs: + doctest: + <<: *common + docker: + - image: circleci/python:3.5 + environment: + TOXENV: doctest lint: <<: *common docker: @@ -46,6 +52,7 @@ workflows: version: 2 test: jobs: + - doctest - lint - py35-core - py36-core From b3461e9c934bcf017c90744192f218d2ab0a504c Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 7 Feb 2018 14:40:01 -0800 Subject: [PATCH 030/159] tox.ini bugfix: whitelist make --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index e7e9713..34a66b4 100644 --- a/tox.ini +++ b/tox.ini @@ -32,7 +32,7 @@ basepython = extras= test doctest: doc -whitelest_externals=make +whitelist_externals=make [testenv:lint] basepython=python From f0e0b10cc5f9a6086c249074d91c0ca18f63a575 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 20 Feb 2018 18:09:58 -0800 Subject: [PATCH 031/159] add pypy3 as a default test environment in circle --- .circleci/config.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2ba8898..821d1b4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -48,6 +48,12 @@ jobs: - image: circleci/python:3.6 environment: TOXENV: py36-core + pypy3-core: + <<: *common + docker: + - image: pypy + environment: + TOXENV: pypy3-core workflows: version: 2 test: @@ -56,3 +62,4 @@ workflows: - lint - py35-core - py36-core + - pypy3-core From 974fae3a2b6a414dab8eafc4aea2f968a6d5c8d7 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 20 Feb 2018 18:10:30 -0800 Subject: [PATCH 032/159] travis config: use latest pypy3 container --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5600ec0..78c56a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ matrix: # pypy3 testing # # core - - python: "pypy3" + - python: "pypy3.5" env: TOX_POSARGS="-e pypy3-core" cache: - pip: true From 588b1af6ee556cfd39b5681383c84b326b153a60 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 28 Feb 2018 10:29:45 -0800 Subject: [PATCH 033/159] Makefile: deploy to upstream --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bb5c6a0..5b0f799 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ release: clean CURRENT_SIGN_SETTING=$(git config commit.gpgSign) git config commit.gpgSign true bumpversion $(bump) - git push && git push --tags + git push upstream && git push upstream --tags python setup.py sdist bdist_wheel upload git config commit.gpgSign "$(CURRENT_SIGN_SETTING)" From 031b1175f4c03ead623b54067fbc95485de17966 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 28 Feb 2018 14:20:39 -0800 Subject: [PATCH 034/159] force tox to rebuild in circle runs --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 821d1b4..2393a06 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,7 +14,7 @@ common: &common command: pip install --user tox - run: name: run tox - command: ~/.local/bin/tox + command: ~/.local/bin/tox -r - save_cache: paths: - .tox From 84ecb7effc827b9f070b5eb6d50e4e7a341d078d Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 10 Apr 2018 10:16:17 -0700 Subject: [PATCH 035/159] require python 3.5 during setup (and reject py4) --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 4eeb8d7..4308294 100644 --- a/setup.py +++ b/setup.py @@ -48,6 +48,7 @@ "eth-utils>=0.7.4,<1.0.0", ], setup_requires=['setuptools-markdown'], + python_requires='>=3.5, <4', extras_require=extras_require, py_modules=[''], license="MIT", From 30473b3ff54da0b6f06e7cd761fd9ec40f6651f1 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Thu, 19 Apr 2018 16:31:48 -0600 Subject: [PATCH 036/159] Make Circle CI test against merge with PR base --- .circleci/config.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2393a06..7c636af 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,6 +6,22 @@ common: &common working_directory: ~/repo steps: - checkout + - run: + name: merge pull request base + command: | + if [[ -n "${CIRCLE_PR_NUMBER}" ]]; then + PR_INFO_URL=https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pulls/$CIRCLE_PR_NUMBER + + PR_BASE_BRANCH=$(curl -L "$PR_INFO_URL" | python -c 'import json, sys; obj = json.load(sys.stdin); sys.stdout.write(obj["base"]["ref"])') + git fetch origin +"$PR_BASE_BRANCH":circleci/pr-base + + # We need these config values or git complains when creating the + # merge commit + git config --global user.name "Circle CI" + git config --global user.email "circleci@example.com" + + git merge --no-edit circleci/pr-base + fi - restore_cache: keys: - cache-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} From f7535eb99204e2c691aa6b330e5672caa29a29c0 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Sun, 22 Apr 2018 01:34:42 -0600 Subject: [PATCH 037/159] Add circle ci status badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d478ded..ac1ee8b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # [![Join the chat at https://gitter.im/ethereum/](https://badges.gitter.im/ethereum/.svg)](https://gitter.im/ethereum/?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Build Status](https://travis-ci.org/ethereum/.png)](https://travis-ci.org/ethereum/) +[![Build Status](https://circleci.com/gh/ethereum/.svg?style=shield)](https://circleci.com/gh/ethereum/) [![PyPI version](https://badge.fury.io/py/.svg)](https://badge.fury.io/py/) [![Python versions](https://img.shields.io/pypi/pyversions/.svg)](https://pypi.python.org/pypi/) [![Docs build](https://readthedocs.org/projects//badge/?version=latest)](http://.readthedocs.io/en/latest/?badge=latest) From cdc83bd498d3e145109a760314d41ea3504f821f Mon Sep 17 00:00:00 2001 From: David Sanders Date: Sun, 22 Apr 2018 01:35:08 -0600 Subject: [PATCH 038/159] Make find replace script more macOS friendly Also, make handling of arbitrary filenames a bit more robust. --- fill_template_vars.sh | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/fill_template_vars.sh b/fill_template_vars.sh index 17f2503..531efcf 100755 --- a/fill_template_vars.sh +++ b/fill_template_vars.sh @@ -4,9 +4,6 @@ set -o errexit set -o nounset set -o pipefail -# List of all non-executable files -TEMPLATE_FILES=$(find . ! -perm -u=x -type f | grep -v "\.git") - echo "What is your python module name?" read MODULE_NAME @@ -29,12 +26,20 @@ PROJECT_NAME=${PROJECT_INPUT:-$REPO_NAME} echo "What is a one-liner describing the project?" read SHORT_DESCRIPTION -sed -i "s//$MODULE_NAME/g" $TEMPLATE_FILES -sed -i "s//$PYPI_NAME/g" $TEMPLATE_FILES -sed -i "s//$REPO_NAME/g" $TEMPLATE_FILES -sed -i "s//$RTD_NAME/g" $TEMPLATE_FILES -sed -i "s//$PROJECT_NAME/g" $TEMPLATE_FILES -sed -i "s//$SHORT_DESCRIPTION/g" $TEMPLATE_FILES +_replace() { + local find_cmd=(find . ! -perm -u=x ! -path '*/.git/*' -type f) + + if [[ $(uname) == Darwin ]]; then + "${find_cmd[@]}" -exec sed -i '' "$1" {} + + else + "${find_cmd[@]}" -exec sed -i "$1" {} + + fi +} +_replace "s//$PYPI_NAME/g" +_replace "s//$REPO_NAME/g" +_replace "s//$RTD_NAME/g" +_replace "s//$PROJECT_NAME/g" +_replace "s//$SHORT_DESCRIPTION/g" mkdir $MODULE_NAME touch $MODULE_NAME/__init__.py From d7ce1100ed8c80b108d98f78dc080c6e64d74b9f Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 25 Apr 2018 15:05:30 -0700 Subject: [PATCH 039/159] gitignore utils and internals docs; fill-in fixup --- .gitignore | 3 ++- fill_template_vars.sh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index c380203..e5902e4 100644 --- a/.gitignore +++ b/.gitignore @@ -43,7 +43,8 @@ output/*/index.html # Sphinx docs/_build docs/modules.rst -docs/web3.* +docs/*.internals.rst +docs/*.utils.rst # Blockchain chains diff --git a/fill_template_vars.sh b/fill_template_vars.sh index 531efcf..197f490 100755 --- a/fill_template_vars.sh +++ b/fill_template_vars.sh @@ -41,7 +41,7 @@ _replace "s//$RTD_NAME/g" _replace "s//$PROJECT_NAME/g" _replace "s//$SHORT_DESCRIPTION/g" -mkdir $MODULE_NAME +mkdir -p $MODULE_NAME touch $MODULE_NAME/__init__.py # template filler is no longer needed, delete it From 0dd03f0a3fc3a895a4276789f0043c150b6a7705 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 25 Apr 2018 15:19:05 -0700 Subject: [PATCH 040/159] re-add MODULE_NAME in new template filler --- fill_template_vars.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/fill_template_vars.sh b/fill_template_vars.sh index 197f490..286daad 100755 --- a/fill_template_vars.sh +++ b/fill_template_vars.sh @@ -35,6 +35,7 @@ _replace() { "${find_cmd[@]}" -exec sed -i "$1" {} + fi } +_replace "s//$MODULE_NAME/g" _replace "s//$PYPI_NAME/g" _replace "s//$REPO_NAME/g" _replace "s//$RTD_NAME/g" From b98147efcabaca4dfbc61c53fa55eaf81b880ee8 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 25 Apr 2018 15:20:03 -0700 Subject: [PATCH 041/159] keep template filler around for future merges --- fill_template_vars.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/fill_template_vars.sh b/fill_template_vars.sh index 286daad..5360f31 100755 --- a/fill_template_vars.sh +++ b/fill_template_vars.sh @@ -44,6 +44,3 @@ _replace "s//$SHORT_DESCRIPTION/g" mkdir -p $MODULE_NAME touch $MODULE_NAME/__init__.py - -# template filler is no longer needed, delete it -rm "$0" From 285f5c6c70b6b5ac1204ecd81a31cf1a5d4c591e Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 25 Apr 2018 15:39:52 -0700 Subject: [PATCH 042/159] Remove duplicate python version mention in readme Rely on the badge instead --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index ac1ee8b..041ad81 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,6 @@ -* Python 3.5+ support - Read more in the [documentation on ReadTheDocs](http://.readthedocs.io/). [View the change log](http://.readthedocs.io/en/latest/releases.html). ## Quickstart From 1f89c6385ab4c9b2cdf6ce18e52c1f40cd25f075 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 25 Apr 2018 18:50:01 -0700 Subject: [PATCH 043/159] fix gitignore typo about internals module in docs/ --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e5902e4..58654f8 100644 --- a/.gitignore +++ b/.gitignore @@ -43,7 +43,7 @@ output/*/index.html # Sphinx docs/_build docs/modules.rst -docs/*.internals.rst +docs/*.internal.rst docs/*.utils.rst # Blockchain From 8815766abf57e21498c7e8422c7dece38f503ec9 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 15 May 2018 11:52:40 -0700 Subject: [PATCH 044/159] circleci: merge (and reattempt) PR before testing --- .circleci/config.yml | 12 ++++++++++++ .circleci/merge_pr.sh | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 .circleci/merge_pr.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 7c636af..af93963 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,6 +6,17 @@ common: &common working_directory: ~/repo steps: - checkout + - run: + name: merge pull request base + command: ./.circleci/merge_pr.sh + - run: + name: merge pull request base (2nd try) + command: ./.circleci/merge_pr.sh + when: on_fail + - run: + name: merge pull request base (3nd try) + command: ./.circleci/merge_pr.sh + when: on_fail - run: name: merge pull request base command: | @@ -33,6 +44,7 @@ common: &common command: ~/.local/bin/tox -r - save_cache: paths: + - .hypothesis - .tox - ~/.cache/pip - ~/.local diff --git a/.circleci/merge_pr.sh b/.circleci/merge_pr.sh new file mode 100644 index 0000000..91eb47c --- /dev/null +++ b/.circleci/merge_pr.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +if [[ -n "${CIRCLE_PR_NUMBER}" ]]; then + PR_INFO_URL=https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pulls/$CIRCLE_PR_NUMBER + PR_BASE_BRANCH=$(curl -L "$PR_INFO_URL" | python -c 'import json, sys; obj = json.load(sys.stdin); sys.stdout.write(obj["base"]["ref"])') + git fetch origin +"$PR_BASE_BRANCH":circleci/pr-base + # We need these config values or git complains when creating the + # merge commit + git config --global user.name "Circle CI" + git config --global user.email "circleci@example.com" + git merge --no-edit circleci/pr-base +fi From 1091971637ff0afc3531cc011c4d00db1a2fc620 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 15 May 2018 12:09:51 -0700 Subject: [PATCH 045/159] remove old merge code from circle template --- .circleci/config.yml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index af93963..7f542a1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,22 +17,6 @@ common: &common name: merge pull request base (3nd try) command: ./.circleci/merge_pr.sh when: on_fail - - run: - name: merge pull request base - command: | - if [[ -n "${CIRCLE_PR_NUMBER}" ]]; then - PR_INFO_URL=https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pulls/$CIRCLE_PR_NUMBER - - PR_BASE_BRANCH=$(curl -L "$PR_INFO_URL" | python -c 'import json, sys; obj = json.load(sys.stdin); sys.stdout.write(obj["base"]["ref"])') - git fetch origin +"$PR_BASE_BRANCH":circleci/pr-base - - # We need these config values or git complains when creating the - # merge commit - git config --global user.name "Circle CI" - git config --global user.email "circleci@example.com" - - git merge --no-edit circleci/pr-base - fi - restore_cache: keys: - cache-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} From 85e33cf3801b19e9d46b237c7837baab0eb1e468 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 15 May 2018 12:17:36 -0700 Subject: [PATCH 046/159] move template filler to own directory --- .../fill_template_vars.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename fill_template_vars.sh => .project-template/fill_template_vars.sh (89%) diff --git a/fill_template_vars.sh b/.project-template/fill_template_vars.sh similarity index 89% rename from fill_template_vars.sh rename to .project-template/fill_template_vars.sh index 5360f31..7ae7ebb 100755 --- a/fill_template_vars.sh +++ b/.project-template/fill_template_vars.sh @@ -4,6 +4,8 @@ set -o errexit set -o nounset set -o pipefail +PROJECT_ROOT=$(dirname $(dirname $(readlink -f $0))) + echo "What is your python module name?" read MODULE_NAME @@ -27,7 +29,7 @@ echo "What is a one-liner describing the project?" read SHORT_DESCRIPTION _replace() { - local find_cmd=(find . ! -perm -u=x ! -path '*/.git/*' -type f) + local find_cmd=(find "$PROJECT_ROOT" ! -perm -u=x ! -path '*/.git/*' -type f) if [[ $(uname) == Darwin ]]; then "${find_cmd[@]}" -exec sed -i '' "$1" {} + From 71ba221c493d70b04046fc624bf39ea05b8b38d5 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 15 May 2018 12:25:21 -0700 Subject: [PATCH 047/159] Enable template refilling --- .project-template/fill_template_vars.sh | 4 ++-- .project-template/refill_template_vars.sh | 1 + .project-template/template_vars.txt | 6 ++++++ 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 .project-template/refill_template_vars.sh create mode 100644 .project-template/template_vars.txt diff --git a/.project-template/fill_template_vars.sh b/.project-template/fill_template_vars.sh index 7ae7ebb..1e76d8a 100755 --- a/.project-template/fill_template_vars.sh +++ b/.project-template/fill_template_vars.sh @@ -44,5 +44,5 @@ _replace "s//$RTD_NAME/g" _replace "s//$PROJECT_NAME/g" _replace "s//$SHORT_DESCRIPTION/g" -mkdir -p $MODULE_NAME -touch $MODULE_NAME/__init__.py +mkdir -p "$PROJECT_ROOT/$MODULE_NAME" +touch "$PROJECT_ROOT/$MODULE_NAME/__init__.py" diff --git a/.project-template/refill_template_vars.sh b/.project-template/refill_template_vars.sh new file mode 100644 index 0000000..bbb39e9 --- /dev/null +++ b/.project-template/refill_template_vars.sh @@ -0,0 +1 @@ + + + + + + From b357fda082fa2d560ea7fb8e07d2560c1404dbb3 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 15 May 2018 12:33:36 -0700 Subject: [PATCH 048/159] refill from any directory --- .project-template/refill_template_vars.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) mode change 100644 => 100755 .project-template/refill_template_vars.sh diff --git a/.project-template/refill_template_vars.sh b/.project-template/refill_template_vars.sh old mode 100644 new mode 100755 index bbb39e9..6e7943f --- a/.project-template/refill_template_vars.sh +++ b/.project-template/refill_template_vars.sh @@ -1 +1,2 @@ - Date: Tue, 15 May 2018 13:02:56 -0700 Subject: [PATCH 049/159] make merge script executable --- .circleci/merge_pr.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .circleci/merge_pr.sh diff --git a/.circleci/merge_pr.sh b/.circleci/merge_pr.sh old mode 100644 new mode 100755 From 5e509100e7174eef6169f1d152197c0db22163d9 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Fri, 1 Jun 2018 14:05:57 -0600 Subject: [PATCH 050/159] Some readme updates --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 041ad81..937344d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ -Read more in the [documentation on ReadTheDocs](http://.readthedocs.io/). [View the change log](http://.readthedocs.io/en/latest/releases.html). +Read more in the [documentation on ReadTheDocs](https://.readthedocs.io/). [View the change log](https://.readthedocs.io/en/latest/releases.html). ## Quickstart @@ -17,7 +17,7 @@ Read more in the [documentation on ReadTheDocs](http://.readthedocs.io pip install ``` -## Developer setup +## Developer Setup If you would like to hack on , please check out the [Ethereum Development Tactical Manual](https://github.com/pipermerriam/ethereum-dev-tactical-manual) @@ -33,7 +33,6 @@ for information on how we do: You can set up your dev environment with: ```sh - git clone git@github.com:ethereum/.git cd virtualenv -p python3 venv From 32c8c981f262248b20730d18e2d4fcad074488dd Mon Sep 17 00:00:00 2001 From: David Sanders Date: Mon, 4 Jun 2018 16:36:02 -0600 Subject: [PATCH 051/159] Remove references to deprecated "py.test" --- Makefile | 2 +- pytest.ini | 2 +- tox.ini | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 5b0f799..7b93655 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ lint-roll: $(MAKE) lint test: - py.test tests + pytest tests test-all: tox diff --git a/pytest.ini b/pytest.ini index d53de3a..f5fdc0e 100644 --- a/pytest.ini +++ b/pytest.ini @@ -4,4 +4,4 @@ python_paths= . xfail_strict=true [pytest-watch] -runner= py.test --failed-first --maxfail=1 --no-success-flaky-report +runner= pytest --failed-first --maxfail=1 --no-success-flaky-report diff --git a/tox.ini b/tox.ini index 34a66b4..066b377 100644 --- a/tox.ini +++ b/tox.ini @@ -22,7 +22,7 @@ ignore= [testenv] usedevelop=True commands= - core: py.test {posargs:tests/core} + core: pytest {posargs:tests/core} doctest: make -C {toxinidir}/docs doctest basepython = doctest: python From 00819dd924174c78829f97679871fd181dd12509 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Mon, 4 Jun 2018 16:36:35 -0600 Subject: [PATCH 052/159] Whitespace --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 066b377..74ea1d4 100644 --- a/tox.ini +++ b/tox.ini @@ -38,5 +38,5 @@ whitelist_externals=make basepython=python extras=lint commands= - flake8 {toxinidir}/ {toxinidir}/tests - isort --recursive --check-only --diff {toxinidir}/ {toxinidir}/tests + flake8 {toxinidir}/ {toxinidir}/tests + isort --recursive --check-only --diff {toxinidir}/ {toxinidir}/tests From e7d0a8577b8f6f5cac11e6f86199f7bca24b3ecd Mon Sep 17 00:00:00 2001 From: David Sanders Date: Mon, 4 Jun 2018 16:37:38 -0600 Subject: [PATCH 053/159] Fix testing dependencies --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4308294..92ee090 100644 --- a/setup.py +++ b/setup.py @@ -8,6 +8,7 @@ extras_require={ 'test': [ "pytest==3.3.2", + "pytest-xdist", "tox>=2.9.1,<3", ], 'lint': [ @@ -20,7 +21,6 @@ ], 'dev': [ "bumpversion>=0.5.3,<1", - "pytest-xdist", "pytest-watch>=4.1.0,<5", "wheel", "ipython", From 0a83658b3ee41fdc8473e3156a5b7591ef992c9b Mon Sep 17 00:00:00 2001 From: David Sanders Date: Mon, 4 Jun 2018 16:37:52 -0600 Subject: [PATCH 054/159] Lint in setup.py --- setup.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 92ee090..55b3c90 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ find_packages, ) -extras_require={ +extras_require = { 'test': [ "pytest==3.3.2", "pytest-xdist", @@ -28,10 +28,10 @@ } extras_require['dev'] = ( - extras_require['dev'] - + extras_require['test'] - + extras_require['lint'] - + extras_require['doc'] + extras_require['dev'] + + extras_require['test'] + + extras_require['lint'] + + extras_require['doc'] ) setup( From 0088da3781742674729aa54eb423f35e4a3826ae Mon Sep 17 00:00:00 2001 From: David Sanders Date: Mon, 4 Jun 2018 18:40:58 -0600 Subject: [PATCH 055/159] Fix possibly incorrect isort config --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 74ea1d4..6ae707b 100644 --- a/tox.ini +++ b/tox.ini @@ -8,7 +8,7 @@ envlist= combine_as_imports=True force_sort_within_sections=True include_trailing_comma=True -known_standard_library=pytest +known_third_party=hypothesis,pytest known_first_party= line_length=21 multi_line_output=3 From 6ed7bb011f7c7bd77c0e3a1802e3381d6bf3d8a5 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Wed, 6 Jun 2018 18:30:40 -0600 Subject: [PATCH 056/159] Make template filler more BSD friendly --- .project-template/fill_template_vars.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.project-template/fill_template_vars.sh b/.project-template/fill_template_vars.sh index 1e76d8a..f09e8ff 100755 --- a/.project-template/fill_template_vars.sh +++ b/.project-template/fill_template_vars.sh @@ -4,7 +4,7 @@ set -o errexit set -o nounset set -o pipefail -PROJECT_ROOT=$(dirname $(dirname $(readlink -f $0))) +PROJECT_ROOT=$(dirname $(dirname $(python -c 'import os, sys; sys.stdout.write(os.path.realpath(sys.argv[1]))' "$0"))) echo "What is your python module name?" read MODULE_NAME From 016f48d17ddf549955f2baea0c6dd32fefdbd5a8 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Wed, 6 Jun 2018 19:35:31 -0600 Subject: [PATCH 057/159] Use twine for pypi uploading per packaging docs See here: https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives --- Makefile | 3 ++- setup.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7b93655..db66037 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,8 @@ release: clean git config commit.gpgSign true bumpversion $(bump) git push upstream && git push upstream --tags - python setup.py sdist bdist_wheel upload + python setup.py sdist bdist_wheel + twine upload dist/* git config commit.gpgSign "$(CURRENT_SIGN_SETTING)" dist: clean diff --git a/setup.py b/setup.py index 55b3c90..511490f 100644 --- a/setup.py +++ b/setup.py @@ -23,6 +23,7 @@ "bumpversion>=0.5.3,<1", "pytest-watch>=4.1.0,<5", "wheel", + "twine", "ipython", ], } From a9d531615da67410bc42fe7285e0e049dc42a78d Mon Sep 17 00:00:00 2001 From: David Sanders Date: Thu, 7 Jun 2018 12:23:32 -0600 Subject: [PATCH 058/159] Fix ineffectual commands in Makefile --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7b93655..8339d7d 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +CURRENT_SIGN_SETTING := $(shell git config commit.gpgSign) + .PHONY: clean-pyc clean-build docs help: @@ -47,7 +49,6 @@ linux-docs: build-docs xdg-open docs/_build/html/index.html release: clean - CURRENT_SIGN_SETTING=$(git config commit.gpgSign) git config commit.gpgSign true bumpversion $(bump) git push upstream && git push upstream --tags From d3537cf1ab18cf813c5bfd957e51ca6699e3e0a3 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Thu, 7 Jun 2018 12:27:07 -0600 Subject: [PATCH 059/159] Update eth-utils version requirement --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 55b3c90..4bfc7a7 100644 --- a/setup.py +++ b/setup.py @@ -45,7 +45,7 @@ url='https://github.com/ethereum/', include_package_data=True, install_requires=[ - "eth-utils>=0.7.4,<1.0.0", + "eth-utils>=1,<2", ], setup_requires=['setuptools-markdown'], python_requires='>=3.5, <4', From 5ad0973c3d16c0a43a705db6ce33b1510989d8cb Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 29 Aug 2018 09:47:22 -0700 Subject: [PATCH 060/159] Ignore any internal `_utils` module --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 58654f8..9a48c01 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ docs/_build docs/modules.rst docs/*.internal.rst docs/*.utils.rst +docs/*._utils.* # Blockchain chains From 0b004a8597fcf27cf259d9002d9bc30c2e2a0179 Mon Sep 17 00:00:00 2001 From: Nick Gheorghita Date: Mon, 27 Aug 2018 11:15:43 -0600 Subject: [PATCH 061/159] Add changelog instructions --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 937344d..8843960 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,11 @@ The version format for this repo is `{major}.{minor}.{patch}` for stable, and `{major}.{minor}.{patch}-{stage}.{devnum}` for unstable (`stage` can be alpha or beta). To issue the next version in line, specify which part to bump, -like `make release bump=minor` or `make release bump=devnum`. +like `make release bump=minor` or `make release bump=devnum`. This is typically done from the +master branch, except when releasing a beta (in which case the beta is released from master, +and the previous stable branch is released from said branch). To include changes made with each +release, update "docs/releases.rst" with the changes, and apply commit directly to master +before release. If you are in a beta version, `make release bump=stage` will switch to a stable. From caf9050a19a889c90afd23a05b6d5f9aefadd665 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 15 Jan 2019 16:06:18 -0800 Subject: [PATCH 062/159] Drop py3.5, add py3.7 --- .circleci/config.yml | 18 +++++++++--------- .travis.yml | 18 +++++++++--------- docs/conf.py | 2 +- setup.py | 4 ++-- tox.ini | 4 ++-- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7f542a1..bbc56d0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -39,27 +39,27 @@ jobs: doctest: <<: *common docker: - - image: circleci/python:3.5 + - image: circleci/python:3.6 environment: TOXENV: doctest lint: <<: *common docker: - - image: circleci/python:3.5 + - image: circleci/python:3.6 environment: TOXENV: lint - py35-core: - <<: *common - docker: - - image: circleci/python:3.5 - environment: - TOXENV: py35-core py36-core: <<: *common docker: - image: circleci/python:3.6 environment: TOXENV: py36-core + py37-core: + <<: *common + docker: + - image: circleci/python:3.7 + environment: + TOXENV: py37-core pypy3-core: <<: *common docker: @@ -72,6 +72,6 @@ workflows: jobs: - doctest - lint - - py35-core - py36-core + - py37-core - pypy3-core diff --git a/.travis.yml b/.travis.yml index 78c56a6..c523874 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,23 +4,23 @@ dist: trusty matrix: include: # - # Python 3.5 testing + # Python 3.6 testing # + # core + - python: "3.6" + env: TOX_POSARGS="-e py36-core" # lint - - python: "3.5" + - python: "3.6" env: TOX_POSARGS="-e lint" # doctest - - python: "3.5" + - python: "3.6" env: TOX_POSARGS="-e doctest" - # core - - python: "3.5" - env: TOX_POSARGS="-e py35-core" # - # Python 3.6 testing + # Python 3.7 testing # # core - - python: "3.6" - env: TOX_POSARGS="-e py36-core" + - python: "3.7" + env: TOX_POSARGS="-e py37-core" # # pypy3 testing # diff --git a/docs/conf.py b/docs/conf.py index a74a977..0c63ed4 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -273,7 +273,7 @@ # -- Intersphinx configuration ------------------------------------------------ intersphinx_mapping = { - 'python': ('https://docs.python.org/3.5', None), + 'python': ('https://docs.python.org/3.6', None), } # -- Doctest configuration ---------------------------------------- diff --git a/setup.py b/setup.py index 99618aa..047d6ff 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ "eth-utils>=1,<2", ], setup_requires=['setuptools-markdown'], - python_requires='>=3.5, <4', + python_requires='>=3.6, <4', extras_require=extras_require, py_modules=[''], license="MIT", @@ -62,8 +62,8 @@ 'License :: OSI Approved :: MIT License', 'Natural Language :: English', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: Implementation :: PyPy', ], ) diff --git a/tox.ini b/tox.ini index 6ae707b..71e19f2 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist= - py{35,36,py3}-core + py{36,37,py3}-core lint doctest @@ -26,8 +26,8 @@ commands= doctest: make -C {toxinidir}/docs doctest basepython = doctest: python - py35: python3.5 py36: python3.6 + py37: python3.7 pypy3: pypy3 extras= test From dd74824840c0b5899dcbc4b5a7b61b4398218fd1 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Thu, 24 Jan 2019 13:57:17 -0700 Subject: [PATCH 063/159] Add docstring checking with pydocstyle --- .pydocstyle.ini | 30 ++++++++++++++++++++++++++++++ setup.py | 1 + tox.ini | 1 + 3 files changed, 32 insertions(+) create mode 100644 .pydocstyle.ini diff --git a/.pydocstyle.ini b/.pydocstyle.ini new file mode 100644 index 0000000..0d40aa8 --- /dev/null +++ b/.pydocstyle.ini @@ -0,0 +1,30 @@ +[pydocstyle] +; All error codes found here: +; http://www.pydocstyle.org/en/3.0.0/error_codes.html +; +; Ignored: +; D1 - Missing docstring error codes +; +; Selected: +; D2 - Whitespace error codes +; D3 - Quote error codes +; D4 - Content related error codes +select=D2,D3,D4 + +; Extra ignores: +; D200 - One-line docstring should fit on one line with quotes +; D203 - 1 blank line required before class docstring +; D204 - 1 blank line required after class docstring +; D205 - 1 blank line required between summary line and description +; D212 - Multi-line docstring summary should start at the first line +; D302 - Use u""" for Unicode docstrings +; D400 - First line should end with a period +; D401 - First line should be in imperative mood +; D412 - No blank lines allowed between a section header and its content +add-ignore=D200,D203,D204,D205,D212,D302,D400,D401,D412 + +; Explanation: +; D400 - Enabling this error code seems to make it a requirement that the first +; sentence in a docstring is not split across two lines. It also makes it a +; requirement that no docstring can have a multi-sentence description without a +; summary line. Neither one of those requirements seem appropriate. diff --git a/setup.py b/setup.py index 047d6ff..6c02fb2 100644 --- a/setup.py +++ b/setup.py @@ -14,6 +14,7 @@ 'lint': [ "flake8==3.4.1", "isort>=4.2.15,<5", + "pydocstyle>=3.0.0,<4", ], 'doc': [ "Sphinx>=1.6.5,<2", diff --git a/tox.ini b/tox.ini index 71e19f2..6372125 100644 --- a/tox.ini +++ b/tox.ini @@ -40,3 +40,4 @@ extras=lint commands= flake8 {toxinidir}/ {toxinidir}/tests isort --recursive --check-only --diff {toxinidir}/ {toxinidir}/tests + pydocstyle {toxinidir}/ {toxinidir}/tests From de4bdf9e308e7eba871e7399a67dcdbf6c5a8bbc Mon Sep 17 00:00:00 2001 From: David Sanders Date: Mon, 25 Mar 2019 15:14:04 -0600 Subject: [PATCH 064/159] Remove attribution to specific person --- LICENSE | 2 +- README.md | 4 ++-- docs/conf.py | 8 ++++---- setup.py | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/LICENSE b/LICENSE index 1b7a2b5..d93175a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2018 Jason Carver +Copyright (c) 2019 The Ethereum Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 8843960..ad7eb27 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ pip install ## Developer Setup -If you would like to hack on , please check out the -[Ethereum Development Tactical Manual](https://github.com/pipermerriam/ethereum-dev-tactical-manual) +If you would like to hack on , please check out the [Snake Charmers +Tactical Manual](https://github.com/ethereum/snake-charmers-tactical-manual) for information on how we do: - Testing diff --git a/docs/conf.py b/docs/conf.py index 0c63ed4..aaf6fb6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,7 +54,7 @@ # General information about the project. project = '' -copyright = '2018, Jason Carver, Piper Merriam' +copyright = '2019, The Ethereum Foundation' __version__ = setup_version # The version info for the project you're documenting, acts as replacement for @@ -210,7 +210,7 @@ # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', '.tex', ' Documentation', - 'Jason Carver', 'manual'), + 'The Ethereum Foundation', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -240,7 +240,7 @@ # (source start file, name, description, authors, manual section). man_pages = [ ('index', '', ' Documentation', - ['Jason Carver'], 1) + ['The Ethereum Foundation'], 1) ] # If true, show URL addresses after external links. @@ -254,7 +254,7 @@ # dir menu entry, description, category) texinfo_documents = [ ('index', '', ' Documentation', - 'Jason Carver', '', '', + 'The Ethereum Foundation', '', '', 'Miscellaneous'), ] diff --git a/setup.py b/setup.py index 6c02fb2..904429c 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ version='0.1.0-alpha.0', description=""": """, long_description_markdown_filename='README.md', - author='Jason Carver', + author='The Ethereum Foundation', author_email='ethcalibur+pip@gmail.com', url='https://github.com/ethereum/', include_package_data=True, From 5f3e6b37bf6f596e23b05bac12069ddc1c34fd83 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Mon, 25 Mar 2019 20:04:26 -0600 Subject: [PATCH 065/159] Remove travis config --- .travis.yml | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c523874..0000000 --- a/.travis.yml +++ /dev/null @@ -1,40 +0,0 @@ -sudo: false -language: python -dist: trusty -matrix: - include: - # - # Python 3.6 testing - # - # core - - python: "3.6" - env: TOX_POSARGS="-e py36-core" - # lint - - python: "3.6" - env: TOX_POSARGS="-e lint" - # doctest - - python: "3.6" - env: TOX_POSARGS="-e doctest" - # - # Python 3.7 testing - # - # core - - python: "3.7" - env: TOX_POSARGS="-e py37-core" - # - # pypy3 testing - # - # core - - python: "pypy3.5" - env: TOX_POSARGS="-e pypy3-core" -cache: - - pip: true -install: - - travis_retry pip install pip setuptools --upgrade - - travis_retry pip install tox -before_script: - - python --version - - pip --version - - pip freeze -script: - - tox $TOX_POSARGS From 5e6dc2999162c19f87bf123d839f693399babbb5 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Tue, 26 Mar 2019 11:51:15 -0600 Subject: [PATCH 066/159] Update default author email --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 904429c..0203cbf 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ description=""": """, long_description_markdown_filename='README.md', author='The Ethereum Foundation', - author_email='ethcalibur+pip@gmail.com', + author_email='snakecharmers@ethereum.org', url='https://github.com/ethereum/', include_package_data=True, install_requires=[ From 720b2cf3d2cbef46d73cff6d0e237a60d59a6b62 Mon Sep 17 00:00:00 2001 From: Christoph Burgdorf Date: Fri, 26 Apr 2019 15:59:33 +0200 Subject: [PATCH 067/159] Add mypy support --- mypy.ini | 16 ++++++++++++++++ setup.py | 1 + tox.ini | 1 + 3 files changed, 18 insertions(+) create mode 100644 mypy.ini diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000..1fcbd14 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,16 @@ +[mypy] + +check_untyped_defs = True +disallow_incomplete_defs = True +disallow_untyped_defs = True +disallow_any_generics = True +disallow_untyped_calls = True +disallow_untyped_decorators = True +disallow_subclassing_any = True +ignore_missing_imports = True +strict_optional = True +strict_equality = True +warn_redundant_casts = True +warn_return_any = True +warn_unused_configs = True +warn_unused_ignores = True diff --git a/setup.py b/setup.py index 0203cbf..97ac1c3 100644 --- a/setup.py +++ b/setup.py @@ -14,6 +14,7 @@ 'lint': [ "flake8==3.4.1", "isort>=4.2.15,<5", + "mypy==0.701", "pydocstyle>=3.0.0,<4", ], 'doc': [ diff --git a/tox.ini b/tox.ini index 6372125..e7e9920 100644 --- a/tox.ini +++ b/tox.ini @@ -38,6 +38,7 @@ whitelist_externals=make basepython=python extras=lint commands= + mypy -p {toxinidir}/ --config-file {toxinidir}/mypy.ini flake8 {toxinidir}/ {toxinidir}/tests isort --recursive --check-only --diff {toxinidir}/ {toxinidir}/tests pydocstyle {toxinidir}/ {toxinidir}/tests From 84d2b22a7b9214b3ff40463325b2ffb338594628 Mon Sep 17 00:00:00 2001 From: Piper Merriam Date: Wed, 1 May 2019 14:31:32 -0600 Subject: [PATCH 068/159] switch to native pypy markdown support --- setup.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 97ac1c3..edd6685 100644 --- a/setup.py +++ b/setup.py @@ -31,18 +31,24 @@ } extras_require['dev'] = ( - extras_require['dev'] + - extras_require['test'] + - extras_require['lint'] + + extras_require['dev'] + # noqa: W504 + extras_require['test'] + # noqa: W504 + extras_require['lint'] + # noqa: W504 extras_require['doc'] ) + +with open('./README.md') as readme: + long_description = readme.read() + + setup( name='', # *IMPORTANT*: Don't manually change the version here. Use `make bump`, as described in readme version='0.1.0-alpha.0', description=""": """, - long_description_markdown_filename='README.md', + long_description=long_description, + long_description_content_type='text/markdown', author='The Ethereum Foundation', author_email='snakecharmers@ethereum.org', url='https://github.com/ethereum/', @@ -50,7 +56,6 @@ install_requires=[ "eth-utils>=1,<2", ], - setup_requires=['setuptools-markdown'], python_requires='>=3.6, <4', extras_require=extras_require, py_modules=[''], From dc9f04c18f9a96d6e0252275bab454c793fe1e44 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Fri, 3 May 2019 14:45:31 -0700 Subject: [PATCH 069/159] Skip venv in template filler & print progress --- .project-template/fill_template_vars.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.project-template/fill_template_vars.sh b/.project-template/fill_template_vars.sh index f09e8ff..c9cb826 100755 --- a/.project-template/fill_template_vars.sh +++ b/.project-template/fill_template_vars.sh @@ -29,7 +29,8 @@ echo "What is a one-liner describing the project?" read SHORT_DESCRIPTION _replace() { - local find_cmd=(find "$PROJECT_ROOT" ! -perm -u=x ! -path '*/.git/*' -type f) + echo "Replacing values: $1" + local find_cmd=(find "$PROJECT_ROOT" ! -perm -u=x ! -path '*/.git/*' ! -path '*/venv*/*' -type f) if [[ $(uname) == Darwin ]]; then "${find_cmd[@]}" -exec sed -i '' "$1" {} + From a6f607881443a06c3bbf3be3aad0651651b84c8a Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Mon, 3 Jun 2019 12:22:46 -0700 Subject: [PATCH 070/159] Add vim .swo files and .mypy_cache to .gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9a48c01..0e05727 100644 --- a/.gitignore +++ b/.gitignore @@ -85,7 +85,10 @@ logs .idea/mongoSettings.xml # VIM temp files -*.swp +*.sw[op] + +# mypy +.mypy_cache ## File-based project format: *.iws From 02fe35663c96b81bbd7512480653fbd6140d7ff5 Mon Sep 17 00:00:00 2001 From: Christoph Burgdorf Date: Mon, 29 Jul 2019 12:51:01 +0200 Subject: [PATCH 071/159] Setup towncrier to generate release notes --- .circleci/config.yml | 6 ++-- .github/PULL_REQUEST_TEMPLATE.md | 10 ++++++ Makefile | 14 ++++++++- README.md | 4 +-- docs/index.rst | 2 +- docs/{releases.rst => release_notes.rst} | 2 ++ newsfragments/README.md | 26 ++++++++++++++++ newsfragments/validate_files.py | 32 +++++++++++++++++++ pyproject.toml | 39 ++++++++++++++++++++++++ setup.py | 1 + tox.ini | 8 ++--- 11 files changed, 132 insertions(+), 12 deletions(-) rename docs/{releases.rst => release_notes.rst} (78%) create mode 100644 newsfragments/README.md create mode 100755 newsfragments/validate_files.py create mode 100644 pyproject.toml diff --git a/.circleci/config.yml b/.circleci/config.yml index bbc56d0..fa7691e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -36,12 +36,12 @@ common: &common key: cache-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} jobs: - doctest: + docs: <<: *common docker: - image: circleci/python:3.6 environment: - TOXENV: doctest + TOXENV: docs lint: <<: *common docker: @@ -70,7 +70,7 @@ workflows: version: 2 test: jobs: - - doctest + - docs - lint - py36-core - py37-core diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 76ef5ac..21d4db5 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,6 +6,16 @@ Issue # Summary of approach. +### To-Do + +[//]: # (Stay ahead of things, add list items here!) +- [ ] Clean up commit history + +[//]: # (For important changes that should go into the release notes please add a newsfragment file as explained here: https://github.com/ethereum//blob/master/newsfragments/README.md) + +[//]: # (See: https://.readthedocs.io/en/latest/contributing.html#pull-requests) +- [ ] Add entry to the [release notes](https://github.com/ethereum//blob/master/newsfragments/README.md) + #### Cute Animal Picture ![put a cute animal picture link inside the parentheses]() diff --git a/Makefile b/Makefile index 18f7003..5603310 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,8 @@ build-docs: $(MAKE) -C docs clean $(MAKE) -C docs html $(MAKE) -C docs doctest + ./newsfragments/validate_files.py + towncrier --draft --version preview docs: build-docs open docs/_build/html/index.html @@ -49,13 +51,23 @@ linux-docs: build-docs xdg-open docs/_build/html/index.html release: clean + CURRENT_SIGN_SETTING=$(git config commit.gpgSign) git config commit.gpgSign true - bumpversion $(bump) + # Let UPCOMING_VERSION be the version that is used for the current bump + $(eval UPCOMING_VERSION=$(shell bumpversion $(bump) --dry-run --list | grep new_version= | sed 's/new_version=//g')) + # Now generate the release notes to have them included in the release commit + towncrier --yes --version $(UPCOMING_VERSION) + # Before we bump the version, make sure that the towncrier-generated docs will build + make build-docs + # We need --allow-dirty because of the generated release_notes file that goes into the release + # commit. No other files are added accidentially. The dry-run still runs *without* --allow-dirty + bumpversion --allow-dirty $(bump) git push upstream && git push upstream --tags python setup.py sdist bdist_wheel twine upload dist/* git config commit.gpgSign "$(CURRENT_SIGN_SETTING)" + dist: clean python setup.py sdist bdist_wheel ls -l dist diff --git a/README.md b/README.md index ad7eb27..3ceb98c 100644 --- a/README.md +++ b/README.md @@ -88,9 +88,7 @@ The version format for this repo is `{major}.{minor}.{patch}` for stable, and To issue the next version in line, specify which part to bump, like `make release bump=minor` or `make release bump=devnum`. This is typically done from the master branch, except when releasing a beta (in which case the beta is released from master, -and the previous stable branch is released from said branch). To include changes made with each -release, update "docs/releases.rst" with the changes, and apply commit directly to master -before release. +and the previous stable branch is released from said branch). If you are in a beta version, `make release bump=stage` will switch to a stable. diff --git a/docs/index.rst b/docs/index.rst index b3598a4..89815ef 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,7 +10,7 @@ Contents :maxdepth: 3 - releases + release_notes Indices and tables diff --git a/docs/releases.rst b/docs/release_notes.rst similarity index 78% rename from docs/releases.rst rename to docs/release_notes.rst index 6fdd6c9..63786ac 100644 --- a/docs/releases.rst +++ b/docs/release_notes.rst @@ -1,6 +1,8 @@ Release Notes ============= +.. towncrier release notes start + v0.1.0-alpha.1 -------------- diff --git a/newsfragments/README.md b/newsfragments/README.md new file mode 100644 index 0000000..09c1cc8 --- /dev/null +++ b/newsfragments/README.md @@ -0,0 +1,26 @@ +This directory collects "newsfragments": short files that each contain +a snippet of ReST-formatted text that will be added to the next +release notes. This should be a description of aspects of the change +(if any) that are relevant to users. (This contrasts with the +commit message and PR description, which are a description of the change as +relevant to people working on the code itself.) + +Each file should be named like `..rst`, where +`` is an issue numbers, and `` is one of: + +* `feature` +* `bugfix` +* `performance` +* `doc` +* `removal` +* `misc` + +So for example: `123.feature.rst`, `456.bugfix.rst` + +If the PR fixes an issue, use that number here. If there is no issue, +then open up the PR first and use the PR number for the newsfragment. + +Note that the `towncrier` tool will automatically +reflow your text, so don't try to do any fancy formatting. Run + `towncrier --draft` to get a preview of what the release notes entry + will look like in the final release notes. \ No newline at end of file diff --git a/newsfragments/validate_files.py b/newsfragments/validate_files.py new file mode 100755 index 0000000..c6695bc --- /dev/null +++ b/newsfragments/validate_files.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +# Towncrier silently ignores files that do not match the expected ending. +# We use this script to ensure we catch these as errors in CI. + +import os +import pathlib + +ALLOWED_EXTENSIONS = { + '.bugfix.rst', + '.doc.rst', + '.feature.rst', + '.misc.rst', + '.performance.rst', + '.removal.rst', +} + +ALLOWED_FILES = { + 'validate_files.py', + 'README.md', +} + +THIS_DIR = pathlib.Path(__file__).parent + +for fragment_file in THIS_DIR.iterdir(): + + if fragment_file.name in ALLOWED_FILES: + continue + + full_extension = "".join(fragment_file.suffixes) + if full_extension not in ALLOWED_EXTENSIONS: + raise Exception(f"Unexpected file: {fragment_file}") diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..42a4130 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,39 @@ +[tool.towncrier] +# Read https://github.com/ethereum//newsfragments/README.md for instructions +package = "" +filename = "docs/release_notes.rst" +directory = "newsfragments" +underlines = ["-", "~", "^"] +issue_format = "`#{issue} /issues/{issue}>`__" + +# Configure all default sections plus an extra one for performance improvements. + +[[tool.towncrier.type]] +directory = "feature" +name = "Features" +showcontent = true + +[[tool.towncrier.type]] +directory = "bugfix" +name = "Bugfixes" +showcontent = true + +[[tool.towncrier.type]] +directory = "performance" +name = "Performance improvements" +showcontent = true + +[[tool.towncrier.type]] +directory = "doc" +name = "Improved Documentation" +showcontent = true + +[[tool.towncrier.type]] +directory = "removal" +name = "Deprecations and Removals" +showcontent = true + +[[tool.towncrier.type]] +directory = "misc" +name = "Miscellaneous internal changes" +showcontent = false \ No newline at end of file diff --git a/setup.py b/setup.py index edd6685..54dbd6c 100644 --- a/setup.py +++ b/setup.py @@ -20,6 +20,7 @@ 'doc': [ "Sphinx>=1.6.5,<2", "sphinx_rtd_theme>=0.1.9", + "towncrier>=19.2.0, <20", ], 'dev': [ "bumpversion>=0.5.3,<1", diff --git a/tox.ini b/tox.ini index e7e9920..953e83a 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist= py{36,37,py3}-core lint - doctest + docs [isort] combine_as_imports=True @@ -23,15 +23,15 @@ ignore= usedevelop=True commands= core: pytest {posargs:tests/core} - doctest: make -C {toxinidir}/docs doctest + docs: make build-docs basepython = - doctest: python + docs: python py36: python3.6 py37: python3.7 pypy3: pypy3 extras= test - doctest: doc + docs: doc whitelist_externals=make [testenv:lint] From 07eecb5c69b9c92e5e5699fafded51bbfaddca54 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Mon, 25 Nov 2019 12:22:29 -0800 Subject: [PATCH 072/159] Separate release-note build from release --- Makefile | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 5603310..5e087e3 100644 --- a/Makefile +++ b/Makefile @@ -50,18 +50,24 @@ docs: build-docs linux-docs: build-docs xdg-open docs/_build/html/index.html -release: clean - CURRENT_SIGN_SETTING=$(git config commit.gpgSign) - git config commit.gpgSign true +notes: # Let UPCOMING_VERSION be the version that is used for the current bump $(eval UPCOMING_VERSION=$(shell bumpversion $(bump) --dry-run --list | grep new_version= | sed 's/new_version=//g')) # Now generate the release notes to have them included in the release commit towncrier --yes --version $(UPCOMING_VERSION) # Before we bump the version, make sure that the towncrier-generated docs will build make build-docs - # We need --allow-dirty because of the generated release_notes file that goes into the release - # commit. No other files are added accidentially. The dry-run still runs *without* --allow-dirty - bumpversion --allow-dirty $(bump) + git commit -m "Compile release notes" + +release: clean + # require that you be on a branch that's linked to upstream/master + git status -s -b | head -1 | grep "\.\.upstream/master" + # verify that docs build correctly + ./newsfragments/validate_files.py is-empty + make build-docs + CURRENT_SIGN_SETTING=$(git config commit.gpgSign) + git config commit.gpgSign true + bumpversion $(bump) git push upstream && git push upstream --tags python setup.py sdist bdist_wheel twine upload dist/* From 89363b2d9b67c30a04dc9aa3ef2ad6e1ad1b1709 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Mon, 25 Nov 2019 12:28:05 -0800 Subject: [PATCH 073/159] Add internal type for release notes --- newsfragments/README.md | 3 ++- newsfragments/validate_files.py | 17 ++++++++++++++--- pyproject.toml | 11 +++++++---- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/newsfragments/README.md b/newsfragments/README.md index 09c1cc8..09a10dd 100644 --- a/newsfragments/README.md +++ b/newsfragments/README.md @@ -12,6 +12,7 @@ Each file should be named like `..rst`, where * `bugfix` * `performance` * `doc` +* `internal` * `removal` * `misc` @@ -23,4 +24,4 @@ then open up the PR first and use the PR number for the newsfragment. Note that the `towncrier` tool will automatically reflow your text, so don't try to do any fancy formatting. Run `towncrier --draft` to get a preview of what the release notes entry - will look like in the final release notes. \ No newline at end of file + will look like in the final release notes. diff --git a/newsfragments/validate_files.py b/newsfragments/validate_files.py index c6695bc..c0e9b28 100755 --- a/newsfragments/validate_files.py +++ b/newsfragments/validate_files.py @@ -5,11 +5,13 @@ import os import pathlib +import sys ALLOWED_EXTENSIONS = { '.bugfix.rst', '.doc.rst', '.feature.rst', + '.internal.rst', '.misc.rst', '.performance.rst', '.removal.rst', @@ -22,11 +24,20 @@ THIS_DIR = pathlib.Path(__file__).parent +num_args = len(sys.argv) - 1 +assert num_args in {0, 1} +if num_args == 1: + assert sys.argv[1] in ('is-empty', ) + for fragment_file in THIS_DIR.iterdir(): if fragment_file.name in ALLOWED_FILES: continue - - full_extension = "".join(fragment_file.suffixes) - if full_extension not in ALLOWED_EXTENSIONS: + elif num_args == 0: + full_extension = "".join(fragment_file.suffixes) + if full_extension not in ALLOWED_EXTENSIONS: + raise Exception(f"Unexpected file: {fragment_file}") + elif sys.argv[1] == 'is-empty': raise Exception(f"Unexpected file: {fragment_file}") + else: + raise RuntimeError("Strange: arguments {sys.argv} were validated, but not found") diff --git a/pyproject.toml b/pyproject.toml index 42a4130..a9724ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,8 +6,6 @@ directory = "newsfragments" underlines = ["-", "~", "^"] issue_format = "`#{issue} /issues/{issue}>`__" -# Configure all default sections plus an extra one for performance improvements. - [[tool.towncrier.type]] directory = "feature" name = "Features" @@ -33,7 +31,12 @@ directory = "removal" name = "Deprecations and Removals" showcontent = true +[[tool.towncrier.type]] +directory = "internal" +name = "Internal Changes - for Contributors" +showcontent = true + [[tool.towncrier.type]] directory = "misc" -name = "Miscellaneous internal changes" -showcontent = false \ No newline at end of file +name = "Miscellaneous changes" +showcontent = false From 4ab4a01a360d2e6b61f4c144f5613f7c5a9acddd Mon Sep 17 00:00:00 2001 From: Nick Gheorghita Date: Thu, 12 Dec 2019 13:21:22 +0100 Subject: [PATCH 074/159] Add MANIFEST.in file --- MANIFEST.in | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 MANIFEST.in diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..fbff980 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,8 @@ +include LICENSE +include README.md +include requirements-docs.txt + +global-include *.pyi + +recursive-exclude * __pycache__ +recursive-exclude * *.py[co] From c8f686f0771d18ea5fdb45db7f38f1b981f02c88 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Fri, 24 Jan 2020 11:07:11 -0800 Subject: [PATCH 075/159] Update MIT License to 2020 --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index d93175a..17bc694 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2019 The Ethereum Foundation +Copyright (c) 2020 The Ethereum Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From e6e69625bb32c8a595a19f750aa8e8fdd6725e2b Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Fri, 24 Jan 2020 11:21:24 -0800 Subject: [PATCH 076/159] Replace web3 reference with Some hard-coded references to web3.py slipped through. Clearly this user path is not tested very often. In eth-abi, it still said EthereumAlarmClock X) --- docs/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index 3280093..aa0085b 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -85,17 +85,17 @@ qthelp: @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/web3.qhcp" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/.qhcp" @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/web3.qhc" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/web3" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/web3" + @echo "# mkdir -p $$HOME/.local/share/devhelp/" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/" @echo "# devhelp" epub: From 6d75c9aa8d4bd3f8e5791bdf936ee319a9abb1dd Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Fri, 24 Jan 2020 11:28:54 -0800 Subject: [PATCH 077/159] Update docs copyright to the year 2020 --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index aaf6fb6..977f3ab 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,7 +54,7 @@ # General information about the project. project = '' -copyright = '2019, The Ethereum Foundation' +copyright = '2020, The Ethereum Foundation' __version__ = setup_version # The version info for the project you're documenting, acts as replacement for From 4195de314249a740de65a91c6644fec921c05d10 Mon Sep 17 00:00:00 2001 From: Piper Merriam Date: Thu, 23 Apr 2020 09:13:32 -0600 Subject: [PATCH 078/159] Update testing and lint deps --- setup.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 54dbd6c..845b8ab 100644 --- a/setup.py +++ b/setup.py @@ -7,14 +7,14 @@ extras_require = { 'test': [ - "pytest==3.3.2", + "pytest==5.4.1", "pytest-xdist", - "tox>=2.9.1,<3", + "tox==3.14.6", ], 'lint': [ - "flake8==3.4.1", + "flake8==3.7.9", "isort>=4.2.15,<5", - "mypy==0.701", + "mypy==0.770", "pydocstyle>=3.0.0,<4", ], 'doc': [ From c447735449cf0d7b633bcc10395f024f5292238f Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Mon, 11 May 2020 13:55:17 -0700 Subject: [PATCH 079/159] Better error if bump missing in make notes/release --- Makefile | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5e087e3..264cd19 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,12 @@ docs: build-docs linux-docs: build-docs xdg-open docs/_build/html/index.html -notes: +check-bump: +ifndef bump + $(error bump must be set, typically: major, minor, patch, or devnum) +endif + +notes: check-bump # Let UPCOMING_VERSION be the version that is used for the current bump $(eval UPCOMING_VERSION=$(shell bumpversion $(bump) --dry-run --list | grep new_version= | sed 's/new_version=//g')) # Now generate the release notes to have them included in the release commit @@ -59,7 +64,7 @@ notes: make build-docs git commit -m "Compile release notes" -release: clean +release: check-bump clean # require that you be on a branch that's linked to upstream/master git status -s -b | head -1 | grep "\.\.upstream/master" # verify that docs build correctly From ea7038bd263ccc9ba981b12044e41bee14774e8f Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 1 Sep 2020 11:29:19 -0700 Subject: [PATCH 080/159] Update link to correct URL for release notes --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ceb98c..92b70be 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ -Read more in the [documentation on ReadTheDocs](https://.readthedocs.io/). [View the change log](https://.readthedocs.io/en/latest/releases.html). +Read more in the [documentation on ReadTheDocs](https://.readthedocs.io/). [View the change log](https://.readthedocs.io/en/latest/release_notes.html). ## Quickstart From d74a5e2bd8383dafe2f981df37e2f012736d9d24 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 2 Sep 2020 15:54:34 -0700 Subject: [PATCH 081/159] Latest mypy refuses package with file path --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 953e83a..07b2179 100644 --- a/tox.ini +++ b/tox.ini @@ -38,7 +38,7 @@ whitelist_externals=make basepython=python extras=lint commands= - mypy -p {toxinidir}/ --config-file {toxinidir}/mypy.ini + mypy -p --config-file {toxinidir}/mypy.ini flake8 {toxinidir}/ {toxinidir}/tests isort --recursive --check-only --diff {toxinidir}/ {toxinidir}/tests pydocstyle {toxinidir}/ {toxinidir}/tests From 27d0c7f0e56d023587baf6bac81ac2531d7f2517 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 24 Sep 2020 08:46:51 -0700 Subject: [PATCH 082/159] Customize section title, because default is bad It has weird capitalization rules, in particular. --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index a9724ba..b03fe29 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,6 +4,7 @@ package = "" filename = "docs/release_notes.rst" directory = "newsfragments" underlines = ["-", "~", "^"] +title_format = " v{version} ({project_date})" issue_format = "`#{issue} /issues/{issue}>`__" [[tool.towncrier.type]] From be1c3242048035106bc137ed2558424c5f4d860b Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 24 Sep 2020 08:58:58 -0700 Subject: [PATCH 083/159] Add some Makefile doc strings --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 264cd19..68ed417 100644 --- a/Makefile +++ b/Makefile @@ -6,9 +6,12 @@ help: @echo "clean-build - remove build artifacts" @echo "clean-pyc - remove Python file artifacts" @echo "lint - check style with flake8" + @echo "lint-roll - automatically fix problems with isort, flake8, etc" @echo "test - run tests quickly with the default Python" @echo "testall - run tests on every Python version with tox" - @echo "release - package and upload a release" + @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" clean: clean-build clean-pyc From 4d0358f67b56335d395aee4d49abd5276811a6b5 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 24 Sep 2020 08:59:09 -0700 Subject: [PATCH 084/159] Be sure to remove py3 cache files --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 68ed417..d38ac9d 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,7 @@ clean-pyc: find . -name '*.pyc' -exec rm -f {} + find . -name '*.pyo' -exec rm -f {} + find . -name '*~' -exec rm -f {} + + find . -name '__pycache__' -exec rm -rf {} + lint: tox -elint From 57f829250d5704e12f9bbd347fcaf565f7c596fa Mon Sep 17 00:00:00 2001 From: Tiffany McKenzie <25855566+tmckenzie51@users.noreply.github.com> Date: Mon, 7 Dec 2020 11:18:39 -0500 Subject: [PATCH 085/159] update .gitignore --- .gitignore | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0e05727..b43bb7b 100644 --- a/.gitignore +++ b/.gitignore @@ -97,9 +97,10 @@ logs # IntelliJ /out/ +.idea* -# mpeltonen/sbt-idea plugin -.idea_modules/ +#pip wheel metadata +pip-wheel-metadata # JIRA plugin atlassian-ide-plugin.xml From f962541b66cf5febf78c76b237203e9cad1f03c9 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 19 Jan 2021 15:30:31 -0800 Subject: [PATCH 086/159] Export type annotations to importing projects --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 845b8ab..3e3cdf0 100644 --- a/setup.py +++ b/setup.py @@ -64,6 +64,7 @@ zip_safe=False, keywords='ethereum', packages=find_packages(exclude=["tests", "tests.*"]), + package_data={'': ['py.typed']}, classifiers=[ 'Development Status :: 3 - Alpha', 'Intended Audience :: Developers', From 8434801bfc740f35ceeb27e76af1c3d2ce0db1b8 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 19 Jan 2021 15:45:12 -0800 Subject: [PATCH 087/159] Upgrade pydocstyle to v5 Fixes https://github.com/ethereum/ethereum-python-project-template/issues/52 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 845b8ab..40edee8 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ "flake8==3.7.9", "isort>=4.2.15,<5", "mypy==0.770", - "pydocstyle>=3.0.0,<4", + "pydocstyle>=5.0.0,<6", ], 'doc': [ "Sphinx>=1.6.5,<2", From 9d0cbd4a9fca511fab6e8f8ee49edc8c750bf4c3 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 19 Jan 2021 15:51:46 -0800 Subject: [PATCH 088/159] Add pip-wheel-metadata & .pytest_cache to ignore Fixes https://github.com/ethereum/ethereum-python-project-template/issues/51 --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index b43bb7b..0ec1cd3 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ develop-eggs .installed.cfg lib lib64 +pip-wheel-metadata venv* # Installer logs @@ -55,6 +56,7 @@ chains # tox/pytest cache .cache +.pytest_cache # Test output logs logs From f4f5c051f59122e1889ddb68c6e4720b1243eb94 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 19 Jan 2021 15:55:52 -0800 Subject: [PATCH 089/159] Clean up IntelliJ .gitignore a bit --- .gitignore | 49 ++++++++++++++++--------------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index 0ec1cd3..011ac1c 100644 --- a/.gitignore +++ b/.gitignore @@ -60,31 +60,6 @@ chains # Test output logs logs -### 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 # VIM temp files *.sw[op] @@ -92,24 +67,32 @@ logs # mypy .mypy_cache +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# For a more precise, explicit template, see: +# https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +## General +.idea/* +.idea_modules/* + ## File-based project format: *.iws -## Plugin-specific files: +## IntelliJ +out/ -# IntelliJ -/out/ -.idea* +## Plugin-specific files: -#pip wheel metadata -pip-wheel-metadata +### mpeltonen/sbt-idea plugin +.idea_modules/ -# JIRA plugin +### JIRA plugin atlassian-ide-plugin.xml -# Crashlytics plugin (for Android Studio and IntelliJ) +### Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties +# END JetBrains section From 8c7f30b0b7276bc33e10d8fe57e3e34d1c5b8f18 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 19 Jan 2021 16:14:16 -0800 Subject: [PATCH 090/159] Add supported OS's Fixes https://github.com/ethereum/ethereum-python-project-template/issues/37 --- setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.py b/setup.py index 40edee8..a78d2af 100644 --- a/setup.py +++ b/setup.py @@ -69,6 +69,8 @@ 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Natural Language :: English', + 'Operating System :: MacOS', + 'Operating System :: POSIX', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', From b7baeca0cd92dda123f34931a695e30556b4b270 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 19 Jan 2021 16:15:22 -0800 Subject: [PATCH 091/159] Pin sphinx-rtd-theme to =1.6.5,<2", - "sphinx_rtd_theme>=0.1.9", + "sphinx_rtd_theme>=0.1.9,<1", "towncrier>=19.2.0, <20", ], 'dev': [ From 1410bcb22028fc92b9dec180cc88571742eac2c2 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 21 Jan 2021 11:35:29 -0800 Subject: [PATCH 092/159] Fix the type annotations export, adding py.typed Fixes https://github.com/ethereum/ethereum-python-project-template/issues/30 --- .project-template/fill_template_vars.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.project-template/fill_template_vars.sh b/.project-template/fill_template_vars.sh index c9cb826..250f551 100755 --- a/.project-template/fill_template_vars.sh +++ b/.project-template/fill_template_vars.sh @@ -47,3 +47,4 @@ _replace "s//$SHORT_DESCRIPTION/g" mkdir -p "$PROJECT_ROOT/$MODULE_NAME" touch "$PROJECT_ROOT/$MODULE_NAME/__init__.py" +touch "$PROJECT_ROOT/$MODULE_NAME/py.typed" From 765b2e441461217a8fada93d51ecf6969cdcda75 Mon Sep 17 00:00:00 2001 From: kclowes Date: Fri, 19 Nov 2021 13:43:20 -0700 Subject: [PATCH 093/159] Add python3.8 support --- .circleci/config.yml | 6 ++++++ setup.py | 1 + tox.ini | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fa7691e..0027cef 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -60,6 +60,12 @@ jobs: - image: circleci/python:3.7 environment: TOXENV: py37-core + py38-core: + <<: *common + docker: + - image: circleci/python:3.8 + environment: + TOXENV: py38-core pypy3-core: <<: *common docker: diff --git a/setup.py b/setup.py index 2b8c720..65d7904 100644 --- a/setup.py +++ b/setup.py @@ -75,6 +75,7 @@ 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: Implementation :: PyPy', ], ) diff --git a/tox.ini b/tox.ini index 07b2179..33b16f2 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist= - py{36,37,py3}-core + py{36,37,38,py3}-core lint docs @@ -28,6 +28,7 @@ basepython = docs: python py36: python3.6 py37: python3.7 + py37: python3.8 pypy3: pypy3 extras= test From fcb5577fa1e20ebe489e26e3a1e588fe87ba1211 Mon Sep 17 00:00:00 2001 From: kclowes Date: Fri, 19 Nov 2021 13:43:36 -0700 Subject: [PATCH 094/159] Add python 3.9 support --- .circleci/config.yml | 6 ++++++ setup.py | 1 + tox.ini | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0027cef..35ab4b8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -66,6 +66,12 @@ jobs: - image: circleci/python:3.8 environment: TOXENV: py38-core + py39-core: + <<: *common + docker: + - image: circleci/python:3.9 + environment: + TOXENV: py39-core pypy3-core: <<: *common docker: diff --git a/setup.py b/setup.py index 65d7904..1456764 100644 --- a/setup.py +++ b/setup.py @@ -76,6 +76,7 @@ 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: Implementation :: PyPy', ], ) diff --git a/tox.ini b/tox.ini index 33b16f2..049e8e3 100644 --- a/tox.ini +++ b/tox.ini @@ -28,7 +28,8 @@ basepython = docs: python py36: python3.6 py37: python3.7 - py37: python3.8 + py38: python3.8 + py39: python3.9 pypy3: pypy3 extras= test From d21d58250bc5547993a0e2ec5ab88c3de06a473c Mon Sep 17 00:00:00 2001 From: kclowes Date: Fri, 19 Nov 2021 13:48:19 -0700 Subject: [PATCH 095/159] Add python 3.10 support --- .circleci/config.yml | 6 ++++++ setup.py | 1 + tox.ini | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 35ab4b8..167ae52 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -72,6 +72,12 @@ jobs: - image: circleci/python:3.9 environment: TOXENV: py39-core + py310-core: + <<: *common + docker: + - image: circleci/python:3.10 + environment: + TOXENV: py310-core pypy3-core: <<: *common docker: diff --git a/setup.py b/setup.py index 1456764..7924134 100644 --- a/setup.py +++ b/setup.py @@ -77,6 +77,7 @@ 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: Implementation :: PyPy', ], ) diff --git a/tox.ini b/tox.ini index 049e8e3..3148e02 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist= - py{36,37,38,py3}-core + py{36,37,38,39,310,py3}-core lint docs @@ -30,6 +30,7 @@ basepython = py37: python3.7 py38: python3.8 py39: python3.9 + py310: python3.10 pypy3: pypy3 extras= test From 0649062150d7894dd74b00f589f62c7823e3a1ae Mon Sep 17 00:00:00 2001 From: kclowes Date: Fri, 19 Nov 2021 13:51:55 -0700 Subject: [PATCH 096/159] Update pytest to support python 3.10, pin pytest-xdist, bump eth-utils to >=2,<3 --- setup.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 7924134..38e0d78 100644 --- a/setup.py +++ b/setup.py @@ -7,8 +7,8 @@ extras_require = { 'test': [ - "pytest==5.4.1", - "pytest-xdist", + "pytest>=6.2.5,<7", + "pytest-xdist>=2.4.0,<3", "tox==3.14.6", ], 'lint': [ @@ -55,7 +55,7 @@ url='https://github.com/ethereum/', include_package_data=True, install_requires=[ - "eth-utils>=1,<2", + "eth-utils>=2,<3", ], python_requires='>=3.6, <4', extras_require=extras_require, From c6f13bfd943282c452e29dafbde595186010ee53 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 18 May 2022 12:19:24 -0700 Subject: [PATCH 097/159] Show full explanation for pydocstyle failures --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 3148e02..edd1dcd 100644 --- a/tox.ini +++ b/tox.ini @@ -44,4 +44,4 @@ commands= mypy -p --config-file {toxinidir}/mypy.ini flake8 {toxinidir}/ {toxinidir}/tests isort --recursive --check-only --diff {toxinidir}/ {toxinidir}/tests - pydocstyle {toxinidir}/ {toxinidir}/tests + pydocstyle --explain {toxinidir}/ {toxinidir}/tests From d3a5a3e9e5ccaac942115ef95bdb87db1644d118 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Fri, 20 May 2022 10:18:36 -0700 Subject: [PATCH 098/159] Exclude huge and unnecessary venv*/ from dist See an example issue here: https://github.com/ethereum/eth-account/issues/150 --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index fbff980..0d9ffe9 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -6,3 +6,4 @@ global-include *.pyi recursive-exclude * __pycache__ recursive-exclude * *.py[co] +recursive-exclude * venv* From 2e22e2d0b64850ff03356a9d52c06e79c23ef65f Mon Sep 17 00:00:00 2001 From: kclowes Date: Fri, 20 May 2022 14:12:01 -0600 Subject: [PATCH 099/159] Add breaking change type to newsfragment (#61) * Add breaking change type to newsfragment * Move breaking-change -> breaking --- newsfragments/README.md | 1 + newsfragments/validate_files.py | 1 + pyproject.toml | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/newsfragments/README.md b/newsfragments/README.md index 09a10dd..bcb0412 100644 --- a/newsfragments/README.md +++ b/newsfragments/README.md @@ -15,6 +15,7 @@ Each file should be named like `..rst`, where * `internal` * `removal` * `misc` +* `breaking` So for example: `123.feature.rst`, `456.bugfix.rst` diff --git a/newsfragments/validate_files.py b/newsfragments/validate_files.py index c0e9b28..0a13ec2 100755 --- a/newsfragments/validate_files.py +++ b/newsfragments/validate_files.py @@ -8,6 +8,7 @@ import sys ALLOWED_EXTENSIONS = { + '.breaking.rst', '.bugfix.rst', '.doc.rst', '.feature.rst', diff --git a/pyproject.toml b/pyproject.toml index b03fe29..3143314 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,3 +41,8 @@ showcontent = true directory = "misc" name = "Miscellaneous changes" showcontent = false + +[[tool.towncrier.type]] +directory = "breaking" +name = "Breaking changes" +showcontent = true From e2e1f9d079093737402e31b4f8b65e2be47d22de Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 26 May 2022 14:01:42 -0700 Subject: [PATCH 100/159] Use prune instead of recursive-exclude for venv* Frankly not sure why recursive-exclude doesn't work here, but prune does, and that's good enough for me now. It's also probably preferable to only exclude venv* at the root, anyway. --- MANIFEST.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 0d9ffe9..bb1b0f3 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -6,4 +6,4 @@ global-include *.pyi recursive-exclude * __pycache__ recursive-exclude * *.py[co] -recursive-exclude * venv* +prune venv* From 5e100467599407e2aeff854f7624b34c0efff511 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 1 Jun 2022 13:05:34 -0700 Subject: [PATCH 101/159] Use updated CircleCI images See https://discuss.circleci.com/t/legacy-convenience-image-deprecation/41034 --- .circleci/config.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 167ae52..9664ee1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -39,43 +39,43 @@ jobs: docs: <<: *common docker: - - image: circleci/python:3.6 + - image: cimg/python:3.6 environment: TOXENV: docs lint: <<: *common docker: - - image: circleci/python:3.6 + - image: cimg/python:3.6 environment: TOXENV: lint py36-core: <<: *common docker: - - image: circleci/python:3.6 + - image: cimg/python:3.6 environment: TOXENV: py36-core py37-core: <<: *common docker: - - image: circleci/python:3.7 + - image: cimg/python:3.7 environment: TOXENV: py37-core py38-core: <<: *common docker: - - image: circleci/python:3.8 + - image: cimg/python:3.8 environment: TOXENV: py38-core py39-core: <<: *common docker: - - image: circleci/python:3.9 + - image: cimg/python:3.9 environment: TOXENV: py39-core py310-core: <<: *common docker: - - image: circleci/python:3.10 + - image: cimg/python:3.10 environment: TOXENV: py310-core pypy3-core: From cb112ef9c12e16d2caaf71f7f0c067663499fddf Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 2 Jun 2022 15:36:24 -0700 Subject: [PATCH 102/159] Upgrade towncrier to fix the duplicate title bug --- Makefile | 4 ++-- setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index d38ac9d..bc39881 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ build-docs: $(MAKE) -C docs html $(MAKE) -C docs doctest ./newsfragments/validate_files.py - towncrier --draft --version preview + towncrier build --draft --version preview docs: build-docs open docs/_build/html/index.html @@ -63,7 +63,7 @@ notes: check-bump # Let UPCOMING_VERSION be the version that is used for the current bump $(eval UPCOMING_VERSION=$(shell bumpversion $(bump) --dry-run --list | grep new_version= | sed 's/new_version=//g')) # Now generate the release notes to have them included in the release commit - towncrier --yes --version $(UPCOMING_VERSION) + 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" diff --git a/setup.py b/setup.py index 38e0d78..6f0abaf 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ 'doc': [ "Sphinx>=1.6.5,<2", "sphinx_rtd_theme>=0.1.9,<1", - "towncrier>=19.2.0, <20", + "towncrier>=21,<22", ], 'dev': [ "bumpversion>=0.5.3,<1", From 160c0feb056ece2b3d1f2f92d0991c3180bf5de3 Mon Sep 17 00:00:00 2001 From: kclowes Date: Wed, 22 Jun 2022 13:55:56 -0600 Subject: [PATCH 103/159] Add a validate docs command (#64) --- Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index bc39881..03e193b 100644 --- a/Makefile +++ b/Makefile @@ -45,10 +45,12 @@ build-docs: $(MAKE) -C docs clean $(MAKE) -C docs html $(MAKE) -C docs doctest - ./newsfragments/validate_files.py - towncrier build --draft --version preview -docs: build-docs +validate-docs: + python ./newsfragments/validate_files.py + towncrier --draft --version preview + +docs: build-docs validate-docs open docs/_build/html/index.html linux-docs: build-docs From 007725e84d2913c1faace60fec9df1c677f7a3be Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 31 Aug 2022 14:31:13 -0700 Subject: [PATCH 104/159] Don't push .tox file to tar.gz release It can get big with installed libraries. On a relatively small release of eth-portal, this one change cut the .tar.gz release size from 574Kb to 14Kb. --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index bb1b0f3..e870a41 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -6,4 +6,5 @@ global-include *.pyi recursive-exclude * __pycache__ recursive-exclude * *.py[co] +prune .tox prune venv* From 99af2f4d53ec9da9abe3a5bfa46d37d32f5c7885 Mon Sep 17 00:00:00 2001 From: kclowes Date: Mon, 19 Sep 2022 14:35:39 -0600 Subject: [PATCH 105/159] Misc Updates (#65) * Tweaks to release process * Drop python 3.6 --- .bumpversion.cfg | 8 +- .circleci/config.yml | 14 ++-- Makefile | 9 ++- docs/conf.py | 169 ++++++++++++++++++++++------------------ newsfragments/README.md | 2 +- pytest.ini | 1 - setup.py | 66 ++++++++-------- tox.ini | 6 +- 8 files changed, 144 insertions(+), 131 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index eefe4ad..f683001 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -3,14 +3,14 @@ current_version = 0.1.0-alpha.0 commit = True tag = True parse = (?P\d+)\.(?P\d+)\.(?P\d+)(-(?P[^.]*)\.(?P\d+))? -serialize = +serialize = {major}.{minor}.{patch}-{stage}.{devnum} {major}.{minor}.{patch} [bumpversion:part:stage] optional_value = stable first_value = stable -values = +values = alpha beta stable @@ -18,6 +18,6 @@ values = [bumpversion:part:devnum] [bumpversion:file:setup.py] -search = version='{current_version}', -replace = version='{new_version}', +search = version="{current_version}", +replace = version="{new_version}", diff --git a/.circleci/config.yml b/.circleci/config.yml index 9664ee1..b67caf4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -39,21 +39,15 @@ jobs: docs: <<: *common docker: - - image: cimg/python:3.6 + - image: cimg/python:3.7 environment: TOXENV: docs lint: <<: *common docker: - - image: cimg/python:3.6 + - image: cimg/python:3.7 environment: TOXENV: lint - py36-core: - <<: *common - docker: - - image: cimg/python:3.6 - environment: - TOXENV: py36-core py37-core: <<: *common docker: @@ -90,6 +84,8 @@ workflows: jobs: - docs - lint - - py36-core - py37-core + - py38-core + - py39-core + - py310-core - pypy3-core diff --git a/Makefile b/Makefile index 03e193b..541c166 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,7 @@ lint: lint-roll: isort --recursive tests + black {toxinidir}/ {toxinidir}/tests setup.py $(MAKE) lint test: @@ -48,12 +49,14 @@ build-docs: validate-docs: python ./newsfragments/validate_files.py - towncrier --draft --version preview + towncrier build --draft --version preview -docs: build-docs validate-docs +check-docs: build-docs validate-docs + +docs: check-docs open docs/_build/html/index.html -linux-docs: build-docs +linux-docs: check-docs xdg-open docs/_build/html/index.html check-bump: diff --git a/docs/conf.py b/docs/conf.py index 977f3ab..8264b45 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,46 +15,46 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) import os -DIR = os.path.dirname('__file__') -with open (os.path.join(DIR, '../setup.py'), 'r') as f: +DIR = os.path.dirname("__file__") +with open(os.path.join(DIR, "../setup.py"), "r") as f: for line in f: - if 'version=' in line: - setup_version = line.split('\'')[1] + if "version=" in line: + setup_version = line.split('"')[1] break # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx', + "sphinx.ext.autodoc", + "sphinx.ext.doctest", + "sphinx.ext.intersphinx", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = '' -copyright = '2020, The Ethereum Foundation' +project = "" +copyright = "2020, The Ethereum Foundation" __version__ = setup_version # The version info for the project you're documenting, acts as replacement for @@ -62,176 +62,179 @@ # built documents. # # The short X.Y version. -version = '.'.join(__version__.split('.')[:2]) +version = ".".join(__version__.split(".")[:2]) # The full version, including alpha/beta/rc tags. release = __version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [ - '_build', - 'modules.rst', + "_build", + "modules.rst", ] # The reST default role (used for this markup: `text`) to use for all # documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# keep_warnings = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -#html_extra_path = [] +# html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'doc' +htmlhelp_basename = "doc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ('index', '.tex', ' Documentation', - 'The Ethereum Foundation', 'manual'), + ( + "index", + ".tex", + " Documentation", + "The Ethereum Foundation", + "manual", + ), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output --------------------------------------- @@ -239,12 +242,17 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', '', ' Documentation', - ['The Ethereum Foundation'], 1) + ( + "index", + "", + " Documentation", + ["The Ethereum Foundation"], + 1, + ) ] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------- @@ -253,34 +261,41 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', '', ' Documentation', - 'The Ethereum Foundation', '', '', - 'Miscellaneous'), + ( + "index", + "", + " Documentation", + "The Ethereum Foundation", + "", + "", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False +# texinfo_no_detailmenu = False # -- Intersphinx configuration ------------------------------------------------ intersphinx_mapping = { - 'python': ('https://docs.python.org/3.6', None), + "python": ("https://docs.python.org/3.10", None), } # -- Doctest configuration ---------------------------------------- import doctest -doctest_default_flags = (0 +doctest_default_flags = ( + 0 | doctest.DONT_ACCEPT_TRUE_FOR_1 | doctest.ELLIPSIS | doctest.IGNORE_EXCEPTION_DETAIL diff --git a/newsfragments/README.md b/newsfragments/README.md index bcb0412..f98aef6 100644 --- a/newsfragments/README.md +++ b/newsfragments/README.md @@ -24,5 +24,5 @@ then open up the PR first and use the PR number for the newsfragment. Note that the `towncrier` tool will automatically reflow your text, so don't try to do any fancy formatting. Run - `towncrier --draft` to get a preview of what the release notes entry + `towncrier build --draft` to get a preview of what the release notes entry will look like in the final release notes. diff --git a/pytest.ini b/pytest.ini index f5fdc0e..ae90934 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,6 +1,5 @@ [pytest] addopts= -v --showlocals --durations 10 -python_paths= . xfail_strict=true [pytest-watch] diff --git a/setup.py b/setup.py index 6f0abaf..e319e3e 100644 --- a/setup.py +++ b/setup.py @@ -6,23 +6,24 @@ ) extras_require = { - 'test': [ + "test": [ "pytest>=6.2.5,<7", "pytest-xdist>=2.4.0,<3", "tox==3.14.6", ], - 'lint': [ + "lint": [ "flake8==3.7.9", "isort>=4.2.15,<5", "mypy==0.770", "pydocstyle>=5.0.0,<6", + "black>=22,<23", ], - 'doc': [ + "doc": [ "Sphinx>=1.6.5,<2", "sphinx_rtd_theme>=0.1.9,<1", "towncrier>=21,<22", ], - 'dev': [ + "dev": [ "bumpversion>=0.5.3,<1", "pytest-watch>=4.1.0,<5", "wheel", @@ -31,53 +32,52 @@ ], } -extras_require['dev'] = ( - extras_require['dev'] + # noqa: W504 - extras_require['test'] + # noqa: W504 - extras_require['lint'] + # noqa: W504 - extras_require['doc'] +extras_require["dev"] = ( + extras_require["dev"] + + extras_require["test"] + + extras_require["lint"] + + extras_require["doc"] ) -with open('./README.md') as readme: +with open("./README.md") as readme: long_description = readme.read() setup( - name='', + name="", # *IMPORTANT*: Don't manually change the version here. Use `make bump`, as described in readme - version='0.1.0-alpha.0', + version="0.1.0-alpha.0", description=""": """, long_description=long_description, - long_description_content_type='text/markdown', - author='The Ethereum Foundation', - author_email='snakecharmers@ethereum.org', - url='https://github.com/ethereum/', + long_description_content_type="text/markdown", + author="The Ethereum Foundation", + author_email="snakecharmers@ethereum.org", + url="https://github.com/ethereum/", include_package_data=True, install_requires=[ "eth-utils>=2,<3", ], - python_requires='>=3.6, <4', + python_requires=">=3.7, <4", extras_require=extras_require, - py_modules=[''], + py_modules=[""], license="MIT", zip_safe=False, - keywords='ethereum', + keywords="ethereum", packages=find_packages(exclude=["tests", "tests.*"]), - package_data={'': ['py.typed']}, + package_data={"": ["py.typed"]}, classifiers=[ - 'Development Status :: 3 - Alpha', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', - 'Natural Language :: English', - 'Operating System :: MacOS', - 'Operating System :: POSIX', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: Implementation :: PyPy', + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Natural Language :: English", + "Operating System :: MacOS", + "Operating System :: POSIX", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: Implementation :: PyPy", ], ) diff --git a/tox.ini b/tox.ini index edd1dcd..afe023c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist= - py{36,37,38,39,310,py3}-core + py{37,38,39,310,py3}-core lint docs @@ -23,10 +23,9 @@ ignore= usedevelop=True commands= core: pytest {posargs:tests/core} - docs: make build-docs + docs: make check-docs basepython = docs: python - py36: python3.6 py37: python3.7 py38: python3.8 py39: python3.9 @@ -45,3 +44,4 @@ commands= flake8 {toxinidir}/ {toxinidir}/tests isort --recursive --check-only --diff {toxinidir}/ {toxinidir}/tests pydocstyle --explain {toxinidir}/ {toxinidir}/tests + black --check {toxinidir}/ {toxinidir}/tests setup.py From e785138a21bd8486653e09dd74e2dba1269a235d Mon Sep 17 00:00:00 2001 From: kclowes Date: Mon, 19 Sep 2022 14:55:43 -0600 Subject: [PATCH 106/159] Use updated tox command in CI (#67) --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b67caf4..4ce05a4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,7 +25,7 @@ common: &common command: pip install --user tox - run: name: run tox - command: ~/.local/bin/tox -r + command: python -m tox -r - save_cache: paths: - .hypothesis From 8a4cb1d938c36cac47e60af313d012e2f0fd8065 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 22 Sep 2022 13:38:20 -0700 Subject: [PATCH 107/159] Upgrade isort to v5 for black support --- Makefile | 2 +- setup.py | 2 +- tox.ini | 7 ++----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 541c166..231b2b2 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ lint: tox -elint lint-roll: - isort --recursive tests + isort tests black {toxinidir}/ {toxinidir}/tests setup.py $(MAKE) lint diff --git a/setup.py b/setup.py index e319e3e..1c8088a 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ ], "lint": [ "flake8==3.7.9", - "isort>=4.2.15,<5", + "isort>=5.10.1,<6", "mypy==0.770", "pydocstyle>=5.0.0,<6", "black>=22,<23", diff --git a/tox.ini b/tox.ini index afe023c..d1dc3e6 100644 --- a/tox.ini +++ b/tox.ini @@ -7,12 +7,9 @@ envlist= [isort] combine_as_imports=True force_sort_within_sections=True -include_trailing_comma=True known_third_party=hypothesis,pytest known_first_party= -line_length=21 -multi_line_output=3 -use_parentheses=True +profile=black [flake8] max-line-length= 100 @@ -42,6 +39,6 @@ extras=lint commands= mypy -p --config-file {toxinidir}/mypy.ini flake8 {toxinidir}/ {toxinidir}/tests - isort --recursive --check-only --diff {toxinidir}/ {toxinidir}/tests + isort --check-only --diff {toxinidir}/ {toxinidir}/tests pydocstyle --explain {toxinidir}/ {toxinidir}/tests black --check {toxinidir}/ {toxinidir}/tests setup.py From 94eacb9c30cb84085038f1eb2991623f459114a7 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 22 Sep 2022 13:38:32 -0700 Subject: [PATCH 108/159] A couple extra tweaks for black support --- tox.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index d1dc3e6..0e5a8a1 100644 --- a/tox.ini +++ b/tox.ini @@ -14,7 +14,7 @@ profile=black [flake8] max-line-length= 100 exclude= venv*,.tox,docs,build -ignore= +extend-ignore= E203 [testenv] usedevelop=True @@ -36,6 +36,7 @@ whitelist_externals=make [testenv:lint] basepython=python extras=lint +whitelist_externals=black commands= mypy -p --config-file {toxinidir}/mypy.ini flake8 {toxinidir}/ {toxinidir}/tests From 4bd024028b4f6e4c7bd69d610d84201b666660fa Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 22 Sep 2022 13:47:14 -0700 Subject: [PATCH 109/159] Fix a copy-paste mistake from #65 toxinidir won't mean anything in a Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 231b2b2..abf9454 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ lint: lint-roll: isort tests - black {toxinidir}/ {toxinidir}/tests setup.py + black tests setup.py $(MAKE) lint test: From 7b0bc76f6ff430b7530324dc17f1895ebc38c70c Mon Sep 17 00:00:00 2001 From: kclowes Date: Wed, 9 Nov 2022 11:11:28 -0700 Subject: [PATCH 110/159] Add Python 3.11, add more black checks, remove upper pins (#69) --- .circleci/config.yml | 7 +++++++ setup.py | 21 +++++++++++---------- tox.ini | 5 +++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4ce05a4..db95741 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -72,6 +72,12 @@ jobs: - image: cimg/python:3.10 environment: TOXENV: py310-core + py311-core: + <<: *common + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-core pypy3-core: <<: *common docker: @@ -88,4 +94,5 @@ workflows: - py38-core - py39-core - py310-core + - py311-core - pypy3-core diff --git a/setup.py b/setup.py index 1c8088a..9dfbf78 100644 --- a/setup.py +++ b/setup.py @@ -7,25 +7,25 @@ extras_require = { "test": [ - "pytest>=6.2.5,<7", + "pytest>=6.2.5", "pytest-xdist>=2.4.0,<3", "tox==3.14.6", ], "lint": [ "flake8==3.7.9", - "isort>=5.10.1,<6", + "isort>=5.10.1", "mypy==0.770", - "pydocstyle>=5.0.0,<6", - "black>=22,<23", + "pydocstyle>=5.0.0", + "black>=22", ], "doc": [ - "Sphinx>=1.6.5,<2", - "sphinx_rtd_theme>=0.1.9,<1", - "towncrier>=21,<22", + "Sphinx>=1.6.5", + "sphinx_rtd_theme>=0.1.9", + "towncrier>=21", ], "dev": [ - "bumpversion>=0.5.3,<1", - "pytest-watch>=4.1.0,<5", + "bumpversion>=0.5.3", + "pytest-watch>=4.1.0", "wheel", "twine", "ipython", @@ -56,7 +56,7 @@ url="https://github.com/ethereum/", include_package_data=True, install_requires=[ - "eth-utils>=2,<3", + "eth-utils>=2", ], python_requires=">=3.7, <4", extras_require=extras_require, @@ -78,6 +78,7 @@ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: PyPy", ], ) diff --git a/tox.ini b/tox.ini index 0e5a8a1..00ca446 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist= - py{37,38,39,310,py3}-core + py{37,38,39,310,311,py3}-core lint docs @@ -27,6 +27,7 @@ basepython = py38: python3.8 py39: python3.9 py310: python3.10 + py311: python3.11 pypy3: pypy3 extras= test @@ -42,4 +43,4 @@ commands= flake8 {toxinidir}/ {toxinidir}/tests isort --check-only --diff {toxinidir}/ {toxinidir}/tests pydocstyle --explain {toxinidir}/ {toxinidir}/tests - black --check {toxinidir}/ {toxinidir}/tests setup.py + black --check {toxinidir}/ {toxinidir}/docs {toxinidir}/tests {toxinidir}/setup.py From 3ff1c9cf5d6d1867bc1216e586c65f787e15c0e3 Mon Sep 17 00:00:00 2001 From: fselmo Date: Mon, 21 Nov 2022 17:25:08 -0700 Subject: [PATCH 111/159] Minor refactoring / cleanup - Clean up github PR template to remove double links to the newsfragment README.md - Clean up some typos and make some minor refactors. --- .github/PULL_REQUEST_TEMPLATE.md | 10 +++------- newsfragments/README.md | 4 ++-- newsfragments/validate_files.py | 28 +++++++++++++++------------- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 21d4db5..54da551 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,18 +1,14 @@ -## What was wrong? +### What was wrong? -Issue # +Related to issue # -## How was it fixed? - -Summary of approach. +### How was it fixed? ### To-Do [//]: # (Stay ahead of things, add list items here!) - [ ] Clean up commit history -[//]: # (For important changes that should go into the release notes please add a newsfragment file as explained here: https://github.com/ethereum//blob/master/newsfragments/README.md) - [//]: # (See: https://.readthedocs.io/en/latest/contributing.html#pull-requests) - [ ] Add entry to the [release notes](https://github.com/ethereum//blob/master/newsfragments/README.md) diff --git a/newsfragments/README.md b/newsfragments/README.md index f98aef6..e4740e4 100644 --- a/newsfragments/README.md +++ b/newsfragments/README.md @@ -6,7 +6,7 @@ commit message and PR description, which are a description of the change as relevant to people working on the code itself.) Each file should be named like `..rst`, where -`` is an issue numbers, and `` is one of: +`` is an issue number, and `` is one of: * `feature` * `bugfix` @@ -24,5 +24,5 @@ then open up the PR first and use the PR number for the newsfragment. Note that the `towncrier` tool will automatically reflow your text, so don't try to do any fancy formatting. Run - `towncrier build --draft` to get a preview of what the release notes entry +`towncrier build --draft` to get a preview of what the release notes entry will look like in the final release notes. diff --git a/newsfragments/validate_files.py b/newsfragments/validate_files.py index 0a13ec2..684c798 100755 --- a/newsfragments/validate_files.py +++ b/newsfragments/validate_files.py @@ -8,19 +8,19 @@ import sys ALLOWED_EXTENSIONS = { - '.breaking.rst', - '.bugfix.rst', - '.doc.rst', - '.feature.rst', - '.internal.rst', - '.misc.rst', - '.performance.rst', - '.removal.rst', + ".breaking.rst", + ".bugfix.rst", + ".doc.rst", + ".feature.rst", + ".internal.rst", + ".misc.rst", + ".performance.rst", + ".removal.rst", } ALLOWED_FILES = { - 'validate_files.py', - 'README.md', + "validate_files.py", + "README.md", } THIS_DIR = pathlib.Path(__file__).parent @@ -28,7 +28,7 @@ num_args = len(sys.argv) - 1 assert num_args in {0, 1} if num_args == 1: - assert sys.argv[1] in ('is-empty', ) + assert sys.argv[1] in ("is-empty",) for fragment_file in THIS_DIR.iterdir(): @@ -38,7 +38,9 @@ full_extension = "".join(fragment_file.suffixes) if full_extension not in ALLOWED_EXTENSIONS: raise Exception(f"Unexpected file: {fragment_file}") - elif sys.argv[1] == 'is-empty': + elif sys.argv[1] == "is-empty": raise Exception(f"Unexpected file: {fragment_file}") else: - raise RuntimeError("Strange: arguments {sys.argv} were validated, but not found") + raise RuntimeError( + f"Strange: arguments {sys.argv} were validated, but not found" + ) From 7c85f95a4dfb0e6bbf425b1d22dd69c6c27cf98e Mon Sep 17 00:00:00 2001 From: fselmo Date: Mon, 21 Nov 2022 17:27:18 -0700 Subject: [PATCH 112/159] Do not invoke ``setup.py`` directly - It is not recommended to invoke ``setup.py`` directly, instead opting for ``python -m build`` for the commands in this commit (see: https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html) - Add newsfragment for #70 --- Makefile | 6 +++--- newsfragments/70.internal.rst | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 newsfragments/70.internal.rst diff --git a/Makefile b/Makefile index 541c166..9ec2049 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ clean-pyc: find . -name '__pycache__' -exec rm -rf {} + lint: - tox -elint + tox -e lint lint-roll: isort --recursive tests @@ -83,11 +83,11 @@ release: check-bump clean git config commit.gpgSign true bumpversion $(bump) git push upstream && git push upstream --tags - python setup.py sdist bdist_wheel + python -m build twine upload dist/* git config commit.gpgSign "$(CURRENT_SIGN_SETTING)" dist: clean - python setup.py sdist bdist_wheel + python -m build ls -l dist diff --git a/newsfragments/70.internal.rst b/newsfragments/70.internal.rst new file mode 100644 index 0000000..2e2fd5f --- /dev/null +++ b/newsfragments/70.internal.rst @@ -0,0 +1 @@ +Do not invoke ``setup.py`` directly. Minor cleanup and refactors in newsfragment ``README.md`` and newsfragment validation. Minot cleanup in ``Makefile``. From af2dfa6560c9737fe202ac30a0b3511949406689 Mon Sep 17 00:00:00 2001 From: kclowes Date: Thu, 8 Dec 2022 15:19:05 -0700 Subject: [PATCH 113/159] Fix auto project template errors for MacOS (#71) --- .project-template/fill_template_vars.sh | 2 +- .project-template/refill_template_vars.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.project-template/fill_template_vars.sh b/.project-template/fill_template_vars.sh index 250f551..157c89d 100755 --- a/.project-template/fill_template_vars.sh +++ b/.project-template/fill_template_vars.sh @@ -33,7 +33,7 @@ _replace() { local find_cmd=(find "$PROJECT_ROOT" ! -perm -u=x ! -path '*/.git/*' ! -path '*/venv*/*' -type f) if [[ $(uname) == Darwin ]]; then - "${find_cmd[@]}" -exec sed -i '' "$1" {} + + LC_ALL=C "${find_cmd[@]}" -exec sed -i '' "$1" {} + else "${find_cmd[@]}" -exec sed -i "$1" {} + fi diff --git a/.project-template/refill_template_vars.sh b/.project-template/refill_template_vars.sh index 6e7943f..70832d3 100755 --- a/.project-template/refill_template_vars.sh +++ b/.project-template/refill_template_vars.sh @@ -1,2 +1,2 @@ -TEMPLATE_DIR=$(dirname $(readlink -f "$0")) +TEMPLATE_DIR=$(dirname "$0") <"$TEMPLATE_DIR/template_vars.txt" "$TEMPLATE_DIR/fill_template_vars.sh" From 642ae9627cd28fc9ba8c0c745375a0becbc202eb Mon Sep 17 00:00:00 2001 From: kclowes Date: Fri, 9 Dec 2022 11:25:55 -0700 Subject: [PATCH 114/159] Update isort CLI commands (#72) --- tox.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tox.ini b/tox.ini index 00ca446..23729cf 100644 --- a/tox.ini +++ b/tox.ini @@ -6,9 +6,11 @@ envlist= [isort] combine_as_imports=True +force_grid_wrap=1 force_sort_within_sections=True known_third_party=hypothesis,pytest known_first_party= +multi_line_output=3 profile=black [flake8] From fe19f5a77a5fbba712da052ef3d25f187257ed3c Mon Sep 17 00:00:00 2001 From: pacrob Date: Mon, 3 Apr 2023 14:01:03 -0600 Subject: [PATCH 115/159] bump docs dependencies --- .readthedocs.yml | 5 +++++ docs/conf.py | 1 + newsfragments/70.internal.rst | 1 - setup.py | 6 +++--- 4 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 .readthedocs.yml delete mode 100644 newsfragments/70.internal.rst diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 0000000..ed4fab3 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,5 @@ +version: 2 + +python: + install: + - requirements: requirements-docs.txt \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 8264b45..df931f1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -38,6 +38,7 @@ "sphinx.ext.autodoc", "sphinx.ext.doctest", "sphinx.ext.intersphinx", + "sphinx_rtd_theme", ] # Add any paths that contain templates here, relative to this directory. diff --git a/newsfragments/70.internal.rst b/newsfragments/70.internal.rst deleted file mode 100644 index 2e2fd5f..0000000 --- a/newsfragments/70.internal.rst +++ /dev/null @@ -1 +0,0 @@ -Do not invoke ``setup.py`` directly. Minor cleanup and refactors in newsfragment ``README.md`` and newsfragment validation. Minot cleanup in ``Makefile``. diff --git a/setup.py b/setup.py index 9dfbf78..04028b1 100644 --- a/setup.py +++ b/setup.py @@ -19,9 +19,9 @@ "black>=22", ], "doc": [ - "Sphinx>=1.6.5", - "sphinx_rtd_theme>=0.1.9", - "towncrier>=21", + "sphinx>=5.0.0", + "sphinx_rtd_theme>=1.0.0", + "towncrier>=21,<22", ], "dev": [ "bumpversion>=0.5.3", From 89e5d8ef9c637c9ac8fbefa11230b3beeb4a2e54 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Wed, 5 Apr 2023 18:00:29 -0600 Subject: [PATCH 116/159] new github issue and pr templates (#75) * new issue and pr templates --- .github/ISSUE_TEMPLATE.md | 38 ------------ .github/ISSUE_TEMPLATE/bug_report.yml | 70 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 5 ++ .github/ISSUE_TEMPLATE/feature_request.yml | 11 ++++ .github/PULL_REQUEST_TEMPLATE.md | 17 ------ .github/pull_request_template.md | 17 ++++++ 6 files changed, 103 insertions(+), 55 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/pull_request_template.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 5ff4880..0000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,38 +0,0 @@ - _If this is a bug report, please fill in the following sections. -If this is a feature request, delete and describe what you would like with examples._ - -## What was wrong? - -### Code that produced the error - -```py -CODE_TO_REPRODUCE -``` - -### Full error output - -```sh -ERROR_HERE -``` - -### Expected Result - -_This section may be deleted if the expectation is "don't crash"._ - -```sh -EXPECTED_RESULT -``` - -### Environment - -```sh -# run this: -$ python -m eth_utils - -# then copy the output here: -OUTPUT_HERE -``` - -## How can it be fixed? - -Fill this section in if you know how this could or should be fixed. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..5f1ddfd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,70 @@ +name: Bug Report +description: File a bug report +labels: ["bug"] +body: + - type: markdown + attributes: + value: "## What was wrong" + - type: textarea + id: what-happened + attributes: + label: What happened? + description: Also tell us what you expected to happen + validations: + required: true + - type: textarea + id: code-that-caused + attributes: + label: Code that produced the error + description: Formats to Python, no backticks needed + render: python + validations: + required: false + - type: textarea + id: error-output + attributes: + label: Full error output + description: Formats to shell, no backticks needed + render: shell + validations: + required: false + - type: markdown + attributes: + value: "## Potential Solutions" + - type: textarea + id: how-to-fix + attributes: + label: Fill this section in if you know how this could or should be fixed + description: Include any relevant examples or reference material + validations: + required: false + - type: input + id: lib-version + attributes: + label: Version + description: Which version of are you using? + placeholder: x.x.x + validations: + required: false + - type: input + id: py-version + attributes: + label: Python Version + description: Which version of Python are you using? + placeholder: x.x.x + validations: + required: false + - type: input + id: os + attributes: + label: Operating System + description: Which operating system are you using? + placeholder: osx/linux/win + validations: + required: false + - type: textarea + id: pip-freeze + attributes: + label: Output from pip-freeze + description: Run `pip-freeze` and paste the output below + render: shell diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..9853c79 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Questions about using ? + url: https://discord.gg/GHryRvPB84 + about: You can ask and answer usage questions on the Ethereum Python Community Discord diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..041c8fd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,11 @@ +name: Feature Request +description: Request a new feature +labels: ["feature_request"] +body: + - type: textarea + id: feature-description + attributes: + label: What feature should we add? + description: Include any relevant examples or reference material + validations: + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 54da551..0000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,17 +0,0 @@ -### What was wrong? - -Related to issue # - -### How was it fixed? - -### To-Do - -[//]: # (Stay ahead of things, add list items here!) -- [ ] Clean up commit history - -[//]: # (See: https://.readthedocs.io/en/latest/contributing.html#pull-requests) -- [ ] Add entry to the [release notes](https://github.com/ethereum//blob/master/newsfragments/README.md) - -#### Cute Animal Picture - -![put a cute animal picture link inside the parentheses]() diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..93fb355 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,17 @@ +### What was wrong? + +Related to Issue # +Closes Issue # + +### How was it fixed? + +### Todo: +- [ ] Clean up commit history + +- [ ] Add or update documentation related to these changes + +- [ ] Add entry to the [release notes](https://github.com/ethereum/web3.py/blob/master/newsfragments/README.md) + +#### Cute Animal Picture + +![Put a link to a cute animal picture inside the parenthesis-->]() \ No newline at end of file From 180777d7db608b8db4a271c5502d0568107d8931 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Fri, 7 Apr 2023 10:22:12 -0600 Subject: [PATCH 117/159] convert bash scripts to py (#77) * convert bash scripts to py --- .project-template/fill_template_vars.py | 68 +++++++++++++++++++++++ .project-template/fill_template_vars.sh | 50 ----------------- .project-template/refill_template_vars.py | 39 +++++++++++++ .project-template/refill_template_vars.sh | 2 - 4 files changed, 107 insertions(+), 52 deletions(-) create mode 100644 .project-template/fill_template_vars.py delete mode 100755 .project-template/fill_template_vars.sh create mode 100644 .project-template/refill_template_vars.py delete mode 100755 .project-template/refill_template_vars.sh diff --git a/.project-template/fill_template_vars.py b/.project-template/fill_template_vars.py new file mode 100644 index 0000000..8d4bc35 --- /dev/null +++ b/.project-template/fill_template_vars.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 + +import os +import sys +import re +from pathlib import Path + + +def _find_files(project_root): + path_exclude_pattern = r"\.git($|\/)|venv|_build" + file_exclude_pattern = r"fill_template_vars\.py|\.swp$" + filepaths = [] + for dir_path, _dir_names, file_names in os.walk(project_root): + if not re.search(path_exclude_pattern, dir_path): + for file in file_names: + if not re.search(file_exclude_pattern, file): + filepaths.append(str(Path(dir_path, file))) + + return filepaths + + +def _replace(pattern, replacement, project_root): + print(f"Replacing values: {pattern}") + for file in _find_files(project_root): + with open(file) as f: + content = f.read() + content = re.sub(pattern, replacement, content) + with open(file, "w") as f: + f.write(content) + + +def main(): + project_root = Path(os.path.realpath(sys.argv[0])).parent.parent + + module_name = input("What is your python module name? ") + + pypi_input = input(f"What is your pypi package name? (default: {module_name}) ") + pypi_name = pypi_input or module_name + + repo_input = input(f"What is your github project name? (default: {pypi_name}) ") + repo_name = repo_input or pypi_name + + rtd_input = input( + f"What is your readthedocs.org project name? (default: {pypi_name}) " + ) + rtd_name = rtd_input or pypi_name + + project_input = input( + f"What is your project name (ex: at the top of the README)? (default: {repo_name}) " + ) + project_name = project_input or repo_name + + short_description = input("What is a one-liner describing the project? ") + + _replace("", module_name, project_root) + _replace("", pypi_name, project_root) + _replace("", repo_name, project_root) + _replace("", rtd_name, project_root) + _replace("", project_name, project_root) + _replace("", short_description, project_root) + + os.makedirs(project_root / module_name, exist_ok=True) + Path(project_root / module_name / "__init__.py").touch() + Path(project_root / module_name / "py.typed").touch() + + +if __name__ == "__main__": + main() diff --git a/.project-template/fill_template_vars.sh b/.project-template/fill_template_vars.sh deleted file mode 100755 index 157c89d..0000000 --- a/.project-template/fill_template_vars.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash - -set -o errexit -set -o nounset -set -o pipefail - -PROJECT_ROOT=$(dirname $(dirname $(python -c 'import os, sys; sys.stdout.write(os.path.realpath(sys.argv[1]))' "$0"))) - -echo "What is your python module name?" -read MODULE_NAME - -echo "What is your pypi package name? (default: $MODULE_NAME)" -read PYPI_INPUT -PYPI_NAME=${PYPI_INPUT:-$MODULE_NAME} - -echo "What is your github project name? (default: $PYPI_NAME)" -read REPO_INPUT -REPO_NAME=${REPO_INPUT:-$PYPI_NAME} - -echo "What is your readthedocs.org project name? (default: $PYPI_NAME)" -read RTD_INPUT -RTD_NAME=${RTD_INPUT:-$PYPI_NAME} - -echo "What is your project name (ex: at the top of the README)? (default: $REPO_NAME)" -read PROJECT_INPUT -PROJECT_NAME=${PROJECT_INPUT:-$REPO_NAME} - -echo "What is a one-liner describing the project?" -read SHORT_DESCRIPTION - -_replace() { - echo "Replacing values: $1" - local find_cmd=(find "$PROJECT_ROOT" ! -perm -u=x ! -path '*/.git/*' ! -path '*/venv*/*' -type f) - - if [[ $(uname) == Darwin ]]; then - LC_ALL=C "${find_cmd[@]}" -exec sed -i '' "$1" {} + - else - "${find_cmd[@]}" -exec sed -i "$1" {} + - fi -} -_replace "s//$MODULE_NAME/g" -_replace "s//$PYPI_NAME/g" -_replace "s//$REPO_NAME/g" -_replace "s//$RTD_NAME/g" -_replace "s//$PROJECT_NAME/g" -_replace "s//$SHORT_DESCRIPTION/g" - -mkdir -p "$PROJECT_ROOT/$MODULE_NAME" -touch "$PROJECT_ROOT/$MODULE_NAME/__init__.py" -touch "$PROJECT_ROOT/$MODULE_NAME/py.typed" diff --git a/.project-template/refill_template_vars.py b/.project-template/refill_template_vars.py new file mode 100644 index 0000000..03ab7c0 --- /dev/null +++ b/.project-template/refill_template_vars.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 + +import os +import sys +from pathlib import Path +import subprocess + + +def main(): + template_dir = Path(os.path.dirname(sys.argv[0])) + template_vars_file = template_dir / "template_vars.txt" + fill_template_vars_script = template_dir / "fill_template_vars.py" + + with open(template_vars_file, "r") as input_file: + content_lines = input_file.readlines() + + process = subprocess.Popen( + [sys.executable, str(fill_template_vars_script)], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + + for line in content_lines: + process.stdin.write(line) + process.stdin.flush() + + stdout, stderr = process.communicate() + + if process.returncode != 0: + print(f"Error occurred: {stderr}") + sys.exit(1) + + print(stdout) + + +if __name__ == "__main__": + main() diff --git a/.project-template/refill_template_vars.sh b/.project-template/refill_template_vars.sh deleted file mode 100755 index 70832d3..0000000 --- a/.project-template/refill_template_vars.sh +++ /dev/null @@ -1,2 +0,0 @@ -TEMPLATE_DIR=$(dirname "$0") -<"$TEMPLATE_DIR/template_vars.txt" "$TEMPLATE_DIR/fill_template_vars.sh" From ffd6ad8b9fe4fce1ddd38d3212dca0b14b89a79e Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Mon, 10 Apr 2023 11:10:15 -0600 Subject: [PATCH 118/159] Various template default updates (#74) * bump versions in dependencies and ci builds * move tox to [dev] per issue #34 * move RTD deps pointer into .readthedocs.yml * unpin flake8 add flake8-bugbear to lint deps --- .circleci/config.yml | 41 +++++++++++++++++++++++++++++++---------- .readthedocs.yml | 5 ++++- requirements-docs.txt | 1 - setup.py | 12 ++++++------ tox.ini | 22 +++++++++++++++------- 5 files changed, 56 insertions(+), 25 deletions(-) delete mode 100644 requirements-docs.txt diff --git a/.circleci/config.yml b/.circleci/config.yml index db95741..237a3f6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -39,60 +39,81 @@ jobs: docs: <<: *common docker: - - image: cimg/python:3.7 + - image: cimg/python:3.8 environment: TOXENV: docs - lint: + py37-lint: <<: *common docker: - image: cimg/python:3.7 environment: - TOXENV: lint + TOXENV: py37-lint py37-core: <<: *common docker: - image: cimg/python:3.7 environment: TOXENV: py37-core + py38-lint: + <<: *common + docker: + - image: cimg/python:3.8 + environment: + TOXENV: py38-lint py38-core: <<: *common docker: - image: cimg/python:3.8 environment: TOXENV: py38-core + py39-lint: + <<: *common + docker: + - image: cimg/python:3.9 + environment: + TOXENV: py39-lint py39-core: <<: *common docker: - image: cimg/python:3.9 environment: TOXENV: py39-core + py310-lint: + <<: *common + docker: + - image: cimg/python:3.10 + environment: + TOXENV: py310-lint py310-core: <<: *common docker: - image: cimg/python:3.10 environment: TOXENV: py310-core - py311-core: + py311-lint: <<: *common docker: - image: cimg/python:3.11 environment: - TOXENV: py311-core - pypy3-core: + TOXENV: py311-lint + py311-core: <<: *common docker: - - image: pypy + - image: cimg/python:3.11 environment: - TOXENV: pypy3-core + TOXENV: py311-core workflows: version: 2 test: jobs: - docs - - lint + - py37-lint + - py38-lint + - py39-lint + - py310-lint + - py311-lint - py37-core - py38-core - py39-core - py310-core - py311-core - - pypy3-core diff --git a/.readthedocs.yml b/.readthedocs.yml index ed4fab3..959cf71 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -2,4 +2,7 @@ version: 2 python: install: - - requirements: requirements-docs.txt \ No newline at end of file + - method: pip + path: . + extra_requirements: + - doc diff --git a/requirements-docs.txt b/requirements-docs.txt deleted file mode 100644 index 1b49b74..0000000 --- a/requirements-docs.txt +++ /dev/null @@ -1 +0,0 @@ -[doc] diff --git a/setup.py b/setup.py index 04028b1..33f9425 100644 --- a/setup.py +++ b/setup.py @@ -7,14 +7,14 @@ extras_require = { "test": [ - "pytest>=6.2.5", - "pytest-xdist>=2.4.0,<3", - "tox==3.14.6", + "pytest>=7.0.0", + "pytest-xdist>=2.4.0", ], "lint": [ - "flake8==3.7.9", + "flake8>=5.0.0", + "flake8-bugbear>=22.0.0", "isort>=5.10.1", - "mypy==0.770", + "mypy==0.971", "pydocstyle>=5.0.0", "black>=22", ], @@ -26,6 +26,7 @@ "dev": [ "bumpversion>=0.5.3", "pytest-watch>=4.1.0", + "tox>=3.18.0", "wheel", "twine", "ipython", @@ -79,6 +80,5 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: Implementation :: PyPy", ], ) diff --git a/tox.ini b/tox.ini index 23729cf..64147d4 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] envlist= - py{37,38,39,310,311,py3}-core - lint + py{37,38,39,310,311}-core + py{37,38,39,310,311}-lint docs [isort] @@ -14,7 +14,7 @@ multi_line_output=3 profile=black [flake8] -max-line-length= 100 +max-line-length= 88 exclude= venv*,.tox,docs,build extend-ignore= E203 @@ -30,19 +30,27 @@ basepython = py39: python3.9 py310: python3.10 py311: python3.11 - pypy3: pypy3 extras= test docs: doc -whitelist_externals=make +allowlist_externals=make -[testenv:lint] +[common-lint] basepython=python extras=lint -whitelist_externals=black +allowlist_externals=black commands= mypy -p --config-file {toxinidir}/mypy.ini flake8 {toxinidir}/ {toxinidir}/tests isort --check-only --diff {toxinidir}/ {toxinidir}/tests pydocstyle --explain {toxinidir}/ {toxinidir}/tests black --check {toxinidir}/ {toxinidir}/docs {toxinidir}/tests {toxinidir}/setup.py + +[testenv:lint] +basepython: python +extras: {[common-lint]extras} +commands: {[common-lint]commands} + +[testenv:py{37,38,39,310,311}-lint] +extras: {[common-lint]extras} +commands: {[common-lint]commands} From 91d93efdd09189d841a733ce0329f234c73a908c Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Mon, 10 Apr 2023 11:11:35 -0600 Subject: [PATCH 119/159] remove outdated sections of README (#76) * remove gitter, testing setup, and pandoc sections, add quotes to dev install --- README.md | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/README.md b/README.md index 92b70be..a3bc2c7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # -[![Join the chat at https://gitter.im/ethereum/](https://badges.gitter.im/ethereum/.svg)](https://gitter.im/ethereum/?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://circleci.com/gh/ethereum/.svg?style=shield)](https://circleci.com/gh/ethereum/) [![PyPI version](https://badge.fury.io/py/.svg)](https://badge.fury.io/py/) [![Python versions](https://img.shields.io/pypi/pyversions/.svg)](https://pypi.python.org/pypi/) @@ -37,43 +36,11 @@ git clone git@github.com:ethereum/.git cd virtualenv -p python3 venv . venv/bin/activate -pip install -e .[dev] -``` - -### Testing Setup - -During development, you might like to have tests run on every file save. - -Show flake8 errors on file change: - -```sh -# Test flake8 -when-changed -v -s -r -1 / tests/ -c "clear; flake8 tests && echo 'flake8 success' || echo 'error'" -``` - -Run multi-process tests in one command, but without color: - -```sh -# in the project root: -pytest --numprocesses=4 --looponfail --maxfail=1 -# the same thing, succinctly: -pytest -n 4 -f --maxfail=1 -``` - -Run in one thread, with color and desktop notifications: - -```sh -cd venv -ptw --onfail "notify-send -t 5000 'Test failure ⚠⚠⚠⚠⚠' 'python 3 test on failed'" ../tests ../ +pip install -e ".[dev]" ``` ### Release setup -For Debian-like systems: -``` -apt install pandoc -``` - To release a new version: ```sh From 68d37fa50ff45980823c2259178d1339520870d8 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Mon, 10 Apr 2023 14:02:45 -0600 Subject: [PATCH 120/159] repin flake8 and misc updates (#79) * repin flake8, bump tox to >=4.0.0 as that's where whitelist was deprecated, misc updates --- .circleci/config.yml | 1 + .project-template/fill_template_vars.py | 2 +- MANIFEST.in | 1 - setup.py | 6 +++--- tox.ini | 8 ++++---- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 237a3f6..eb10bbe 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -102,6 +102,7 @@ jobs: - image: cimg/python:3.11 environment: TOXENV: py311-core + workflows: version: 2 test: diff --git a/.project-template/fill_template_vars.py b/.project-template/fill_template_vars.py index 8d4bc35..bbbe2f7 100644 --- a/.project-template/fill_template_vars.py +++ b/.project-template/fill_template_vars.py @@ -7,7 +7,7 @@ def _find_files(project_root): - path_exclude_pattern = r"\.git($|\/)|venv|_build" + path_exclude_pattern = r"\.git($|\/)|venv|_build|\.tox" file_exclude_pattern = r"fill_template_vars\.py|\.swp$" filepaths = [] for dir_path, _dir_names, file_names in os.walk(project_root): diff --git a/MANIFEST.in b/MANIFEST.in index e870a41..22c6165 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,5 @@ include LICENSE include README.md -include requirements-docs.txt global-include *.pyi diff --git a/setup.py b/setup.py index 33f9425..a18d9bc 100644 --- a/setup.py +++ b/setup.py @@ -11,8 +11,8 @@ "pytest-xdist>=2.4.0", ], "lint": [ - "flake8>=5.0.0", - "flake8-bugbear>=22.0.0", + "flake8==6.0.0", + "flake8-bugbear==23.3.23", "isort>=5.10.1", "mypy==0.971", "pydocstyle>=5.0.0", @@ -26,7 +26,7 @@ "dev": [ "bumpversion>=0.5.3", "pytest-watch>=4.1.0", - "tox>=3.18.0", + "tox>=4.0.0", "wheel", "twine", "ipython", diff --git a/tox.ini b/tox.ini index 64147d4..e5255ba 100644 --- a/tox.ini +++ b/tox.ini @@ -14,16 +14,16 @@ multi_line_output=3 profile=black [flake8] -max-line-length= 88 -exclude= venv*,.tox,docs,build -extend-ignore= E203 +max-line-length=88 +exclude=venv*,.tox,docs,build +extend-ignore=E203 [testenv] usedevelop=True commands= core: pytest {posargs:tests/core} docs: make check-docs -basepython = +basepython= docs: python py37: python3.7 py38: python3.8 From 431db897535642e3b4f1616e3cb393171ae1c063 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Wed, 12 Apr 2023 15:35:34 -0600 Subject: [PATCH 121/159] template cleanup following initial merge with py-evm (#80) * template cleanup following initial merge with py-evm * add flake8 pin comment * correct license years * add pin note to mypy --- .circleci/config.yml | 4 ++-- .project-template/fill_template_vars.py | 15 +++++++++------ LICENSE | 2 +- README.md | 3 ++- docs/_static/.suppress-sphinx-build-warning | 0 newsfragments/validate_files.py | 1 - pytest.ini | 5 ++++- setup.py | 8 ++++---- tests/core/conftest.py | 0 tests/core/test_import.py | 2 -- 10 files changed, 22 insertions(+), 18 deletions(-) delete mode 100644 docs/_static/.suppress-sphinx-build-warning delete mode 100644 tests/core/conftest.py diff --git a/.circleci/config.yml b/.circleci/config.yml index eb10bbe..b4b822a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,7 +19,7 @@ common: &common when: on_fail - restore_cache: keys: - - cache-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} + - cache-v1-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} - run: name: install dependencies command: pip install --user tox @@ -33,7 +33,7 @@ common: &common - ~/.cache/pip - ~/.local - ./eggs - key: cache-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} + key: cache-v1-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} jobs: docs: diff --git a/.project-template/fill_template_vars.py b/.project-template/fill_template_vars.py index bbbe2f7..52ceb02 100644 --- a/.project-template/fill_template_vars.py +++ b/.project-template/fill_template_vars.py @@ -7,7 +7,7 @@ def _find_files(project_root): - path_exclude_pattern = r"\.git($|\/)|venv|_build|\.tox" + path_exclude_pattern = r"\.git($|\/)|venv|_build" file_exclude_pattern = r"fill_template_vars\.py|\.swp$" filepaths = [] for dir_path, _dir_names, file_names in os.walk(project_root): @@ -22,11 +22,14 @@ def _find_files(project_root): def _replace(pattern, replacement, project_root): print(f"Replacing values: {pattern}") for file in _find_files(project_root): - with open(file) as f: - content = f.read() - content = re.sub(pattern, replacement, content) - with open(file, "w") as f: - f.write(content) + try: + with open(file) as f: + content = f.read() + content = re.sub(pattern, replacement, content) + with open(file, "w") as f: + f.write(content) + except UnicodeDecodeError: + pass def main(): diff --git a/LICENSE b/LICENSE index 17bc694..b76b24d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2020 The Ethereum Foundation +Copyright (c) 2019-2023 The Ethereum Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index a3bc2c7..86b1e41 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ # +[![Join the conversation on Discord](https://img.shields.io/discord/809793915578089484?color=blue&label=chat&logo=discord&logoColor=white)](https://discord.gg/GHryRvPB84) [![Build Status](https://circleci.com/gh/ethereum/.svg?style=shield)](https://circleci.com/gh/ethereum/) [![PyPI version](https://badge.fury.io/py/.svg)](https://badge.fury.io/py/) [![Python versions](https://img.shields.io/pypi/pyversions/.svg)](https://pypi.python.org/pypi/) -[![Docs build](https://readthedocs.org/projects//badge/?version=latest)](http://.readthedocs.io/en/latest/?badge=latest) +[![Docs build](https://readthedocs.org/projects//badge/?version=latest)](https://.readthedocs.io/en/latest/?badge=latest) diff --git a/docs/_static/.suppress-sphinx-build-warning b/docs/_static/.suppress-sphinx-build-warning deleted file mode 100644 index e69de29..0000000 diff --git a/newsfragments/validate_files.py b/newsfragments/validate_files.py index 684c798..c4bd29f 100755 --- a/newsfragments/validate_files.py +++ b/newsfragments/validate_files.py @@ -3,7 +3,6 @@ # Towncrier silently ignores files that do not match the expected ending. # We use this script to ensure we catch these as errors in CI. -import os import pathlib import sys diff --git a/pytest.ini b/pytest.ini index ae90934..95a6b2d 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,6 +1,9 @@ [pytest] -addopts= -v --showlocals --durations 10 +addopts= -v --showlocals --durations 10 xfail_strict=true +log_format = %(levelname)8s %(asctime)s %(filename)20s %(message)s +log_date_format = %m-%d %H:%M:%S +timeout = 300 [pytest-watch] runner= pytest --failed-first --maxfail=1 --no-success-flaky-report diff --git a/setup.py b/setup.py index a18d9bc..c359d0b 100644 --- a/setup.py +++ b/setup.py @@ -11,11 +11,11 @@ "pytest-xdist>=2.4.0", ], "lint": [ - "flake8==6.0.0", - "flake8-bugbear==23.3.23", + "flake8==6.0.0", # flake8 claims semver but adds new warnings at minor releases, leave it pinned. + "flake8-bugbear==23.3.23", # flake8-bugbear does not follow semver, leave it pinned. "isort>=5.10.1", - "mypy==0.971", - "pydocstyle>=5.0.0", + "mypy==0.971", # mypy does not follow semver, leave it pinned. + "pydocstyle>=6.0.0", "black>=22", ], "doc": [ diff --git a/tests/core/conftest.py b/tests/core/conftest.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/core/test_import.py b/tests/core/test_import.py index f146ae7..07b2a18 100644 --- a/tests/core/test_import.py +++ b/tests/core/test_import.py @@ -1,4 +1,2 @@ - - def test_import(): import # noqa: F401 From 3314247037b6e686f372aae98ff0f32cffb5b48a Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Thu, 13 Apr 2023 12:47:12 -0600 Subject: [PATCH 122/159] apply template updates found following merge with eth-typing (#81) * apply template updates found following merge with eth-typing * add build as a dev dependency * remove timeout from pytest.ini, it doesn't do anything without pytest-timeout as a dep --- .github/pull_request_template.md | 4 ++-- docs/conf.py | 2 +- pyproject.toml | 2 +- pytest.ini | 3 +-- setup.py | 5 ++--- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 93fb355..b329885 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,7 +1,7 @@ ### What was wrong? Related to Issue # -Closes Issue # +Closes # ### How was it fixed? @@ -10,7 +10,7 @@ Closes Issue # - [ ] Add or update documentation related to these changes -- [ ] Add entry to the [release notes](https://github.com/ethereum/web3.py/blob/master/newsfragments/README.md) +- [ ] Add entry to the [release notes](https://github.com/ethereum//blob/master/newsfragments/README.md) #### Cute Animal Picture diff --git a/docs/conf.py b/docs/conf.py index df931f1..6469208 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -55,7 +55,7 @@ # General information about the project. project = "" -copyright = "2020, The Ethereum Foundation" +copyright = "2019-2023, The Ethereum Foundation" __version__ = setup_version # The version info for the project you're documenting, acts as replacement for diff --git a/pyproject.toml b/pyproject.toml index 3143314..7348350 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.towncrier] -# Read https://github.com/ethereum//newsfragments/README.md for instructions +# Read https://github.com/ethereum//blob/master/newsfragments/README.md for instructions package = "" filename = "docs/release_notes.rst" directory = "newsfragments" diff --git a/pytest.ini b/pytest.ini index 95a6b2d..fd5ea7c 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,9 +1,8 @@ [pytest] -addopts= -v --showlocals --durations 10 +addopts= -v --showlocals --durations 10 xfail_strict=true log_format = %(levelname)8s %(asctime)s %(filename)20s %(message)s log_date_format = %m-%d %H:%M:%S -timeout = 300 [pytest-watch] runner= pytest --failed-first --maxfail=1 --no-success-flaky-report diff --git a/setup.py b/setup.py index c359d0b..e4d82fa 100644 --- a/setup.py +++ b/setup.py @@ -27,6 +27,7 @@ "bumpversion>=0.5.3", "pytest-watch>=4.1.0", "tox>=4.0.0", + "build>=0.9.0", "wheel", "twine", "ipython", @@ -59,7 +60,7 @@ install_requires=[ "eth-utils>=2", ], - python_requires=">=3.7, <4", + python_requires=">=3.7.2, <4", extras_require=extras_require, py_modules=[""], license="MIT", @@ -72,8 +73,6 @@ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", - "Operating System :: MacOS", - "Operating System :: POSIX", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", From 484b6b55cd09757c9721fcaa50e6c39d8cee34af Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Wed, 19 Apr 2023 14:00:40 -0600 Subject: [PATCH 123/159] Template updates post ssz and ethabi (#82) * add updates found when merging template with py-ssz and eth-abi * add wheel and wheel-windows to ci and reorg --- .circleci/config.yml | 130 ++++++++++++++++++++++++-------- .gitignore | 9 ++- docs/conf.py | 2 +- newsfragments/README.md | 9 ++- newsfragments/validate_files.py | 1 + pyproject.toml | 27 ++++--- setup.py | 4 +- tox.ini | 31 ++++++++ 8 files changed, 161 insertions(+), 52 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b4b822a..0eb6f4a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,4 +1,4 @@ -version: 2.0 +version: 2.1 # heavily inspired by https://raw.githubusercontent.com/pinax/pinax-wiki/6bd2a99ab6f702e300d708532a6d1d9aa638b9f8/.circleci/config.yml @@ -22,7 +22,7 @@ common: &common - cache-v1-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} - run: name: install dependencies - command: pip install --user tox + command: python -m pip install --user tox - run: name: run tox command: python -m tox -r @@ -35,6 +35,30 @@ common: &common - ./eggs key: cache-v1-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} +orbs: + win: circleci/windows@5.0.0 + +windows_steps: &windows_steps + executor: + name: win/default + shell: bash.exe + working_directory: C:\Users\circleci\project\ + steps: + - checkout + - restore_cache: + keys: + - cache-v1-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} + - run: + name: install dependencies + command: python -m pip install --user tox + - run: + name: run tox + command: python -m tox -r + - save_cache: + paths: + - .tox + key: cache-v1-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} + jobs: docs: <<: *common @@ -42,79 +66,123 @@ jobs: - image: cimg/python:3.8 environment: TOXENV: docs - py37-lint: - <<: *common - docker: - - image: cimg/python:3.7 - environment: - TOXENV: py37-lint + py37-core: <<: *common docker: - image: cimg/python:3.7 environment: TOXENV: py37-core - py38-lint: - <<: *common - docker: - - image: cimg/python:3.8 - environment: - TOXENV: py38-lint py38-core: <<: *common docker: - image: cimg/python:3.8 environment: TOXENV: py38-core - py39-lint: - <<: *common - docker: - - image: cimg/python:3.9 - environment: - TOXENV: py39-lint py39-core: <<: *common docker: - image: cimg/python:3.9 environment: TOXENV: py39-core - py310-lint: + py310-core: <<: *common docker: - image: cimg/python:3.10 environment: - TOXENV: py310-lint - py310-core: + TOXENV: py310-core + py311-core: + <<: *common + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-core + + py37-lint: + <<: *common + docker: + - image: cimg/python:3.7 + environment: + TOXENV: py37-lint + py38-lint: + <<: *common + docker: + - image: cimg/python:3.8 + environment: + TOXENV: py38-lint + py39-lint: + <<: *common + docker: + - image: cimg/python:3.9 + environment: + TOXENV: py39-lint + py310-lint: <<: *common docker: - image: cimg/python:3.10 environment: - TOXENV: py310-core + TOXENV: py310-lint py311-lint: <<: *common docker: - image: cimg/python:3.11 environment: TOXENV: py311-lint - py311-core: + + py37-wheel: + <<: *common + docker: + - image: cimg/python:3.7 + environment: + TOXENV: py37-wheel + py38-wheel: + <<: *common + docker: + - image: cimg/python:3.8 + environment: + TOXENV: py38-wheel + py39-wheel: + <<: *common + docker: + - image: cimg/python:3.9 + environment: + TOXENV: py39-wheel + py310-wheel: + <<: *common + docker: + - image: cimg/python:3.10 + environment: + TOXENV: py310-wheel + py311-wheel: <<: *common docker: - image: cimg/python:3.11 environment: - TOXENV: py311-core + TOXENV: py311-wheel + + py311-wheel-windows: + <<: *windows_steps + environment: + TOXENV: py311-wheel-windows workflows: version: 2 test: jobs: - docs - - py37-lint - - py38-lint - - py39-lint - - py310-lint - - py311-lint - py37-core - py38-core - py39-core - py310-core - py311-core + - py37-lint + - py38-lint + - py39-lint + - py310-lint + - py311-lint + - py37-wheel + - py38-wheel + - py39-wheel + - py310-wheel + - py311-wheel + - py311-wheel-windows diff --git a/.gitignore b/.gitignore index 011ac1c..e0e2be5 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,12 @@ logs # mypy .mypy_cache +# macOS +.DS_Store + +# pyenv +.python-version + # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm # For a more precise, explicit template, see: # https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 @@ -83,9 +89,6 @@ out/ ## Plugin-specific files: -### mpeltonen/sbt-idea plugin -.idea_modules/ - ### JIRA plugin atlassian-ide-plugin.xml diff --git a/docs/conf.py b/docs/conf.py index 6469208..db3f349 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -141,7 +141,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] +# html_static_path = ["_static"] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied diff --git a/newsfragments/README.md b/newsfragments/README.md index e4740e4..0e9b74a 100644 --- a/newsfragments/README.md +++ b/newsfragments/README.md @@ -8,14 +8,15 @@ relevant to people working on the code itself.) Each file should be named like `..rst`, where `` is an issue number, and `` is one of: -* `feature` +* `breaking` * `bugfix` -* `performance` +* `deprecation`, * `doc` +* `feature` * `internal` -* `removal` * `misc` -* `breaking` +* `performance` +* `removal` So for example: `123.feature.rst`, `456.bugfix.rst` diff --git a/newsfragments/validate_files.py b/newsfragments/validate_files.py index c4bd29f..edd5e05 100755 --- a/newsfragments/validate_files.py +++ b/newsfragments/validate_files.py @@ -9,6 +9,7 @@ ALLOWED_EXTENSIONS = { ".breaking.rst", ".bugfix.rst", + ".deprecation.rst", ".doc.rst", ".feature.rst", ".internal.rst", diff --git a/pyproject.toml b/pyproject.toml index 7348350..64f8b8a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,12 +4,12 @@ package = "" filename = "docs/release_notes.rst" directory = "newsfragments" underlines = ["-", "~", "^"] -title_format = " v{version} ({project_date})" +title_format = " v{version} ({project_date})" issue_format = "`#{issue} /issues/{issue}>`__" [[tool.towncrier.type]] -directory = "feature" -name = "Features" +directory = "breaking" +name = "Breaking Changes" showcontent = true [[tool.towncrier.type]] @@ -18,8 +18,8 @@ name = "Bugfixes" showcontent = true [[tool.towncrier.type]] -directory = "performance" -name = "Performance improvements" +directory = "deprecation" +name = "Deprecations" showcontent = true [[tool.towncrier.type]] @@ -28,21 +28,26 @@ name = "Improved Documentation" showcontent = true [[tool.towncrier.type]] -directory = "removal" -name = "Deprecations and Removals" +directory = "feature" +name = "Features" showcontent = true [[tool.towncrier.type]] directory = "internal" -name = "Internal Changes - for Contributors" +name = "Internal Changes - for Contributors" showcontent = true [[tool.towncrier.type]] directory = "misc" -name = "Miscellaneous changes" +name = "Miscellaneous Changes" showcontent = false [[tool.towncrier.type]] -directory = "breaking" -name = "Breaking changes" +directory = "performance" +name = "Performance Improvements" +showcontent = true + +[[tool.towncrier.type]] +directory = "removal" +name = "Removals" showcontent = true diff --git a/setup.py b/setup.py index e4d82fa..00994c2 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ "isort>=5.10.1", "mypy==0.971", # mypy does not follow semver, leave it pinned. "pydocstyle>=6.0.0", - "black>=22", + "black>=23", ], "doc": [ "sphinx>=5.0.0", @@ -60,7 +60,7 @@ install_requires=[ "eth-utils>=2", ], - python_requires=">=3.7.2, <4", + python_requires=">=3.7, <4", extras_require=extras_require, py_modules=[""], license="MIT", diff --git a/tox.ini b/tox.ini index e5255ba..35503e2 100644 --- a/tox.ini +++ b/tox.ini @@ -2,6 +2,8 @@ envlist= py{37,38,39,310,311}-core py{37,38,39,310,311}-lint + py{37,38,39,310,311}-wheel + py311-wheel-windows docs [isort] @@ -54,3 +56,32 @@ commands: {[common-lint]commands} [testenv:py{37,38,39,310,311}-lint] extras: {[common-lint]extras} commands: {[common-lint]commands} + +[testenv:py{37,38,39,310,311}-wheel] +deps= + wheel + build[virtualenv] +allowlist_externals= + /bin/rm + /bin/bash +commands= + python -m pip install --upgrade pip + /bin/rm -rf build dist + python -m build + /bin/bash -c 'python -m pip install --upgrade "$(ls dist/-*-py3-none-any.whl)" --progress-bar off' + python -c "import " +skip_install=true + +[testenv:py311-wheel-windows] +deps= + wheel + build[virtualenv] +allowlist_externals= + bash.exe +commands= + python -m pip install --upgrade pip + bash.exe -c "rm -rf build dist" + python -m build + bash.exe -c 'python -m pip install --upgrade "$(ls dist/-*-py3-none-any.whl)" --progress-bar off' + python -c "import " +skip_install=true From 28dbedcbfad5b03f50505e0d990c4d63dba27c36 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Mon, 24 Apr 2023 17:21:09 -0600 Subject: [PATCH 124/159] upgrade pip and remove --user from tox install during ci (#85) --- .circleci/config.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0eb6f4a..b00ff6b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,7 +22,9 @@ common: &common - cache-v1-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} - run: name: install dependencies - command: python -m pip install --user tox + command: | + python -m pip install --upgrade pip + python -m pip install tox - run: name: run tox command: python -m tox -r @@ -50,7 +52,9 @@ windows_steps: &windows_steps - cache-v1-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} - run: name: install dependencies - command: python -m pip install --user tox + command: | + python -m pip install --upgrade pip + python -m pip install tox - run: name: run tox command: python -m tox -r From da9b95f37c2b9c33582e430d0e7b4d858dec2212 Mon Sep 17 00:00:00 2001 From: Marc Garreau <3621728+wolovim@users.noreply.github.com> Date: Tue, 25 Apr 2023 14:45:59 -0600 Subject: [PATCH 125/159] introduce contributing doc + main branch convention (#84) --- Makefile | 4 +- README.md | 11 +- docs/contributing.rst | 161 ++++++++++++++++++++++++ docs/fragments/virtualenv_explainer.rst | 25 ++++ docs/index.rst | 6 + pyproject.toml | 2 +- 6 files changed, 200 insertions(+), 9 deletions(-) create mode 100644 docs/contributing.rst create mode 100644 docs/fragments/virtualenv_explainer.rst diff --git a/Makefile b/Makefile index a8af4eb..5f73189 100644 --- a/Makefile +++ b/Makefile @@ -74,8 +74,8 @@ notes: check-bump git commit -m "Compile release notes" release: check-bump clean - # require that you be on a branch that's linked to upstream/master - git status -s -b | head -1 | grep "\.\.upstream/master" + # require that you be on a branch that's linked to upstream/main + git status -s -b | head -1 | grep "\.\.upstream/main" # verify that docs build correctly ./newsfragments/validate_files.py is-empty make build-docs diff --git a/README.md b/README.md index 86b1e41..7d12645 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ [![PyPI version](https://badge.fury.io/py/.svg)](https://badge.fury.io/py/) [![Python versions](https://img.shields.io/pypi/pyversions/.svg)](https://pypi.python.org/pypi/) [![Docs build](https://readthedocs.org/projects//badge/?version=latest)](https://.readthedocs.io/en/latest/?badge=latest) - @@ -23,10 +22,10 @@ If you would like to hack on , please check out the [Snake Charmers Tactical Manual](https://github.com/ethereum/snake-charmers-tactical-manual) for information on how we do: -- Testing -- Pull Requests -- Code Style -- Documentation +- Testing +- Pull Requests +- Code Style +- Documentation ### Development Environment Setup @@ -55,7 +54,7 @@ The version format for this repo is `{major}.{minor}.{patch}` for stable, and To issue the next version in line, specify which part to bump, like `make release bump=minor` or `make release bump=devnum`. This is typically done from the -master branch, except when releasing a beta (in which case the beta is released from master, +main branch, except when releasing a beta (in which case the beta is released from main, and the previous stable branch is released from said branch). If you are in a beta version, `make release bump=stage` will switch to a stable. diff --git a/docs/contributing.rst b/docs/contributing.rst new file mode 100644 index 0000000..926b87c --- /dev/null +++ b/docs/contributing.rst @@ -0,0 +1,161 @@ +Contributing +------------ + +Thank you for your interest in contributing! We welcome all contributions no matter their size. Please read along to learn how to get started. + + +Setting the stage +~~~~~~~~~~~~~~~~~ + +First, we need to clone the repository: + +.. code:: sh + + $ git clone https://github.com/ethereum/.git + + +.. include:: /fragments/virtualenv_explainer.rst + +After we have activated our virtual environment, we need to install all dependencies that are needed to run, develop, and test. +This is as easy as navigating to the directory and running: + +.. code:: sh + + pip install -e ".[dev]" + + +Running the tests +~~~~~~~~~~~~~~~~~ + +A great way to explore the code base is to run the tests. + +We can run all tests with: + +.. code:: sh + + pytest tests + +However, you may just want to run a subset instead, like: + +.. code:: sh + + pytest tests/core/padding-utils/test_padding.py + + +We can also install ``tox`` to run the full test suite which also covers things like testing the code against different Python versions, linting etc. + +It is important to understand that each Pull Request must pass the full test suite as part of the CI check, hence it is often convenient to have ``tox`` installed locally as well. + + +Code Style +~~~~~~~~~~ + +When multiple people are working on the same body of code, it is important that they write code that conforms to a similar style. It often doesn't matter as much which style, but rather that they conform to one style. + +To ensure your contribution conforms to the style being used in this project, we encourage you to read our `style guide `_. + + +Type Hints +~~~~~~~~~~ + +This codebase uses `type hints `_. Type hints make it easy to prevent certain types of bugs, enable richer tooling, and enhance the documentation, making the code easier to follow. + +All new code is required to land with type hints, with the exception of test code that is not expected to use type hints. + +All parameters, as well as the return type of defs, are expected to be typed, with the exception of ``self`` and ``cls`` as seen in the following example. + +.. code:: python + + def __init__(self, wrapped_db: DatabaseAPI) -> None: + self.wrapped_db = wrapped_db + self.reset() + + +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 /blob/main/newsfragments/README.md>`_. + +If possible, the change to the release notes file should be included in the commit that introduces the +feature or bugfix. + + +Releasing +~~~~~~~~~ + + +Final test before each release +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Before releasing a new version, build and test the package that will be released: + +.. code:: sh + + git checkout main && git pull + + make package + + + # Preview the upcoming release notes + towncrier --draft + + +Build the release notes +^^^^^^^^^^^^^^^^^^^^^^^ + +Before bumping the version number, build the release notes. +You must include the part of the version to bump (see below), +which changes how the version number will show in the release notes. + +.. code:: sh + + 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 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +After confirming that the release package looks okay, release a new version: + +.. code:: sh + + make release bump=$$VERSION_PART_TO_BUMP$$ + + +Which version part to bump +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The version format for this repo is ``{major}.{minor}.{patch}`` for +stable, and ``{major}.{minor}.{patch}-{stage}.{devnum}`` for unstable +(``stage`` can be alpha or beta). + +During a release, specify which part to bump, like +``make release bump=minor`` or ``make release bump=devnum``. + +If you are in a beta version, ``make release bump=stage`` will switch to a +stable. + +To issue an unstable version when the current version is stable, specify +the new version explicitly, like +``make release bump="--new-version 4.0.0-alpha.1 devnum"`` diff --git a/docs/fragments/virtualenv_explainer.rst b/docs/fragments/virtualenv_explainer.rst new file mode 100644 index 0000000..ecc6d4c --- /dev/null +++ b/docs/fragments/virtualenv_explainer.rst @@ -0,0 +1,25 @@ +**Optional:** Often, the best way to guarantee a clean Python 3 environment is with +`virtualenv `_. If we don't have ``virtualenv`` installed +already, we first need to install it via pip. + +.. code:: sh + + pip install virtualenv + +Then, we can initialize a new virtual environment ``venv``, like: + +.. code:: sh + + virtualenv -p python3 venv + +This creates a new directory ``venv`` where packages are installed isolated from any other global +packages. + +To activate the virtual directory we have to *source* it + +.. code:: sh + + . venv/bin/activate + + # and when leaving this context: + deactivate diff --git a/docs/index.rst b/docs/index.rst index 89815ef..4f1f0b3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -11,6 +11,12 @@ Contents release_notes + +.. toctree:: + :maxdepth: 1 + :caption: Community + + contributing Indices and tables diff --git a/pyproject.toml b/pyproject.toml index 64f8b8a..aa7ddcd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.towncrier] -# Read https://github.com/ethereum//blob/master/newsfragments/README.md for instructions +# Read https://github.com/ethereum//blob/main/newsfragments/README.md for instructions package = "" filename = "docs/release_notes.rst" directory = "newsfragments" From cc24e7e468d652f59ac9f484f9600460f6b8a295 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Tue, 25 Apr 2023 15:20:55 -0600 Subject: [PATCH 126/159] update tox calls to use run, update all pip calls to use python -m (#86) --- .circleci/config.yml | 4 ++-- .github/ISSUE_TEMPLATE/bug_report.yml | 6 ++++-- Makefile | 4 ++-- README.md | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b00ff6b..791a433 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,7 +27,7 @@ common: &common python -m pip install tox - run: name: run tox - command: python -m tox -r + command: python -m tox run -r - save_cache: paths: - .hypothesis @@ -57,7 +57,7 @@ windows_steps: &windows_steps python -m pip install tox - run: name: run tox - command: python -m tox -r + command: python -m tox run -r - save_cache: paths: - .tox diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 5f1ddfd..a0c80c0 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -65,6 +65,8 @@ body: - type: textarea id: pip-freeze attributes: - label: Output from pip-freeze - description: Run `pip-freeze` and paste the output below + label: Output from `pip freeze` + description: Run `python -m pip freeze` and paste the output below render: shell + validations: + required: false diff --git a/Makefile b/Makefile index 5f73189..b674c55 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ clean-pyc: find . -name '__pycache__' -exec rm -rf {} + lint: - tox -e lint + tox run -e lint lint-roll: isort tests @@ -39,7 +39,7 @@ test: pytest tests test-all: - tox + tox run build-docs: sphinx-apidoc -o docs/ . setup.py "*conftest*" diff --git a/README.md b/README.md index 7d12645..b3be748 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Read more in the [documentation on ReadTheDocs](https://.readthedocs.i ## Quickstart ```sh -pip install +python -m pip install ``` ## Developer Setup @@ -36,7 +36,7 @@ git clone git@github.com:ethereum/.git cd virtualenv -p python3 venv . venv/bin/activate -pip install -e ".[dev]" +python -m pip install -e ".[dev]" ``` ### Release setup From 1f5fc7208bbd7d86a35ef466cf58d5129d4852f9 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Thu, 27 Apr 2023 14:02:54 -0600 Subject: [PATCH 127/159] Remove testall (#88) * remove testall because it doesnt work --- .github/pull_request_template.md | 2 +- Makefile | 4 ---- newsfragments/README.md | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b329885..2ff2e07 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -10,7 +10,7 @@ Closes # - [ ] Add or update documentation related to these changes -- [ ] Add entry to the [release notes](https://github.com/ethereum//blob/master/newsfragments/README.md) +- [ ] Add entry to the [release notes](https://github.com/ethereum//blob/main/newsfragments/README.md) #### Cute Animal Picture diff --git a/Makefile b/Makefile index b674c55..67a7573 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,6 @@ help: @echo "lint - check style with flake8" @echo "lint-roll - automatically fix problems with isort, flake8, etc" @echo "test - run tests quickly with the default Python" - @echo "testall - run tests on every Python version with tox" @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)" @@ -38,9 +37,6 @@ lint-roll: test: pytest tests -test-all: - tox run - build-docs: sphinx-apidoc -o docs/ . setup.py "*conftest*" $(MAKE) -C docs clean diff --git a/newsfragments/README.md b/newsfragments/README.md index 0e9b74a..93ae2c0 100644 --- a/newsfragments/README.md +++ b/newsfragments/README.md @@ -26,4 +26,4 @@ then open up the PR first and use the PR number for the newsfragment. Note that the `towncrier` tool will automatically reflow your text, so don't try to do any fancy formatting. Run `towncrier build --draft` to get a preview of what the release notes entry - will look like in the final release notes. +will look like in the final release notes. From 2a1c8f83b49c97c57838098fef30f3b59baf755a Mon Sep 17 00:00:00 2001 From: pacrob Date: Mon, 1 May 2023 16:25:14 -0600 Subject: [PATCH 128/159] minor formatting updates, remove contributing docs --- README.md | 8 +- docs/contributing.rst | 161 ------------------------ docs/fragments/virtualenv_explainer.rst | 25 ---- docs/index.rst | 6 - newsfragments/README.md | 2 +- 5 files changed, 5 insertions(+), 197 deletions(-) delete mode 100644 docs/contributing.rst delete mode 100644 docs/fragments/virtualenv_explainer.rst diff --git a/README.md b/README.md index b3be748..5acd94d 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,10 @@ If you would like to hack on , please check out the [Snake Charmers Tactical Manual](https://github.com/ethereum/snake-charmers-tactical-manual) for information on how we do: -- Testing -- Pull Requests -- Code Style -- Documentation +- Testing +- Pull Requests +- Code Style +- Documentation ### Development Environment Setup diff --git a/docs/contributing.rst b/docs/contributing.rst deleted file mode 100644 index 926b87c..0000000 --- a/docs/contributing.rst +++ /dev/null @@ -1,161 +0,0 @@ -Contributing ------------- - -Thank you for your interest in contributing! We welcome all contributions no matter their size. Please read along to learn how to get started. - - -Setting the stage -~~~~~~~~~~~~~~~~~ - -First, we need to clone the repository: - -.. code:: sh - - $ git clone https://github.com/ethereum/.git - - -.. include:: /fragments/virtualenv_explainer.rst - -After we have activated our virtual environment, we need to install all dependencies that are needed to run, develop, and test. -This is as easy as navigating to the directory and running: - -.. code:: sh - - pip install -e ".[dev]" - - -Running the tests -~~~~~~~~~~~~~~~~~ - -A great way to explore the code base is to run the tests. - -We can run all tests with: - -.. code:: sh - - pytest tests - -However, you may just want to run a subset instead, like: - -.. code:: sh - - pytest tests/core/padding-utils/test_padding.py - - -We can also install ``tox`` to run the full test suite which also covers things like testing the code against different Python versions, linting etc. - -It is important to understand that each Pull Request must pass the full test suite as part of the CI check, hence it is often convenient to have ``tox`` installed locally as well. - - -Code Style -~~~~~~~~~~ - -When multiple people are working on the same body of code, it is important that they write code that conforms to a similar style. It often doesn't matter as much which style, but rather that they conform to one style. - -To ensure your contribution conforms to the style being used in this project, we encourage you to read our `style guide `_. - - -Type Hints -~~~~~~~~~~ - -This codebase uses `type hints `_. Type hints make it easy to prevent certain types of bugs, enable richer tooling, and enhance the documentation, making the code easier to follow. - -All new code is required to land with type hints, with the exception of test code that is not expected to use type hints. - -All parameters, as well as the return type of defs, are expected to be typed, with the exception of ``self`` and ``cls`` as seen in the following example. - -.. code:: python - - def __init__(self, wrapped_db: DatabaseAPI) -> None: - self.wrapped_db = wrapped_db - self.reset() - - -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 /blob/main/newsfragments/README.md>`_. - -If possible, the change to the release notes file should be included in the commit that introduces the -feature or bugfix. - - -Releasing -~~~~~~~~~ - - -Final test before each release -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Before releasing a new version, build and test the package that will be released: - -.. code:: sh - - git checkout main && git pull - - make package - - - # Preview the upcoming release notes - towncrier --draft - - -Build the release notes -^^^^^^^^^^^^^^^^^^^^^^^ - -Before bumping the version number, build the release notes. -You must include the part of the version to bump (see below), -which changes how the version number will show in the release notes. - -.. code:: sh - - 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 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -After confirming that the release package looks okay, release a new version: - -.. code:: sh - - make release bump=$$VERSION_PART_TO_BUMP$$ - - -Which version part to bump -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The version format for this repo is ``{major}.{minor}.{patch}`` for -stable, and ``{major}.{minor}.{patch}-{stage}.{devnum}`` for unstable -(``stage`` can be alpha or beta). - -During a release, specify which part to bump, like -``make release bump=minor`` or ``make release bump=devnum``. - -If you are in a beta version, ``make release bump=stage`` will switch to a -stable. - -To issue an unstable version when the current version is stable, specify -the new version explicitly, like -``make release bump="--new-version 4.0.0-alpha.1 devnum"`` diff --git a/docs/fragments/virtualenv_explainer.rst b/docs/fragments/virtualenv_explainer.rst deleted file mode 100644 index ecc6d4c..0000000 --- a/docs/fragments/virtualenv_explainer.rst +++ /dev/null @@ -1,25 +0,0 @@ -**Optional:** Often, the best way to guarantee a clean Python 3 environment is with -`virtualenv `_. If we don't have ``virtualenv`` installed -already, we first need to install it via pip. - -.. code:: sh - - pip install virtualenv - -Then, we can initialize a new virtual environment ``venv``, like: - -.. code:: sh - - virtualenv -p python3 venv - -This creates a new directory ``venv`` where packages are installed isolated from any other global -packages. - -To activate the virtual directory we have to *source* it - -.. code:: sh - - . venv/bin/activate - - # and when leaving this context: - deactivate diff --git a/docs/index.rst b/docs/index.rst index 4f1f0b3..472a482 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,12 +12,6 @@ Contents release_notes -.. toctree:: - :maxdepth: 1 - :caption: Community - - contributing - Indices and tables ------------------ diff --git a/newsfragments/README.md b/newsfragments/README.md index 93ae2c0..2ef923e 100644 --- a/newsfragments/README.md +++ b/newsfragments/README.md @@ -10,7 +10,7 @@ Each file should be named like `..rst`, where * `breaking` * `bugfix` -* `deprecation`, +* `deprecation` * `doc` * `feature` * `internal` From f802bd04398df7f915916dabbc1ba2b129796be0 Mon Sep 17 00:00:00 2001 From: pacrob Date: Wed, 3 May 2023 10:53:12 -0600 Subject: [PATCH 129/159] bump sphinx version and set py version rtd uses to 3.8 --- .readthedocs.yml | 8 ++++++++ setup.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 959cf71..bb96642 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,5 +1,13 @@ version: 2 +build: + os: ubuntu-22.04 + tools: + python: "3.8" + +sphinx: + configuration: docs/conf.py + python: install: - method: pip diff --git a/setup.py b/setup.py index 00994c2..dc1a39f 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ "black>=23", ], "doc": [ - "sphinx>=5.0.0", + "sphinx>=6.0.0", "sphinx_rtd_theme>=1.0.0", "towncrier>=21,<22", ], From 23a192f62c6ad5bff2beb54284652c215971dfa6 Mon Sep 17 00:00:00 2001 From: pacrob Date: Wed, 3 May 2023 14:05:29 -0600 Subject: [PATCH 130/159] change references to doc to all be docs --- .readthedocs.yml | 2 +- docs/conf.py | 2 +- newsfragments/README.md | 2 +- newsfragments/validate_files.py | 2 +- pyproject.toml | 2 +- setup.py | 4 ++-- tox.ini | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index bb96642..50b9b38 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -13,4 +13,4 @@ python: - method: pip path: . extra_requirements: - - doc + - docs diff --git a/docs/conf.py b/docs/conf.py index db3f349..1d0560d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -190,7 +190,7 @@ # html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = "doc" +htmlhelp_basename = "docs" # -- Options for LaTeX output --------------------------------------------- diff --git a/newsfragments/README.md b/newsfragments/README.md index 2ef923e..7c8981f 100644 --- a/newsfragments/README.md +++ b/newsfragments/README.md @@ -11,7 +11,7 @@ Each file should be named like `..rst`, where * `breaking` * `bugfix` * `deprecation` -* `doc` +* `docs` * `feature` * `internal` * `misc` diff --git a/newsfragments/validate_files.py b/newsfragments/validate_files.py index edd5e05..bc68bfe 100755 --- a/newsfragments/validate_files.py +++ b/newsfragments/validate_files.py @@ -10,7 +10,7 @@ ".breaking.rst", ".bugfix.rst", ".deprecation.rst", - ".doc.rst", + ".docs.rst", ".feature.rst", ".internal.rst", ".misc.rst", diff --git a/pyproject.toml b/pyproject.toml index aa7ddcd..d94ebfd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ name = "Deprecations" showcontent = true [[tool.towncrier.type]] -directory = "doc" +directory = "docs" name = "Improved Documentation" showcontent = true diff --git a/setup.py b/setup.py index dc1a39f..859008e 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ "pydocstyle>=6.0.0", "black>=23", ], - "doc": [ + "docs": [ "sphinx>=6.0.0", "sphinx_rtd_theme>=1.0.0", "towncrier>=21,<22", @@ -38,7 +38,7 @@ extras_require["dev"] + extras_require["test"] + extras_require["lint"] - + extras_require["doc"] + + extras_require["docs"] ) diff --git a/tox.ini b/tox.ini index 35503e2..b1dae72 100644 --- a/tox.ini +++ b/tox.ini @@ -34,7 +34,7 @@ basepython= py311: python3.11 extras= test - docs: doc + docs allowlist_externals=make [common-lint] From 86b5d52149e561080c2c5629e68a9810f8552090 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Fri, 12 May 2023 14:47:15 -0600 Subject: [PATCH 131/159] Update .gitignore spelling error --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e0e2be5..0d725c7 100644 --- a/.gitignore +++ b/.gitignore @@ -51,7 +51,7 @@ docs/*._utils.* # Blockchain chains -# Hypothese Property base testing +# Hypothesis Property base testing .hypothesis # tox/pytest cache From 42be4de76cba63fddccd95fb0f4c5289b777b403 Mon Sep 17 00:00:00 2001 From: pacrob Date: Thu, 25 May 2023 14:33:14 -0600 Subject: [PATCH 132/159] fix typos in ci config and Makefile --- .circleci/config.yml | 2 +- Makefile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 791a433..0f1436c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,7 +14,7 @@ common: &common command: ./.circleci/merge_pr.sh when: on_fail - run: - name: merge pull request base (3nd try) + name: merge pull request base (3rd try) command: ./.circleci/merge_pr.sh when: on_fail - restore_cache: diff --git a/Makefile b/Makefile index 67a7573..06d85b7 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,8 @@ CURRENT_SIGN_SETTING := $(shell git config commit.gpgSign) help: @echo "clean-build - remove build artifacts" @echo "clean-pyc - remove Python file artifacts" - @echo "lint - check style with flake8" - @echo "lint-roll - automatically fix problems with isort, flake8, etc" + @echo "lint - check style with mypy, flake8, isort, pydocstyle, and black" + @echo "lint-roll - automatically fix problems with flake8 and black" @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/" From 024f9dbd54735d7d00b0c537bb9976bcb08c813d Mon Sep 17 00:00:00 2001 From: kclowes Date: Wed, 14 Jun 2023 07:59:07 -0600 Subject: [PATCH 133/159] Add tests to distribution by default (#97) --- MANIFEST.in | 2 ++ Makefile | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 22c6165..a122460 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,8 @@ include LICENSE include README.md +recursive-include tests * + global-include *.pyi recursive-exclude * __pycache__ diff --git a/Makefile b/Makefile index 06d85b7..f91dd72 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ notes: check-bump make build-docs git commit -m "Compile release notes" -release: check-bump clean +release: check-bump test clean # require that you be on a branch that's linked to upstream/main git status -s -b | head -1 | grep "\.\.upstream/main" # verify that docs build correctly From 37841d57ed4d8fa89973414d68a5e4e738812100 Mon Sep 17 00:00:00 2001 From: Stuart Reed Date: Tue, 13 Jun 2023 09:46:18 -0600 Subject: [PATCH 134/159] Update release command to check remote for upstream --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index f91dd72..60ed00e 100644 --- a/Makefile +++ b/Makefile @@ -69,9 +69,9 @@ notes: check-bump make build-docs git commit -m "Compile release notes" -release: check-bump test clean - # require that you be on a branch that's linked to upstream/main - git status -s -b | head -1 | grep "\.\.upstream/main" +release: check-bump clean + # require that upstream is configured for ethereum/ + git remote -v | grep "upstream\tgit@github.com:ethereum/.git (push)\|upstream\thttps://github.com/ethereum/ (push)" # verify that docs build correctly ./newsfragments/validate_files.py is-empty make build-docs From 8a57adf9503919c9f273d742ce257042211ae082 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Tue, 5 Sep 2023 16:29:30 -0600 Subject: [PATCH 135/159] Update .gitignore add `.venv*` to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0d725c7..7d6b0b0 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ lib lib64 pip-wheel-metadata venv* +.venv* # Installer logs pip-log.txt From 4245675648f6e0937e5865c31fc2176344af3a80 Mon Sep 17 00:00:00 2001 From: pacrob Date: Thu, 14 Sep 2023 12:11:55 -0600 Subject: [PATCH 136/159] ignore flake8 F401 errors in __init__.py files --- tox.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index b1dae72..cdb3560 100644 --- a/tox.ini +++ b/tox.ini @@ -16,9 +16,10 @@ multi_line_output=3 profile=black [flake8] -max-line-length=88 exclude=venv*,.tox,docs,build extend-ignore=E203 +max-line-length=88 +per-file-ignores=__init__.py:F401 [testenv] usedevelop=True From 26005569ce71ab26ce1e847ea2122a860bbb9b2d Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Wed, 4 Oct 2023 11:40:01 -0600 Subject: [PATCH 137/159] Update .gitignore add `.build` to be ignored --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7d6b0b0..f9dcb54 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ *.egg-info dist build +.build eggs .eggs parts From 23d8fb5bf77a62d6472b29758f1b8424bfab7aa6 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Wed, 4 Oct 2023 11:40:49 -0600 Subject: [PATCH 138/159] Update .readthedocs.yml fix indent, add sphinx fail_on_warning --- .readthedocs.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 50b9b38..593793c 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -6,7 +6,8 @@ build: python: "3.8" sphinx: - configuration: docs/conf.py + configuration: docs/conf.py + fail_on_warning: true python: install: From efcb97c348892b7e85a6300226e26e41bcceb4b9 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Wed, 4 Oct 2023 12:13:56 -0600 Subject: [PATCH 139/159] Update .gitignore gitignore local vs-code settings --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index f9dcb54..5127a4d 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,9 @@ logs # pyenv .python-version +# vs-code +.vscode + # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm # For a more precise, explicit template, see: # https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 From 7099bbaaa48504ec9609d3b34648f0177dbccba8 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Wed, 4 Oct 2023 13:32:07 -0600 Subject: [PATCH 140/159] Add pre commit (#103) * add pre-commit * run pre-commit * skip lint on README.md as it breaks template filling --- .bumpversion.cfg | 1 - .circleci/config.yml | 9 ++--- .../{bug_report.yml => bug_report.yaml} | 0 .../{config.yml => config.yaml} | 0 ...ature_request.yml => feature_request.yaml} | 0 .github/pull_request_template.md | 9 +++-- .pre-commit-config.yaml | 37 ++++++++++++++++++ .readthedocs.yml => .readthedocs.yaml | 0 Makefile | 10 +---- README.md | 7 +++- docs/index.rst | 2 +- newsfragments/README.md | 18 ++++----- newsfragments/validate_files.py | 1 - setup.py | 38 +++++++------------ tox.ini | 17 +++------ 15 files changed, 82 insertions(+), 67 deletions(-) rename .github/ISSUE_TEMPLATE/{bug_report.yml => bug_report.yaml} (100%) rename .github/ISSUE_TEMPLATE/{config.yml => config.yaml} (100%) rename .github/ISSUE_TEMPLATE/{feature_request.yml => feature_request.yaml} (100%) create mode 100644 .pre-commit-config.yaml rename .readthedocs.yml => .readthedocs.yaml (100%) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index f683001..39ae22d 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -20,4 +20,3 @@ values = [bumpversion:file:setup.py] search = version="{current_version}", replace = version="{new_version}", - diff --git a/.circleci/config.yml b/.circleci/config.yml index 0f1436c..bbc9029 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,6 +25,9 @@ common: &common command: | python -m pip install --upgrade pip python -m pip install tox + - run: + name: install pre-commit + command: python -m pip install --progress-bar=off pre-commit - run: name: run tox command: python -m tox run -r @@ -102,12 +105,6 @@ jobs: environment: TOXENV: py311-core - py37-lint: - <<: *common - docker: - - image: cimg/python:3.7 - environment: - TOXENV: py37-lint py38-lint: <<: *common docker: diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/bug_report.yml rename to .github/ISSUE_TEMPLATE/bug_report.yaml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/config.yml rename to .github/ISSUE_TEMPLATE/config.yaml diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/feature_request.yml rename to .github/ISSUE_TEMPLATE/feature_request.yaml diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 2ff2e07..3691f6b 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -6,12 +6,13 @@ Closes # ### How was it fixed? ### Todo: -- [ ] Clean up commit history -- [ ] Add or update documentation related to these changes +- \[ \] Clean up commit history -- [ ] Add entry to the [release notes](https://github.com/ethereum//blob/main/newsfragments/README.md) +- \[ \] Add or update documentation related to these changes + +- \[ \] Add entry to the [release notes](https://github.com/ethereum/%3CREPO_NAME%3E/blob/main/newsfragments/README.md) #### Cute Animal Picture -![Put a link to a cute animal picture inside the parenthesis-->]() \ No newline at end of file +![Put a link to a cute animal picture inside the parenthesis-->](<>) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..58f9e1d --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,37 @@ +exclude: '.project-template|docs/conf.py' +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.4.0 + hooks: + - id: check-yaml + - id: check-toml + - id: end-of-file-fixer + - id: trailing-whitespace +- repo: https://github.com/psf/black + rev: 23.9.1 + hooks: + - id: black +- repo: https://github.com/PyCQA/flake8 + rev: 6.1.0 + hooks: + - id: flake8 + additional_dependencies: + - flake8-bugbear==23.9.16 + exclude: setup.py +- repo: https://github.com/pycqa/isort + rev: 5.12.0 + hooks: + - id: isort +- repo: https://github.com/pycqa/pydocstyle + rev: 6.3.0 + hooks: + - id: pydocstyle +- repo: https://github.com/executablebooks/mdformat + rev: 0.7.17 + hooks: + - id: mdformat +- repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.5.1 + hooks: + - id: mypy + exclude: tests/ diff --git a/.readthedocs.yml b/.readthedocs.yaml similarity index 100% rename from .readthedocs.yml rename to .readthedocs.yaml diff --git a/Makefile b/Makefile index 60ed00e..28d7fa4 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,7 @@ CURRENT_SIGN_SETTING := $(shell git config commit.gpgSign) help: @echo "clean-build - remove build artifacts" @echo "clean-pyc - remove Python file artifacts" - @echo "lint - check style with mypy, flake8, isort, pydocstyle, and black" - @echo "lint-roll - automatically fix problems with flake8 and black" + @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/" @@ -27,12 +26,7 @@ clean-pyc: find . -name '__pycache__' -exec rm -rf {} + lint: - tox run -e lint - -lint-roll: - isort tests - black tests setup.py - $(MAKE) lint + pre-commit run --all-files --show-diff-on-failure test: pytest tests diff --git a/README.md b/README.md index 5acd94d..fa56f2e 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,13 @@ for information on how we do: - Testing - Pull Requests -- Code Style - Documentation +We use [pre-commit](https://pre-commit.com/) to maintain consistent code style. Once +installed, it will run automatically with every commit. You can also run it manually +with `make lint`. If you need to make a commit that skips the `pre-commit` checks, you +can do so with `git commit --no-verify`. + ### Development Environment Setup You can set up your dev environment with: @@ -37,6 +41,7 @@ cd virtualenv -p python3 venv . venv/bin/activate python -m pip install -e ".[dev]" +pre-commit install ``` ### Release setup diff --git a/docs/index.rst b/docs/index.rst index 472a482..89815ef 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -11,7 +11,7 @@ Contents release_notes - + Indices and tables ------------------ diff --git a/newsfragments/README.md b/newsfragments/README.md index 7c8981f..177d649 100644 --- a/newsfragments/README.md +++ b/newsfragments/README.md @@ -8,15 +8,15 @@ relevant to people working on the code itself.) Each file should be named like `..rst`, where `` is an issue number, and `` is one of: -* `breaking` -* `bugfix` -* `deprecation` -* `docs` -* `feature` -* `internal` -* `misc` -* `performance` -* `removal` +- `breaking` +- `bugfix` +- `deprecation` +- `docs` +- `feature` +- `internal` +- `misc` +- `performance` +- `removal` So for example: `123.feature.rst`, `456.bugfix.rst` diff --git a/newsfragments/validate_files.py b/newsfragments/validate_files.py index bc68bfe..02b0e3e 100755 --- a/newsfragments/validate_files.py +++ b/newsfragments/validate_files.py @@ -31,7 +31,6 @@ assert sys.argv[1] in ("is-empty",) for fragment_file in THIS_DIR.iterdir(): - if fragment_file.name in ALLOWED_FILES: continue elif num_args == 0: diff --git a/setup.py b/setup.py index 859008e..5efcc3c 100644 --- a/setup.py +++ b/setup.py @@ -1,44 +1,34 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from setuptools import ( - setup, find_packages, + setup, ) extras_require = { - "test": [ - "pytest>=7.0.0", - "pytest-xdist>=2.4.0", - ], - "lint": [ - "flake8==6.0.0", # flake8 claims semver but adds new warnings at minor releases, leave it pinned. - "flake8-bugbear==23.3.23", # flake8-bugbear does not follow semver, leave it pinned. - "isort>=5.10.1", - "mypy==0.971", # mypy does not follow semver, leave it pinned. - "pydocstyle>=6.0.0", - "black>=23", + "dev": [ + "build>=0.9.0", + "bumpversion>=0.5.3", + "ipython", + "pre-commit>=3.4.0", + "pytest-watch>=4.1.0", + "tox>=4.0.0", + "twine", + "wheel", ], "docs": [ "sphinx>=6.0.0", "sphinx_rtd_theme>=1.0.0", "towncrier>=21,<22", ], - "dev": [ - "bumpversion>=0.5.3", - "pytest-watch>=4.1.0", - "tox>=4.0.0", - "build>=0.9.0", - "wheel", - "twine", - "ipython", + "test": [ + "pytest>=7.0.0", + "pytest-xdist>=2.4.0", ], } extras_require["dev"] = ( - extras_require["dev"] - + extras_require["test"] - + extras_require["lint"] - + extras_require["docs"] + extras_require["dev"] + extras_require["docs"] + extras_require["test"] ) diff --git a/tox.ini b/tox.ini index cdb3560..cf23aa2 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] envlist= py{37,38,39,310,311}-core - py{37,38,39,310,311}-lint + py{38,39,310,311}-lint py{37,38,39,310,311}-wheel py311-wheel-windows docs @@ -36,26 +36,19 @@ basepython= extras= test docs -allowlist_externals=make +allowlist_externals=make,pre-commit [common-lint] basepython=python -extras=lint -allowlist_externals=black +deps=pre-commit commands= - mypy -p --config-file {toxinidir}/mypy.ini - flake8 {toxinidir}/ {toxinidir}/tests - isort --check-only --diff {toxinidir}/ {toxinidir}/tests - pydocstyle --explain {toxinidir}/ {toxinidir}/tests - black --check {toxinidir}/ {toxinidir}/docs {toxinidir}/tests {toxinidir}/setup.py + pre-commit run --all-files --show-diff-on-failure [testenv:lint] basepython: python -extras: {[common-lint]extras} commands: {[common-lint]commands} -[testenv:py{37,38,39,310,311}-lint] -extras: {[common-lint]extras} +[testenv:py{38,39,310,311}-lint] commands: {[common-lint]commands} [testenv:py{37,38,39,310,311}-wheel] From 2ed5fba28d19109150175cd37394ab1e745d6633 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Wed, 4 Oct 2023 13:51:01 -0600 Subject: [PATCH 141/159] Update pull_request_template.md fix linting broke template formatting --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 3691f6b..3f52eeb 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -11,7 +11,7 @@ Closes # - \[ \] Add or update documentation related to these changes -- \[ \] Add entry to the [release notes](https://github.com/ethereum/%3CREPO_NAME%3E/blob/main/newsfragments/README.md) +- \[ \] Add entry to the [release notes](https://github.com/ethereum//blob/main/newsfragments/README.md) #### Cute Animal Picture From 0065691db7c072eb818f125e7595afb59db205f9 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Wed, 4 Oct 2023 13:55:19 -0600 Subject: [PATCH 142/159] Update Makefile missing doublequote --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 28d7fa4..74f1640 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CURRENT_SIGN_SETTING := $(shell git config commit.gpgSign) help: @echo "clean-build - remove build artifacts" @echo "clean-pyc - remove Python file artifacts" - @echo "lint - fix linting issues with pre-commit + @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/" From 82425694f63c6eb610e10451cb1c93317dbb6eeb Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Wed, 4 Oct 2023 15:36:57 -0600 Subject: [PATCH 143/159] drop py37 support (#104) --- .circleci/config.yml | 15 --------------- setup.py | 3 +-- tox.ini | 7 +++---- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bbc9029..2a438f5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -74,12 +74,6 @@ jobs: environment: TOXENV: docs - py37-core: - <<: *common - docker: - - image: cimg/python:3.7 - environment: - TOXENV: py37-core py38-core: <<: *common docker: @@ -130,12 +124,6 @@ jobs: environment: TOXENV: py311-lint - py37-wheel: - <<: *common - docker: - - image: cimg/python:3.7 - environment: - TOXENV: py37-wheel py38-wheel: <<: *common docker: @@ -171,17 +159,14 @@ workflows: test: jobs: - docs - - py37-core - py38-core - py39-core - py310-core - py311-core - - py37-lint - py38-lint - py39-lint - py310-lint - py311-lint - - py37-wheel - py38-wheel - py39-wheel - py310-wheel diff --git a/setup.py b/setup.py index 5efcc3c..ad552d5 100644 --- a/setup.py +++ b/setup.py @@ -50,7 +50,7 @@ install_requires=[ "eth-utils>=2", ], - python_requires=">=3.7, <4", + python_requires=">=3.8, <4", extras_require=extras_require, py_modules=[""], license="MIT", @@ -64,7 +64,6 @@ "License :: OSI Approved :: MIT License", "Natural Language :: English", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", diff --git a/tox.ini b/tox.ini index cf23aa2..df00ee6 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,8 @@ [tox] envlist= - py{37,38,39,310,311}-core + py{38,39,310,311}-core py{38,39,310,311}-lint - py{37,38,39,310,311}-wheel + py{38,39,310,311}-wheel py311-wheel-windows docs @@ -28,7 +28,6 @@ commands= docs: make check-docs basepython= docs: python - py37: python3.7 py38: python3.8 py39: python3.9 py310: python3.10 @@ -51,7 +50,7 @@ commands: {[common-lint]commands} [testenv:py{38,39,310,311}-lint] commands: {[common-lint]commands} -[testenv:py{37,38,39,310,311}-wheel] +[testenv:py{38,39,310,311}-wheel] deps= wheel build[virtualenv] From 146a3a9b020b87ccbbf44b783c254a84be1b34b2 Mon Sep 17 00:00:00 2001 From: pacrob Date: Wed, 11 Oct 2023 10:11:13 -0600 Subject: [PATCH 144/159] drop egg references --- .circleci/config.yml | 1 - Makefile | 1 - 2 files changed, 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2a438f5..5dcf001 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -37,7 +37,6 @@ common: &common - .tox - ~/.cache/pip - ~/.local - - ./eggs key: cache-v1-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }} orbs: diff --git a/Makefile b/Makefile index 74f1640..9deaab8 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,6 @@ clean: clean-build clean-pyc clean-build: rm -fr build/ rm -fr dist/ - rm -fr *.egg-info clean-pyc: find . -name '*.pyc' -exec rm -f {} + From c3c29ddf43ed091d7e3bd92841503d3a15f564ee Mon Sep 17 00:00:00 2001 From: pacrob Date: Wed, 11 Oct 2023 08:31:24 -0600 Subject: [PATCH 145/159] bump pre-commit to 4.5 and add github-flavored markdown linting extension --- .github/pull_request_template.md | 6 +++--- .pre-commit-config.yaml | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 3f52eeb..18c01e2 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -7,11 +7,11 @@ Closes # ### Todo: -- \[ \] Clean up commit history +- [ ] Clean up commit history -- \[ \] Add or update documentation related to these changes +- [ ] Add or update documentation related to these changes -- \[ \] Add entry to the [release notes](https://github.com/ethereum//blob/main/newsfragments/README.md) +- [ ] Add entry to the [release notes](https://github.com/ethereum//blob/main/newsfragments/README.md) #### Cute Animal Picture diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 58f9e1d..3ad4843 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ exclude: '.project-template|docs/conf.py' repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.4.0 + rev: v4.5.0 hooks: - id: check-yaml - id: check-toml @@ -30,6 +30,8 @@ repos: rev: 0.7.17 hooks: - id: mdformat + additional_dependencies: + - mdformat-gfm - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.5.1 hooks: From 86440ee879a96dfc9410010ae3fad829c21277fa Mon Sep 17 00:00:00 2001 From: pacrob Date: Thu, 12 Oct 2023 08:57:17 -0600 Subject: [PATCH 146/159] add autoflake to lint and move config to pyproject.toml --- .pre-commit-config.yaml | 6 ++++ .pydocstyle.ini | 30 ------------------ Makefile | 5 ++- mypy.ini | 16 ---------- pyproject.toml | 68 +++++++++++++++++++++++++++++++++++++++++ pytest.ini | 8 ----- tox.ini | 9 ------ 7 files changed, 78 insertions(+), 64 deletions(-) delete mode 100644 .pydocstyle.ini delete mode 100644 mypy.ini delete mode 100644 pytest.ini diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3ad4843..d2fae1c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,6 +18,10 @@ repos: additional_dependencies: - flake8-bugbear==23.9.16 exclude: setup.py +- repo: https://github.com/PyCQA/autoflake + rev: v2.2.1 + hooks: + - id: autoflake - repo: https://github.com/pycqa/isort rev: 5.12.0 hooks: @@ -26,6 +30,8 @@ repos: rev: 6.3.0 hooks: - id: pydocstyle + additional_dependencies: + - tomli # required until >= python311 - repo: https://github.com/executablebooks/mdformat rev: 0.7.17 hooks: diff --git a/.pydocstyle.ini b/.pydocstyle.ini deleted file mode 100644 index 0d40aa8..0000000 --- a/.pydocstyle.ini +++ /dev/null @@ -1,30 +0,0 @@ -[pydocstyle] -; All error codes found here: -; http://www.pydocstyle.org/en/3.0.0/error_codes.html -; -; Ignored: -; D1 - Missing docstring error codes -; -; Selected: -; D2 - Whitespace error codes -; D3 - Quote error codes -; D4 - Content related error codes -select=D2,D3,D4 - -; Extra ignores: -; D200 - One-line docstring should fit on one line with quotes -; D203 - 1 blank line required before class docstring -; D204 - 1 blank line required after class docstring -; D205 - 1 blank line required between summary line and description -; D212 - Multi-line docstring summary should start at the first line -; D302 - Use u""" for Unicode docstrings -; D400 - First line should end with a period -; D401 - First line should be in imperative mood -; D412 - No blank lines allowed between a section header and its content -add-ignore=D200,D203,D204,D205,D212,D302,D400,D401,D412 - -; Explanation: -; D400 - Enabling this error code seems to make it a requirement that the first -; sentence in a docstring is not split across two lines. It also makes it a -; requirement that no docstring can have a multi-sentence description without a -; summary line. Neither one of those requirements seem appropriate. diff --git a/Makefile b/Makefile index 9deaab8..fd94b2c 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,10 @@ clean-pyc: find . -name '__pycache__' -exec rm -rf {} + lint: - pre-commit run --all-files --show-diff-on-failure + @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..." \ + && pre-commit run --all-files --show-diff-on-failure \ + ) test: pytest tests diff --git a/mypy.ini b/mypy.ini deleted file mode 100644 index 1fcbd14..0000000 --- a/mypy.ini +++ /dev/null @@ -1,16 +0,0 @@ -[mypy] - -check_untyped_defs = True -disallow_incomplete_defs = True -disallow_untyped_defs = True -disallow_any_generics = True -disallow_untyped_calls = True -disallow_untyped_decorators = True -disallow_subclassing_any = True -ignore_missing_imports = True -strict_optional = True -strict_equality = True -warn_redundant_casts = True -warn_return_any = True -warn_unused_configs = True -warn_unused_ignores = True diff --git a/pyproject.toml b/pyproject.toml index d94ebfd..5abd4c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,71 @@ +[tool.autoflake] +remove_all_unused_imports = "True" +exclude = "__init__.py" + +[tool.isort] +combine_as_imports = "True" +extra_standard_library = "pytest" +force_grid_wrap = 1 +force_sort_within_sections = "True" +known_third_party = "hypothesis,pytest" +known_first_party = "" +multi_line_output = 3 +profile = "black" + +[tool.mypy] +check_untyped_defs = "True" +disallow_incomplete_defs = "True" +disallow_untyped_defs = "True" +disallow_any_generics = "True" +disallow_untyped_calls = "True" +disallow_untyped_decorators = "True" +disallow_subclassing_any = "True" +ignore_missing_imports = "True" +strict_optional = "True" +strict_equality = "True" +warn_redundant_casts = "True" +warn_return_any = "True" +warn_unused_configs = "True" +warn_unused_ignores = "True" + + +[tool.pydocstyle] +# All error codes found here: +# http://www.pydocstyle.org/en/3.0.0/error_codes.html +# +# Ignored: +# D1 - Missing docstring error codes +# +# Selected: +# D2 - Whitespace error codes +# D3 - Quote error codes +# D4 - Content related error codes +select = "D2,D3,D4" + +# Extra ignores: +# D200 - One-line docstring should fit on one line with quotes +# D203 - 1 blank line required before class docstring +# D204 - 1 blank line required after class docstring +# D205 - 1 blank line required between summary line and description +# D212 - Multi-line docstring summary should start at the first line +# D302 - Use u""" for Unicode docstrings +# D400 - First line should end with a period +# D401 - First line should be in imperative mood +# D412 - No blank lines allowed between a section header and its content +add-ignore = "D200,D203,D204,D205,D212,D302,D400,D401,D412,D415" + +# Explanation: +# D400 - Enabling this error code seems to make it a requirement that the first +# sentence in a docstring is not split across two lines. It also makes it a +# requirement that no docstring can have a multi-sentence description without a +# summary line. Neither one of those requirements seem appropriate. + +[tool.pytest.ini_options] +addopts = "-v --showlocals --durations 10" +xfail_strict = "True" +log_format = "%(levelname)8s %(asctime)s %(filename)20s %(message)s" +log_date_format = "%m-%d %H:%M:%S" + [tool.towncrier] # Read https://github.com/ethereum//blob/main/newsfragments/README.md for instructions package = "" diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index fd5ea7c..0000000 --- a/pytest.ini +++ /dev/null @@ -1,8 +0,0 @@ -[pytest] -addopts= -v --showlocals --durations 10 -xfail_strict=true -log_format = %(levelname)8s %(asctime)s %(filename)20s %(message)s -log_date_format = %m-%d %H:%M:%S - -[pytest-watch] -runner= pytest --failed-first --maxfail=1 --no-success-flaky-report diff --git a/tox.ini b/tox.ini index df00ee6..2742f06 100644 --- a/tox.ini +++ b/tox.ini @@ -6,15 +6,6 @@ envlist= py311-wheel-windows docs -[isort] -combine_as_imports=True -force_grid_wrap=1 -force_sort_within_sections=True -known_third_party=hypothesis,pytest -known_first_party= -multi_line_output=3 -profile=black - [flake8] exclude=venv*,.tox,docs,build extend-ignore=E203 From 662b35d09a8e33bd5bd4cbc611142fd06b0d1956 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Thu, 12 Oct 2023 12:14:28 -0600 Subject: [PATCH 147/159] Update pyproject.toml Add description of pydocstyle D415 rule --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 5abd4c2..8c23be3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,6 +52,7 @@ select = "D2,D3,D4" # D400 - First line should end with a period # D401 - First line should be in imperative mood # D412 - No blank lines allowed between a section header and its content +# D415 - First line should end with a period, question mark, or exclamation point add-ignore = "D200,D203,D204,D205,D212,D302,D400,D401,D412,D415" # Explanation: From 8d5d92ddd8fe0cb45f648fd7fa276c16987b5d82 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Thu, 26 Oct 2023 12:54:07 -0600 Subject: [PATCH 148/159] Update setup.py drop pytest-watch from dev dependencies --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index ad552d5..193ed7b 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,6 @@ "bumpversion>=0.5.3", "ipython", "pre-commit>=3.4.0", - "pytest-watch>=4.1.0", "tox>=4.0.0", "twine", "wheel", From 885bef7b5e7792af12fbe8f365e6410035f07fc5 Mon Sep 17 00:00:00 2001 From: pacrob Date: Fri, 27 Oct 2023 12:13:12 -0600 Subject: [PATCH 149/159] condense tox lint envs as linting now a pre-commit call, not tox --- tox.ini | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tox.ini b/tox.ini index 2742f06..f52da5f 100644 --- a/tox.ini +++ b/tox.ini @@ -28,19 +28,11 @@ extras= docs allowlist_externals=make,pre-commit -[common-lint] -basepython=python +[testenv:py{38,39,310,311}-lint] deps=pre-commit commands= pre-commit run --all-files --show-diff-on-failure -[testenv:lint] -basepython: python -commands: {[common-lint]commands} - -[testenv:py{38,39,310,311}-lint] -commands: {[common-lint]commands} - [testenv:py{38,39,310,311}-wheel] deps= wheel From 3c654831215dafd772e220d314b3c9221417f461 Mon Sep 17 00:00:00 2001 From: fselmo Date: Tue, 7 Nov 2023 12:07:54 -0700 Subject: [PATCH 150/159] update the grep command for upstream branch check - Sometimes 'www.' is used in the url for https --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fd94b2c..29815fa 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,9 @@ notes: check-bump release: check-bump clean # require that upstream is configured for ethereum/ - git remote -v | grep "upstream\tgit@github.com:ethereum/.git (push)\|upstream\thttps://github.com/ethereum/ (push)" + @git remote -v | grep \ + -e "upstream\tgit@github.com:ethereum/.git (push)" \ + -Ee "upstream\thttps://(www.)?github.com/ethereum/ \(push\)" # verify that docs build correctly ./newsfragments/validate_files.py is-empty make build-docs From 7f75b270a530924a91c776f32c708c9a82881771 Mon Sep 17 00:00:00 2001 From: fselmo Date: Tue, 7 Nov 2023 12:13:48 -0700 Subject: [PATCH 151/159] Use upcoming version in make notes commit --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 29815fa..6afbaf3 100644 --- a/Makefile +++ b/Makefile @@ -63,7 +63,7 @@ notes: check-bump 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" + git commit -m "Compile release notes for v$(UPCOMING_VERSION)" release: check-bump clean # require that upstream is configured for ethereum/ From 4d17820fca41d23d1e69cfd21282cd6e89f03231 Mon Sep 17 00:00:00 2001 From: fselmo Date: Mon, 27 Nov 2023 13:02:31 -0700 Subject: [PATCH 152/159] Further generalize the grep command for remote check --- Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 6afbaf3..c5956da 100644 --- a/Makefile +++ b/Makefile @@ -67,9 +67,7 @@ notes: check-bump release: check-bump clean # require that upstream is configured for ethereum/ - @git remote -v | grep \ - -e "upstream\tgit@github.com:ethereum/.git (push)" \ - -Ee "upstream\thttps://(www.)?github.com/ethereum/ \(push\)" + @git remote -v | grep -E "upstream\tgit@github.com:ethereum/.git \(push\)|upstream\thttps://(www.)?github.com/ethereum/ \(push\)" # verify that docs build correctly ./newsfragments/validate_files.py is-empty make build-docs From 67c0fb4f7b2e72be5161942af68b27a11a7b0e9d Mon Sep 17 00:00:00 2001 From: Stuart Reed Date: Mon, 27 Nov 2023 15:51:31 -0700 Subject: [PATCH 153/159] Ignore all __pycache__ directories (#114) * Ignore all __pycache__ directories * Newsfragment * Revert Newsfragment --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 5127a4d..57eac52 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,9 @@ chains .cache .pytest_cache +# pycache +__pycache__/ + # Test output logs logs From 0b0593880dbcebbfd6ae496b08e63f01ad814418 Mon Sep 17 00:00:00 2001 From: pacrob Date: Tue, 28 Nov 2023 09:21:12 -0700 Subject: [PATCH 154/159] add formats key to RTD to make downloadable docs available --- .readthedocs.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 593793c..e55e07e 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -15,3 +15,6 @@ python: path: . extra_requirements: - docs + +# Build all formats for RTD Downloads - htmlzip, pdf, epub +formats: all From d1395aaad2b26dffc61aec7ee821c597784ae816 Mon Sep 17 00:00:00 2001 From: Paul Robinson <5199899+pacrob@users.noreply.github.com> Date: Fri, 1 Dec 2023 16:01:08 -0700 Subject: [PATCH 155/159] add .bumpversion.cfg to pre-commit ignore Causes problems with releasing when pre-commit changes the file after bumpversion updates it --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d2fae1c..789b16c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -exclude: '.project-template|docs/conf.py' +exclude: '.project-template|docs/conf.py|.bumpversion.cfg' repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 From 621cd56059b73ea60f315ebef437a998d15481be Mon Sep 17 00:00:00 2001 From: pacrob Date: Thu, 7 Dec 2023 14:39:09 -0700 Subject: [PATCH 156/159] add pyupgrade to pre-commit hooks --- .pre-commit-config.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 789b16c..d1aa72c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -43,3 +43,8 @@ repos: hooks: - id: mypy exclude: tests/ +- repo: https://github.com/asottile/pyupgrade + rev: v3.15.0 + hooks: + - id: pyupgrade + args: [--py38-plus] From cb3f556315ba864450c975b88058f08da0a9c399 Mon Sep 17 00:00:00 2001 From: pacrob Date: Sat, 9 Dec 2023 12:12:52 -0700 Subject: [PATCH 157/159] move pyupgrade before black --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d1aa72c..82b01b7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,6 +7,11 @@ repos: - id: check-toml - id: end-of-file-fixer - id: trailing-whitespace +- repo: https://github.com/asottile/pyupgrade + rev: v3.15.0 + hooks: + - id: pyupgrade + args: [--py38-plus] - repo: https://github.com/psf/black rev: 23.9.1 hooks: @@ -43,8 +48,3 @@ repos: hooks: - id: mypy exclude: tests/ -- repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 - hooks: - - id: pyupgrade - args: [--py38-plus] From e91bfd685a0bf241b8dba65f3da479f595d10196 Mon Sep 17 00:00:00 2001 From: pacrob Date: Thu, 21 Dec 2023 09:45:32 -0700 Subject: [PATCH 158/159] lint and clean up typing, drop upper pins, match coincurve ci to proper python versions --- .bumpversion.cfg | 4 +- .circleci/config.yml | 100 ++++--- Makefile | 2 +- README.md | 196 ++++++-------- eth_keys/__init__.py | 20 +- eth_keys/backends/__init__.py | 22 +- eth_keys/backends/base.py | 34 +-- eth_keys/backends/coincurve.py | 64 ++--- eth_keys/backends/native/__init__.py | 4 +- eth_keys/backends/native/ecdsa.py | 71 ++--- eth_keys/backends/native/jacobian.py | 26 +- eth_keys/backends/native/main.py | 53 ++-- eth_keys/constants.py | 25 +- eth_keys/datatypes.py | 246 +++++++++--------- eth_keys/main.py | 49 ++-- eth_keys/tools/factories.py | 9 +- eth_keys/utils/der.py | 24 +- eth_keys/utils/module_loading.py | 28 +- eth_keys/utils/numeric.py | 3 +- eth_keys/utils/padding.py | 2 +- eth_keys/validation.py | 38 ++- mypy.ini | 15 -- pyproject.toml | 36 +-- pytest.ini | 2 - setup.py | 22 +- tests/backends/conftest.py | 88 ++++--- tests/backends/strategies.py | 18 +- tests/backends/test_backends.py | 91 ++++--- .../test_native_backend_against_coincurve.py | 110 ++++---- tests/conftest.py | 11 +- tests/core/test_factories.py | 4 +- .../test_key_and_signature_datastructures.py | 42 +-- tests/core/test_key_api_proxy_methods.py | 18 +- tests/core/test_keyapi_backend_formats.py | 16 +- tests/core/test_utils_der.py | 29 +-- tox.ini | 15 +- 36 files changed, 754 insertions(+), 783 deletions(-) delete mode 100644 mypy.ini delete mode 100644 pytest.ini diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 6b94a15..95fb46f 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -3,14 +3,14 @@ current_version = 0.4.0 commit = True tag = True parse = (?P\d+)\.(?P\d+)\.(?P\d+)(-(?P[^.]*)\.(?P\d+))? -serialize = +serialize = {major}.{minor}.{patch}-{stage}.{devnum} {major}.{minor}.{patch} [bumpversion:part:stage] optional_value = stable first_value = stable -values = +values = alpha beta stable diff --git a/.circleci/config.yml b/.circleci/config.yml index 5c56313..35d67e9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -159,96 +159,93 @@ jobs: - image: cimg/python:3.8 environment: TOXENV: py38-backends-coincurve12 - py39-backends-coincurve12: + py38-backends-coincurve13: <<: *common docker: - - image: cimg/python:3.9 + - image: cimg/python:3.8 environment: - TOXENV: py39-backends-coincurve12 - py310-backends-coincurve12: + TOXENV: py38-backends-coincurve13 + py38-backends-coincurve14: <<: *common docker: - - image: cimg/python:3.10 + - image: cimg/python:3.8 environment: - TOXENV: py310-backends-coincurve12 - py311-backends-coincurve12: + TOXENV: py38-backends-coincurve14 + py38-backends-coincurve15: <<: *common docker: - - image: cimg/python:3.11 + - image: cimg/python:3.8 environment: - TOXENV: py311-backends-coincurve12 - py38-backends-coincurve13: + TOXENV: py38-backends-coincurve15 + py39-backends-coincurve15: <<: *common docker: - - image: cimg/python:3.8 + - image: cimg/python:3.9 environment: - TOXENV: py38-backends-coincurve13 - py39-backends-coincurve13: + TOXENV: py39-backends-coincurve15 + + py38-backends-coincurve16: <<: *common docker: - - image: cimg/python:3.9 + - image: cimg/python:3.8 environment: - TOXENV: py39-backends-coincurve13 - py310-backends-coincurve13: + TOXENV: py38-backends-coincurve16 + py39-backends-coincurve16: <<: *common docker: - - image: cimg/python:3.10 + - image: cimg/python:3.9 environment: - TOXENV: py310-backends-coincurve13 - py311-backends-coincurve13: + TOXENV: py39-backends-coincurve16 + py310-backends-coincurve16: <<: *common docker: - - image: cimg/python:3.11 + - image: cimg/python:3.10 environment: - TOXENV: py311-backends-coincurve13 - py38-backends-coincurve14: + TOXENV: py310-backends-coincurve16 + + py38-backends-coincurve17: <<: *common docker: - image: cimg/python:3.8 environment: - TOXENV: py38-backends-coincurve14 - py39-backends-coincurve14: + TOXENV: py38-backends-coincurve17 + py39-backends-coincurve17: <<: *common docker: - image: cimg/python:3.9 environment: - TOXENV: py39-backends-coincurve14 - py310-backends-coincurve14: + TOXENV: py39-backends-coincurve17 + py310-backends-coincurve17: <<: *common docker: - image: cimg/python:3.10 environment: - TOXENV: py310-backends-coincurve14 - py311-backends-coincurve14: - <<: *common - docker: - - image: cimg/python:3.11 - environment: - TOXENV: py311-backends-coincurve14 - py38-backends-coincurve15: + TOXENV: py310-backends-coincurve17 + + py38-backends-coincurve18: <<: *common docker: - image: cimg/python:3.8 environment: - TOXENV: py38-backends-coincurve15 - py39-backends-coincurve15: + TOXENV: py38-backends-coincurve18 + py39-backends-coincurve18: <<: *common docker: - image: cimg/python:3.9 environment: - TOXENV: py39-backends-coincurve15 - py310-backends-coincurve15: + TOXENV: py39-backends-coincurve18 + py310-backends-coincurve18: <<: *common docker: - image: cimg/python:3.10 environment: - TOXENV: py310-backends-coincurve15 - py311-backends-coincurve15: + TOXENV: py310-backends-coincurve18 + py311-backends-coincurve18: <<: *common docker: - image: cimg/python:3.11 environment: - TOXENV: py311-backends-coincurve15 + TOXENV: py311-backends-coincurve18 workflows: version: 2 @@ -269,18 +266,17 @@ workflows: - py311-wheel - py311-wheel-windows - py38-backends-coincurve12 - - py39-backends-coincurve12 - - py310-backends-coincurve12 - - py311-backends-coincurve12 - py38-backends-coincurve13 - - py39-backends-coincurve13 - - py310-backends-coincurve13 - - py311-backends-coincurve13 - py38-backends-coincurve14 - - py39-backends-coincurve14 - - py310-backends-coincurve14 - - py311-backends-coincurve14 - py38-backends-coincurve15 - py39-backends-coincurve15 - - py310-backends-coincurve15 - - py311-backends-coincurve15 + - py38-backends-coincurve16 + - py39-backends-coincurve16 + - py310-backends-coincurve16 + - py38-backends-coincurve17 + - py39-backends-coincurve17 + - py310-backends-coincurve17 + - py38-backends-coincurve18 + - py39-backends-coincurve18 + - py310-backends-coincurve18 + - py311-backends-coincurve18 diff --git a/Makefile b/Makefile index 2490edb..48faed9 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ lint: test: pytest tests -docs: check-docs +docs: python ./newsfragments/validate_files.py towncrier build --draft --version preview diff --git a/README.md b/README.md index 5bd1211..7e41ff2 100644 --- a/README.md +++ b/README.md @@ -17,61 +17,6 @@ Read more in the documentation below. [View the change log](https://github.com/e python -m pip install eth-keys ``` -## Developer Setup - -If you would like to hack on eth-keys, please check out the [Snake Charmers -Tactical Manual](https://github.com/ethereum/snake-charmers-tactical-manual) -for information on how we do: - -- Testing -- Pull Requests -- Documentation - -We use [pre-commit](https://pre-commit.com/) to maintain consistent code style. Once -installed, it will run automatically with every commit. You can also run it manually -with `make lint`. If you need to make a commit that skips the `pre-commit` checks, you -can do so with `git commit --no-verify`. - -### Development Environment Setup - -You can set up your dev environment with: - -```sh -git clone git@github.com:ethereum/eth-keys.git -cd eth-keys -virtualenv -p python3 venv -. venv/bin/activate -python -m pip install -e ".[dev]" -pre-commit install -``` - -### Release setup - -To release a new version: - -```sh -make release bump=$$VERSION_PART_TO_BUMP$$ -``` - -#### How to bumpversion - -The version format for this repo is `{major}.{minor}.{patch}` for stable, and -`{major}.{minor}.{patch}-{stage}.{devnum}` for unstable (`stage` can be alpha or beta). - -To issue the next version in line, specify which part to bump, -like `make release bump=minor` or `make release bump=devnum`. This is typically done from the -main branch, except when releasing a beta (in which case the beta is released from main, -and the previous stable branch is released from said branch). - -If you are in a beta version, `make release bump=stage` will switch to a stable. - -To issue an unstable version when the current version is stable, specify the -new version explicitly, like `make release bump="--new-version 4.0.0-alpha.1 devnum"` - - - -## QuickStart - ```python >>> from eth_keys import keys >>> pk = keys.PrivateKey(b'\x01' * 32) @@ -90,7 +35,6 @@ True True ``` - ## Documentation ### `KeyAPI(backend=None)` @@ -100,8 +44,8 @@ libary. The object takes a single optional argument in its constructor which designates what backend will be used for eliptical curve cryptography operations. The built-in backends are: -* `eth_keys.backends.NativeECCBackend`: A pure python implementation of the ECC operations. -* `eth_keys.backends.CoinCurveECCBackend`: Uses the [`coincurve`](https://github.com/ofek/coincurve) library for ECC operations. +- `eth_keys.backends.NativeECCBackend`: A pure python implementation of the ECC operations. +- `eth_keys.backends.CoinCurveECCBackend`: Uses the [`coincurve`](https://github.com/ofek/coincurve) library for ECC operations. By default, `eth-keys` will *try* to use the `CoinCurveECCBackend`, falling back to the `NativeECCBackend` if the `coincurve` library is not @@ -111,9 +55,9 @@ available. The `backend` argument can be given in any of the following forms. -* Instance of the backend class -* The backend class -* String with the dot-separated import path for the backend class. +- Instance of the backend class +- The backend class +- String with the dot-separated import path for the backend class. ```python >>> from eth_keys import KeyAPI @@ -135,56 +79,50 @@ to the desired backend. >>> os.environ['ECC_BACKEND_CLASS'] = 'eth_keys.backends.CoinCurveECCBackend' ``` - ### `KeyAPI.ecdsa_sign(message_hash, private_key) -> Signature` This method returns a signature for the given `message_hash`, signed by the provided `private_key`. -* `message_hash`: **must** be a byte string of length 32 -* `private_key`: **must** be an instance of `PrivateKey` - +- `message_hash`: **must** be a byte string of length 32 +- `private_key`: **must** be an instance of `PrivateKey` ### `KeyAPI.ecdsa_verify(message_hash, signature, public_key) -> bool` Returns `True` or `False` based on whether the provided `signature` is a valid signature for the provided `message_hash` and `public_key`. -* `message_hash`: **must** be a byte string of length 32 -* `signature`: **must** be an instance of `Signature` -* `public_key`: **must** be an instance of `PublicKey` - +- `message_hash`: **must** be a byte string of length 32 +- `signature`: **must** be an instance of `Signature` +- `public_key`: **must** be an instance of `PublicKey` ### `KeyAPI.ecdsa_recover(message_hash, signature) -> PublicKey` Returns the `PublicKey` instances recovered from the given `signature` and `message_hash`. -* `message_hash`: **must** be a byte string of length 32 -* `signature`: **must** be an instance of `Signature` - +- `message_hash`: **must** be a byte string of length 32 +- `signature`: **must** be an instance of `Signature` ### `KeyAPI.private_key_to_public_key(private_key) -> PublicKey` Returns the `PublicKey` instances computed from the given `private_key` instance. -* `private_key`: **must** be an instance of `PublicKey` - +- `private_key`: **must** be an instance of `PublicKey` ### Common APIs for `PublicKey`, `PrivateKey` and `Signature` There is a common API for the following objects. -* `PublicKey` -* `PrivateKey` -* `Signature` +- `PublicKey` +- `PrivateKey` +- `Signature` Each of these objects has all of the following APIs. -* `obj.to_bytes()`: Returns the object in it's canonical `bytes` serialization. -* `obj.to_hex()`: Returns a text string of the hex encoded canonical representation. - +- `obj.to_bytes()`: Returns the object in it's canonical `bytes` serialization. +- `obj.to_hex()`: Returns a text string of the hex encoded canonical representation. ### `KeyAPI.PublicKey(public_key_bytes)` @@ -196,101 +134,86 @@ The `PublicKey` class takes a single argument which must be a bytes string with The following methods are available: - #### `PublicKey.from_compressed_bytes(compressed_bytes) -> PublicKey` This `classmethod` returns a new `PublicKey` instance computed from its compressed representation. -* `compressed_bytes` **must** be a byte string of length 33 starting with `\x02` or `\x03`. - +- `compressed_bytes` **must** be a byte string of length 33 starting with `\x02` or `\x03`. #### `PublicKey.from_private(private_key) -> PublicKey` This `classmethod` returns a new `PublicKey` instance computed from the -given `private_key`. - -* `private_key` may either be a byte string of length 32 or an instance of the `KeyAPI.PrivateKey` class. +given `private_key`. +- `private_key` may either be a byte string of length 32 or an instance of the `KeyAPI.PrivateKey` class. #### `PublicKey.recover_from_msg(message, signature) -> PublicKey` This `classmethod` returns a new `PublicKey` instance computed from the provided `message` and `signature`. -* `message` **must** be a byte string -* `signature` **must** be an instance of `KeyAPI.Signature` - +- `message` **must** be a byte string +- `signature` **must** be an instance of `KeyAPI.Signature` #### `PublicKey.recover_from_msg_hash(message_hash, signature) -> PublicKey` Same as `PublicKey.recover_from_msg` except that `message_hash` should be the Keccak hash of the `message`. - #### `PublicKey.verify_msg(message, signature) -> bool` This method returns `True` or `False` based on whether the signature is a valid for the given message. - #### `PublicKey.verify_msg_hash(message_hash, signature) -> bool` Same as `PublicKey.verify_msg` except that `message_hash` should be the Keccak hash of the `message`. - #### `PublicKey.to_compressed_bytes() -> bytes` Returns the compressed representation of this public key. - #### `PublicKey.to_address() -> text` Returns the hex encoded ethereum address for this public key. - #### `PublicKey.to_checksum_address() -> text` Returns the ERC55 checksum formatted ethereum address for this public key. - #### `PublicKey.to_canonical_address() -> bytes` Returns the 20-byte representation of the ethereum address for this public key. - ### `KeyAPI.PrivateKey(private_key_bytes)` The `PrivateKey` class takes a single argument which must be a bytes string with length 32. The following methods and properties are available - #### `PrivateKey.public_key` This *property* holds the `PublicKey` instance coresponding to this private key. - #### `PrivateKey.sign_msg(message) -> Signature` This method returns a signature for the given `message` in the form of a `Signature` instance -* `message` **must** be a byte string. - +- `message` **must** be a byte string. #### `PrivateKey.sign_msg_hash(message_hash) -> Signature` Same as `PrivateKey.sign` except that `message_hash` should be the Keccak hash of the `message`. - ### `KeyAPI.Signature(signature_bytes=None, vrs=None)` The `Signature` class can be instantiated in one of two ways. -* `signature_bytes`: a bytes string with length 65. -* `vrs`: a 3-tuple composed of the integers `v`, `r`, and `s`. +- `signature_bytes`: a bytes string with length 65. +- `vrs`: a 3-tuple composed of the integers `v`, `r`, and `s`. > Note: If using the `signature_bytes` to instantiate, the byte string should be encoded as `r_bytes | s_bytes | v_bytes` where `|` represents concatenation. `r_bytes` and `s_bytes` should be 32 bytes in length. `v_bytes` should be a single byte `\x00` or `\x01`. @@ -298,55 +221,46 @@ Signatures are expected to use `1` or `0` for their `v` value. The following methods and properties are available - #### `Signature.v` This property returns the `v` value from the signature as an integer. - #### `Signature.r` This property returns the `r` value from the signature as an integer. - #### `Signature.s` This property returns the `s` value from the signature as an integer. - #### `Signature.vrs` This property returns a 3-tuple of `(v, r, s)`. - #### `Signature.verify_msg(message, public_key) -> bool` This method returns `True` or `False` based on whether the signature is a valid for the given public key. -* `message`: **must** be a byte string. -* `public_key`: **must** be an instance of `PublicKey` - +- `message`: **must** be a byte string. +- `public_key`: **must** be an instance of `PublicKey` #### `Signature.verify_msg_hash(message_hash, public_key) -> bool` Same as `Signature.verify_msg` except that `message_hash` should be the Keccak hash of the `message`. - #### `Signature.recover_public_key_from_msg(message) -> PublicKey` This method returns a `PublicKey` instance recovered from the signature. -* `message`: **must** be a byte string. - +- `message`: **must** be a byte string. #### `Signature.recover_public_key_from_msg_hash(message_hash) -> PublicKey` Same as `Signature.recover_public_key_from_msg` except that `message_hash` should be the Keccak hash of the `message`. - ### Exceptions #### `eth_api.exceptions.ValidationError` @@ -355,8 +269,58 @@ This error is raised during instantaition of any of the `PublicKey`, `PrivateKey` or `Signature` classes if their constructor parameters are invalid. - #### `eth_api.exceptions.BadSignature` This error is raised from any of the `recover` or `verify` methods involving signatures if the signature is invalid. + +## Developer Setup + +If you would like to hack on eth-keys, please check out the [Snake Charmers +Tactical Manual](https://github.com/ethereum/snake-charmers-tactical-manual) +for information on how we do: + +- Testing +- Pull Requests +- Documentation + +We use [pre-commit](https://pre-commit.com/) to maintain consistent code style. Once +installed, it will run automatically with every commit. You can also run it manually +with `make lint`. If you need to make a commit that skips the `pre-commit` checks, you +can do so with `git commit --no-verify`. + +### Development Environment Setup + +You can set up your dev environment with: + +```sh +git clone git@github.com:ethereum/eth-keys.git +cd eth-keys +virtualenv -p python3 venv +. venv/bin/activate +python -m pip install -e ".[dev]" +pre-commit install +``` + +### Release setup + +To release a new version: + +```sh +make release bump=$$VERSION_PART_TO_BUMP$$ +``` + +#### How to bumpversion + +The version format for this repo is `{major}.{minor}.{patch}` for stable, and +`{major}.{minor}.{patch}-{stage}.{devnum}` for unstable (`stage` can be alpha or beta). + +To issue the next version in line, specify which part to bump, +like `make release bump=minor` or `make release bump=devnum`. This is typically done from the +main branch, except when releasing a beta (in which case the beta is released from main, +and the previous stable branch is released from said branch). + +If you are in a beta version, `make release bump=stage` will switch to a stable. + +To issue an unstable version when the current version is stable, specify the +new version explicitly, like `make release bump="--new-version 4.0.0-alpha.1 devnum"` diff --git a/eth_keys/__init__.py b/eth_keys/__init__.py index e02dc18..8601480 100644 --- a/eth_keys/__init__.py +++ b/eth_keys/__init__.py @@ -1,18 +1,10 @@ -from __future__ import absolute_import - -import sys -import warnings - - -if sys.version_info.major < 3: - warnings.simplefilter('always', DeprecationWarning) - warnings.warn(DeprecationWarning( - "The `eth-keys` library is dropping support for Python 2. Upgrade to Python 3." - )) - warnings.resetwarnings() - +from importlib.metadata import ( + version as __version, +) -from .main import ( # noqa: F401 +from .main import ( KeyAPI, lazy_key_api as keys, ) + +__version__ = __version("eth-keys") diff --git a/eth_keys/backends/__init__.py b/eth_keys/backends/__init__.py index aaa3683..d19af45 100644 --- a/eth_keys/backends/__init__.py +++ b/eth_keys/backends/__init__.py @@ -1,31 +1,35 @@ -from __future__ import absolute_import - import os -from typing import Type +from typing import ( + Type, +) from eth_keys.utils.module_loading import ( import_string, ) -from .base import BaseECCBackend # noqa: F401 -from .coincurve import ( # noqa: F401 +from .base import ( + BaseECCBackend, +) +from .coincurve import ( CoinCurveECCBackend, is_coincurve_available, ) -from .native import NativeECCBackend # noqa: F401 +from .native import ( + NativeECCBackend, +) def get_default_backend_class() -> str: if is_coincurve_available(): - return 'eth_keys.backends.CoinCurveECCBackend' + return "eth_keys.backends.CoinCurveECCBackend" else: - return 'eth_keys.backends.NativeECCBackend' + return "eth_keys.backends.NativeECCBackend" def get_backend_class(import_path: str = None) -> Type[BaseECCBackend]: if import_path is None: import_path = os.environ.get( - 'ECC_BACKEND_CLASS', + "ECC_BACKEND_CLASS", get_default_backend_class(), ) return import_string(import_path) diff --git a/eth_keys/backends/base.py b/eth_keys/backends/base.py index 8991f95..0b6356d 100644 --- a/eth_keys/backends/base.py +++ b/eth_keys/backends/base.py @@ -1,5 +1,3 @@ -from typing import Any # noqa: F401 - from eth_keys.datatypes import ( BaseSignature, NonRecoverableSignature, @@ -9,36 +7,28 @@ ) -class BaseECCBackend(object): - def ecdsa_sign(self, - msg_hash: bytes, - private_key: PrivateKey) -> Signature: +class BaseECCBackend: + def ecdsa_sign(self, msg_hash: bytes, private_key: PrivateKey) -> Signature: raise NotImplementedError() - def ecdsa_sign_non_recoverable(self, - msg_hash: bytes, - private_key: PrivateKey) -> NonRecoverableSignature: + def ecdsa_sign_non_recoverable( + self, msg_hash: bytes, private_key: PrivateKey + ) -> NonRecoverableSignature: raise NotImplementedError() - def ecdsa_verify(self, - msg_hash: bytes, - signature: BaseSignature, - public_key: PublicKey) -> bool: + def ecdsa_verify( + self, msg_hash: bytes, signature: BaseSignature, public_key: PublicKey + ) -> bool: raise NotImplementedError() - def ecdsa_recover(self, - msg_hash: bytes, - signature: Signature) -> PublicKey: + def ecdsa_recover(self, msg_hash: bytes, signature: Signature) -> PublicKey: raise NotImplementedError() - def private_key_to_public_key(self, - private_key: PrivateKey) -> PublicKey: + def private_key_to_public_key(self, private_key: PrivateKey) -> PublicKey: raise NotImplementedError() - def decompress_public_key_bytes(self, - compressed_public_key_bytes: bytes) -> bytes: + def decompress_public_key_bytes(self, compressed_public_key_bytes: bytes) -> bytes: raise NotImplementedError() - def compress_public_key_bytes(self, - uncompressed_public_key_bytes: bytes) -> bytes: + def compress_public_key_bytes(self, uncompressed_public_key_bytes: bytes) -> bytes: raise NotImplementedError() diff --git a/eth_keys/backends/coincurve.py b/eth_keys/backends/coincurve.py index 8b65968..d6d5e51 100644 --- a/eth_keys/backends/coincurve.py +++ b/eth_keys/backends/coincurve.py @@ -1,12 +1,8 @@ -from __future__ import absolute_import - -from typing import Optional # noqa: F401 - from eth_utils import ( big_endian_to_int, ) -from eth_keys.datatypes import ( # noqa: F401 +from eth_keys.datatypes import ( BaseSignature, NonRecoverableSignature, PrivateKey, @@ -16,17 +12,19 @@ from eth_keys.exceptions import ( BadSignature, ) -from eth_keys.validation import ( - validate_uncompressed_public_key_bytes, -) from eth_keys.utils import ( der, ) from eth_keys.utils.numeric import ( coerce_low_s, ) +from eth_keys.validation import ( + validate_uncompressed_public_key_bytes, +) -from .base import BaseECCBackend +from .base import ( + BaseECCBackend, +) def is_coincurve_available() -> bool: @@ -43,15 +41,15 @@ def __init__(self) -> None: try: import coincurve except ImportError: - raise ImportError("The CoinCurveECCBackend requires the coincurve \ - library which is not available for import.") + raise ImportError( + "The CoinCurveECCBackend requires the coincurve " + "library which is not available for import." + ) self.keys = coincurve.keys self.ecdsa = coincurve.ecdsa - super(CoinCurveECCBackend, self).__init__() + super().__init__() - def ecdsa_sign(self, - msg_hash: bytes, - private_key: PrivateKey) -> Signature: + def ecdsa_sign(self, msg_hash: bytes, private_key: PrivateKey) -> Signature: private_key_bytes = private_key.to_bytes() signature_bytes = self.keys.PrivateKey(private_key_bytes).sign_recoverable( msg_hash, @@ -60,9 +58,9 @@ def ecdsa_sign(self, signature = Signature(signature_bytes, backend=self) return signature - def ecdsa_sign_non_recoverable(self, - msg_hash: bytes, - private_key: PrivateKey) -> NonRecoverableSignature: + def ecdsa_sign_non_recoverable( + self, msg_hash: bytes, private_key: PrivateKey + ) -> NonRecoverableSignature: private_key_bytes = private_key.to_bytes() der_encoded_signature = self.keys.PrivateKey(private_key_bytes).sign( @@ -74,11 +72,11 @@ def ecdsa_sign_non_recoverable(self, signature = NonRecoverableSignature(rs=rs, backend=self) return signature - def ecdsa_verify(self, - msg_hash: bytes, - signature: BaseSignature, - public_key: PublicKey) -> bool: - # coincurve rejects signatures with a high s, so convert to the equivalent low s form + def ecdsa_verify( + self, msg_hash: bytes, signature: BaseSignature, public_key: PublicKey + ) -> bool: + # coincurve rejects signatures with a high s, + # so convert to the equivalent low s form low_s = coerce_low_s(signature.s) der_encoded_signature = der.two_int_sequence_encoder(signature.r, low_s) coincurve_public_key = self.keys.PublicKey(b"\x04" + public_key.to_bytes()) @@ -88,9 +86,7 @@ def ecdsa_verify(self, hasher=None, ) - def ecdsa_recover(self, - msg_hash: bytes, - signature: Signature) -> PublicKey: + def ecdsa_recover(self, msg_hash: bytes, signature: Signature) -> PublicKey: signature_bytes = signature.to_bytes() try: public_key_bytes = self.keys.PublicKey.from_signature_and_message( @@ -98,26 +94,22 @@ def ecdsa_recover(self, msg_hash, hasher=None, ).format(compressed=False)[1:] - except (ValueError, Exception) as err: - # `coincurve` can raise `ValueError` or `Exception` dependending on - # how the signature is invalid. + except Exception as err: raise BadSignature(str(err)) public_key = PublicKey(public_key_bytes, backend=self) return public_key def private_key_to_public_key(self, private_key: PrivateKey) -> PublicKey: - public_key_bytes = self.keys.PrivateKey(private_key.to_bytes()).public_key.format( - compressed=False, - )[1:] + public_key_bytes = self.keys.PrivateKey( + private_key.to_bytes() + ).public_key.format(compressed=False,)[1:] return PublicKey(public_key_bytes, backend=self) - def decompress_public_key_bytes(self, - compressed_public_key_bytes: bytes) -> bytes: + def decompress_public_key_bytes(self, compressed_public_key_bytes: bytes) -> bytes: public_key = self.keys.PublicKey(compressed_public_key_bytes) return public_key.format(compressed=False)[1:] - def compress_public_key_bytes(self, - uncompressed_public_key_bytes: bytes) -> bytes: + def compress_public_key_bytes(self, uncompressed_public_key_bytes: bytes) -> bytes: validate_uncompressed_public_key_bytes(uncompressed_public_key_bytes) point = ( big_endian_to_int(uncompressed_public_key_bytes[:32]), diff --git a/eth_keys/backends/native/__init__.py b/eth_keys/backends/native/__init__.py index d7a2a73..b9e24f8 100644 --- a/eth_keys/backends/native/__init__.py +++ b/eth_keys/backends/native/__init__.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - -from .main import ( # noqa: F401 +from .main import ( NativeECCBackend, ) diff --git a/eth_keys/backends/native/ecdsa.py b/eth_keys/backends/native/ecdsa.py index 6719b7f..72068f3 100644 --- a/eth_keys/backends/native/ecdsa.py +++ b/eth_keys/backends/native/ecdsa.py @@ -3,36 +3,41 @@ """ import hashlib import hmac -from typing import (Any, Callable, Optional, Tuple) # noqa: F401 +from typing import ( + Any, + Callable, + Tuple, +) from eth_utils import ( - int_to_big_endian, big_endian_to_int, + int_to_big_endian, ) from eth_keys.constants import ( - SECPK1_N as N, + SECPK1_A as A, + SECPK1_B as B, SECPK1_G as G, + SECPK1_N as N, + SECPK1_P as P, SECPK1_Gx as Gx, SECPK1_Gy as Gy, - SECPK1_P as P, - SECPK1_A as A, - SECPK1_B as B, ) from eth_keys.exceptions import ( BadSignature, ) - -from eth_keys.utils.padding import pad32 +from eth_keys.utils.padding import ( + pad32, +) from .jacobian import ( - inv, - fast_multiply, fast_add, + fast_multiply, + from_jacobian, + inv, is_identity, jacobian_add, jacobian_multiply, - from_jacobian, ) @@ -44,10 +49,12 @@ def decode_public_key(public_key_bytes: bytes) -> Tuple[int, int]: def encode_raw_public_key(raw_public_key: Tuple[int, int]) -> bytes: left, right = raw_public_key - return b''.join(( - pad32(int_to_big_endian(left)), - pad32(int_to_big_endian(right)), - )) + return b"".join( + ( + pad32(int_to_big_endian(left)), + pad32(int_to_big_endian(right)), + ) + ) def private_key_to_public_key(private_key_bytes: bytes) -> bytes: @@ -90,15 +97,21 @@ def decompress_public_key(compressed_public_key_bytes: bytes) -> bytes: return encode_raw_public_key((x, y)) -def deterministic_generate_k(msg_hash: bytes, - private_key_bytes: bytes, - digest_fn: Callable[[], Any] = hashlib.sha256) -> int: - v_0 = b'\x01' * 32 - k_0 = b'\x00' * 32 +def deterministic_generate_k( + msg_hash: bytes, + private_key_bytes: bytes, + digest_fn: Callable[[], Any] = hashlib.sha256, +) -> int: + v_0 = b"\x01" * 32 + k_0 = b"\x00" * 32 - k_1 = hmac.new(k_0, v_0 + b'\x00' + private_key_bytes + msg_hash, digest_fn).digest() + k_1 = hmac.new( + k_0, v_0 + b"\x00" + private_key_bytes + msg_hash, digest_fn + ).digest() v_1 = hmac.new(k_1, v_0, digest_fn).digest() - k_2 = hmac.new(k_1, v_1 + b'\x01' + private_key_bytes + msg_hash, digest_fn).digest() + k_2 = hmac.new( + k_1, v_1 + b"\x01" + private_key_bytes + msg_hash, digest_fn + ).digest() v_2 = hmac.new(k_2, v_1, digest_fn).digest() kb = hmac.new(k_2, v_2, digest_fn).digest() @@ -106,8 +119,7 @@ def deterministic_generate_k(msg_hash: bytes, return k -def ecdsa_raw_sign(msg_hash: bytes, - private_key_bytes: bytes) -> Tuple[int, int, int]: +def ecdsa_raw_sign(msg_hash: bytes, private_key_bytes: bytes) -> Tuple[int, int, int]: z = big_endian_to_int(msg_hash) k = deterministic_generate_k(msg_hash, private_key_bytes) @@ -120,9 +132,9 @@ def ecdsa_raw_sign(msg_hash: bytes, return v - 27, r, s -def ecdsa_raw_verify(msg_hash: bytes, - rs: Tuple[int, int], - public_key_bytes: bytes) -> bool: +def ecdsa_raw_verify( + msg_hash: bytes, rs: Tuple[int, int], public_key_bytes: bytes +) -> bool: raw_public_key = decode_public_key(public_key_bytes) r, s = rs @@ -138,13 +150,12 @@ def ecdsa_raw_verify(msg_hash: bytes, return bool(r == x and (r % N) and (s % N)) -def ecdsa_raw_recover(msg_hash: bytes, - vrs: Tuple[int, int, int]) -> bytes: +def ecdsa_raw_recover(msg_hash: bytes, vrs: Tuple[int, int, int]) -> bytes: v, r, s = vrs v += 27 if not (27 <= v <= 34): - raise BadSignature("%d must in range 27-31" % v) + raise BadSignature(f"{v} must in range 27-31") x = r diff --git a/eth_keys/backends/native/jacobian.py b/eth_keys/backends/native/jacobian.py index 1ea09fe..383a240 100644 --- a/eth_keys/backends/native/jacobian.py +++ b/eth_keys/backends/native/jacobian.py @@ -1,10 +1,12 @@ -from typing import Tuple # noqa: F401 +from typing import ( + Tuple, +) from eth_keys.constants import ( IDENTITY_POINTS, - SECPK1_P as P, - SECPK1_N as N, SECPK1_A as A, + SECPK1_N as N, + SECPK1_P as P, ) @@ -32,13 +34,14 @@ def jacobian_double(p: Tuple[int, int, int]) -> Tuple[int, int, int]: S = (4 * p[0] * ysq) % P M = (3 * p[0] ** 2 + A * p[2] ** 4) % P nx = (M**2 - 2 * S) % P - ny = (M * (S - nx) - 8 * ysq ** 2) % P + ny = (M * (S - nx) - 8 * ysq**2) % P nz = (2 * p[1] * p[2]) % P return (nx, ny, nz) -def jacobian_add(p: Tuple[int, int, int], - q: Tuple[int, int, int]) -> Tuple[int, int, int]: +def jacobian_add( + p: Tuple[int, int, int], q: Tuple[int, int, int] +) -> Tuple[int, int, int]: if not p[1]: return q if not q[1]: @@ -56,7 +59,7 @@ def jacobian_add(p: Tuple[int, int, int], H2 = (H * H) % P H3 = (H * H2) % P U1H2 = (U1 * H2) % P - nx = (R ** 2 - H3 - 2 * U1H2) % P + nx = (R**2 - H3 - 2 * U1H2) % P ny = (R * (U1H2 - nx) - S1 * H3) % P nz = (H * p[2] * q[2]) % P return (nx, ny, nz) @@ -67,8 +70,7 @@ def from_jacobian(p: Tuple[int, int, int]) -> Tuple[int, int]: return ((p[0] * z**2) % P, (p[1] * z**3) % P) -def jacobian_multiply(a: Tuple[int, int, int], - n: int) -> Tuple[int, int, int]: +def jacobian_multiply(a: Tuple[int, int, int], n: int) -> Tuple[int, int, int]: if a[1] == 0 or n == 0: return (0, 0, 1) if n == 1: @@ -83,13 +85,11 @@ def jacobian_multiply(a: Tuple[int, int, int], raise Exception("Invariant: Unreachable code path") -def fast_multiply(a: Tuple[int, int], - n: int) -> Tuple[int, int]: +def fast_multiply(a: Tuple[int, int], n: int) -> Tuple[int, int]: return from_jacobian(jacobian_multiply(to_jacobian(a), n)) -def fast_add(a: Tuple[int, int], - b: Tuple[int, int]) -> Tuple[int, int]: +def fast_add(a: Tuple[int, int], b: Tuple[int, int]) -> Tuple[int, int]: return from_jacobian(jacobian_add(to_jacobian(a), to_jacobian(b))) diff --git a/eth_keys/backends/native/main.py b/eth_keys/backends/native/main.py index ca7094f..8237ceb 100644 --- a/eth_keys/backends/native/main.py +++ b/eth_keys/backends/native/main.py @@ -1,18 +1,7 @@ -from __future__ import absolute_import - -from typing import Optional # noqa: F401 - -from .ecdsa import ( - ecdsa_raw_recover, - ecdsa_raw_sign, - ecdsa_raw_verify, - private_key_to_public_key, - compress_public_key, - decompress_public_key, +from eth_keys.backends.base import ( + BaseECCBackend, ) - -from eth_keys.backends.base import BaseECCBackend -from eth_keys.datatypes import ( # noqa: F401 +from eth_keys.datatypes import ( BaseSignature, NonRecoverableSignature, PrivateKey, @@ -20,31 +9,35 @@ Signature, ) +from .ecdsa import ( + compress_public_key, + decompress_public_key, + ecdsa_raw_recover, + ecdsa_raw_sign, + ecdsa_raw_verify, + private_key_to_public_key, +) + class NativeECCBackend(BaseECCBackend): - def ecdsa_sign(self, - msg_hash: bytes, - private_key: PrivateKey) -> Signature: + def ecdsa_sign(self, msg_hash: bytes, private_key: PrivateKey) -> Signature: signature_vrs = ecdsa_raw_sign(msg_hash, private_key.to_bytes()) signature = Signature(vrs=signature_vrs, backend=self) return signature - def ecdsa_sign_non_recoverable(self, - msg_hash: bytes, - private_key: PrivateKey) -> NonRecoverableSignature: + def ecdsa_sign_non_recoverable( + self, msg_hash: bytes, private_key: PrivateKey + ) -> NonRecoverableSignature: _, signature_r, signature_s = ecdsa_raw_sign(msg_hash, private_key.to_bytes()) signature = NonRecoverableSignature(rs=(signature_r, signature_s), backend=self) return signature - def ecdsa_verify(self, - msg_hash: bytes, - signature: BaseSignature, - public_key: PublicKey) -> bool: + def ecdsa_verify( + self, msg_hash: bytes, signature: BaseSignature, public_key: PublicKey + ) -> bool: return ecdsa_raw_verify(msg_hash, signature.rs, public_key.to_bytes()) - def ecdsa_recover(self, - msg_hash: bytes, - signature: Signature) -> PublicKey: + def ecdsa_recover(self, msg_hash: bytes, signature: Signature) -> PublicKey: public_key_bytes = ecdsa_raw_recover(msg_hash, signature.vrs) public_key = PublicKey(public_key_bytes, backend=self) return public_key @@ -54,10 +47,8 @@ def private_key_to_public_key(self, private_key: PrivateKey) -> PublicKey: public_key = PublicKey(public_key_bytes, backend=self) return public_key - def decompress_public_key_bytes(self, - compressed_public_key_bytes: bytes) -> bytes: + def decompress_public_key_bytes(self, compressed_public_key_bytes: bytes) -> bytes: return decompress_public_key(compressed_public_key_bytes) - def compress_public_key_bytes(self, - uncompressed_public_key_bytes: bytes) -> bytes: + def compress_public_key_bytes(self, uncompressed_public_key_bytes: bytes) -> bytes: return compress_public_key(uncompressed_public_key_bytes) diff --git a/eth_keys/constants.py b/eth_keys/constants.py index b7757ce..9b62f00 100644 --- a/eth_keys/constants.py +++ b/eth_keys/constants.py @@ -1,16 +1,23 @@ -from typing import Tuple # noqa: F401 - +from typing import ( + Tuple, +) # # SECPK1N # -SECPK1_P = 2**256 - 2**32 - 977 # type: int -SECPK1_N = 115792089237316195423570985008687907852837564279074904382605163141518161494337 # type: int # noqa: E501 -SECPK1_A = 0 # type: int # noqa: E501 -SECPK1_B = 7 # type: int # noqa: E501 -SECPK1_Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240 # type: int # noqa: E501 -SECPK1_Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424 # type: int # noqa: E501 -SECPK1_G = (SECPK1_Gx, SECPK1_Gy) # type: Tuple[int, int] +SECPK1_P: int = 2**256 - 2**32 - 977 +SECPK1_N: int = ( + 115792089237316195423570985008687907852837564279074904382605163141518161494337 +) +SECPK1_A: int = 0 +SECPK1_B: int = 7 +SECPK1_Gx: int = ( + 55066263022277343669578718895168534326250603453777594175500187360389116729240 +) +SECPK1_Gy: int = ( + 32670510020758816978083085130507043184471273380659243275938904335757337482424 +) +SECPK1_G: Tuple[int, int] = (SECPK1_Gx, SECPK1_Gy) # diff --git a/eth_keys/datatypes.py b/eth_keys/datatypes.py index 386d173..b5d4058 100644 --- a/eth_keys/datatypes.py +++ b/eth_keys/datatypes.py @@ -1,24 +1,22 @@ -from __future__ import absolute_import - from abc import ( ABC, abstractmethod, ) import codecs import collections -import sys -from typing import ( # noqa: F401 +from typing import ( + TYPE_CHECKING, Any, Tuple, - Union, Type, - TYPE_CHECKING, + Union, ) from eth_typing import ( ChecksumAddress, ) from eth_utils import ( + ValidationError, big_endian_to_int, encode_hex, int_to_big_endian, @@ -27,10 +25,11 @@ keccak, to_checksum_address, to_normalized_address, - ValidationError, - ) +from eth_keys.exceptions import ( + BadSignature, +) from eth_keys.utils.address import ( public_key_bytes_to_address, ) @@ -40,39 +39,27 @@ from eth_keys.utils.padding import ( pad32, ) - -from eth_keys.exceptions import ( - BadSignature, -) from eth_keys.validation import ( - validate_private_key_bytes, validate_compressed_public_key_bytes, - validate_uncompressed_public_key_bytes, - validate_recoverable_signature_bytes, validate_non_recoverable_signature_bytes, - validate_signature_v, + validate_private_key_bytes, + validate_recoverable_signature_bytes, validate_signature_r_or_s, + validate_signature_v, + validate_uncompressed_public_key_bytes, ) if TYPE_CHECKING: - from eth_keys.backends.base import BaseECCBackend # noqa: F401 - - -# Must compare against version_info[0] and not version_info.major to please mypy. -if sys.version_info[0] == 2: - ByteString = type( - b'BaseString', - (collections.abc.Sequence, basestring), # noqa: F821 - {}, - ) # type: Any -else: - ByteString = collections.abc.ByteString + from eth_keys.backends.base import ( + BaseECCBackend, + ) class LazyBackend: - def __init__(self, - backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None, - ) -> None: + def __init__( + self, + backend: "Union[BaseECCBackend, Type[BaseECCBackend], str, None]" = None, + ) -> None: from eth_keys.backends.base import ( # noqa: F811 BaseECCBackend, ) @@ -94,30 +81,33 @@ def __init__(self, self.backend = backend - _backend = None # type: BaseECCBackend + _backend: "BaseECCBackend" = None @property - def backend(self) -> 'BaseECCBackend': + def backend(self) -> "BaseECCBackend": if self._backend is None: return self.get_backend() else: return self._backend @backend.setter - def backend(self, value: 'BaseECCBackend') -> None: + def backend(self, value: "BaseECCBackend") -> None: self._backend = value @classmethod - def get_backend(cls, *args: Any, **kwargs: Any) -> 'BaseECCBackend': - from eth_keys.backends import get_backend + def get_backend(cls, *args: Any, **kwargs: Any) -> "BaseECCBackend": + from eth_keys.backends import ( + get_backend, + ) + return get_backend(*args, **kwargs) -class BaseKey(ByteString, collections.abc.Hashable): - _raw_key = None # type: bytes +class BaseKey(collections.abc.Hashable): + _raw_key: bytes = None def to_hex(self) -> str: - return '0x' + codecs.decode(codecs.encode(self._raw_key, 'hex'), 'ascii') + return "0x" + codecs.decode(codecs.encode(self._raw_key, "hex"), "ascii") def to_bytes(self) -> bytes: return self._raw_key @@ -135,13 +125,11 @@ def __len__(self) -> int: # TODO: this seems wrong. return 64 - # Must be typed with `ignore` due to - # https://github.com/python/mypy/issues/1237 - def __getitem__(self, index: int) -> int: # type: ignore + def __getitem__(self, index: int) -> int: return self._raw_key[index] def __eq__(self, other: Any) -> bool: - if hasattr(other, 'to_bytes'): + if hasattr(other, "to_bytes"): return self.to_bytes() == other.to_bytes() elif is_bytes(other): return self.to_bytes() == other @@ -149,80 +137,86 @@ def __eq__(self, other: Any) -> bool: return False def __repr__(self) -> str: - return "'{0}'".format(self.to_hex()) + return f"'{self.to_hex()}'" def __index__(self) -> int: return self.__int__() def __hex__(self) -> str: - if sys.version_info[0] == 2: - return codecs.encode(self.to_hex(), 'ascii') - else: - return self.to_hex() + return self.to_hex() class PublicKey(BaseKey, LazyBackend): - def __init__(self, - public_key_bytes: bytes, - backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None, - ) -> None: + def __init__( + self, + public_key_bytes: bytes, + backend: "Union[BaseECCBackend, Type[BaseECCBackend], str, None]" = None, + ) -> None: validate_uncompressed_public_key_bytes(public_key_bytes) self._raw_key = public_key_bytes super().__init__(backend=backend) @classmethod - def from_compressed_bytes(cls, - compressed_public_key_bytes: bytes, - backend: 'BaseECCBackend' = None, - ) -> 'PublicKey': + def from_compressed_bytes( + cls, + compressed_public_key_bytes: bytes, + backend: "BaseECCBackend" = None, + ) -> "PublicKey": validate_compressed_public_key_bytes(compressed_public_key_bytes) if backend is None: backend = cls.get_backend() - uncompressed_key = backend.decompress_public_key_bytes(compressed_public_key_bytes) + uncompressed_key = backend.decompress_public_key_bytes( + compressed_public_key_bytes + ) return cls(uncompressed_key, backend) @classmethod - def from_private(cls, - private_key: 'PrivateKey', - backend: 'BaseECCBackend' = None, - ) -> 'PublicKey': + def from_private( + cls, + private_key: "PrivateKey", + backend: "BaseECCBackend" = None, + ) -> "PublicKey": if backend is None: backend = cls.get_backend() return backend.private_key_to_public_key(private_key) @classmethod - def recover_from_msg(cls, - message: bytes, - signature: 'Signature', - backend: 'BaseECCBackend' = None, - ) -> 'PublicKey': + def recover_from_msg( + cls, + message: bytes, + signature: "Signature", + backend: "BaseECCBackend" = None, + ) -> "PublicKey": message_hash = keccak(message) return cls.recover_from_msg_hash(message_hash, signature, backend) @classmethod - def recover_from_msg_hash(cls, - message_hash: bytes, - signature: 'Signature', - backend: 'BaseECCBackend' = None, - ) -> 'PublicKey': + def recover_from_msg_hash( + cls, + message_hash: bytes, + signature: "Signature", + backend: "BaseECCBackend" = None, + ) -> "PublicKey": if backend is None: backend = cls.get_backend() return backend.ecdsa_recover(message_hash, signature) - def verify_msg(self, - message: bytes, - signature: 'Signature', - ) -> bool: + def verify_msg( + self, + message: bytes, + signature: "Signature", + ) -> bool: message_hash = keccak(message) return self.verify_msg_hash(message_hash, signature) - def verify_msg_hash(self, - message_hash: bytes, - signature: 'Signature', - ) -> bool: + def verify_msg_hash( + self, + message_hash: bytes, + signature: "Signature", + ) -> bool: return self.backend.ecdsa_verify(message_hash, signature, self) def to_compressed_bytes(self) -> bytes: @@ -242,12 +236,13 @@ def to_canonical_address(self) -> bytes: class PrivateKey(BaseKey, LazyBackend): - public_key = None # type: PublicKey + public_key: PublicKey = None - def __init__(self, - private_key_bytes: bytes, - backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None, - ) -> None: + def __init__( + self, + private_key_bytes: bytes, + backend: "Union[BaseECCBackend, Type[BaseECCBackend], str, None]" = None, + ) -> None: validate_private_key_bytes(private_key_bytes) self._raw_key = private_key_bytes @@ -255,29 +250,32 @@ def __init__(self, self.public_key = self.backend.private_key_to_public_key(self) super().__init__(backend=backend) - def sign_msg(self, message: bytes) -> 'Signature': + def sign_msg(self, message: bytes) -> "Signature": message_hash = keccak(message) return self.sign_msg_hash(message_hash) - def sign_msg_hash(self, message_hash: bytes) -> 'Signature': + def sign_msg_hash(self, message_hash: bytes) -> "Signature": return self.backend.ecdsa_sign(message_hash, self) - def sign_msg_non_recoverable(self, message: bytes) -> 'NonRecoverableSignature': + def sign_msg_non_recoverable(self, message: bytes) -> "NonRecoverableSignature": message_hash = keccak(message) return self.sign_msg_hash_non_recoverable(message_hash) - def sign_msg_hash_non_recoverable(self, message_hash: bytes) -> 'NonRecoverableSignature': + def sign_msg_hash_non_recoverable( + self, message_hash: bytes + ) -> "NonRecoverableSignature": return self.backend.ecdsa_sign_non_recoverable(message_hash, self) -class BaseSignature(ByteString, LazyBackend, ABC): - _r = None # type: int - _s = None # type: int +class BaseSignature(LazyBackend, ABC): + _r: int = None + _s: int = None - def __init__(self, - rs: Tuple[int, int], - backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None - ) -> None: + def __init__( + self, + rs: Tuple[int, int], + backend: "Union[BaseECCBackend, Type[BaseECCBackend], str, None]" = None, + ) -> None: for value in rs: try: validate_signature_r_or_s(value) @@ -319,20 +317,18 @@ def __len__(self) -> int: return len(bytes(self)) def __eq__(self, other: Any) -> bool: - if hasattr(other, 'to_bytes'): + if hasattr(other, "to_bytes"): return self.to_bytes() == other.to_bytes() elif is_bytes(other): return self.to_bytes() == other else: return False - # Must be typed with `ignore` due to - # https://github.com/python/mypy/issues/1237 - def __getitem__(self, index: int) -> int: # type: ignore + def __getitem__(self, index: int) -> int: return self.to_bytes()[index] def __repr__(self) -> str: - return "'{0}'".format(self.to_hex()) + return f"'{self.to_hex()}'" def __index__(self) -> int: return self.__int__() @@ -343,26 +339,23 @@ def __hex__(self) -> str: def __int__(self) -> int: return big_endian_to_int(self.to_bytes()) - def verify_msg(self, - message: bytes, - public_key: PublicKey) -> bool: + def verify_msg(self, message: bytes, public_key: PublicKey) -> bool: message_hash = keccak(message) return self.verify_msg_hash(message_hash, public_key) - def verify_msg_hash(self, - message_hash: bytes, - public_key: PublicKey) -> bool: + def verify_msg_hash(self, message_hash: bytes, public_key: PublicKey) -> bool: return self.backend.ecdsa_verify(message_hash, self, public_key) class Signature(BaseSignature): - _v = None # type: int - - def __init__(self, - signature_bytes: bytes = None, - vrs: Tuple[int, int, int] = None, - backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None, - ) -> None: + _v: int = None + + def __init__( + self, + signature_bytes: bytes = None, + vrs: Tuple[int, int, int] = None, + backend: "Union[BaseECCBackend, Type[BaseECCBackend], str, None]" = None, + ) -> None: if bool(signature_bytes) is bool(vrs): raise TypeError("You must provide one of `signature_bytes` or `vrs`") elif signature_bytes: @@ -371,7 +364,11 @@ def __init__(self, s = big_endian_to_int(signature_bytes[32:64]) v = ord(signature_bytes[64:65]) elif vrs: - v, r, s, = vrs + ( + v, + r, + s, + ) = vrs else: raise TypeError("Invariant: unreachable code path") @@ -411,7 +408,7 @@ def to_bytes(self) -> bytes: vb = int_to_byte(self.v) rb = pad32(int_to_big_endian(self.r)) sb = pad32(int_to_big_endian(self.s)) - return b''.join((rb, sb, vb)) + return b"".join((rb, sb, vb)) def recover_public_key_from_msg(self, message: bytes) -> PublicKey: message_hash = keccak(message) @@ -420,17 +417,17 @@ def recover_public_key_from_msg(self, message: bytes) -> PublicKey: def recover_public_key_from_msg_hash(self, message_hash: bytes) -> PublicKey: return self.backend.ecdsa_recover(message_hash, self) - def to_non_recoverable_signature(self) -> 'NonRecoverableSignature': + def to_non_recoverable_signature(self) -> "NonRecoverableSignature": return NonRecoverableSignature(rs=self.rs) class NonRecoverableSignature(BaseSignature): - - def __init__(self, - signature_bytes: bytes = None, - rs: Tuple[int, int] = None, - backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None, - ) -> None: + def __init__( + self, + signature_bytes: bytes = None, + rs: Tuple[int, int] = None, + backend: "Union[BaseECCBackend, Type[BaseECCBackend], str, None]" = None, + ) -> None: if signature_bytes is None and rs is None: raise TypeError("You must provide one of `signature_bytes` or `vr`") elif signature_bytes: @@ -445,7 +442,4 @@ def __init__(self, super().__init__(rs=(r, s), backend=backend) def to_bytes(self) -> bytes: - return b''.join( - pad32(int_to_big_endian(value)) - for value in self.rs - ) + return b"".join(pad32(int_to_big_endian(value)) for value in self.rs) diff --git a/eth_keys/main.py b/eth_keys/main.py index 678a7b8..f6a87e1 100644 --- a/eth_keys/main.py +++ b/eth_keys/main.py @@ -1,5 +1,3 @@ -from typing import (Any, Union, Type) # noqa: F401 - from eth_utils import ( ValidationError, ) @@ -8,15 +6,14 @@ BaseSignature, LazyBackend, NonRecoverableSignature, - PublicKey, PrivateKey, + PublicKey, Signature, ) from eth_keys.validation import ( validate_message_hash, ) - # These must be aliased due to a scoping issue in mypy # https://github.com/python/mypy/issues/1775 _PublicKey = PublicKey @@ -26,24 +23,20 @@ class KeyAPI(LazyBackend): - # - # datatype shortcuts - # - PublicKey = PublicKey # type: Type[_PublicKey] - PrivateKey = PrivateKey # type: Type[_PrivateKey] - Signature = Signature # type: Type[_Signature] - NonRecoverableSignature = NonRecoverableSignature # type: Type[_NonRecoverableSignature] + PublicKey = PublicKey + PrivateKey = PrivateKey + Signature = Signature + NonRecoverableSignature = NonRecoverableSignature # # Proxy method calls to the backends # - def ecdsa_sign(self, - message_hash: bytes, - private_key: _PrivateKey) -> _Signature: + def ecdsa_sign(self, message_hash: bytes, private_key: _PrivateKey) -> _Signature: validate_message_hash(message_hash) if not isinstance(private_key, PrivateKey): raise ValidationError( - "The `private_key` must be an instance of `eth_keys.datatypes.PrivateKey`" + "The `private_key` must be an instance of " + "`eth_keys.datatypes.PrivateKey`" ) signature = self.backend.ecdsa_sign(message_hash, private_key) if not isinstance(signature, Signature): @@ -53,13 +46,14 @@ def ecdsa_sign(self, ) return signature - def ecdsa_sign_non_recoverable(self, - message_hash: bytes, - private_key: _PrivateKey) -> _NonRecoverableSignature: + def ecdsa_sign_non_recoverable( + self, message_hash: bytes, private_key: _PrivateKey + ) -> _NonRecoverableSignature: validate_message_hash(message_hash) if not isinstance(private_key, PrivateKey): raise ValidationError( - "The `private_key` must be an instance of `eth_keys.datatypes.PrivateKey`" + "The `private_key` must be an instance of " + "`eth_keys.datatypes.PrivateKey`" ) signature = self.backend.ecdsa_sign_non_recoverable(message_hash, private_key) if not isinstance(signature, NonRecoverableSignature): @@ -69,10 +63,9 @@ def ecdsa_sign_non_recoverable(self, ) return signature - def ecdsa_verify(self, - message_hash: bytes, - signature: BaseSignature, - public_key: _PublicKey) -> bool: + def ecdsa_verify( + self, message_hash: bytes, signature: BaseSignature, public_key: _PublicKey + ) -> bool: validate_message_hash(message_hash) if not isinstance(public_key, PublicKey): raise ValidationError( @@ -80,13 +73,12 @@ def ecdsa_verify(self, ) if not isinstance(signature, BaseSignature): raise ValidationError( - "The `signature` must be an instance of `eth_keys.datatypes.BaseSignature`" + "The `signature` must be an instance of " + "`eth_keys.datatypes.BaseSignature`" ) return self.backend.ecdsa_verify(message_hash, signature, public_key) - def ecdsa_recover(self, - message_hash: bytes, - signature: _Signature) -> _PublicKey: + def ecdsa_recover(self, message_hash: bytes, signature: _Signature) -> _PublicKey: validate_message_hash(message_hash) if not isinstance(signature, Signature): raise ValidationError( @@ -103,7 +95,8 @@ def ecdsa_recover(self, def private_key_to_public_key(self, private_key: _PrivateKey) -> _PublicKey: if not isinstance(private_key, PrivateKey): raise ValidationError( - "The `private_key` must be an instance of `eth_keys.datatypes.PrivateKey`" + "The `private_key` must be an instance of " + "`eth_keys.datatypes.PrivateKey`" ) public_key = self.backend.private_key_to_public_key(private_key) if not isinstance(public_key, PublicKey): diff --git a/eth_keys/tools/factories.py b/eth_keys/tools/factories.py index ffc01bb..c4a3ebb 100644 --- a/eth_keys/tools/factories.py +++ b/eth_keys/tools/factories.py @@ -6,7 +6,9 @@ "which does not appear to be installed." ) from err -from eth_keys import keys +from eth_keys import ( + keys, +) def _mk_random_bytes(num_bytes: int) -> bytes: @@ -14,6 +16,7 @@ def _mk_random_bytes(num_bytes: int) -> bytes: import secrets except ImportError: import os + return os.urandom(num_bytes) else: return secrets.token_bytes(num_bytes) @@ -30,4 +33,6 @@ class PublicKeyFactory(factory.Factory): # type: ignore class Meta: model = keys.PublicKey - public_key_bytes = factory.LazyFunction(lambda: PrivateKeyFactory().public_key.to_bytes()) + public_key_bytes = factory.LazyFunction( + lambda: PrivateKeyFactory().public_key.to_bytes() + ) diff --git a/eth_keys/utils/der.py b/eth_keys/utils/der.py index ddeee83..c06e591 100644 --- a/eth_keys/utils/der.py +++ b/eth_keys/utils/der.py @@ -1,8 +1,9 @@ # Non-recoverable signatures are encoded using a DER sequence of two integers # We locally implement serialization and deserialization for this specific spec # with constrained inputs. -# This is done locally to avoid importing a 3rd-party library, in this very sensitive project. -# asn1tools and pyasn1 were used as reference APIs, see how in tests/core/test_utils_asn1.py +# This is done locally to avoid importing a 3rd-party library, in this very sensitive +# project. asn1tools and pyasn1 were used as reference APIs, see how in +# tests/core/test_utils_asn1.py # # See more about DER encodings, and ASN.1 in general, here: # http://luca.ntop.org/Teaching/Appunti/asn1.html @@ -73,14 +74,19 @@ def two_int_sequence_decoder(encoded: bytes) -> Tuple[int, int]: See: https://docs.microsoft.com/en-us/windows/desktop/seccertenroll/about-sequence """ if encoded[0] != 0x30: - raise ValueError("Encoded sequence must start with 0x30 byte, but got %s" % encoded[0]) + raise ValueError( + f"Encoded sequence must start with 0x30 byte, but got {encoded[0]}" + ) # skip sequence length int1, rest = _decode_int(encoded[2:]) int2, empty = _decode_int(rest) if len(empty) != 0: - raise ValueError("Encoded sequence must not contain any trailing data, but had %r" % empty) + raise ValueError( + "Encoded sequence must not contain any trailing data, but had " + f"{repr(empty)}" + ) return int1, int2 @@ -94,7 +100,8 @@ def _encode_int(primitive: int) -> Iterator[int]: encoded = int_to_big_endian(primitive) if encoded[0] >= 128: - # Indicate that integer is positive (it always is, but doesn't always need the flag) + # Indicate that integer is positive + # (it always is, but doesn't always need the flag) yield len(encoded) + 1 yield 0x00 else: @@ -108,11 +115,12 @@ def _decode_int(encoded: bytes) -> Tuple[int, bytes]: if encoded[0] != 0x02: raise ValueError( - "Encoded value must be an integer, starting with on 0x02 byte, but got %s" % encoded[0] + "Encoded value must be an integer, starting with on 0x02 byte, but got " + f"{encoded[0]}" ) length = encoded[1] # to_int can handle leading zeros - decoded_int = big_endian_to_int(encoded[2:2 + length]) + decoded_int = big_endian_to_int(encoded[2 : 2 + length]) - return decoded_int, encoded[2 + length:] + return decoded_int, encoded[2 + length :] diff --git a/eth_keys/utils/module_loading.py b/eth_keys/utils/module_loading.py index 03b4a78..308acea 100644 --- a/eth_keys/utils/module_loading.py +++ b/eth_keys/utils/module_loading.py @@ -1,6 +1,11 @@ +from importlib import ( + import_module, +) import operator -from typing import (Any, Tuple) -from importlib import import_module +from typing import ( + Any, + Tuple, +) def import_string(dotted_path: str) -> Any: @@ -10,9 +15,9 @@ def import_string(dotted_path: str) -> Any: last name in the path. Raise ImportError if the import failed. """ try: - module_path, class_name = dotted_path.rsplit('.', 1) + module_path, class_name = dotted_path.rsplit(".", 1) except ValueError: - msg = "%s doesn't look like a module path" % dotted_path + msg = f"{dotted_path} doesn't look like a module path" raise ImportError(msg) module = import_module(module_path) @@ -20,18 +25,17 @@ def import_string(dotted_path: str) -> Any: try: return getattr(module, class_name) except AttributeError: - msg = 'Module "%s" does not define a "%s" attribute/class' % ( - module_path, class_name) + msg = f'Module "{module_path}" does not define a "{class_name}" attribute/class' raise ImportError(msg) def split_at_longest_importable_path(dotted_path: str) -> Tuple[str, str]: - num_path_parts = len(dotted_path.split('.')) + num_path_parts = len(dotted_path.split(".")) for i in range(1, num_path_parts): - path_parts = dotted_path.rsplit('.', i) + path_parts = dotted_path.rsplit(".", i) import_part = path_parts[0] - remainder = '.'.join(path_parts[1:]) + remainder = ".".join(path_parts[1:]) try: module = import_module(import_part) @@ -42,11 +46,9 @@ def split_at_longest_importable_path(dotted_path: str) -> Tuple[str, str]: operator.attrgetter(remainder)(module) except AttributeError: raise ImportError( - "Unable to derive appropriate import path for {0}".format( - dotted_path, - ) + f"Unable to derive appropriate import path for {dotted_path}" ) else: return import_part, remainder else: - return '', dotted_path + return "", dotted_path diff --git a/eth_keys/utils/numeric.py b/eth_keys/utils/numeric.py index 9041e0a..42a86a1 100644 --- a/eth_keys/utils/numeric.py +++ b/eth_keys/utils/numeric.py @@ -8,7 +8,8 @@ def int_to_byte(value: int) -> bytes: def coerce_low_s(value: int) -> int: - """Coerce the s component of an ECDSA signature into its low-s form. + """ + Coerce the s component of an ECDSA signature into its low-s form. See https://bitcoin.stackexchange.com/questions/83408/in-ecdsa-why-is-r-%E2%88%92s-mod-n-complementary-to-r-s # noqa: E501 or https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md. diff --git a/eth_keys/utils/padding.py b/eth_keys/utils/padding.py index 58665bf..d03fcbd 100644 --- a/eth_keys/utils/padding.py +++ b/eth_keys/utils/padding.py @@ -1,2 +1,2 @@ def pad32(value: bytes) -> bytes: - return value.rjust(32, b'\x00') + return value.rjust(32, b"\x00") diff --git a/eth_keys/validation.py b/eth_keys/validation.py index 96ae759..878adda 100644 --- a/eth_keys/validation.py +++ b/eth_keys/validation.py @@ -1,12 +1,16 @@ -from typing import Any +from typing import ( + Any, +) from eth_utils import ( + ValidationError, encode_hex, is_bytes, is_integer, - ValidationError, ) -from eth_utils.toolz import curry +from eth_utils.toolz import ( + curry, +) from eth_keys.constants import ( SECPK1_N, @@ -15,12 +19,12 @@ def validate_integer(value: Any) -> None: if not is_integer(value) or isinstance(value, bool): - raise ValidationError("Value must be a an integer. Got: {0}".format(type(value))) + raise ValidationError(f"Value must be a an integer. Got: {type(value)}") def validate_bytes(value: Any) -> None: if not is_bytes(value): - raise ValidationError("Value must be a byte string. Got: {0}".format(type(value))) + raise ValidationError(f"Value must be a byte string. Got: {type(value)}") @curry @@ -28,9 +32,7 @@ def validate_gte(value: Any, minimum: int) -> None: validate_integer(value) if value < minimum: raise ValidationError( - "Value {0} is not greater than or equal to {1}".format( - value, minimum, - ) + f"Value {value} is not greater than or equal to {minimum}" ) @@ -38,11 +40,7 @@ def validate_gte(value: Any, minimum: int) -> None: def validate_lte(value: Any, maximum: int) -> None: validate_integer(value) if value > maximum: - raise ValidationError( - "Value {0} is not less than or equal to {1}".format( - value, maximum, - ) - ) + raise ValidationError(f"Value {value} is not less than or equal to {maximum}") validate_lt_secpk1n = validate_lte(maximum=SECPK1_N - 1) @@ -52,12 +50,8 @@ def validate_bytes_length(value: bytes, expected_length: int, name: str) -> None actual_length = len(value) if actual_length != expected_length: raise ValidationError( - "Unexpected {name} length: Expected {expected_length}, but got {actual_length} " - "bytes".format( - name=name, - expected_length=expected_length, - actual_length=actual_length, - ) + f"Unexpected {name} length: Expected {expected_length}, but got " + f"{actual_length} bytes" ) @@ -77,10 +71,8 @@ def validate_compressed_public_key_bytes(value: Any) -> None: first_byte = value[0:1] if first_byte not in (b"\x02", b"\x03"): raise ValidationError( - "Unexpected compressed public key format: Must start with 0x02 or 0x03, but starts " - "with {first_byte}".format( - first_byte=encode_hex(first_byte), - ) + "Unexpected compressed public key format: Must start with 0x02 or 0x03, " + f"but starts with {encode_hex(first_byte)}" ) diff --git a/mypy.ini b/mypy.ini deleted file mode 100644 index 457f52c..0000000 --- a/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] - -check_untyped_defs = True -disallow_incomplete_defs = True -disallow_untyped_defs = True -disallow_any_generics = True -disallow_untyped_calls = True -disallow_subclassing_any = True -ignore_missing_imports = True -strict_optional = False -strict_equality = True -warn_redundant_casts = True -warn_unused_configs = True -warn_unused_ignores = True - diff --git a/pyproject.toml b/pyproject.toml index 023f5d2..4497cd5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,32 +1,32 @@ [tool.autoflake] -remove_all_unused_imports = "True" +remove_all_unused_imports = true exclude = "__init__.py" [tool.isort] -combine_as_imports = "True" +combine_as_imports = true extra_standard_library = "pytest" force_grid_wrap = 1 -force_sort_within_sections = "True" +force_sort_within_sections = true known_third_party = "hypothesis,pytest" known_first_party = "eth_keys" multi_line_output = 3 profile = "black" [tool.mypy] -check_untyped_defs = "True" -disallow_incomplete_defs = "True" -disallow_untyped_defs = "True" -disallow_any_generics = "True" -disallow_untyped_calls = "True" -disallow_untyped_decorators = "True" -disallow_subclassing_any = "True" -ignore_missing_imports = "True" -strict_optional = "True" -strict_equality = "True" -warn_redundant_casts = "True" -warn_return_any = "True" -warn_unused_configs = "True" -warn_unused_ignores = "True" +check_untyped_defs = true +disallow_incomplete_defs = true +disallow_untyped_defs = true +disallow_any_generics = true +disallow_untyped_calls = true +disallow_untyped_decorators = false +disallow_subclassing_any = true +ignore_missing_imports = true +strict_optional = false +strict_equality = true +warn_redundant_casts = true +warn_return_any = false +warn_unused_configs = true +warn_unused_ignores = true [tool.pydocstyle] @@ -63,7 +63,7 @@ add-ignore = "D200,D203,D204,D205,D212,D302,D400,D401,D412,D415" [tool.pytest.ini_options] addopts = "-v --showlocals --durations 10" -xfail_strict = "True" +xfail_strict = true log_format = "%(levelname)8s %(asctime)s %(filename)20s %(message)s" log_date_format = "%m-%d %H:%M:%S" diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index beaabb6..0000000 --- a/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -addopts= -v --showlocals diff --git a/setup.py b/setup.py index 421b671..879a294 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from setuptools import ( find_packages, setup, @@ -7,7 +6,7 @@ extras_require = { "coincurve": [ - "coincurve>=7.0.0,<16.0.0", + "coincurve>=12.0.0", ], "dev": [ "build>=0.9.0", @@ -23,18 +22,19 @@ ], "test": [ "pytest>=7.0.0", - "pytest-xdist>=2.4.0", - "asn1tools>=0.146.2,<0.147", - "factory-boy>=3.0.1,<3.1", - "pyasn1>=0.4.5,<0.5", - "hypothesis>=5.10.3, <6.0.0", - "eth-hash[pysha3];implementation_name=='cpython'", - "eth-hash[pycryptodome];implementation_name=='pypy'", + "asn1tools>=0.146.2", + "factory-boy>=3.0.1", + "pyasn1>=0.4.5", + "hypothesis>=5.10.3,<6", + "eth-hash[pysha3]", ], } extras_require["dev"] = ( - extras_require["coincurve"] + extras_require["dev"] + extras_require["docs"] + extras_require["test"] + extras_require["coincurve"] + + extras_require["dev"] + + extras_require["docs"] + + extras_require["test"] ) @@ -45,7 +45,7 @@ setup( name="eth-keys", # *IMPORTANT*: Don't manually change the version here. Use `make bump`, as described in readme - version="0.1.0-alpha.0", + version="0.4.0", description="""eth-keys: Common API for Ethereum key operations""", long_description=long_description, long_description_content_type="text/markdown", diff --git a/tests/backends/conftest.py b/tests/backends/conftest.py index 613f7b8..8aed26e 100644 --- a/tests/backends/conftest.py +++ b/tests/backends/conftest.py @@ -1,18 +1,16 @@ -import pytest - from eth_utils import ( decode_hex, keccak, ) +import pytest - -MSG = b'message' +MSG = b"message" MSGHASH = keccak(MSG) # This is a sample of signatures generated with a known-good implementation of the ECDSA -# algorithm, which we use to test our ECC backends. If necessary, it can be generated from scratch -# with the following code: +# algorithm, which we use to test our ECC backends. If necessary, it can be generated +# from scratch with the following code: """ from devp2p import crypto from eth_utils import encode_hex @@ -35,48 +33,72 @@ SECRETS = { "alice": dict( - privkey=decode_hex('0x9c0257114eb9399a2985f8e75dad7600c5d89fe3824ffa99ec1c3eb8bf3b0501'), - pubkey=decode_hex('0x5eed5fa3a67696c334762bb4823e585e2ee579aba3558d9955296d6c04541b426078dbd48d74af1fd0c72aa1a05147cf17be6b60bdbed6ba19b08ec28445b0ca'), # noqa: E501 - compressed_pubkey=decode_hex('0x025eed5fa3a67696c334762bb4823e585e2ee579aba3558d9955296d6c04541b42'), # noqa: E501 - sig=decode_hex('0xb20e2ea5d3cbaa83c1e0372f110cf12535648613b479b64c1a8c1a20c5021f380434d07ec5795e3f789794351658e80b7faf47a46328f41e019d7b853745cdfd01'), # noqa: E501 + privkey=decode_hex( + "0x9c0257114eb9399a2985f8e75dad7600c5d89fe3824ffa99ec1c3eb8bf3b0501" + ), + pubkey=decode_hex( + "0x5eed5fa3a67696c334762bb4823e585e2ee579aba3558d9955296d6c04541b426078dbd48d74af1fd0c72aa1a05147cf17be6b60bdbed6ba19b08ec28445b0ca" # noqa: E501 + ), + compressed_pubkey=decode_hex( + "0x025eed5fa3a67696c334762bb4823e585e2ee579aba3558d9955296d6c04541b42" + ), + sig=decode_hex( + "0xb20e2ea5d3cbaa83c1e0372f110cf12535648613b479b64c1a8c1a20c5021f380434d07ec5795e3f789794351658e80b7faf47a46328f41e019d7b853745cdfd01" # noqa: E501 + ), raw_sig=( 1, - 80536744857756143861726945576089915884233437828013729338039544043241440681784, - 1902566422691403459035240420865094128779958320521066670269403689808757640701, - ) + 80536744857756143861726945576089915884233437828013729338039544043241440681784, # noqa: E501 + 1902566422691403459035240420865094128779958320521066670269403689808757640701, # noqa: E501 + ), ), "bob": dict( - privkey=decode_hex('0x38e47a7b719dce63662aeaf43440326f551b8a7ee198cee35cb5d517f2d296a2'), - pubkey=decode_hex('0x347746ccb908e583927285fa4bd202f08e2f82f09c920233d89c47c79e48f937d049130e3d1c14cf7b21afefc057f71da73dec8e8ff74ff47dc6a574ccd5d570'), # noqa: E501 - compressed_pubkey=decode_hex('0x02347746ccb908e583927285fa4bd202f08e2f82f09c920233d89c47c79e48f937'), # noqa: E501 - sig=decode_hex('0x5c48ea4f0f2257fa23bd25e6fcb0b75bbe2ff9bbda0167118dab2bb6e31ba76e691dbdaf2a231fc9958cd8edd99507121f8184042e075cf10f98ba88abff1f3601'), # noqa: E501 + privkey=decode_hex( + "0x38e47a7b719dce63662aeaf43440326f551b8a7ee198cee35cb5d517f2d296a2" + ), + pubkey=decode_hex( + "0x347746ccb908e583927285fa4bd202f08e2f82f09c920233d89c47c79e48f937d049130e3d1c14cf7b21afefc057f71da73dec8e8ff74ff47dc6a574ccd5d570" # noqa: E501 + ), + compressed_pubkey=decode_hex( + "0x02347746ccb908e583927285fa4bd202f08e2f82f09c920233d89c47c79e48f937" + ), + sig=decode_hex( + "0x5c48ea4f0f2257fa23bd25e6fcb0b75bbe2ff9bbda0167118dab2bb6e31ba76e691dbdaf2a231fc9958cd8edd99507121f8184042e075cf10f98ba88abff1f3601" # noqa: E501 + ), raw_sig=( 1, - 41741612198399299636429810387160790514780876799439767175315078161978521003886, - 47545396818609319588074484786899049290652725314938191835667190243225814114102, + 41741612198399299636429810387160790514780876799439767175315078161978521003886, # noqa: E501 + 47545396818609319588074484786899049290652725314938191835667190243225814114102, # noqa: E501 ), ), "eve": dict( - privkey=decode_hex('0x876be0999ed9b7fc26f1b270903ef7b0c35291f89407903270fea611c85f515c'), - pubkey=decode_hex('0xc06641f0d04f64dba13eac9e52999f2d10a1ff0ca68975716b6583dee0318d91e7c2aed363ed22edeba2215b03f6237184833fd7d4ad65f75c2c1d5ea0abecc0'), # noqa: E501 - compressed_pubkey=decode_hex('0x02c06641f0d04f64dba13eac9e52999f2d10a1ff0ca68975716b6583dee0318d91'), # noqa: E501 - sig=decode_hex('0xbabeefc5082d3ca2e0bc80532ab38f9cfb196fb9977401b2f6a98061f15ed603603d0af084bf906b2cdf6cdde8b2e1c3e51a41af5e9adec7f3643b3f1aa2aadf00'), # noqa: E501 + privkey=decode_hex( + "0x876be0999ed9b7fc26f1b270903ef7b0c35291f89407903270fea611c85f515c" + ), + pubkey=decode_hex( + "0xc06641f0d04f64dba13eac9e52999f2d10a1ff0ca68975716b6583dee0318d91e7c2aed363ed22edeba2215b03f6237184833fd7d4ad65f75c2c1d5ea0abecc0" # noqa: E501 + ), + compressed_pubkey=decode_hex( + "0x02c06641f0d04f64dba13eac9e52999f2d10a1ff0ca68975716b6583dee0318d91" + ), + sig=decode_hex( + "0xbabeefc5082d3ca2e0bc80532ab38f9cfb196fb9977401b2f6a98061f15ed603603d0af084bf906b2cdf6cdde8b2e1c3e51a41af5e9adec7f3643b3f1aa2aadf00" # noqa: E501 + ), raw_sig=( 0, - 84467545608142925331782333363288012579669270632210954476013542647119929595395, - 43529886636775750164425297556346136250671451061152161143648812009114516499167, + 84467545608142925331782333363288012579669270632210954476013542647119929595395, # noqa: E501 + 43529886636775750164425297556346136250671451061152161143648812009114516499167, # noqa: E501 ), ), } -@pytest.fixture(params=['alice', 'bob', 'eve']) +@pytest.fixture(params=["alice", "bob", "eve"]) def key_fixture(request): - if request.param == 'alice': - return SECRETS['alice'] - elif request.param == 'bob': - return SECRETS['bob'] - elif request.param == 'eve': - return SECRETS['eve'] + if request.param == "alice": + return SECRETS["alice"] + elif request.param == "bob": + return SECRETS["bob"] + elif request.param == "eve": + return SECRETS["eve"] else: - assert False, "Should be unreachable" + raise AssertionError("Should be unreachable") diff --git a/tests/backends/strategies.py b/tests/backends/strategies.py index 6e896b7..f7b32cb 100644 --- a/tests/backends/strategies.py +++ b/tests/backends/strategies.py @@ -1,10 +1,9 @@ -from hypothesis import ( - strategies as st, -) - from eth_utils import ( int_to_big_endian, ) +from hypothesis import ( + strategies as st, +) from eth_keys.constants import ( SECPK1_N, @@ -13,10 +12,13 @@ pad32, ) - -private_key_st = st.integers(min_value=1, max_value=SECPK1_N).map( - int_to_big_endian, -).map(pad32) +private_key_st = ( + st.integers(min_value=1, max_value=SECPK1_N) + .map( + int_to_big_endian, + ) + .map(pad32) +) message_hash_st = st.binary(min_size=32, max_size=32) diff --git a/tests/backends/test_backends.py b/tests/backends/test_backends.py index 2ba8c19..b2e1e3e 100644 --- a/tests/backends/test_backends.py +++ b/tests/backends/test_backends.py @@ -1,33 +1,35 @@ import os -import pytest - +from eth_utils import ( + keccak, +) from hypothesis import ( given, ) +import pytest +from strategies import ( + message_hash_st, + private_key_st, +) -from eth_keys import KeyAPI -from eth_keys.backends import CoinCurveECCBackend -from eth_keys.backends import NativeECCBackend +from eth_keys import ( + KeyAPI, +) +from eth_keys.backends import ( + CoinCurveECCBackend, + NativeECCBackend, +) from eth_keys.constants import ( SECPK1_N, ) -from eth_keys.exceptions import BadSignature +from eth_keys.exceptions import ( + BadSignature, +) from eth_keys.utils.numeric import ( coerce_low_s, ) -from eth_utils import ( - keccak, -) - -from strategies import ( - private_key_st, - message_hash_st, -) - - -MSG = b'message' +MSG = b"message" MSGHASH = keccak(MSG) @@ -36,10 +38,11 @@ ] try: - import coincurve + pass + backends.append(CoinCurveECCBackend()) except ImportError: - if 'REQUIRE_COINCURVE' in os.environ: + if "REQUIRE_COINCURVE" in os.environ: raise @@ -47,20 +50,20 @@ def backend_id_fn(backend): return type(backend).__name__ -@pytest.fixture(params=backends, ids=backend_id_fn, scope='module') +@pytest.fixture(params=backends, ids=backend_id_fn, scope="module") def key_api(request): return KeyAPI(backend=request.param) def test_ecdsa_sign(key_api, key_fixture): - private_key = key_api.PrivateKey(key_fixture['privkey']) + private_key = key_api.PrivateKey(key_fixture["privkey"]) signature = key_api.ecdsa_sign(MSGHASH, private_key) assert key_api.ecdsa_verify(MSGHASH, signature, private_key.public_key) def test_ecdsa_sign_non_recoverable(key_api, key_fixture): - private_key = key_api.PrivateKey(key_fixture['privkey']) + private_key = key_api.PrivateKey(key_fixture["privkey"]) signature = key_api.ecdsa_sign_non_recoverable(MSGHASH, private_key) non_recoverable_signature = key_api.ecdsa_sign_non_recoverable(MSGHASH, private_key) assert non_recoverable_signature.r == signature.r @@ -70,35 +73,43 @@ def test_ecdsa_sign_non_recoverable(key_api, key_fixture): def test_ecdsa_verify(key_api, key_fixture): - signature = key_api.Signature(vrs=key_fixture['raw_sig']) - public_key = key_api.PublicKey(key_fixture['pubkey']) + signature = key_api.Signature(vrs=key_fixture["raw_sig"]) + public_key = key_api.PublicKey(key_fixture["pubkey"]) assert key_api.ecdsa_verify(MSGHASH, signature, public_key) def test_ecdsa_recover(key_api, key_fixture): - signature = key_api.Signature(vrs=key_fixture['raw_sig']) - public_key = key_api.PublicKey(key_fixture['pubkey']) + signature = key_api.Signature(vrs=key_fixture["raw_sig"]) + public_key = key_api.PublicKey(key_fixture["pubkey"]) assert key_api.ecdsa_recover(MSGHASH, signature) == public_key @pytest.mark.parametrize( - 'v,r,s,msghash', + "v,r,s,msghash", ( ( # Test params from the ethereum/tests repo 0, - int("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", 16), - int("0x6b8d2c81b11b2d699528dde488dbdf2f94293d0d33c32e347f255fa4a6c1f0a9", 16), - bytes.fromhex("6b8d2c81b11b2d699528dde488dbdf2f94293d0d33c32e347f255fa4a6c1f0a9") + int( + "0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", 16 + ), + int( + "0x6b8d2c81b11b2d699528dde488dbdf2f94293d0d33c32e347f255fa4a6c1f0a9", 16 + ), + bytes.fromhex( + "6b8d2c81b11b2d699528dde488dbdf2f94293d0d33c32e347f255fa4a6c1f0a9" + ), ), ( # Test params from signing a message using the private key: '0x' + '00' * 32 1, - 29836180350949573232951565573845061551093497675544587026406064656720118638890, - 36811185137926304485684021052401800813557229270017380070056792973957337676018, - bytes.fromhex('1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750'), + 29836180350949573232951565573845061551093497675544587026406064656720118638890, # noqa: E501 + 36811185137926304485684021052401800813557229270017380070056792973957337676018, # noqa: E501 + bytes.fromhex( + "1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750" + ), ), ), ) @@ -106,20 +117,20 @@ def test_ecdsa_recover_identity_point(key_api, key_fixture, v, r, s, msghash): signature = key_api.Signature(vrs=(v, r, s)) with pytest.raises(BadSignature): - key_api.ecdsa_recover(msghash, signature) + key_api.ecdsa_recover(msghash, signature) def test_decompress_public_key_bytes(key_api, key_fixture): - compressed = key_fixture['compressed_pubkey'] - uncompressed = key_fixture['pubkey'] + compressed = key_fixture["compressed_pubkey"] + uncompressed = key_fixture["pubkey"] key_from_compressed = key_api.PublicKey.from_compressed_bytes(compressed) assert key_from_compressed.to_bytes() == uncompressed def test_compress_public_key_bytes(key_api, key_fixture): - uncompressed = key_fixture['pubkey'] - compressed = key_fixture['compressed_pubkey'] + uncompressed = key_fixture["pubkey"] + compressed = key_fixture["compressed_pubkey"] key_from_uncompressed = key_api.PublicKey(uncompressed) assert key_from_uncompressed.to_compressed_bytes() == compressed @@ -147,5 +158,7 @@ def test_signatures_with_high_s(key_api, private_key_bytes, message_hash): assert coerce_low_s(low_s_signature.s) == low_s_signature.s high_s = -low_s_signature.s % SECPK1_N assert coerce_low_s(high_s) == low_s_signature.s - high_s_signature = key_api.Signature(vrs=(low_s_signature.v, low_s_signature.r, high_s)) + high_s_signature = key_api.Signature( + vrs=(low_s_signature.v, low_s_signature.r, high_s) + ) assert key_api.ecdsa_verify(message_hash, high_s_signature, private_key.public_key) diff --git a/tests/backends/test_native_backend_against_coincurve.py b/tests/backends/test_native_backend_against_coincurve.py index 2980386..e89ead0 100644 --- a/tests/backends/test_native_backend_against_coincurve.py +++ b/tests/backends/test_native_backend_against_coincurve.py @@ -1,42 +1,41 @@ -import pytest - +from eth_utils import ( + keccak, +) from hypothesis import ( given, settings, strategies as st, ) - -from eth_utils import ( - keccak, -) - -from eth_keys.exceptions import ( - BadSignature, -) - -from eth_keys import KeyAPI -from eth_keys.backends import CoinCurveECCBackend -from eth_keys.backends import NativeECCBackend - +import pytest from strategies import ( - private_key_st, message_hash_st, + private_key_st, signature_st, ) +from eth_keys import ( + KeyAPI, +) +from eth_keys.backends import ( + CoinCurveECCBackend, + NativeECCBackend, +) +from eth_keys.exceptions import ( + BadSignature, +) -MSG = b'message' +MSG = b"message" MSGHASH = keccak(MSG) MAX_EXAMPLES = 200 -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def native_key_api(): return KeyAPI(backend=NativeECCBackend()) -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def coincurve_key_api(): return KeyAPI(backend=CoinCurveECCBackend()) @@ -45,9 +44,9 @@ def coincurve_key_api(): private_key_bytes=private_key_st, ) @settings(max_examples=MAX_EXAMPLES) -def test_public_key_generation_is_equal(private_key_bytes, - native_key_api, - coincurve_key_api): +def test_public_key_generation_is_equal( + private_key_bytes, native_key_api, coincurve_key_api +): native_public_key = native_key_api.PrivateKey(private_key_bytes).public_key coincurve_public_key = coincurve_key_api.PrivateKey(private_key_bytes).public_key @@ -59,10 +58,9 @@ def test_public_key_generation_is_equal(private_key_bytes, message_hash=message_hash_st, ) @settings(max_examples=MAX_EXAMPLES) -def test_signing_is_equal(private_key_bytes, - message_hash, - native_key_api, - coincurve_key_api): +def test_signing_is_equal( + private_key_bytes, message_hash, native_key_api, coincurve_key_api +): native_private_key = native_key_api.PrivateKey(private_key_bytes) native_signature = native_key_api.ecdsa_sign(message_hash, native_private_key) native_non_recoverable_signature = native_key_api.ecdsa_sign_non_recoverable( @@ -71,7 +69,9 @@ def test_signing_is_equal(private_key_bytes, ) coincurve_private_key = coincurve_key_api.PrivateKey(private_key_bytes) - coincurve_signature = coincurve_key_api.ecdsa_sign(message_hash, coincurve_private_key) + coincurve_signature = coincurve_key_api.ecdsa_sign( + message_hash, coincurve_private_key + ) coincurve_non_recoverable_signature = coincurve_key_api.ecdsa_sign_non_recoverable( message_hash, coincurve_private_key, @@ -85,24 +85,22 @@ def test_signing_is_equal(private_key_bytes, private_key_bytes=private_key_st, message_hash=message_hash_st, direction=st.one_of( - st.just('coincurve-to-native'), - st.just('native-to-coincurve'), + st.just("coincurve-to-native"), + st.just("native-to-coincurve"), ), ) @settings(max_examples=MAX_EXAMPLES) -def test_native_to_coincurve_recover(private_key_bytes, - message_hash, - direction, - native_key_api, - coincurve_key_api): - if direction == 'coincurve-to-native': +def test_native_to_coincurve_recover( + private_key_bytes, message_hash, direction, native_key_api, coincurve_key_api +): + if direction == "coincurve-to-native": backend_a = coincurve_key_api backend_b = native_key_api - elif direction == 'native-to-coincurve': + elif direction == "native-to-coincurve": backend_b = coincurve_key_api backend_a = native_key_api else: - assert False, "invariant" + raise AssertionError("invariant") private_key_a = backend_a.PrivateKey(private_key_bytes) public_key_a = private_key_a.public_key @@ -117,24 +115,22 @@ def test_native_to_coincurve_recover(private_key_bytes, message_hash=message_hash_st, signature_bytes=signature_st, direction=st.one_of( - st.just('coincurve-to-native'), - st.just('native-to-coincurve'), + st.just("coincurve-to-native"), + st.just("native-to-coincurve"), ), ) @settings(max_examples=MAX_EXAMPLES) -def test_coincurve_to_native_invalid_signatures(message_hash, - signature_bytes, - direction, - native_key_api, - coincurve_key_api): - if direction == 'coincurve-to-native': +def test_coincurve_to_native_invalid_signatures( + message_hash, signature_bytes, direction, native_key_api, coincurve_key_api +): + if direction == "coincurve-to-native": backend_a = coincurve_key_api backend_b = native_key_api - elif direction == 'native-to-coincurve': + elif direction == "native-to-coincurve": backend_b = coincurve_key_api backend_a = native_key_api else: - assert False, "invariant" + raise AssertionError("invariant") try: signature_a = backend_a.Signature(signature_bytes) @@ -167,9 +163,9 @@ def test_coincurve_to_native_invalid_signatures(message_hash, @given( private_key_bytes=private_key_st, ) -def test_public_key_compression_is_equal(private_key_bytes, - native_key_api, - coincurve_key_api): +def test_public_key_compression_is_equal( + private_key_bytes, native_key_api, coincurve_key_api +): native_public_key = native_key_api.PrivateKey(private_key_bytes).public_key coincurve_public_key = coincurve_key_api.PrivateKey(private_key_bytes).public_key @@ -182,13 +178,17 @@ def test_public_key_compression_is_equal(private_key_bytes, @given( private_key_bytes=private_key_st, ) -def test_public_key_decompression_is_equal(private_key_bytes, - native_key_api, - coincurve_key_api): +def test_public_key_decompression_is_equal( + private_key_bytes, native_key_api, coincurve_key_api +): public_key_template = coincurve_key_api.PrivateKey(private_key_bytes).public_key compressed_public_key = public_key_template.to_compressed_bytes() - native_public_key = native_key_api.PublicKey.from_compressed_bytes(compressed_public_key) - coincurve_public_key = coincurve_key_api.PublicKey.from_compressed_bytes(compressed_public_key) + native_public_key = native_key_api.PublicKey.from_compressed_bytes( + compressed_public_key + ) + coincurve_public_key = coincurve_key_api.PublicKey.from_compressed_bytes( + compressed_public_key + ) assert native_public_key == coincurve_public_key diff --git a/tests/conftest.py b/tests/conftest.py index 0e9fd82..e167fb4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,12 +1,13 @@ import pytest - -# Change COLLECT_TYPE_INFO to True here, and run the tests with python2.7 to get a type info dump -# that can later be fed to pyannotate to generate type annotation comments. +# Change COLLECT_TYPE_INFO to True here, and run the tests with python2.7 to get a type +# info dump that can later be fed to pyannotate to generate type annotation comments. COLLECT_TYPE_INFO = False if COLLECT_TYPE_INFO: - from pyannotate_runtime import collect_types + from pyannotate_runtime import ( + collect_types, + ) @pytest.fixture(autouse=True) def collect_types_fixture(): @@ -14,10 +15,8 @@ def collect_types_fixture(): yield collect_types.pause() - def pytest_sessionstart(session): collect_types.init_types_collection() - def pytest_sessionfinish(session, exitstatus): collect_types.dump_stats("type_info.json") diff --git a/tests/core/test_factories.py b/tests/core/test_factories.py index b74f2d2..1855665 100644 --- a/tests/core/test_factories.py +++ b/tests/core/test_factories.py @@ -1,4 +1,6 @@ -from eth_keys import keys +from eth_keys import ( + keys, +) from eth_keys.tools.factories import ( PrivateKeyFactory, PublicKeyFactory, diff --git a/tests/core/test_key_and_signature_datastructures.py b/tests/core/test_key_and_signature_datastructures.py index bfc7dc0..9976a38 100644 --- a/tests/core/test_key_and_signature_datastructures.py +++ b/tests/core/test_key_and_signature_datastructures.py @@ -1,24 +1,26 @@ -from __future__ import unicode_literals - -import pytest - from eth_utils import ( + ValidationError, decode_hex, encode_hex, - keccak, - is_same_address, - is_normalized_address, - is_checksum_address, is_canonical_address, - ValidationError, + is_checksum_address, + is_normalized_address, + is_same_address, + keccak, ) +import pytest -from eth_keys import KeyAPI -from eth_keys.backends import NativeECCBackend -from eth_keys.exceptions import ValidationError as EthKeysValidationErrorCopy - +from eth_keys import ( + KeyAPI, +) +from eth_keys.backends import ( + NativeECCBackend, +) +from eth_keys.exceptions import ( + ValidationError as EthKeysValidationErrorCopy, +) -MSG = b'message' +MSG = b"message" MSGHASH = keccak(MSG) @@ -28,9 +30,9 @@ def key_api(): PK_BYTES = decode_hex( - '0x58d23b55bc9cdce1f18c2500f40ff4ab7245df9a89505e9b1fa4851f623d241d' + "0x58d23b55bc9cdce1f18c2500f40ff4ab7245df9a89505e9b1fa4851f623d241d" ) -ADDRESS = '0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd' +ADDRESS = "0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd" @pytest.fixture @@ -129,7 +131,7 @@ def test_to_canonical_address_from_public_key(private_key): def test_hex_conversion(private_key): public_key = private_key.public_key - signature = private_key.sign_msg(b'message') + signature = private_key.sign_msg(b"message") assert hex(public_key) == encode_hex(public_key.to_bytes()) assert hex(private_key) == encode_hex(private_key.to_bytes()) @@ -142,7 +144,7 @@ def test_hex_conversion(private_key): def test_bytes_conversion(key_api, private_key): public_key = private_key.public_key - signature = private_key.sign_msg(b'message') + signature = private_key.sign_msg(b"message") assert public_key.to_bytes() == public_key._raw_key assert private_key.to_bytes() == private_key._raw_key @@ -156,7 +158,9 @@ def test_compressed_bytes_conversion(key_api, private_key): assert key_api.PublicKey.from_compressed_bytes(compressed_bytes) == public_key -@pytest.mark.parametrize('validation_error', (ValidationError, EthKeysValidationErrorCopy)) +@pytest.mark.parametrize( + "validation_error", (ValidationError, EthKeysValidationErrorCopy) +) def test_compressed_bytes_validation(key_api, private_key, validation_error): valid_key = private_key.public_key.to_compressed_bytes() diff --git a/tests/core/test_key_api_proxy_methods.py b/tests/core/test_key_api_proxy_methods.py index 3f9dfd6..dc4cffd 100644 --- a/tests/core/test_key_api_proxy_methods.py +++ b/tests/core/test_key_api_proxy_methods.py @@ -1,17 +1,19 @@ -import pytest - from eth_utils import ( - keccak, ValidationError, + keccak, ) +import pytest -from eth_keys import KeyAPI -from eth_keys.backends import NativeECCBackend - +from eth_keys import ( + KeyAPI, +) +from eth_keys.backends import ( + NativeECCBackend, +) -MSG = b'message' +MSG = b"message" MSGHASH = keccak(MSG) -PK_BYTES = b'\x01' * 32 +PK_BYTES = b"\x01" * 32 @pytest.fixture diff --git a/tests/core/test_keyapi_backend_formats.py b/tests/core/test_keyapi_backend_formats.py index 60f0350..c0ec81e 100644 --- a/tests/core/test_keyapi_backend_formats.py +++ b/tests/core/test_keyapi_backend_formats.py @@ -1,22 +1,26 @@ import pytest -from eth_keys import KeyAPI -from eth_keys.backends import NativeECCBackend +from eth_keys import ( + KeyAPI, +) +from eth_keys.backends import ( + NativeECCBackend, +) @pytest.fixture(autouse=True) def native_backend_env_var(monkeypatch): - monkeypatch.setenv('ECC_BACKEND_CLASS', 'eth_keys.backends.native.NativeECCBackend') + monkeypatch.setenv("ECC_BACKEND_CLASS", "eth_keys.backends.native.NativeECCBackend") @pytest.mark.parametrize( - 'backend', + "backend", ( None, NativeECCBackend(), NativeECCBackend, - 'eth_keys.backends.NativeECCBackend', - 'eth_keys.backends.native.NativeECCBackend', + "eth_keys.backends.NativeECCBackend", + "eth_keys.backends.native.NativeECCBackend", ), ) def test_supported_backend_formats(backend): diff --git a/tests/core/test_utils_der.py b/tests/core/test_utils_der.py index 297925b..0afe8ee 100644 --- a/tests/core/test_utils_der.py +++ b/tests/core/test_utils_der.py @@ -1,21 +1,19 @@ -import itertools -import pytest - import asn1tools from hypothesis import ( example, + given, settings, strategies as st, - given, ) from pyasn1.codec.der import ( - encoder as pyasn1_encoder, decoder as pyasn1_decoder, + encoder as pyasn1_encoder, ) from pyasn1.type import ( - univ, namedtype, + univ, ) +import pytest from eth_keys.utils.der import ( two_int_sequence_decoder, @@ -44,8 +42,8 @@ def asn1tools_decode(encoded): class TwoInts(univ.Sequence): componentType = namedtype.NamedTypes( - namedtype.NamedType('r', univ.Integer()), - namedtype.NamedType('s', univ.Integer()), + namedtype.NamedType("r", univ.Integer()), + namedtype.NamedType("s", univ.Integer()), ) @@ -61,11 +59,12 @@ def pyasn1_decode(encoded): return decoded[0]["r"], decoded[0]["s"] -MAX_32_BYTE_INT = 256 ** 32 - 1 +MAX_32_BYTE_INT = 256**32 - 1 uint32strategy = st.integers(min_value=0, max_value=MAX_32_BYTE_INT) + @pytest.mark.parametrize( - 'encoder, decoder', + "encoder, decoder", ( (two_int_sequence_encoder, asn1tools_decode), (two_int_sequence_encoder, pyasn1_decode), @@ -74,11 +73,11 @@ def pyasn1_decode(encoded): (pyasn1_encode, two_int_sequence_decoder), ), ids=( - 'local_encode=>asn1tools_decode', - 'local_encode=>pyasn1_decode', - 'local_encode=>local_decode', - 'asn1tools_encode=>local_decode', - 'pyasn1_encode=>local_decode', + "local_encode=>asn1tools_decode", + "local_encode=>pyasn1_decode", + "local_encode=>local_decode", + "asn1tools_encode=>local_decode", + "pyasn1_encode=>local_decode", ), ) @given( diff --git a/tox.ini b/tox.ini index b27b4b7..6c528ae 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,9 @@ [tox] envlist= - py{38,39,310,311}-backends-coincurve{7,8,9,10,11,12,13,14,15} + py38-backends-coincurve{12,13,14} + py{38,39}-backends-coincurve15 + py{38,39,10}-backends-coincurve{16,17} + py{38,39,10,11}-backends-coincurve18 py{38,39,310,311}-core py{38,39,310,311}-lint py{38,39,310,311}-wheel @@ -18,7 +21,7 @@ usedevelop=True commands= core: pytest {posargs:tests/core} backends: pytest {posargs:tests/backends} - docs: make check-docs + docs: make docs basepython= docs: python py38: python3.8 @@ -26,15 +29,13 @@ basepython= py310: python3.10 py311: python3.11 deps= .[test] - coincurve7: coincurve>=7.0.0,<8.0.0 - coincurve8: coincurve>=8.0.0,<9.0.0 - coincurve9: coincurve>=9.0.0,<10.0.0 - coincurve10: coincurve>=10.0.0,<11.0.0 - coincurve11: coincurve>=11.0.0,<12.0.0 coincurve12: coincurve>=12.0.0,<13.0.0 coincurve13: coincurve>=13.0.0,<14.0.0 coincurve14: coincurve>=14.0.0,<15.0.0 coincurve15: coincurve>=15.0.0,<16.0.0 + coincurve16: coincurve>=16.0.0,<17.0.0 + coincurve17: coincurve>=17.0.0,<18.0.0 + coincurve18: coincurve>=18.0.0,<19.0.0 setenv= backends: REQUIRE_COINCURVE=True extras= From 5afb5957d4d04f4ddadc141014378c68f5a95bea Mon Sep 17 00:00:00 2001 From: pacrob Date: Wed, 3 Jan 2024 12:34:25 -0700 Subject: [PATCH 159/159] newsfragments --- newsfragments/96.breaking.rst | 1 + newsfragments/96.feature.rst | 1 + newsfragments/96.internal.rst | 1 + 3 files changed, 3 insertions(+) create mode 100644 newsfragments/96.breaking.rst create mode 100644 newsfragments/96.feature.rst create mode 100644 newsfragments/96.internal.rst diff --git a/newsfragments/96.breaking.rst b/newsfragments/96.breaking.rst new file mode 100644 index 0000000..8c18340 --- /dev/null +++ b/newsfragments/96.breaking.rst @@ -0,0 +1 @@ +Drop python 3.6 and 3.7 support diff --git a/newsfragments/96.feature.rst b/newsfragments/96.feature.rst new file mode 100644 index 0000000..cc8e290 --- /dev/null +++ b/newsfragments/96.feature.rst @@ -0,0 +1 @@ +Add python 3.11 support diff --git a/newsfragments/96.internal.rst b/newsfragments/96.internal.rst new file mode 100644 index 0000000..5138f8f --- /dev/null +++ b/newsfragments/96.internal.rst @@ -0,0 +1 @@ +Merge template updates, notably using ``pre-commit`` for linting and change the name of the ``master`` branch to ``main``