Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ABI types fully specified #222

Merged
merged 23 commits into from
Mar 18, 2022
Merged

Make ABI types fully specified #222

merged 23 commits into from
Mar 18, 2022

Conversation

jasonpaulos
Copy link
Contributor

@jasonpaulos jasonpaulos commented Mar 2, 2022

Problem

Currently the ABI types Tuple and StaticArray are not fully specified from only their type signature. Tuple has no generic arguments, and StaticArray lacks a generic argument for length. This causes a problem when used to define a subroutine that accepts these types, since the exact types the subroutine should accept is underspecified. For example:

def mySubroutine(a: abi.Tuple, b: abi.StaticArray[abi.Uint64]):
    pass

Solution

The solution is to make all type-level arguments "generic" arguments, like so:

from typing import Literal

def mySubroutine(a: abi.Tuple2[abi.Uint8, abi.Uint64], b: abi.StaticArray[abi.Uint64, Literal[10]]):
    pass

In order to support this usage, the TypeSpec class and subclasses were introduced. These classes are responsible for containing the information necessary to instantiate a type, such as the value types of a tuple.

Related to this change, many methods that were defined on Type (refactored to BaseType in this PR) have been changed to methods on TypeSpec to emphasize that they don't depend on a specific value of an ABI type.

This PR also introduces, but does not use, the function type_spec_from_annotation, which can transform an annotation like abi.StaticArray[abi.Uint64, Literal[10]] into the corresponding TypeSpec object, which in this case would be abi.StaticArrayTypeSpec(abi.Uint64TypeSpec(), 10).

A note about Tuples

Until Python 3.11 is released with support for PEP 646 -- Variadic Generics, it's not possible to parameterize abi.Tuple with an arbitrary number of generic types. As a workaround, I've created the subclasses abi.Tuple0, abi.Tuple1, ..., abi.Tuple5 which take a fixed number of generic parameters. These should be used instead of the base abi.Tuple class when you need to fully specify a tuple in a type annotation.

It could make sense to add more classes like this to support larger tuples, but I thought 5 was enough for now.

Progress

  • Implementation
    • Type
    • Tuple
    • Uint types
    • Bool
    • StaticArray
    • DynamicArray
  • Tests
    • Fix existing tests
    • Satisfy mypy
    • Consider new tests & replace assertions in code

@jasonpaulos jasonpaulos changed the title Make ABI types indexable Make ABI types fully specified Mar 2, 2022
Copy link
Contributor

@ahangsu ahangsu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Waiting on array implementations, largely looks good by now

pyteal/ast/abi/uint.py Outdated Show resolved Hide resolved
pyteal/ast/abi/tuple.py Outdated Show resolved Hide resolved
Copy link
Contributor

@ahangsu ahangsu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array part looks largely good to me

pyteal/ast/abi/tuple.py Outdated Show resolved Hide resolved
@jasonpaulos jasonpaulos marked this pull request as ready for review March 14, 2022 23:51
pyteal/ast/abi/tuple.py Outdated Show resolved Hide resolved
pyteal/ast/abi/bool.py Outdated Show resolved Hide resolved
pyteal/ast/abi/bool.py Outdated Show resolved Hide resolved
pyteal/ast/abi/uint.py Outdated Show resolved Hide resolved
pyteal/ast/abi/uint.py Outdated Show resolved Hide resolved
pyteal/ast/abi/array_base.py Show resolved Hide resolved
return self.stored_value.load()

@abstractmethod
def length(self) -> Expr:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: I would like to propose length renamed as elem_num or array_length for readability...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is an array I think length makes the most sense, but I'm open to other ideas. For context, this is how I imagine it would be used:

myArray = abi.DynamicArray[abi.Uint64](abi.Uint64TypeSpec())

