-
Notifications
You must be signed in to change notification settings - Fork 648
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
Refactor dependency handling #548
Refactor dependency handling #548
Conversation
You can run the tests with: | ||
A great way to explore the code base is to run the tests. | ||
|
||
We can run all tests with: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably worth an admonition here that naively running the full test suite is likely to take multiple hours to run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added:
However, running the entire test suite does take a very long time so often we just want to run a subset instead, like:
setup.py
Outdated
"aiohttp>=2.3.1,<3.0.0", | ||
"async_lru>=0.1.0,<1.0.0", | ||
"coincurve>=7.0.0,<8.0.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should not be part of the default py-evm
install. It requires a system dependency and we are working to avoid as many system dependencies for the base library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, so that explains the existing grouping that I couldn't make sense of 👍
However, I think I haven't fully grokked that yet.
It requires a system dependency and we are working to avoid as many system dependencies for the base library
So, if I get you right you want that the install_requires
(the ones taken into account for anyone running pip install py-evm
) dependencies to not include coincurve
, eth-hash
and plyvel
but still want these to be included for everyone running a pip install -e .[dev]
. Is that correct?
Do you mind elaborating a bit on that? I understand that we want to avoid system dependencies for the base library but if not installing these dependencies means that the evm doesn't work how would that help?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but still want these to be included for everyone running a
pip install -e .[dev]
. Is that correct?
Yes.
The reasoning for having pip install py-evm
install an absolute minimum number of requirements (and absolute minimal system requirements) is to make the base library very easy to install and use as a library with minimal assumptions about underlying things like what crypto implementations they want to use, what database backend they want to use, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if not installing these dependencies means that the evm doesn't work how would that help?
This is not the case. eth-keys
ships with a pure python backend for the ecc operations. coincurve
is just faster. Same with plyvel
. py-evm doesn't care about what database backend it uses and it does just fine with a minimal MemoryDB
.
So while trinity
doesn't work (or is slower) without these dependencies, the base library py-evm
does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah py-evm
has existing fallbacks for these libraries in case these are missing. That clears it up! 👍
setup.py
Outdated
"cryptography>=2.0.3,<3.0.0", | ||
"cytoolz>=0.9.0,<1.0.0", | ||
"eth-bloom>=1.0.0,<2.0.0", | ||
"eth-hash[pycryptodome]", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same, should not be part of the base py-evm
install.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved it into new evm-extras
section (see longer comment below)
setup.py
Outdated
"eth-utils>=1.0.1,<2.0.0", | ||
"plyvel==1.0.4", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same, should not be part of the base py-evm
install.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved it into new evm-extras
section (see longer comment below)
setup.py
Outdated
"pytest-logging>=2015.11.4", | ||
"pytest-xdist==1.18.1", | ||
"pytest-watch>=4.1.0,<5", | ||
"tox==2.7.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be part of the dev
requirements as the test
requirements would be what tox
installs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, moved it to dev
. 👍
setup.py
Outdated
], | ||
'test': [ | ||
"flake8==3.5.0", | ||
"mypy>=0.580", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should probably be under a separate lint
section so that in tox we can reduce the installation size for the linting and mypy runs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do that but considering that we cache all packages between runs anyway I wouldn't expect it to have a big impact on CI performance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Less about performance and more about isolation. Not a big deal but it matches the convention we've used elsewhere and I think I like the distinction.
setup.py
Outdated
"web3>=4.0.0b11,<5.0.0", | ||
], | ||
'test': [ | ||
"flake8==3.5.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should probably be under a separate lint
section so that in tox we can reduce the installation size for the linting and mypy runs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, it's now separated and the linting jobs also only require lint
as extras.
tox.ini
Outdated
p2p: p2p | ||
deps = -r{toxinidir}/requirements-dev.txt | ||
|
||
deps = .[dev] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yous can just change this to extras=dev
which is the slightly more semantically correct way to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was wrong with the extras as the were? They had a clean isolation of which dependencies to install for which tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the ideal setup, we shouldn't need to install the "developer" extra inside the test suite at all: https://github.com/ethereum/eth-account/blob/master/tox.ini#L32-L35
Specifically:
extras =
+ test
database: leveldb
trinity: trinity, p2p
rpc: trinity, p2p
p2p: p2p
-deps = -r{toxinidir}/requirements-dev.txt
Where the test
extra includes any backends that are needed by core libraries, I'm guessing: coincurve
, pycryptodome
for eth-hash, and plyvel
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One quirk that I never found an answer for: I'd like to specify eth-hash
as a primary dependency in a library like py-evm
and then specify an extra, such that py-evm[test]
depends on eth-hash[pycryptodome]
. The first few ways I've tried that didn't work as I expected, so I was stuck doing it as an explicit dependency outside the test extra, like:
https://github.com/ethereum/eth-utils/blob/03eabede3d55e2d00686d2b14bda0cb2148c63af/tox.ini#L14-L16
deps =
eth-hash[pycryptodome]
extras = test
This is a tradeoff that seems like the better option, but does have a downside:
- Explicit
eth-hash[pycryptodome]
intox.ini
- Bad: We have to specify the backend of choice twice: once in the tox file and once in setup.py. Changing the preferred backend means changing it twice (or more realistically: changing it once by accident, and hunting down a confusing bug from two slightly different environments)
- Good: We get to specify which major versions of pycryptodome that eth-hash supports inside eth-hash, so any changes in supported versions auto-propagate to all libraries that use eth-hash
- Specify
pycryptodome
version explicitly inpy-evm[test]
- Bad: if we need to change the supported versions of pycryptodome (say, they make a non-semver-compliant release, and we have to explicitly exclude some minor version), then all libraries that depend on eth-hash will be broken until we go tweak the lib.
- Good: the backend is only specified once in
py-evm
so we eliminate the class of bugs from the first approach
Since a breakage in the first one only affects this one library (py-evm), and the second one affects all libraries depending on eth-hash, the first one seems the clear winner. (unless we have a strong reason to believe that one kind of breakage is orders of magnitude less likely than the other)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pipermerriam now that I refactored the CI runs to not depend on the dev
dependencies anymore the trinity tests are missing ipython
. Is trinity supposed to have a hard dependency against ipython by default (e.g. putting it into the trinity
section directly) or should that go into something like trinity-extras
(somewhat reasonable I believe since one can also run trinity with --vanilla-shell
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember seeing a conversation that concluded that we should be opinionated and require ipython for trinity. (since the shell is part of the "UI" of trinity, and it gives a better shell experience)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, yay for uncovering missing dependencies with the more isolated tox setup! 🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe anyone who runs pip install py-evm does expect this to install evm, p2p and trinity fully to the point that no further manual installs are needed. At least for now that p2p and trinity are part of this package.
Fair enough. This mostly just makes me eager to split trinity out into its own repo for real (but we're not there right now).
So, if I understand you correctly you are saying that if you specify eth-hash as install_requires you can not overwrite it in an extra with eth-hash[pycryptodome]?
That was my experience, but I don't know for sure. It was one of those things that didn't just work and I didn't have time to investigate if it was travis or tox or pip.
As soon as you don't have deps anymore the extras didn't seem to have an effect.
That's super-weird and feels broken. Heck, that might have even been the cause of the previous problem. If that's trivially reproducible, that sounds like a fairly straightforward thing to file a bug against tox for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's super-weird and feels broken
Yep, in fact it really felt broken because it sometimes seemed to work for one run and then failed for another whereas .deps[x,y,z]
worked reliably every single time.
Heck, that might have even been the cause of the previous problem
Yes, that might be it.
If that's trivially reproducible, that sounds like a fairly straightforward thing to file a bug against tox for
I can investigate that further another time 😬
2f3a5cc
to
10b542d
Compare
This is to not waste more computational CI resources on linting than necessary. Fixes ethereum#551
10b542d
to
2f912f4
Compare
Alright, I just updated this again and made iPython a base dependency of trinity. I also added one more commit to this PR and combined |
Looks like this reduced our build time by about 7 minutes 🎉 |
What was wrong?
If one follows the current development instructions, one is left with a system that doesn't have all needed dependencies installed (See #538 )
How was it fixed?
This PR is based on #546 because it also updates the documentation which I couldn't get to work without #546.
Basically this PR follows the pattern that @carver already uses for
eth-account
. Maybe I implemented it with a tiny twist but it seemed most logical to me.The gist of it goes like this.
requirements-dev.txt
andrequirements-doc.txt
are no moresetup.py
there's a dictionary of dependencies with dependencies grouped asevm
,p2p
,trinity
,tests
,docs
anddev
.dev
group automatically includes all others which means there is nothing else to run apart frompip install -e .[dev]
to get all dependencies that are needed to run, develop, test and release anything related to this repository.Let me finish with my usual disclaimer that I'm still quite new to Python and have no idea what I'm doing so please be nice in case this turns out as utter nonsense. 😅
Cute Animal Picture