Having the mess of different blog posts and documentation sources saying different stuff is far from ideal though. If you can't sum up the process in a clear concise way you are far from done.
Having the mess of different blog posts and documentation sources saying different stuff is far from ideal though. If you can't sum up the process in a clear concise way you are far from done.
What prevents the pip from a normal CPython installation from doing an install?
You can even bootstrap pip via the ensurepip module documented at https://docs.python.org/3/library/ensurepip.html which notes "This module does not access the internet. All of the components needed to bootstrap pip are included as internal parts of the package."
Can you do that without setuptools or similar?
> Can you do that without setuptools or similar?
Sure.
Here is a program which, when run, creates the zipfile "hello-1.0-py3-none-any.whl" containing the wheel for a package named "hello" along with an entry point for the command-line program also named "hello"
# Create a wheel for a 'Hello, world!' Python package.
#
# To install:
# pip install hello-1.0-py3-none-any.whl
#
# To use on the command-line:
# hello
#
# To use from Python:
# >>> import hello
# >>> hello.main()
# Hello, world!
#
# To uninstall:
# pip uninstall hello
import base64, hashlib, zipfile
package_name = "hello"
version = "1.0"
# This will go in hello/__init__.py
payload = """
def main():
print("Hello, world!")
"""
METADATA = f"""\
Metadata-Version: 2.1
Name: {package_name}
Version: {version}
Summary: Example of a hand-built wheel.
Home-page: http://news.ycombinator.com/
Author: eesmith
Author-email: eesmith@example.com
License: Public Domain
Platform: UNKNOWN
UNKNOWN
"""
# This causes the installer to create the command-line 'hello' program.
entry_points = """\
[console_scripts]
hello = hello:main
"""
WHEEL = """\
Wheel-Version: 1.0
Generator: eesmith_wheelgen (0.0.0)
Root-Is-Purelib: true
Tag: py3-none-any
"""
top_level = f"""
{package_name}
"""
def build():
wheel_name = f"{package_name}-{version}-py3-none-any.whl"
with zipfile.ZipFile(wheel_name, "w") as zip:
dist_info = f"{package_name}-{version}.dist-info"
# Add a file and build up information needed for the RECORD .
record_lines = []
def add_file(filename, content):
with zip.open(filename, "w") as f:
byte_content = content.encode("utf8")
f.write(byte_content)
digest = hashlib.sha256(byte_content).digest()
encoded = base64.urlsafe_b64encode(digest).rstrip(b"=")
record_line = f"{filename},sha256={encoded},{len(byte_content)}\n"
record_lines.append(record_line.encode("utf8"))
add_file(f"{package_name}/__init__.py", payload)
add_file(f"{dist_info}/METADATA", METADATA)
add_file(f"{dist_info}/WHEEL", WHEEL)
add_file(f"{dist_info}/entry_points.txt", entry_points)
add_file(f"{dist_info}/top_level.txt", top_level)
with zip.open(f"{dist_info}/RECORD", "w") as f:
f.writelines(record_lines)
if __name__ == "__main__":
build()But, okay, you want to install a package you wrote, using only a stock Python installation.
1) Why? That is, you can modify your PYTHONPATH to include your working directory.
2) Why use an installer? For simple packages you can drop the file/directory into site-packages.
3) I've been using Python for long enough that I distributed Python packages before there was a setup.py or setuptools. I used a Makefile.
In fact, I still use a Makefile when I need faster build cycle times as setup.py does not do good dependency management.
4) I showed you how to build a wheel using only stock Python code, which lets you use pip as the installer.
Finally, with a source distribution you can tweak Python's own Makefile to build your own module, including a C extension: https://docs.python.org/3/extending/extending.html#compilati...
Why don't any of these resolve your issue?