Hacker News new | past | comments | ask | show | jobs | submit login

Python removed distutils… basically now there is no official way to install things.



The Python documentation says "pip is the preferred installer program. Starting with Python 3.4, it is included by default with the Python binary installers." - https://docs.python.org/3/installing/index.html#installing-i...


Except that pip doesn't actually do the install part, you need some other module for that.


I do not understand your comment. What module are you talking about?

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."


How do create a package that can be installed using pip?

Can you do that without setuptools or similar?


Right, but creating a package is not the same as installing a package, and your comment at https://news.ycombinator.com/item?id=38083296 concerned installing.

> 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()


Surely you can't install a package if you first can't create it?


You can easily install a third-party package, which will bootstrap you to one way to create package.

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?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: