Every time I need to produce a Python package I spend a lot of time searching for what should be put in a modern setup.py file, since there is so many old examples that still use distutils. I thus decided to put here a decent example of such file, in the hope that it is useful to my future self and to others.

# setup.py
import setuptools

# Use as long description of the project the README file
with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="my-package-name",
    version="0.1.2",
    author="Name Surname",
    author_email="my-email@example.com",
    # In case of maintainer: `maintainer` and `maintainer_email` fields
    description="A short description of the package",
    long_description=long_description,
    # Remember to change the content-type if your README file is in another format
    long_description_content_type="text/markdown",
    # The URL for the package source code
    url="https://github.com/USER/PACKAGE_PATH.git",
    # Packages has a list of the folders and files you want to include
    packages=["my_package_name"],
    zip_safe=False,
    # Optional keywords separated by spaces
    keywords="cool-things packages",
    # Requirements for installation of the package
    install_requires=[
        "other-package-name",
        "cool-package >= 0.3, < 0.5",
        "unpublished-package @ git+https://github.com/organization/repository@commit_sha_or_branch",
    ],
    # If you use nose2 for the tests
    test_suite="nose2.collector.collector",
    # Dependencies to run the tests
    tests_require=["nose2"],
    # Include other files in the zip, otherwise we cannot read README.md
    # The files to include are to be written in MANIFEST.in file, one per line
    include_package_data=True,
    # Other licenses: BSD / MIT
    license="GPL-3.0",
    # Optional requirements on Python version
    python_requires='>=3.6',
    # Optional entry points, useful for declaring scripts
    entry_points={
        "console_scripts": [
            "my_script=my_package_name.cli:main",
        ],
    },
    # Optional extras features mapping to requirements
    extras_require={
        "s3": ["botocore"],
    },
)

Let me know if there are some errors, or if you think an useful field is missing.