diff --git a/.circleci/config.yml b/.circleci/config.yml index 43b36c58..a9f67825 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -36,12 +36,12 @@ common: &common key: v4-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: @@ -64,7 +64,7 @@ workflows: version: 2 test: jobs: - - doctest + - docs - lint - py36-core - py37-core diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 9b05d235..5ff4880e 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,16 +1,38 @@ -* Version: x.x.x -* Python: 2.7/3.4/3.5 -* OS: osx/linux/win + _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? -### What was wrong? +### Code that produced the error -Please include any of the following that are applicable: +```py +CODE_TO_REPRODUCE +``` -* The code which produced the error -* The full output of the error +### Full error output +```sh +ERROR_HERE +``` -### How can it be fixed? +### 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 index a9937bb7..419d7fd2 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,11 +1,21 @@ -### What was wrong? +## What was wrong? +Issue # +## How was it fixed? -### How was it fixed? +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/eth-abi/blob/master/newsfragments/README.md) + +[//]: # (See: https://eth-abi.readthedocs.io/en/latest/contributing.html#pull-requests) +- [ ] Add entry to the [release notes](https://github.com/ethereum/eth-abi/blob/master/newsfragments/README.md) #### Cute Animal Picture -![Cute animal picture]() +![put a cute animal picture link inside the parentheses]() diff --git a/.gitignore b/.gitignore index 311fdd39..0e057278 100644 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,8 @@ *.egg-info dist build -.eggs eggs +.eggs parts bin var @@ -18,19 +18,15 @@ develop-eggs .installed.cfg lib lib64 -venv +venv* # Installer logs pip-log.txt # Unit test / coverage reports -.mypy_cache .coverage -htmlcov/ .tox nosetests.xml -.cache -.pytest_cache # Translations *.mo @@ -46,9 +42,71 @@ output/*/index.html # Sphinx docs/_build +docs/modules.rst +docs/*.internal.rst +docs/*.utils.rst +docs/*._utils.* + +# Blockchain +chains -# Hypothesis +# Hypothese Property base testing .hypothesis -# Editors -*.swp +# 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 +*.sw[op] + +# mypy +.mypy_cache + +## 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/.project-template/fill_template_vars.sh b/.project-template/fill_template_vars.sh new file mode 100755 index 00000000..c9cb8261 --- /dev/null +++ b/.project-template/fill_template_vars.sh @@ -0,0 +1,49 @@ +#!/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 + "${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" diff --git a/.project-template/refill_template_vars.sh b/.project-template/refill_template_vars.sh new file mode 100755 index 00000000..6e7943fb --- /dev/null +++ b/.project-template/refill_template_vars.sh @@ -0,0 +1,2 @@ +TEMPLATE_DIR=$(dirname $(readlink -f "$0")) +<"$TEMPLATE_DIR/template_vars.txt" "$TEMPLATE_DIR/fill_template_vars.sh" diff --git a/.project-template/template_vars.txt b/.project-template/template_vars.txt new file mode 100644 index 00000000..4d9c6b2a --- /dev/null +++ b/.project-template/template_vars.txt @@ -0,0 +1,6 @@ +eth_abi +eth_abi +eth-abi +eth-abi +Ethereum Contract Interface (ABI) Utility +Python utilities for working with Ethereum ABI definitions, especially encoding and decoding diff --git a/.pydocstyle.ini b/.pydocstyle.ini new file mode 100644 index 00000000..0d40aa88 --- /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/LICENSE b/LICENSE index 8c67f6d0..d93175ab 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016 Piper Merriam +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/MANIFEST.in b/MANIFEST.in index 1109e8dc..fbff9807 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,8 @@ include LICENSE -include VERSION include README.md -include requirements.txt +include requirements-docs.txt + +global-include *.pyi recursive-exclude * __pycache__ recursive-exclude * *.py[co] diff --git a/Makefile b/Makefile index c15a83c2..01ed9ede 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ help: @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 "sdist - package" + @echo "dist - package" clean: clean-build clean-pyc @@ -24,14 +24,14 @@ clean-pyc: find . -name '*~' -exec rm -f {} + lint: - tox -e lint + tox -elint lint-roll: isort --recursive eth_abi tests $(MAKE) lint test: - py.test tests + pytest tests test-all: tox @@ -40,6 +40,9 @@ build-docs: sphinx-apidoc -o docs/ . setup.py 'eth_abi/utils/*' 'eth_abi/tools/*' 'tests/*' $(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 @@ -47,7 +50,22 @@ docs: build-docs linux-docs: build-docs xdg-open docs/_build/html/index.html +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 + 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 @@ -55,6 +73,6 @@ release: clean twine upload dist/* git config commit.gpgSign "$(CURRENT_SIGN_SETTING)" -sdist: clean +dist: clean python setup.py sdist bdist_wheel ls -l dist diff --git a/README.md b/README.md index 10c425d0..4909a7b5 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,77 @@ -# Ethereum Contract +# Ethereum Contract Interface (ABI) Utility +[![Join the chat at https://gitter.im/ethereum/eth-abi](https://badges.gitter.im/ethereum/eth-abi.svg)](https://gitter.im/ethereum/eth-abi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://circleci.com/gh/ethereum/eth-abi.svg?style=shield)](https://circleci.com/gh/ethereum/eth-abi) -[![Documentation Status](https://readthedocs.org/projects/eth-abi/badge/?version=latest)](https://readthedocs.org/projects/eth-abi/?badge=latest) -[![PyPi version](https://img.shields.io/pypi/v/eth-abi.svg)](https://pypi.python.org/pypi/eth-abi) +[![PyPI version](https://badge.fury.io/py/eth_abi.svg)](https://badge.fury.io/py/eth_abi) +[![Python versions](https://img.shields.io/pypi/pyversions/eth_abi.svg)](https://pypi.python.org/pypi/eth_abi) +[![Docs build](https://readthedocs.org/projects/eth-abi/badge/?version=latest)](http://eth-abi.readthedocs.io/en/latest/?badge=latest) + -Python utilities for working with the Ethereum ABI +Python utilities for working with Ethereum ABI definitions, especially encoding and decoding -## Installation +Read more in the [documentation on ReadTheDocs](https://eth-abi.readthedocs.io/). [View the change log](https://eth-abi.readthedocs.io/en/latest/releases.html). + +## Quickstart ```sh -pip install eth-abi +pip install eth_abi ``` -## Documentation +## Developer Setup + +If you would like to hack on eth-abi, please check out the [Snake Charmers +Tactical Manual](https://github.com/ethereum/snake-charmers-tactical-manual) +for information on how we do: -For documentation, visit [https://eth-abi.readthedocs.io/en/latest/](https://eth-abi.readthedocs.io/en/latest/). +- Testing +- Pull Requests +- Code Style +- Documentation -## Development +### Development Environment Setup -Clone the repository and then run: +You can set up your dev environment with: ```sh +git clone git@github.com:ethereum/eth-abi.git +cd eth-abi +virtualenv -p python3 venv +. venv/bin/activate pip install -e .[dev] ``` -You might want to do this inside a virtualenv. +### Testing Setup -### Running the tests +During development, you might like to have tests run on every file save. -You can run the tests with: +Show flake8 errors on file change: ```sh -py.test tests +# Test flake8 +when-changed -v -s -r -1 eth_abi/ tests/ -c "clear; flake8 eth_abi tests && echo 'flake8 success' || echo 'error'" ``` -Or you can install `tox` to run the full test suite. +Run multi-process tests in one command, but without color: -### Releasing - -Pandoc is required for transforming the markdown README to the proper format to -render correctly on pypi. +```sh +# in the project root: +pytest --numprocesses=4 --looponfail --maxfail=1 +# the same thing, succinctly: +pytest -n 4 -f --maxfail=1 +``` -For Debian-like systems: +Run in one thread, with color and desktop notifications: -``` -apt install pandoc +```sh +cd venv +ptw --onfail "notify-send -t 5000 'Test failure ⚠⚠⚠⚠⚠' 'python 3 test on eth-abi failed'" ../tests ../eth_abi ``` -Or on OSX: +### Release setup -```sh -brew install pandoc +For Debian-like systems: +``` +apt install pandoc ``` To release a new version: @@ -65,7 +86,9 @@ 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). If you are in a beta version, `make release bump=stage` will switch to a stable. diff --git a/docs/Makefile b/docs/Makefile index 8739119f..e9f4ffd9 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -87,9 +87,9 @@ qthelp: @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/EthereumAlarmClock.qhcp" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/eth_abi" @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/EthereumAlarmClock.qhc" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/eth_abi" applehelp: $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp @@ -104,8 +104,8 @@ devhelp: @echo @echo "Build finished." @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/EthereumAlarmClock" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/EthereumAlarmClock" + @echo "# mkdir -p $$HOME/.local/share/devhelp/eth_abi" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/eth_abi" @echo "# devhelp" epub: diff --git a/docs/_static/.suppress-sphinx-build-warning b/docs/_static/.suppress-sphinx-build-warning new file mode 100644 index 00000000..e69de29b diff --git a/docs/conf.py b/docs/conf.py index 0b6f242b..918c827b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# eth-abi documentation build configuration file, created by +# Ethereum Contract Interface (ABI) Utility 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 @@ -53,9 +53,8 @@ master_doc = 'index' # General information about the project. -project = 'eth-abi' -copyright = '2018, Piper Merriam ' -author = 'Piper Merriam ' +project = 'Ethereum Contract Interface (ABI) Utility' +copyright = '2020, The Ethereum Foundation' __version__ = setup_version # The version info for the project you're documenting, acts as replacement for @@ -210,8 +209,8 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ('index', 'eth_abi.tex', 'eth-abi Documentation', - 'Piper Merriam \\textless{}pipermerriam@gmail.com\\textgreater{}', 'manual'), + ('index', 'eth_abi.tex', 'Ethereum Contract Interface (ABI) Utility Documentation', + 'The Ethereum Foundation', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -240,8 +239,8 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'eth_abi', 'eth-abi Documentation', - ['Piper Merriam'], 1) + ('index', 'eth_abi', 'Ethereum Contract Interface (ABI) Utility Documentation', + ['The Ethereum Foundation'], 1) ] # If true, show URL addresses after external links. @@ -254,8 +253,8 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'eth-abi', 'eth-abi Documentation', - 'Piper Merriam', 'eth-abi', 'Python utilities for working with the Ethereum ABI', + ('index', 'Ethereum Contract Interface (ABI) Utility', 'Ethereum Contract Interface (ABI) Utility Documentation', + 'The Ethereum Foundation', 'Ethereum Contract Interface (ABI) Utility', 'Python utilities for working with Ethereum ABI definitions, especially encoding and decoding', 'Miscellaneous'), ] @@ -274,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/docs/index.rst b/docs/index.rst index 7ee331f9..df2f28ff 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,8 +1,3 @@ -.. Ethereum ABI Utils documentation master file, created by - sphinx-quickstart on Fri Feb 19 14:30:29 2016. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - Welcome to the eth-abi documentation! ===================================== @@ -34,11 +29,10 @@ Table of Contents grammar tools eth_abi - releases + release_notes Indices and Tables ------------------ * :ref:`API Glossary ` -* :ref:`modindex` diff --git a/docs/releases.rst b/docs/release_notes.rst similarity index 99% rename from docs/releases.rst rename to docs/release_notes.rst index 59929593..16f78379 100644 --- a/docs/releases.rst +++ b/docs/release_notes.rst @@ -1,6 +1,8 @@ Release Notes ============= +.. towncrier release notes start + v2.1.0 ------ diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 00000000..b0b93b95 --- /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 = False +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/newsfragments/139.bugfix.rst b/newsfragments/139.bugfix.rst new file mode 100644 index 00000000..72885e48 --- /dev/null +++ b/newsfragments/139.bugfix.rst @@ -0,0 +1,2 @@ +If subclassing :meth:`eth_abi.decoding.ContextFramesBytesIO.seek`, the new functionality was not +being used up by :meth:`~eth_abi.decoding.ContextFramesBytesIO.seek_in_frame`. Now it will be. diff --git a/newsfragments/140.internal.rst b/newsfragments/140.internal.rst new file mode 100644 index 00000000..7698aa58 --- /dev/null +++ b/newsfragments/140.internal.rst @@ -0,0 +1 @@ +Merged in project template, for changes in release scripts, docs, release notes, etc. diff --git a/newsfragments/README.md b/newsfragments/README.md new file mode 100644 index 00000000..09a10ddc --- /dev/null +++ b/newsfragments/README.md @@ -0,0 +1,27 @@ +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` +* `internal` +* `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. diff --git a/newsfragments/validate_files.py b/newsfragments/validate_files.py new file mode 100755 index 00000000..c0e9b289 --- /dev/null +++ b/newsfragments/validate_files.py @@ -0,0 +1,43 @@ +#!/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 +import sys + +ALLOWED_EXTENSIONS = { + '.bugfix.rst', + '.doc.rst', + '.feature.rst', + '.internal.rst', + '.misc.rst', + '.performance.rst', + '.removal.rst', +} + +ALLOWED_FILES = { + 'validate_files.py', + 'README.md', +} + +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 + 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 new file mode 100644 index 00000000..473f9695 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,42 @@ +[tool.towncrier] +# Read https://github.com/ethereum/eth-abi/newsfragments/README.md for instructions +package = "eth_abi" +filename = "docs/release_notes.rst" +directory = "newsfragments" +underlines = ["-", "~", "^"] +issue_format = "`#{issue} `__" + +[[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 = "internal" +name = "Internal Changes - for eth_abi contributors" +showcontent = true + +[[tool.towncrier.type]] +directory = "misc" +name = "Miscellaneous changes" +showcontent = false diff --git a/pytest.ini b/pytest.ini index 88b65163..9078cd92 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,5 +1,5 @@ [pytest] -addopts= -v --hypothesis-show-statistics --showlocals +addopts= -v --hypothesis-show-statistics --showlocals --durations 10 python_paths= . xfail_strict=true diff --git a/requirements-docs.txt b/requirements-docs.txt new file mode 100644 index 00000000..5c2e680d --- /dev/null +++ b/requirements-docs.txt @@ -0,0 +1 @@ +eth_abi[doc] diff --git a/setup.py b/setup.py index fae1f3b0..a5a60848 100644 --- a/setup.py +++ b/setup.py @@ -5,24 +5,13 @@ find_packages, ) +HYPOTHESIS_REQUIREMENT = "hypothesis>=3.6.1,<4" -def merge_lists(base_list, *other_lists): - new_list = base_list[:] - - for other_list in other_lists: - new_list.extend(i for i in other_list if i not in new_list) - - return new_list - - -HYPOTHESIS_REQUIREMENT = "hypothesis>=3.6.1" - -extras_require = {} -extras_require['tools'] = [ - HYPOTHESIS_REQUIREMENT, -] -extras_require['test'] = merge_lists( - [ +extras_require = { + 'tools': [ + HYPOTHESIS_REQUIREMENT, + ], + 'test': [ "pytest==4.4.1", "pytest-pythonpath>=0.7.1", "pytest-xdist==1.22.3", @@ -30,38 +19,47 @@ def merge_lists(base_list, *other_lists): "eth-hash[pycryptodome]", HYPOTHESIS_REQUIREMENT, ], - extras_require['tools'], -) -extras_require['lint'] = [ - "flake8==3.4.1", - "isort>=4.2.15,<5", - "mypy==0.620", -] -extras_require['doc'] = [ - "Sphinx>=1.6.5,<2", - "sphinx_rtd_theme>=0.1.9", -] -extras_require['dev'] = merge_lists( - [ + 'lint': [ + "flake8==3.4.1", + "isort>=4.2.15,<5", + "mypy==0.701", + "pydocstyle>=3.0.0,<4", + ], + 'doc': [ + "Sphinx>=1.6.5,<2", + "sphinx_rtd_theme>=0.1.9", + "towncrier>=19.2.0, <20", + ], + 'dev': [ "bumpversion>=0.5.3,<1", "pytest-watch>=4.1.0,<5", "wheel", "twine", "ipython", ], - extras_require['test'], - extras_require['lint'], - extras_require['doc'], +} + +extras_require['dev'] = ( + 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='eth-abi', - # *IMPORTANT*: Don't manually change the version here. Use the 'bumpversion' utility. + name='eth_abi', + # *IMPORTANT*: Don't manually change the version here. Use `make bump`, as described in readme version='2.1.0', - description="""Ethereum ABI Utils""", - long_description_markdown_filename='README.md', - author='Piper Merriam', - author_email='pipermerriam@gmail.com', + description="""eth_abi: Python utilities for working with Ethereum ABI definitions, especially encoding and decoding""", + long_description=long_description, + long_description_content_type='text/markdown', + author='The Ethereum Foundation', + author_email='snakecharmers@ethereum.org', url='https://github.com/ethereum/eth-abi', include_package_data=True, install_requires=[ @@ -69,7 +67,6 @@ def merge_lists(base_list, *other_lists): 'eth-typing>=2.0.0,<3.0.0', 'parsimonious>=0.8.0,<0.9.0', ], - setup_requires=['setuptools-markdown'], python_requires='>=3.6, <4', extras_require=extras_require, py_modules=['eth_abi'], @@ -84,8 +81,7 @@ def merge_lists(base_list, *other_lists): '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 :: Implementation :: PyPy', + 'Programming Language :: Python :: 3.7', ], ) diff --git a/tests/common/unit.py b/tests/common/unit.py index 9d34ebb1..afe7fa87 100644 --- a/tests/common/unit.py +++ b/tests/common/unit.py @@ -22,7 +22,8 @@ def make_word(description: str) -> bytes: 'leftpadchar<' or '>rightpadchar') and an optional byte width directive (e.g. '(4 wide)'). Generated words are 32 bytes wide by default. - Examples: + Examples + -------- >>> # Left padding examples >>> assert make_word('0>> assert make_word('f bytes: >>> # Right padding examples >>> assert make_word('deadbeef>0') == zpad32_right(b'\xde\xad\xbe\xef') >>> assert make_word('deadbeef>0 (8 wide)') == b'\xde\xad\xbe\xef\x00\x00\x00\x00' + """ match = WORD_DESC_RE.search(description) if match is None: @@ -57,9 +59,11 @@ def words(*descriptions: str) -> bytes: Converts multiple word descriptions into 32-byte words joined into a single byte string. - Examples: + Examples + -------- >>> assert words('1') == zpad32(b'\x01') >>> assert words('1', '2f>0') == zpad32(b'\x01') + zpad32_right(b'\x2f') + """ return b''.join(make_word(d) for d in descriptions) diff --git a/tests/core/conftest.py b/tests/core/conftest.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/core/test_import.py b/tests/core/test_import.py new file mode 100644 index 00000000..4157efb5 --- /dev/null +++ b/tests/core/test_import.py @@ -0,0 +1,4 @@ + + +def test_import(): + import eth_abi # noqa: F401 diff --git a/tox.ini b/tox.ini index 3e9e42e9..0647d1ec 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist= py{36,37}-core lint - doctest + docs [isort] combine_as_imports=True @@ -23,14 +23,14 @@ ignore= usedevelop=True commands= core: pytest {posargs:tests} - doctest: make -C {toxinidir}/docs doctest + docs: make build-docs basepython = - doctest: python + docs: python py36: python3.6 py37: python3.7 extras= test - doctest: doc + docs: doc whitelist_externals=make passenv=PYTEST_ADDOPTS @@ -38,6 +38,7 @@ passenv=PYTEST_ADDOPTS basepython=python extras=lint commands= + mypy --follow-imports=silent -p eth_abi.utils --config-file {toxinidir}/mypy.ini flake8 {toxinidir}/eth_abi {toxinidir}/tests isort --recursive --check-only --diff {toxinidir}/eth_abi {toxinidir}/tests - mypy --follow-imports=silent --ignore-missing-imports --check-untyped-defs --disallow-incomplete-defs -p eth_abi.utils + pydocstyle {toxinidir}/eth_abi {toxinidir}/tests