i = ScratchVar(TealType.uint64)
program = Seq(
    myArray.decode(Txn.application_args[1]),
    For(i.store(Int(0)), i.load() < myArray.length(), i.store(i.load() + Int(1))).Do(
        myArray[i.load()].use(lambda value: Assert(value.get() == Int(7)))
    ),
    Approve(),
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am fine with the proposed syntax, just one funny thing noticed on first line: seems we still need to pass typespec for array argument in initialization. We should probably keep in mind to optimize that later (if possible)

pyteal/ast/abi/array_static.py Show resolved Hide resolved
pyteal/ast/abi/util.py Show resolved Hide resolved
pyteal/ast/abi/tuple_test.py Outdated Show resolved Hide resolved
Copy link
Contributor

@michaeldiamant michaeldiamant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jasonpaulos Thanks for the effort here - Leaving approval with these notes:

  • Understandably, the PR presents a big diff. I feel like I went as far as I reasonably could in my review. And I think usage in subsequent PRs will help us figure out subsequent modifications.
  • I'm assuming we'll make a pass at PEP 8 naming conventions in feature/abi at a later date. Consequently, I did not attempt to provide convention feedback.

Copy link
Contributor

@ahangsu ahangsu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can merge it in as is right now.

As we proceed in using this, we might optimize/modify them later.

Co-authored-by: Michael Diamant <[email protected]>
@jasonpaulos jasonpaulos merged commit bfaf1c1 into feature/abi Mar 18, 2022
@jasonpaulos jasonpaulos deleted the abi-indexable-types branch March 18, 2022 22:07
jasonpaulos added a commit that referenced this pull request Jul 22, 2022
* ABI Types (#154)

* initial commit to be used for reference and comparison

* Fmt

* move abi to ast

* make tuple return the deocded Tuple

* rename collections, fixed some of the mypy issues

* Fix mypy issues

* remove Literal

* add str method for abi type names

* fix names

* make imports nice

* make imports nice

* make collections generic

* rm param spec

* lie to mypy

* make dynamic array work

* [WIP] Make Add and Mul NaryExprs

* ABI refactor

* Implement decoding

* Make arrays encode to a single value

* Make types mutable

* Proof of concept map implementation

* Remove old comment

* Update Uint16 limit check

Co-authored-by: Giorgio Ciotti <[email protected]>

* provide a method to know the type name (#176)

* Refactor array implementation

* Add ComputedType and fix bug in map

* Add more int types and bool support

* Add string method

* Remove files for features that won't make it into this PR

* Remove Array.map 😢

* Make decode more powerful

* Uint bounds checking and tests

* Remove random line

* Bool tests and bugfixes

* Allow uint and bool set to copy another type

* Begin tuple and array tests, improve dynamic tuple encoding, and remove Array.forEach

* Test indexTuple and fix bugs

* Fix field shadowing

* Finish tuple tests and type tests

* Implement static and dynamic array tests

* Finish testing abi types and fix tuple encoding bug

* Add generic param to new instances of arrays

* Address feedback

* Fix tuple decoding issue

* Fix uint64 decoding test

* minor improvement to distinguish abi.Byte and abi.Uint8 (#194)

* Add docstrings to abi.Type

* Respond to feedback

* Respond to feedback & fix bug

* Fix indexTuple bug

* Add docs for TealBlock methods

* ABI Array docstrings and comments (#216)

Co-authored-by: Jason Paulos <[email protected]>
Co-authored-by: Giorgio Ciotti <[email protected]>
Co-authored-by: Hang Su <[email protected]>

* Merge with master and regenerate `__index__.pyi` (#224)

* Fix build script invocation (#223)

* Regen __init__.pyi

* Reorder CI build steps to change source files before running tests (#225)

Co-authored-by: Michael Diamant <[email protected]>

* Merge #227 into feature/abi (#231)

* Fix build script invocation (#223)

* Bring #225 to master (#227)

* Ignore tests generating TEAL file outputs used for expected comparisons (#228)

* Fix typo in CONTRIBUTING.md (#229)

Co-authored-by: Jason Paulos <[email protected]>

* Make ABI types fully specified (#222)

* Convert Type and Tuple to indexable types

* Convert and combine uint types

* Fix type and unit tests

* Convert Bool

* Fix Tuple getitem

* Convert arrays and array tests

* Fix tuple tests

* [WIP] satisfy mypy

* Refactor ABI types

* Update docs, add Tuple4 and Tuple5, and change type_spec method name

* No longer test on Python 3.6 and 3.7

* No longer test on Python 3.6 and 3.7

* Remove accidentally included file

* Add another literal test case

* Debugging through CI

* blacken

* Remove problematic test case

* Minor test coverage improvements

* Unit test to make sure type_spec_from_annotation always works on all types

* Partially address feedback

* Make uint8 != byte and use typing.Final in a few constructors

* Undo custom set methods

* Fix typo

Co-authored-by: Michael Diamant <[email protected]>

Co-authored-by: Michael Diamant <[email protected]>

* Passing ABI type arguments to Subroutine (#263)

- passing ABI variables into subroutine
- subroutine type annotations with ABI types

* ABI Method Return (#175)

Encode ABI variable and concat with `RETURN_METHOD_SELECTOR` and log it.

* Allow `ComputedType` to be passed to the `set` method on ABI types (#267)

* update minor support for setting ComputedType

* minor tweak

* backwards for 3.8 on subscriptable type

* attempt to test uint set

* minor

* cleanup

* update arrays, tuple to test

* tuple testing

* update documents

* resolving comments

* py3.10 less go

* python typing annotations

* Merge branch 'master' into feature/abi (#284)

* Move to pyteal as pt in ABI tests with concise  prefix (#286)

* ABI Strings (#278)

* Move to pyteal as pt in #278 (#287)

* Merge absolute imports into feature/abi (#288)

* Remove temporary I252 ignore on pyteal.ast.abi (#290)

* Fix abi import (#303)

* Fix abi import

* ignore flake8

* Feature/abi merge master again (#310)

Following major changes:
* Merge in Blackbox testing
* replace `SubroutineDefinition. _arg_types_and_by_refs()` by `SubroutineDefinition._validate()`
* add abi cases to `subroutine_test.py::test_validate()`

* merge conflicts

* merge again

* wip

* pass all tests after resolving conflicts

* Add `set` on address and string, change array init to accept typespec (#289)

* adding set on String and Address types

* Add convenience `make` method for ABI types (#326)

* Add make method for abi types

* Respondn to feedback

* ABI Type subroutine return (#256)

* wtf

* update

* update to f-str

* define void type

* update instantiated computed type returnedType for ABI return in subroutine

* minor

* update stuffs to help infer type annotation of return ABI

* minor

* minor

* minor

* minor

* minor

* try my best to save stuffs

* simplify decorator to single function

* tear it down

* minor

* sheeeesh emacs

* updates

* minor, renaming something

* new design, start over

* updates

* abi fn wrapper for now

* minor

* minor update on subroutine def

* minor fixes

* minor fixes

* changes

* more constraint on void ret

* update comment examples

* import from abi

* update some error msg and comments

* testcases partial

* upgrade testscripts

* Bundle optional refactorings to subroutine.py (#308)

* Bundle optional refactorings to subroutine.py

* Refactor to remove branching

* storing local changes

* pr review partly

* pr review partly

* update test script

* Abi subroutine feature merge (#315)

* resolve conflicts

* lint

* minor reconstruct

* missing imports

* missing requirements from bad merge

* cooperate with typespec n var def change

* update comments

* some comments resolving?

* trim

* update some comments

* bring testcase back

* restriction on output kwarg name

* stop ci! i am reformatting

* simplify name constrain

* resolving comments

* Use deferred subroutine expression for ABI returns (#328)

* Add subroutine deferred expr

* Allow multiple deferred blocks

* Remove error

* flake8

* Make test more realistic

* Add second test

* clean up code and comments

* remove deferred blocks function

* Add coverage for multiple ops in block error

* hack return from abi var

* a hack

* better returned type

* simplify

* add some compiler test

* flake break no way

* PR comment resolve partial

* polishing

Co-authored-by: Michael Diamant <[email protected]>
Co-authored-by: Zeph Grunschlag <[email protected]>
Co-authored-by: Zeph Grunschlag <[email protected]>
Co-authored-by: Jason Paulos <[email protected]>

* adding byte type hint to DyanamicArray parent class (#339)

* adding byte type hint to DyanamicArray parent class

* appease mypy

* specify Byte in set method instead of T

* Define level of support provided for ABIReturnSubroutine (#341)

* Testing ABI Functionality via Graviton / Dry-runs + Txn Friendly Graviton Logic Sig Example (#322)

# Blackbox Testing ABI Functionality
This PR brings in dry-run testing of ABI types and subroutines. The space of ABI-Functionality that needs testing is large, and this PR doesn't purport to provide full coverage. However, the basic tools are provided to obtain greater coverage in the future. The following specific ABI use cases are tested:

* abi_sum() which computes the sume of a DynamicArray
* integers and complex integer number (Gassian integers) are built up from basic types and basic operations are validated
* round-trip encoding and decoding of a number of ABI types

# Testing Logic Sigs which interact with their Payment Transaction
#249 introduced examples/signature/factorizer_game.py which includes a family of logic sigs that provide a payout that depends on the solution to an algebra puzzle. With a recent improvement to graviton we can now run blackbox tests on this logic sig family, and gain confidence in its correctness. See tests/integration/pure_logicsig_test.py for how this is done.

* abi_roundtrip_test::test_abi_types_comprehensive() (#355)

* adding sizeof util (#358)

* adding size_of util

* Reference Types (#361)

* adding reference types to ABI types

* Clearer Comment (#364)

* Clearer Comment and link comment to issue #184

* Bug: Graviton's report no longer has last_rows (#365)

* adding deref type to get the underlying value of the reference type (#372)

* `ABI Router` implementation and test (#170)

* init commit

* minor

* minor

* rm decorator

* update ABI router design, seems we are still working on previous design

* minor

* update condition parser here

* skeleton for handler wrapping, need to tweak on subroutine to expose more message

* module

* use subroutine fn wrapper

* update dummy method return class

* unify ast construct way

* minor

* update notes for tasks and todos

* update handler wrapping for bare app call

* minor

* update redirecting args to method registered

* minor

* minor

* update router src

* update program node

* add questions in build prog

* update executing method branch

* minor

* minor

* minor

* hide other methods, set MethodAppArgNumLimit, keyword args on exposed register func, skeleton for arg de-tuple

* minor

* update notes

* update

* add a default for no registered ast gen

* update ast construction to conds

* need some documentations

* move abi-router in abi dir

* minor

* wtf

* update

* update to f-str

* define void type

* update instantiated computed type returnedType for ABI return in subroutine

* minor

* update stuffs to help infer type annotation of return ABI

* minor

* minor

* minor

* minor

* minor

* try my best to save stuffs

* simplify decorator to single function

* tear it down

* minor

* sheeeesh emacs

* update with latest abi impl

* minors

* minor

* updates

* minor, renaming something

* new design, start over

* updates

* abi fn wrapper for now

* minor

* minor update on subroutine def

* minor fixes

* minor fixes

* changes

* more constraint on void ret

* update comment examples

* import from abi

* update some error msg and comments

* testcases partial

* upgrade testscripts

* merging feature/abi to abi-router (#305)

* merging feature/abi

* missed one

* make router use absolute imports

* linter happy?

* Export Router (#306)

* Merge branch 'master' into feature/abi (#284)

* Move to pyteal as pt in ABI tests with concise  prefix (#286)

* ABI Strings (#278)

* Move to pyteal as pt in #278 (#287)

* Merge absolute imports into feature/abi (#288)

* Remove temporary I252 ignore on pyteal.ast.abi (#290)

* Fix abi import (#303)

* Fix abi import

* ignore flake8

* move router to ast

Co-authored-by: Michael Diamant <[email protected]>
Co-authored-by: Jason Paulos <[email protected]>

* fix spacing issue

* Bundle optional refactorings to subroutine.py (#308)

* Bundle optional refactorings to subroutine.py

* Refactor to remove branching

* storing local changes

* pr review partly

* pr review partly

* update test script

* Abi subroutine feature merge (#315)

* resolve conflicts

* lint

* minor reconstruct

* missing imports

* missing requirements from bad merge

* cooperate with typespec n var def change

* update comments

* some comments resolving?

* trim

* update some comments

* bring testcase back

* restriction on output kwarg name

* stop ci! i am reformatting

* squash merge abi subroutine atm, merge again after abi subroutine into feature/abi

* conform to pep8, reconstructing

* update json generator

* simplify name constrain

* resolving comments

* Use deferred subroutine expression for ABI returns (#328)

* Add subroutine deferred expr

* Allow multiple deferred blocks

* Remove error

* flake8

* Make test more realistic

* Add second test

* clean up code and comments

* remove deferred blocks function

* Add coverage for multiple ops in block error

* updating wrap handler

* change how to de-tuple args

* update checkbox

* minor

* bug fixes

* Method sig for router (#340)

* adding method_signature to ABIReturnSubroutine

* minor, renaming

* minor

* simplify

* compiler test adding...

* documentation

* start testcases

* update router testcase

* docstring tweak

* update testcases

* update testcases

* formatting

* branch cond testing

* router contract test

* subroutine branch wrapper bare call case tested

* more testcases to barecall

* minor, need to work on method call wrapper

* half done on method call wrapper

* update on abi method wrapper with return

* detuple testcase

* compiler test need to see csp

* rm redundant type annotation

* more error msg

* renaming

* renaming is_registrable -> is_abi_routable

* reording imports, eliminate anti patterns

* remove anti-pattern

* section it out

* non_empty_power_set -> power_set

* add conflict detection to protect AST from overshadowing

* error message

* shrinked commits on pr review

* add compile_program

* fixup subroutine testcase

* remove method signature specifying, directly infer from ABIReturnSubroutine

* remove method sign field, directly infer from ABIReturnSubroutine

* relaxation of bare app call arg num restriction

* add barecall class, api change following

* rename barecall to OnCompleteAction

* remove outdated comments

* start changing router api

* eliminate contradiction for oc and creation

* remove restriction on cond

* new interface: add bare-calls on init, register method-call more fine-grained

* documentation for new interface from last discussion

* Refactor #170 to reduce visibility and mutation (#362)

* Refactor to use partition

* Designate _oc_under_call_config as private

* hide wrap handler method

* adding comment changes

* pr review partly

* partition into two methods

* hide all these methods

* arc4 compliant CallConfigs classmethod

* arc4 compliant CallConfigs documentation

* disclaimer comments

* update new abi return hash prefix

* review comments partly

* OnCompleteActions -> BareCallActions

* disclaimer change, rename CallConfigs -> MethodConfig

* disclaimer move to docstring

* better naming for naming prefix

* new ast builder

* review comments

* An attempt to add decorator syntax to abi-router (#370)

* an attempt to use decorator

* no return, or we will have python-level issue?

* minor fix

* per pr comment on on-complete-action

* eliminate potential issue

* update call config testcase

* add testcase for on complete action

* per comments

* Add a check in `method_signature` to disallow reference return types (#368)

* new ast builder

* adding check in method_signature to raise error if its attempted to be called on method with reference type as return value

* use type spec instead of str

* adding recursive type checking method and using it in subroutine method signature

* Adding one more test case for extra nesting

* appease the linter

Co-authored-by: Hang Su <[email protected]>

* add new compiler tests for router

* fix one test for wrapping bare calls

* comments fixing

* simplified oc-action post_init check

* naming variables

* comments

* comments

* testcase for method config update

* add router method only in clearstate prog

* closeout -> clearstate

* removing is_arc4_compliant

* update add method handler and method interface

* remove arc4_compliant

* Add manual test for 15+ args in abi router (#375)

Co-authored-by: Ben Guidarelli <[email protected]>
Co-authored-by: Michael Diamant <[email protected]>
Co-authored-by: Jason Paulos <[email protected]>
Co-authored-by: Zeph Grunschlag <[email protected]>
Co-authored-by: Zeph Grunschlag <[email protected]>

* Adding method_spec to ABIReturnSubroutine (#380)

* adding method_spec to ABIReturnSubroutine

* Txn types (#376)

* Add transaction abi types

* Blackbox testing unifying abi-return-subroutine and subroutine input handling (#374)

* unify subroutine case and abi-returning-subroutine

* reconstruct code on argument prep and call

* an example subroutine taking in abi arguments

* update comment example and explanation

* per pr comment

* Changes to router clear state (#386)

* define reference type spec (#383)

* define reference type spec
Co-authored-by: Jason Paulos <[email protected]>
Co-authored-by: Zeph Grunschlag <[email protected]>

* Rename decode parameters to abide by PEP8 conventions (#389)

* More abi graviton tests (#391)

* test_conditional_factorial()

* Router return subroutine (#422)

* Adding return value to add_method_call

* Method call itxn (#387)

* adding itxn method to call ABI method

* __str__ formatting (#411)

* standardize str formatting

* Check transaction type arguments (#427)

* Check transaction type arguments

* Rename Transaction.set to be private

* Check `Expr` length when converting to `abi.Address` (#432)

* Fix on previous address length check (#433)

* minor fix

* minor

* per Jason comment

* minor, formatting

* unit -> uint (#434)

* Support declaring compatible PyTeal version in source code (#429)

* Add semantic version dependency

* Add `pragma` to enforce compatible compiler versions

* Raise `TealInternalError` instead of `TealInputError`

* Switch back to `pkg_resources` and convert PEP 440 to semantic version 2.0.0

* Fix linter errors

* Make pep 440 converter private

* Add `Pragma` expression

* Refactor pragma functions from compiler to ast to avoid circular dependencies
* Add `is_valid_compiler_version` check helper for the `Pragma` expression
* Use `TealProgramError` instead of `TealInternalError`

* Test underlying TEAL is unchanged

* Refactor underlying pragma methods to parent directory

* Inherit from `Expr` instead

* Fix unclear docstring

* Document init

Document init

* Add caret compiler version tests

* Ignore unused fixture imports

* Consistently use `start_index` and `end_index` (#436)

* Consistently use start_ and end_index

* format

* allow passing router description to Contract constructor (#448)

* allow passing router description to Contract constructor

* Document new ABI features (#400)

* Initial commit

* Fix abi-docs tests (#402)

* Fix abi-docs Sphinx warnings (#401)

* Extend abi-docs with experimental design language (#403)

* Add type fundamentals section

* Add basic type usage and some docstrings for referenced methods

* Finish documenting set and fix overloaded method docs

* Add docstrings for get and __getitem__

* Add reference type docs

* Add txn type examples

* Fix errors

* Make ComputedValue parameter type covariant

* ComputedValue and subroutine sections

* ...wasn't included in previous commit

* Add bare app call and method registration examples

* Add router e2e example and compilation explanation

* Fix post-merge linter/test failures

* Add calling documentation

* Partially address feedback

* Respond to feedback

* Resolve TODOs

* Add pragma references

* didn't make it into the previous commit

* Fix Bool.__module__

* Mention stack size limit

* More pragma documentation

* Address other feedback

* Warn about reference type limits

* **cannot**

Co-authored-by: Michael Diamant <[email protected]>

* Feature/abi merge master (#457)

* Clarify minimum Python version management docs (#435)

* Foreign prefix on App and Asset arrays (#440)

* replacing foreignapps with applications

* fix assets as well

* Add Execute Method (#444)

* adding execute method to allow omission of begin/submit for common use case

* exec docstring

* update testcase

Co-authored-by: Hang Su <[email protected]>

Co-authored-by: Michael Diamant <[email protected]>
Co-authored-by: Ben Guidarelli <[email protected]>
Co-authored-by: Hang Su <[email protected]>

* `abi.Bool` improvements (#453)

* abi.Bool improvements

* Don't need Seq anymore

* nor its import

* No black, that was not a tuple

* modify integreation tests

* missed one

* Missed a file

* Rename pyteal/ast/abi/bool.py functions to follow PEP 8 conventions (#459)

* Specify dependency versions (#464)

* Rename pyteal/ast/abi/util.py functions to follow PEP 8 conventions (#460)

* Rename pyteal/ast/abi/tuple.py functions to follow PEP 8 conventions (#461)

* Fix typos in pyteal/ast/abi/util.py (#467)

* Rename encoded_string to demarcate internal usage (#466)

* Rename pyteal/ast/abi method parameters to follow PEP 8 conventions (#468)

Co-authored-by: Ben Guidarelli <[email protected]>
Co-authored-by: Jason Paulos <[email protected]>
Co-authored-by: Giorgio Ciotti <[email protected]>
Co-authored-by: Hang Su <[email protected]>
Co-authored-by: Hang Su <[email protected]>
Co-authored-by: Zeph Grunschlag <[email protected]>
Co-authored-by: Zeph Grunschlag <[email protected]>
Co-authored-by: Jacob Daitzman <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants