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
Fixup some importing stuff. #20
Conversation
Uh, why? It works fine as it is. |
We at Mercurial (hg) will like to use cbor for serializing and deserializing data for our state files. We cannot rely on users installing libraries using pip and we need to vendor the library ourselves. Imports were not working relatively. For reference: I might be doing something wrong there, feel free to point that out. |
This sounds like something your vendorization script needs to do. From my perspective, this PR only adds useless cruft to the codebase. |
Okay, no worries. Thanks for reviewing. |
This PR doesn't "add cruft." It net adds 4 non-empty lines: all of them Secondly, this PR changes imports so they are relative instead of absolute. There are no regressions as a result of this change. However, there is a meaningful improvement! That improvement is that downstream consumers of Python packages using relative imports can rename packages without the package breaking. When absolute imports are used, modules MUST be available at the absolute name specified. I concede that in most Python environments, packages are at their original, intended name. However, there are Python applications (like Mercurial) that may wish to vendor Python packages in local namespaces such that there is no ambiguity between the package provided by the local application and the package that may happen to be installed on the local machine. If a standalone Python application (like Mercurial) performed an |
While I acknowledge that the changes are trivial, I felt that the problem was being solved from the wrong end. I've been involved in the development of core packaging tools (pip, setuptools) which have to vendor packages since, by virtue of being the very tools used to install those packages, they can't expect them to be available. Can you explain to me what makes Mercurial so special that it cannot simply declare the appropriate dependencies? |
I can't say if this makes Mercurial "so special," but our perspective is that of an application where Python is an implementation detail. Unlike most Python packages where the target audience is Python developers, our audience is general users - users without Python skills. Because of this, we don't want to require our users to know anything about Python or Python packaging. If they get a copy of Mercurial, it should "just work." We can and do distribute Mercurial as a standalone application with a distributed copy of Python embedded. Here, we have total control over the environment and could install packages under their proper names. However, Mercurial is also distributed as a Python package. And in these environments we don't have full control over the Python environment. Mercurial could be running as a global Python package, as part of a virtualenv, etc. There's no way of knowing what other Python packages are present. Having Mercurial rely on non-vendored packages or packages picked up from the /outer/ Python environment is risky for a number of reasons. The most reliable behavior is to have Mercurial ensure it always imports a local, vendored copy of Python packages. Furthermore, Mercurial supports extensions. Those extensions could have dependencies on other Python packages. There could be a scenario where an extension wishes to use a different version of a Python package from the one Mercurial is using. This can happen in environments using the system package manager to install Mercurial where Mercurial is somewhat old and an extension may wish to use a newer version of a Python package than what Mercurial is bundling. Again, having Mercurial reference a local, vendored copy of a package under a Mercurial-specific name avoids conflicts with other Python code. I hope that provides some context. |
Alright, but what is |
|
This was requested by Mercurial developers to facilitate vendoring. See #20 for the discussion.
I just pushed a commit which switches to relative imports but I left out the |
@agronholm Thanks for the commit. If you are interested, @indygreg started a thread on python-dev related to this https://mail.python.org/pipermail/python-dev/2018-March/152446.html |
Switched from absolute to relative imports This was requested by Mercurial developers to facilitate vendoring. See agronholm#20 for the discussion.
Switched from absolute to relative imports This was requested by Mercurial developers to facilitate vendoring. See agronholm#20 for the discussion.
…gronholm#31) Solution: Encode to base16 string and then decode to bytes. * Most performant big integer encodings for 2.7 and >=3.2 Problem: Bug agronholm#15, CBOR maps can contain unhashable types as keys Solution: Use a context manager for decoding keys and set items which makes sure to use a hashable type. Also indefinite length bytestring decoding returns bytes() instead of bytearray(). Fixes for flake8 tests Problem: HashableMap is unclear and bogus Solution: Make it clear we are creating an immutable type and call it FrozenDict to be like the builtin frozenset() Remove premature optimization Add a test for nested immutable maps Test should verify a value that is not nested in a key uses mutable type Whitespace fixes Add tests for unused magic methods on FrozenDict An extra space is a terrible thing Fixing merge conflict: Switched from absolute to relative imports This was requested by Mercurial developers to facilitate vendoring. See agronholm#20 for the discussion. Make the immutable flag a read-only property and document it's use Added FrozenDict to encoder for roundtrip decode->encode Minor whitespace fix
This PR adds
from __future__ import absolute_import
to files and make the imports relative.