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?