-
Notifications
You must be signed in to change notification settings - Fork 336
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
Pip improvements #667
Pip improvements #667
Conversation
-much better pip->rez requirement conversion -much better pip->rez specifier conversion -much better management of extras and env markers -more accurate variants, which include reqs that they should -'packaging' vendor lib imports updated (were broken) -'packaging' lib used more widely -correctly manage differing cases of extras usage
I am working on a test-suite to test with lots of packages. Already found a kind of peculiar issue.
While the resulting path is only invalid on windows it seems, the variant still does not really make sense to me on first sight. Needs more investigation. The shell error may be solved by hashed variants i guess? |
Looking at the package (thanks @lambdaclan for the support on that one!) It seems the variant is indeed correct. That seems to work fine for pytest (and also for using the resulting package). |
Adding some info for reference (pytest) dist-info metadata
Rez pip now handles these:
and creates the variants accordingly but it leads to invalid paths unless hashed variants are used. setup.py
generated package
|
Yeah I expected this, didn't get a chance to mention.
So, hashed variants do work currently. The only downside is that the
variant 'handle' used to define the variant is still integer-based, but
that needs to be updated so it's based on the hash instead. It's still
ok-ish as it is today, but it'd be more robust under all conditions if it
were hash-based. This is a feature I need to get to soon.
I wonder if we should just enabled hashed variants on rez-pipified
packages. Thorsten if you've tested this and it seems to work, perhaps it's
good to go. It would solve the variant problem..
A
…On Fri, Jul 19, 2019 at 6:46 PM Ira ***@***.***> wrote:
Adding the dist-info metadata for reference (pytest)
Requires-Python: >=2.7, !=3.0., !=3.1., !=3.2., !=3.3.
Requires-Dist: py (>=1.5.0)
Requires-Dist: six (>=1.10.0)
Requires-Dist: packaging
Requires-Dist: attrs (>=17.4.0)
Requires-Dist: atomicwrites (>=1.0)
Requires-Dist: pluggy (<1.0,>=0.12)
Requires-Dist: importlib-metadata (>=0.12)
Requires-Dist: wcwidth
Requires-Dist: funcsigs (>=1.0) ; python_version < "3.0"
Requires-Dist: pathlib2 (>=2.2.0) ; python_version < "3.6"
Requires-Dist: more-itertools (<6.0.0,>=4.0.0) ; python_version <= "2.7"
Requires-Dist: more-itertools (>=4.0.0) ; python_version > "2.7"
Requires-Dist: colorama ; sys_platform == "win32"
Provides-Extra: testing
Requires-Dist: argcomplete ; extra == 'testing'
Requires-Dist: hypothesis (>=3.56) ; extra == 'testing'
Requires-Dist: nose ; extra == 'testing'
Requires-Dist: requests ; extra == 'testing'
Requires-Dist: mock ; (python_version == "2.7") and extra == 'testing'
Rez pip now handles these:
Requires-Dist: funcsigs (>=1.0) ; python_version < "3.0"
Requires-Dist: pathlib2 (>=2.2.0) ; python_version < "3.6"
Requires-Dist: more-itertools (<6.0.0,>=4.0.0) ; python_version <= "2.7"
Requires-Dist: more-itertools (>=4.0.0) ; python_version > "2
and creates the variants accordingly but it leads to invalid paths unless
hashed variants are used.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#667>,
or mute the thread
<https:/notifications/unsubscribe-auth/AAMOUSXI7CTTWGLP22GFPRLQAF5NRANCNFSM4IFCTS2A>
.
|
I am in the progress of testing this against a bigger set of pip packages, will report on methodology asap. I do see another weird error that i can not reliably reproduce or track down. When installing packages i sometimes get the following:
So far it has always been these three (or a subset). I am not always getting it or at least fail to find the packages calling this. Every time i call rez-pip only on the packages that seem to call this it works :( If anyone has ideas or pointers that would be really welcome. (Windows of course). |
Note to self: hey, so I found a problem. There was something odd in the original rez-pip code and I didn't know why it was there... now I know |
# Conflicts: # src/rez/utils/_version.py
Fix for case sensitivity issues added |
So I've been thinking about it.. unless there are any objections, I think I'm going to just enable hashed variants on all rez-pipified packages, since that solves the varianting issue (ie ranges such as >N ending up in the variant root path, now that we're correctly constructing variants). I'll also add some custom attributes such as |
That will also give hashed variants some thorough testing! I agree. |
You know it also just struck me that it's a bit of a feat that simply setting |
-use hashed variants in rez-pip -added some pip-specific metadata to package.py
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.
So as promised, here is my code review. Hope my comments make sense.
src/rez/utils/pip.py
Outdated
rez_req_str = pip_to_rez_package_name(packaging_req.name) | ||
|
||
if packaging_req.specifier: | ||
range_ = pip_specifier_to_rez_requirement(str(packaging_req.specifier)) |
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.
packaging.requirements.Requirements.specifier
returns a SpecifierSet
that can be list
'ed. That would save you the split at line https:/nerdvegas/rez/pull/667/files#diff-7dd5a0607b04e979c35f51b0122edf36R212
requirements.extend(_get_dependencies(requirement, distributions)) | ||
|
||
# get list of package and dependencies | ||
distributions = list(distribution_path.get_distributions()) |
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 is already done at line 236. Or does it have to do with the "moving bin folder to expected relative location as per wheel RECORD files" ?
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 think this was just missed after code reorg (moving stuff into utils.pip). Will fix
src/rez/utils/pip.py
Outdated
if pkg_version.release: | ||
# the components of the release segment excluding epoch or any | ||
# prerelease/development/postrelease suffixes | ||
rez_version += '.'.join(str(i) for i in pkg_version.release) |
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 think you can use the base_version
attribute here, like pkg_version.base_version
.
>>> packaging.version.parse('1.0.3rc2.post345.dev456+ubuntu-1').base_version
'1.0.3'
src/rez/utils/pip.py
Outdated
`VersionRange`: Equivalent rez version range. | ||
""" | ||
ranges = [] | ||
parts = specifier.split(',') |
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 you passed the SpecifierSet
as mentioned lower, you could simply do list(specifier)
. packaging
will take care of removing all spaces.
Also, by passing the specifier set object, I think we could benefit from the packaging API here. For example, list
on a SpecifierSet
returns specifiers, from which you can get the operator with .operator
and the version with .version
. From the version we can do packaging.version.Version(v)
and then use the methods to know if it's a pre/post release for example. We might still have to do some endswith
but at least we will do way less than we do right now.
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'm getting to this soon - yeah I'll redo this using native SpecifierSet as it looks like that'll simplify things
src/rez/utils/pip.py
Outdated
if "Windows" in platform.system(): | ||
# https:/nerdvegas/rez/pull/659 | ||
ver_str = subprocess.check_output( | ||
pip_exe + " -V", |
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 might want to do python -m pip
instead. That way we could be sure which pip will be used. I would even go one step further and use sys.executable
to get the path to the correct python (only in the case where we use the system's pip of course).
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 code needs to be updated actually.. currently it causes pip to be run from outside of its rez context (if rezified pip was found), which is completely wrong. I'm gonna fix this quite soon so ignore this for now. I'll make it part of this PR though.
On that note, sys.executable would only get used if no rezified pip packages was found (but yes I agree that it should be used in that case, and that pip exe shouldn't be used directly).
src/rez/utils/pip.py
Outdated
|
||
for req in reqs: | ||
# skip if env marker is present and doesn't evaluate | ||
if req.marker and not req.marker.evaluate(): |
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 have to admit that I'm confused here. Tell me if I have understood everything:
At this point, the extras have been removed from the marker. So the marker should only contain a python version and a platform?
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.
The marker can refer to a number of things - platform, python, os (see https://www.python.org/dev/peps/pep-0508/#id24). I'm not sure what you are getting at though? The marker might specify python-3, and we might be running python-2.7, in which case the req should be skipped.
In any case, I think I see a problem - the marker is going to get evaluated wrt current python interpreter, even though a rezified pip may have been used (and thus, a potentially different python version). We do avoid a lot of potential problems if the system pip (ie the one rez gets installed with) is only ever used, but then you're restricted to rez-pipping only for that version of python.
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 could override the python version all the time with the one we are running under or the one specified when rez-pip
was invoked. So basically always do:
req.marker.evaluate(
environment={
"python_full_version": str(python_version),
"python_version": str(python_version.trim(2)),
"implementation_version": str(python_version)
}
)
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.
Yeah you read my mind, was hoping it was possible to do this way and looks like it is, cheers.
if "os" in sys_requires: | ||
sys_variant_requires.append("os-%s" % _system.os) | ||
|
||
if "python" in sys_requires: |
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.
Is this if necessary?
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 think it's cleaner to have it here, even though python is always a requirement. Then all the code that deals with converting a simple list of system requirements, into a more specific list, is all in the one place. Especially as later, it may get more complex and may not just default to python-MAJOR.MINOR.
src/rez/utils/pip.py
Outdated
|
||
rez_version = "" | ||
|
||
if pkg_version.release: |
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 condition cannot be false right?
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 it can be, for versions like (eg) 1.a2, which is a pre-release, not a release.
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.
Actually, this can only happen if the version is a legacy version, like a2
or 2.0b1pl0
. If it's 1.a2
, the release would be 1
. But that also means it would need the allow_legacy=True
, which mean it would never reach this line. See https:/pypa/packaging/blob/master/packaging/version.py#L92
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 yup I see, removing
src/rez/utils/pip.py
Outdated
|
||
raise PackageRequestError( | ||
"Don't know how to convert PEP440 specifier %r into rez equivalent", | ||
specifier |
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 gives an error: TypeError: __init__() takes at most 2 arguments (3 given)
. It looks like you use the "lazy logger" technic her, which doesn't work for exceptions 😛 .
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.
Fixed in #693
src/rez/utils/pip.py
Outdated
|
||
# the components of the release segment excluding epoch or any | ||
# prerelease/development/postrelease suffixes | ||
rez_version = pkg_version.base_version |
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.
Umm, I'm sorry but that introduces a bug. I thought the base version would be enough, but it includes the epoch... So we will need to go back to the previous version of the code. Sorry about that.
Ah cheers, haven't rerun the tests yet, thx
…On Mon, Aug 19, 2019 at 12:14 PM Jean-Christophe Morin < ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/rez/utils/pip.py
<#667 (comment)>:
> + if isinstance(pkg_version, packaging_LegacyVersion):
+ if allow_legacy:
+ print_warning(
+ "Invalid PEP440 version detected: %r. Reverting to legacy mode.",
+ pkg_version
+ )
+ # this will always be the entire version string
+ return pkg_version.base_version.lower()
+ else:
+ raise packaging_InvalidVersion(
+ "Version: {} is not compatible with PEP440.".format(dist_version)
+ )
+
+ # the components of the release segment excluding epoch or any
+ # prerelease/development/postrelease suffixes
+ rez_version = pkg_version.base_version
Umm, I'm sorry but that introduces a bug. I thought the base version would
be enough, but it includes the epoch... So we will need to go back to the
previous version of the code. Sorry about that.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#667>,
or mute the thread
<https:/notifications/unsubscribe-auth/AAMOUSSEJYGIHP5RJ6IXYA3QFH6WVANCNFSM4IFCTS2A>
.
|
src/rez/utils/pip.py
Outdated
"sys.platform": [_plat], | ||
"sys_platform": [_plat], | ||
|
||
"os.name": [_os], |
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.
Thinking about it even more, os.name
can return posix
(Linux, OSX, etc), nt
(Windows) or java
(Jython). We can't do much about Jython, but for the others, it's basically the platform, not the OS (OS would add a dependency on the arch).
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.
Do you know of a reference anywhere that lists valid os.name values? I'll
update this with a comment.
They are, here: https://docs.python.org/3/library/os.html#os.name
https://docs.python.org/3/library/platform.html#platform.system
These are the values I know that are mentioned in the docs.
Do you know of a reference anywhere that lists valid os.name values? I'll
update this with a comment.
…On Mon, Aug 19, 2019 at 12:18 PM Jean-Christophe Morin < ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/rez/utils/pip.py
<#667 (comment)>:
> + _os = "os"
+
+ sys_requires_lookup = {
+ # TODO There is no way to associate a python version with its implementation
+ # currently (ie CPython etc). When we have "package features", we may be
+ # able to manage this; ignore for now
+ "implementation_name": [_py],
+ "implementation_version": [_py],
+ "platform_python_implementation": [_py],
+ "platform.python_implementation": [_py],
+ "python_implementation": [_py],
+
+ "sys.platform": [_plat],
+ "sys_platform": [_plat],
+
+ "os.name": [_os],
Thinking about it even more, os.name can return posix (Linux, OSX, etc),
nt (Windows) or java (Jython). We can't do much about Jython, but for the
others, it's basically the platform, not the OS (OS would add a dependency
on the arch).
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#667>,
or mute the thread
<https:/notifications/unsubscribe-auth/AAMOUSSMPBXALZWUI3LG3LTQFH7GFANCNFSM4IFCTS2A>
.
|
Pls ignore.. I see that it maps to python os.name.
A
…On Mon, Aug 19, 2019 at 12:22 PM Allan Johns ***@***.***> wrote:
Do you know of a reference anywhere that lists valid os.name values? I'll
update this with a comment.
On Mon, Aug 19, 2019 at 12:18 PM Jean-Christophe Morin <
***@***.***> wrote:
> ***@***.**** commented on this pull request.
> ------------------------------
>
> In src/rez/utils/pip.py
> <#667 (comment)>:
>
> > + _os = "os"
> +
> + sys_requires_lookup = {
> + # TODO There is no way to associate a python version with its implementation
> + # currently (ie CPython etc). When we have "package features", we may be
> + # able to manage this; ignore for now
> + "implementation_name": [_py],
> + "implementation_version": [_py],
> + "platform_python_implementation": [_py],
> + "platform.python_implementation": [_py],
> + "python_implementation": [_py],
> +
> + "sys.platform": [_plat],
> + "sys_platform": [_plat],
> +
> + "os.name": [_os],
>
> Thinking about it even more, os.name can return posix (Linux, OSX, etc),
> nt (Windows) or java (Jython). We can't do much about Jython, but for
> the others, it's basically the platform, not the OS (OS would add a
> dependency on the arch).
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <#667>,
> or mute the thread
> <https:/notifications/unsubscribe-auth/AAMOUSSMPBXALZWUI3LG3LTQFH7GFANCNFSM4IFCTS2A>
> .
>
|
-minor code redundancy removal
# Conflicts: # src/rez/utils/_version.py
Ok, I've merged in those tests and updated wrt PR changes here. Everything looks good. Give it a whirl and let me know how you go. If there aren't any problems ten I'll merge to master tomorrow. Comprehensive tests btw! Would also be good to have a rez-pip install happen from the test installed_distributions dir also; you mention this should be possible but I don't know the details just yet. Thx |
I have a first issue here. Have yet to investigate, but if i rez-pip install pip as a package rez-pip failes afterwards:
|
For me, having pip as a rez package should be prohibited as it's actually searching for quite a lot of trouble... But anyway. Did you get this error while running |
I wonder though: Don't we need pip as a rez package in order to allow installing python-3.x packages with rez-pip? |
Hmm, so I've rez-pip'd pip before, and used the resulting pip, and it's
worked. I'll have a look at this.
Wrt whether this makes sense - absolutely it does. Whatever version of
python/pip rez itself has been installed with should be incidental, it
should have no bearing on how other packages are getting built. So whilst
it's convenient to pip-install packages using python-2.7, and rez's
2.7-based pip, it's also completely feasible that you'd want to pip-install
a python-3.x package... and vice versa.
A
…On Tue, Aug 20, 2019 at 4:49 AM Thorsten Kaufmann ***@***.***> wrote:
rez-pip install pip worked fine, but all subsequent calls to rez-pip then
fail. It tries to find_pip and fails when pip is present as a rez package
it seems.
I wonder though: Don't we need pip as a rez package in order to allow
installing python-3.x packages with rez-pip?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#667>,
or mute the thread
<https:/notifications/unsubscribe-auth/AAMOUSXNWTBLBMQSP43GCGLQFLTLDANCNFSM4IFCTS2A>
.
|
I can `rez-pip -i pip`, then do further `rez-pip -i X`. It uses the
rezified pip and everything seems fine. Perhaps it's a Windows issue...
what happens specifically?
A
…On Tue, Aug 20, 2019 at 8:50 AM Allan Johns ***@***.***> wrote:
Hmm, so I've rez-pip'd pip before, and used the resulting pip, and it's
worked. I'll have a look at this.
Wrt whether this makes sense - absolutely it does. Whatever version of
python/pip rez itself has been installed with should be incidental, it
should have no bearing on how other packages are getting built. So whilst
it's convenient to pip-install packages using python-2.7, and rez's
2.7-based pip, it's also completely feasible that you'd want to pip-install
a python-3.x package... and vice versa.
A
On Tue, Aug 20, 2019 at 4:49 AM Thorsten Kaufmann <
***@***.***> wrote:
> rez-pip install pip worked fine, but all subsequent calls to rez-pip
> then fail. It tries to find_pip and fails when pip is present as a rez
> package it seems.
>
> I wonder though: Don't we need pip as a rez package in order to allow
> installing python-3.x packages with rez-pip?
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <#667>,
> or mute the thread
> <https:/notifications/unsubscribe-auth/AAMOUSXNWTBLBMQSP43GCGLQFLTLDANCNFSM4IFCTS2A>
> .
>
|
I did a bit of research. We have a central python that is added to path through a wrapper. What happens is that rez falls back to this python executable when in a context. So if it finds the package, it somehow picks up the wrong python on the PATH. I will investigate further. If i wipe this central python from PATH it works as expected (note though that the central python is on path AFTER the local one). |
Okay, so the problem is related to system PATH vs. user PATH on windows. This only breaks if there is an additional python on the system path it seems. So for THIS ticket it can be considered out of scope. I will make an issue to track this down as it seems to be more of a general cmd issue. |
In a normal python environment, pip is installed per python installation, either with --ensurepip (for python 2) when compiling python, by default in python 3 there is already pip installed, or by using the So to answer your question, if you would want to install python 3 packages, you would just have to call
When I'm saying that we shouldn't need a |
That would mean that rez-pip depends on specifically locally installed python interpreters that also need to have ensure pip. Wouldn't it be more stable/predictable to have a dependency on a standard pip package as installed by rez-pip itself? |
I have finished my testing and have good news and bad news. Good news first: Here are the remaining ones that did work with pip but not rez-pip:
I have not done thorough investigations yet, but mysql-python is giving me a headache straight away. I called it the same way that rez-pip does ( |
I can probably help with some suggestions for why some of these might fail. Most likely, in some of these cases, you're seeing compilations fail, which are going to depend on finding an appropriate compiler on the host system, or appropriate flags to compile against other rezified pip or unrelated packages. Some also do not declare a dependency on a system-level devel library being installed, which is unfortunate. There are also several packages which, in their setup.py, declare additional dependencies not a part of the pip-fetchable metadata. I can get a larger list of examples of these later, but a typical example is a need for vcversioner or setuptools_scm or pytest_runner. In addition, we have a tool internally that has (at least until this work here can be more directly finished) supplanted rez-pip, which can be supplied an argument like "--links" that specifies packages to which CXXFLAGS / CFLAGS / LDFLAGS are meant to be appended at compile time, so that, for example, a rezified scipy can find and link to a rezified numpy at compile time, when building from a tarball and not just relying on wheels (The vast majority of our packages are compiled from source. Probably 99%+ of all packages that provide an sdist, as a direct result of this ability). I have more ideas, but this is a good starter list of the most common reasons. |
I am fine if they fail in pip, then failure of rez-pip is a given. Just the ones that fail in rez-pip but work in pip are a concern. I could check a few more of the list. I started the test in a different shell and forgot to wipe PIP_INDEX_URL which made it pull internal wheels for some of these packages. With these off the list rez-pip installed all but 2 packages (!!), The only ones that fail with rez-pip are
|
context = None | ||
else: | ||
raise | ||
# fall back on system pip |
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.
Before falling back to system (so virtualenv's python), I would try to get the latest python version (if python was not provided) available as a rez package and assume that there might be pip installed into it. If this fails too, then fallback to rez's virtualenv pip.
Would that make sense?
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 my latest comment addresses this - as in yes we would change things to be expecting python package to provided pip, and would be checking for this before falling back to rezified pip, then to system pip (and rezified pip just for backwards compatibility - current users could very well have python without pip, and rezified pip).
Ah yes that makes sense. So what I would propose is to first assume that python itself provides pip, and only fall back to searching for a rezified pip if that is not the case. Really the reason to do this is just for backwards compatibility. I think I'd rather do this in a separate PR though, as this one is dragging on, and the current behavior already (erroneously as @JeanChristopheMorinPerso points out) expects rezified pip. I would aim to do this directly after merging this PR, and probably will not do a release in the meantime. How does that sound? |
That's good for me. |
Our existing pip integration had some fairly major shortcomings, hopefully this PR addresses many of them.
Main issues addressed: