Giter VIP home page Giter VIP logo

jupyter-packaging's Introduction

Jupyter Packaging

⚠️ We recommend using Hatch Jupyter Builder instead of Jupyter Packaging for new and existing projects. See the blog post Packaging for Jupyter in 2022.

About

Tools to help build and install Jupyter Python packages that require a pre-build step that may include JavaScript build steps.

Install

pip install jupyter-packaging

Usage

There are three ways to use jupyter-packaging in another package. In general, you should not depend on jupyter_packaging as a runtime dependency, only as a build dependency.

As a Build Requirement

Use a pyproject.toml file as outlined in pep-518. An example:

[build-system]
requires = ["jupyter_packaging>=0.10,<2"]
build-backend = "setuptools.build_meta"

Below is an example setup.py using the above config. It assumes the rest of your metadata is in setup.cfg. We wrap the import in a try/catch to allow the file to be run without jupyter_packaging so that python setup.py can be run directly when not building.

from setuptools import setup

try:
    from jupyter_packaging import wrap_installers, npm_builder
    builder = npm_builder()
    cmdclass = wrap_installers(pre_develop=builder, pre_dist=builder)
except ImportError:
    cmdclass = {}

setup(cmdclass=cmdclass))

As a Build Backend

Use the jupyter_packaging build backend. The pre-build command is specified as metadata in pyproject.toml:

[build-system]
requires = ["jupyter_packaging>=0.10,<2"]
build-backend = "jupyter_packaging.build_api"

[tool.jupyter-packaging.builder]
factory = "jupyter_packaging.npm_builder"

[tool.jupyter-packaging.build-args]
build_cmd = "build:src"

The corresponding setup.py would be greatly simplified:

from setuptools import setup
setup()

The tool.jupyter-packaging.builder section expects a func value that points to an importable module and a function with dot separators. If not given, no pre-build function will run.

The optional tool.jupyter-packaging.build-args sections accepts a dict of keyword arguments to give to the pre-build command.

The build backend does not handle the develop command (pip install -e .). If desired, you can wrap just that command:

import setuptools

try:
    from jupyter_packaging import wrap_installers, npm_builder
    builder = npm_builder(build_cmd="build:dev")
    cmdclass = wrap_installers(pre_develop=builder)
except ImportError:
    cmdclass = {}

setup(cmdclass=cmdclass))

The optional tool.jupyter-packaging.options section accepts the following options:

  • skip-if-exists: A list of local files whose presence causes the prebuild to skip
  • ensured-targets: A list of local file paths that should exist when the dist commands are run

As a Vendored File

Vendor setupbase.py locally alongside setup.py and import the module directly.

import setuptools
from setupbase import wrap_installers, npm_builder
func = npm_builder()
cmdclass = wrap_installers(post_develop=func, pre_dist=func)
setup(cmdclass=cmdclass)

Usage Notes

  • This package does not work with the deprecated python setup.py bdist_wheel or python setup.py sdist commands, PyPA recommends using the build package (pip install build && python -m build .).
  • We recommend using include_package_data=True and MANIFEST.in to control the assets included in the package.
  • Tools like check-manifest or manifix can be used to ensure the desired assets are included.
  • Simple uses of data_files can be handled in setup.cfg or in setup.py. If recursive directories are needed use get_data_files() from this package.
  • Unfortunately data_files are not supported in develop mode (a limitation of setuptools). You can work around it by doing a full install (pip install .) before the develop install (pip install -e .), or by adding a script to push the data files to sys.base_prefix.

Development Install

git clone https://github.com/jupyter/jupyter-packaging.git
cd jupyter-packaging
pip install -e .[test]
pre-commit install

You can test changes locally by creating a pyproject.toml with the following, replacing the local path to the git checkout:

[build-system]
requires = ["jupyter_packaging@file://<path-to-git-checkout>"]
build-backend = "setuptools.build_meta"

Note: you need to run pip cache remove jupyter_packaging any time changes are made to prevent pip from using a cached version of the source.

jupyter-packaging's People

Contributors

adamjstewart avatar afshin avatar astrofrog avatar blink1073 avatar dsblank avatar ellert avatar ellisonbg avatar fcollonval avatar frenzymadness avatar github-actions[bot] avatar gnestor avatar hroncok avatar jasongrout avatar jmsdnns avatar jnahmias avatar jtpio avatar maartenbreddels avatar manics avatar meggycal avatar mgorny avatar minrk avatar pre-commit-ci[bot] avatar timkpaine avatar vidartf avatar videlec avatar willingc avatar xmnlab avatar zsailer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jupyter-packaging's Issues

jupyterlab extension package installs fail with 0.9.1

This command:

jupyter labextension install @jupyterlab/server-proxy

exits with the following error:

---> Running in d4a404eceeb0
/srv/conda/envs/notebook/lib/python3.8/site-packages/setuptools/distutils_patch.py:25: UserWarning: Distutils was imported before Setuptools. This usage is discouraged and may exhibit undesirable behaviors or errors. Please use Setuptools' objects directly or at least import Setuptools first.
  warnings.warn(
Traceback (most recent call last):
  File "/srv/conda/envs/notebook/bin/jupyter-labextension", line 5, in <module>
    from jupyterlab.labextensions import main
  File "/srv/conda/envs/notebook/lib/python3.8/site-packages/jupyterlab/__init__.py", line 7, in <module>
    from .labapp import LabApp
  File "/srv/conda/envs/notebook/lib/python3.8/site-packages/jupyterlab/labapp.py", line 15, in <module>
    from jupyterlab_server import slugify, WORKSPACE_EXTENSION
  File "/srv/conda/envs/notebook/lib/python3.8/site-packages/jupyterlab_server/__init__.py", line 4, in <module>
    from .app import LabServerApp
  File "/srv/conda/envs/notebook/lib/python3.8/site-packages/jupyterlab_server/app.py", line 7, in <module>
    from jupyter_server.extension.application import ExtensionApp, ExtensionAppJinjaMixin
  File "/srv/conda/envs/notebook/lib/python3.8/site-packages/jupyter_server/__init__.py", line 15, in <module>
    from ._version import version_info, __version__
  File "/srv/conda/envs/notebook/lib/python3.8/site-packages/jupyter_server/_version.py", line 9, in <module>
    version_info = get_version_info(__version__)
  File "/srv/conda/envs/notebook/lib/python3.8/site-packages/jupyter_packaging/setupbase.py", line 248, in get_version_info
    version_info = [parsed.major, parsed.minor, parsed.micro]
AttributeError: 'Version' object has no attribute 'major'

I think this was introduced in bb68c88#diff-505fa72595b8bee2cea07dead97c94c69a07bb84219e5d66ddb579cffe0bee6c.

I can reproduce this behavior of pkg_resources with just plain python:

>>> from pkg_resources import parse_version
>>> ver = parse_version('0.1.1')
>>> ver.major
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Version' object has no attribute 'major'
>>> ver = parse_version('v0.1.1')
>>> ver.major
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Version' object has no attribute 'major'
>>> 

Warning while running tests

I see this warning when running tests/test_skip_if_exists.py:

$ pytest tests/test_skip_if_exists.py
============================================================================== test session starts ==============================================================================
platform linux -- Python 3.8.6, pytest-4.6.11, py-1.10.0, pluggy-0.13.1
rootdir: ~/devel/jupyter-packaging
plugins: anyio-2.0.2
collected 2 items                                                                                                                                                               

tests/test_skip_if_exists.py ..                                                                                                                                           [100%]

=============================================================================== warnings summary ================================================================================
tests/test_skip_if_exists.py:7
  ~/devel/jupyter-packaging/tests/test_skip_if_exists.py:7: PytestCollectionWarning: cannot collect test class 'TestCommand' because it has a __init__ constructor (from: tests/test_skip_if_exists.py)
    class TestCommand(BaseCommand):

-- Docs: https://docs.pytest.org/en/latest/warnings.html
===================================================================== 2 passed, 1 warnings in 0.09 seconds ======================================================================

Can this be fixed not to produce a warning and finish with a fully clean run?

Switch to Github Actions?

Any objection to switching to GA for CI? The travis/appveyor combination is moving a little slow for my liking :)

package_data_spec not supported anymore?

Being able to pass a package_data_spec to create_cmdclass was quite handy to be able to include package_data as part of the wheel, but it seems to me that it's not supported anymore, or maybe I am missing something?

`ensure_python` should use pypa packaging utilities

Specifically, we should be using the same logic that setuptools is using to parse python_requires, even if we allow a list of arguments to be passed in.

That ends up calling SpecifierSet packaging.specifiers (in check_specifiers), but we should probably use Specifier directly, since we're already passing in a list that doesn't need to be split from a string.

If you want to know why we should be relying on packaging directly… check out the regex inside Specifier… and that's what will be called eventually from inside setuptools.

Question for npm config command

Hi,

I went through the code but could not understand how can run commands like setting a private registry in setup.py using
jupyter-packaging.

e.g.

npm config set registry https://registry.your-registry.npme.io/

for jupyterlab 2 I used to run this command in subprocess in setup.py as my widget has js dependency which is not available on npmjs.com.

Please let me know if this is supported?

Add optional pre-commit install step

As we're switching more libraries to use pre-commit, it would be handy to have an option install pre-commit on editable installs. This should be a config option like:

[tool.jupyter-packaging]
install-pre-commit = True

That runs the following after the setuptools build_editable hook:

subprocess.run([sys.executable, '-m', 'pre_commit', 'install'])

We'd need to add a dependency on pre_commit, which is already on conda-forge.

This depends on #103

Question

Sorry a quick question,
i like to write code in jupyter notebook,
however when coming to package and publish,
i often have to manually convert the notebook to python file,
is there any quick way of packaging that jupyter notebook directly?

Add a test that uses pyproject.toml

I verified that we can use pyproject.toml now after #41. We should add a test for this:

(base) stslve: /tmp/temp
$ ls
.              ..             foo            foo.json       pyproject.toml setup.py
$ ls foo
.           ..          __init__.py bar.py
$ cat setup.py
from setuptools import setup
from jupyter_packaging import create_cmdclass, find_packages

cmdclass = create_cmdclass([], data_files_spec=[('share/jupyter/foo', '.', '*.json')])

setup_args = dict(
    name             = 'foo',
    description      = 'PROJECT_DESCRIPTION',
    long_description = 'PROJECT_LONG_DESCRIPTION',
    packages         = find_packages('.'),
    version          = 'PROJECT_VERSION',
    author           = 'Jupyter Development Team',
    author_email     = '[email protected]',
    url              = 'http://jupyter.org',
    license          = 'BSD',
    platforms        = "Linux, Mac OS X, Windows",
    keywords         = ['ipython', 'jupyter'],
    cmdclass         = cmdclass,
    install_requires = [
        'notebook>=4.3.0',
    ]
)

if __name__ == '__main__':
    setup(**setup_args)
$ cat pyproject.toml
[build-system]
requires = ["jupyter_packaging~=0.6.0", "jupyterlab~=2.0", "setuptools>=40.8.0", "wheel"]
build-backend = "setuptools.build_meta"
$ pip install .
Processing /private/tmp/temp
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
    Preparing wheel metadata ... done
...
  Building wheel for foo (PEP 517) ... done
  Created wheel for foo: filename=foo-PROJECT_VERSION-py3-none-any.whl size=1553 sha256=b52470ef55114761a48a27bc7134038317a7e2fb8d546a00116be026fce39cf3
  Stored in directory: /private/tmp/pip-ephem-wheel-cache-cdnibr9z/wheels/93/cb/f2/a9b0587126a9a8098575e4f151806aab96a2b9f95b8000835e
Successfully built foo
Installing collected packages: foo
  Attempting uninstall: foo
    Found existing installation: foo PROJECT-VERSION
    Uninstalling foo-PROJECT-VERSION:
      Successfully uninstalled foo-PROJECT-VERSION
Successfully installed foo-PROJECT-VERSION
(base) stslve: ~/miniconda/lib/python3.7/site-packages
$ ls foo
.           ..          __init__.py __pycache__ bar.py
$ ls ~/miniconda/share/jupyter/foo
.        ..       foo.json

is_stale is unreliable

If I add the node_modules folder of an npm package for caching on e.g. Travis CI, Travis will create the folder during set up:

Setting up build cache
[...]
fetching master/cache--python-3.4.tgz
could not download cache

adding /home/travis/build/[...]/node_modules to cache
creating directory /home/travis/build/[...]/node_modules

This will cause is_stale in this line to give the wrong result for the node_modules folder, preventing npm install from running. This is because the mtime of the node_modules folder will be very recent.

0.11.1: pytest is failing when `setuptools` > 60 is used

I'm trying to package your module as an rpm package. So I'm using the typical PEP517 based build, install and test cycle used on building packages from non-root account.

  • python3 -sBm build -w --no-isolation
  • because I'm calling build with --no-isolation I'm using during all processes oly locally installed modules
  • install .whl file in </install/prefix>
  • run pytest with PYTHONPATH pointing to sitearch and sitelib inside </install/prefix>

I'm not 100% sure but I have impression that becaue I've started using setuptools > 60 exactly this caused new type of pytest issues.

Here is pytest output:

+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.12, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1
plugins: cov-3.0.0, mock-3.6.1
collected 66 items

tests/test_build_api.py ........                                                                                                                                     [ 12%]
tests/test_core_functions.py .......                                                                                                                                 [ 22%]
tests/test_datafiles_install.py sssssFFFFF                                                                                                                           [ 37%]
tests/test_datafiles_paths.py ........                                                                                                                               [ 50%]
tests/test_deprecated.py ....sF....                                                                                                                                  [ 65%]
tests/test_install.py FFF                                                                                                                                            [ 69%]
tests/test_is_stale.py ...........                                                                                                                                   [ 86%]
tests/test_main.py .                                                                                                                                                 [ 87%]
tests/test_utility_functions.py ........                                                                                                                             [100%]

================================================================================= FAILURES =================================================================================
_______________________________________________________ test_install[source0-spec0-jupyter-packaging-test/test.txt] ________________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7efd64f183a0>, source = ('share/test.txt',), spec = ('jupyter-packaging-test', 'share', '**/*')
target = 'jupyter-packaging-test/test.txt'

    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_install(make_package, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
        try:
            subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
        except subprocess.CalledProcessError:
            pytest.skip("Unable to write to site packages")
>       assert target_path.exists()
E       AssertionError: assert False
E        +  where False = <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/test.txt')>()
E        +    where <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/test.txt')> = PosixPath('/usr/jupyter-packaging-test/test.txt').exists

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:95: AssertionError
____________________________________________________ test_install[source1-spec1-jupyter-packaging-test/level1/test.txt] ____________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7efd64f2baf0>, source = ('share/test.txt',)
spec = ('jupyter-packaging-test/level1', 'share', '**/[a-z]est.txt'), target = 'jupyter-packaging-test/level1/test.txt'

    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_install(make_package, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
        try:
            subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
        except subprocess.CalledProcessError:
            pytest.skip("Unable to write to site packages")
>       assert target_path.exists()
E       AssertionError: assert False
E        +  where False = <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/level1/test.txt')>()
E        +    where <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/level1/test.txt')> = PosixPath('/usr/jupyter-packaging-test/level1/test.txt').exists

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:95: AssertionError
_______________________________________________________ test_install[source2-spec2-jupyter-packaging-test/test.txt] ________________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7efd64f2b1f0>, source = ('level1/test/test.txt',)
spec = ('jupyter-packaging-test', 'level1/test', '**/*'), target = 'jupyter-packaging-test/test.txt'

    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_install(make_package, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
        try:
            subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
        except subprocess.CalledProcessError:
            pytest.skip("Unable to write to site packages")
>       assert target_path.exists()
E       AssertionError: assert False
E        +  where False = <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/test.txt')>()
E        +    where <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/test.txt')> = PosixPath('/usr/jupyter-packaging-test/test.txt').exists

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:95: AssertionError
________________________________________________ test_install[source3-spec3-jupyter-packaging-test//level1/level2/test.txt] ________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7efd64f184c0>, source = ('level1/test/test.txt',)
spec = ('jupyter-packaging-test/level1/level2', 'level1/test', '**/*'), target = 'jupyter-packaging-test//level1/level2/test.txt'

    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_install(make_package, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
        try:
            subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
        except subprocess.CalledProcessError:
            pytest.skip("Unable to write to site packages")
>       assert target_path.exists()
E       AssertionError: assert False
E        +  where False = <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/level1/level2/test.txt')>()
E        +    where <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/level1/level2/test.txt')> = PosixPath('/usr/jupyter-packaging-test/level1/level2/test.txt').exists

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:95: AssertionError
_________________________________________________ test_install[source4-spec4-jupyter-packaging-test/level2/test/test.txt] __________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7efd64f18af0>, source = ('level1/level2/test/test.txt',)
spec = ('jupyter-packaging-test', 'level1', '**/*'), target = 'jupyter-packaging-test/level2/test/test.txt'

    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_install(make_package, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
        try:
            subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
        except subprocess.CalledProcessError:
            pytest.skip("Unable to write to site packages")
>       assert target_path.exists()
E       AssertionError: assert False
E        +  where False = <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/level2/test/test.txt')>()
E        +    where <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/level2/test/test.txt')> = PosixPath('/usr/jupyter-packaging-test/level2/test/test.txt').exists

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:95: AssertionError
___________________________________________________________________________ test_create_cmdclass ___________________________________________________________________________

self = <jupyter_packaging.setupbase._wrap_command.<locals>.WrappedCommand object at 0x7efd64f7d6a0>

    def check_site_dir(self):  # noqa: C901  # is too complex (12)  # FIXME
        """Verify that self.install_dir is .pth-capable dir, if needed"""

        instdir = normalize_path(self.install_dir)
        pth_file = os.path.join(instdir, 'easy-install.pth')

        if not os.path.exists(instdir):
            try:
                os.makedirs(instdir)
            except (OSError, IOError):
                self.cant_write_to_target()

        # Is it a configured, PYTHONPATH, implicit, or explicit site dir?
        is_site_dir = instdir in self.all_site_dirs

        if not is_site_dir and not self.multi_version:
            # No?  Then directly test whether it does .pth file processing
            is_site_dir = self.check_pth_processing()
        else:
            # make sure we can write to target dir
            testfile = self.pseudo_tempname() + '.write-test'
            test_exists = os.path.exists(testfile)
            try:
                if test_exists:
                    os.unlink(testfile)
>               open(testfile, 'w').close()
E               PermissionError: [Errno 13] Permission denied: '/usr/lib/python3.8/site-packages/test-easy-install-307926.write-test'

/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:478: PermissionError

During handling of the above exception, another exception occurred:

make_package_deprecated = <function make_package_base.<locals>.do_stuff at 0x7efd64f18c10>, mocker = <pytest_mock.plugin.MockerFixture object at 0x7efd64f7d490>

    def test_create_cmdclass(make_package_deprecated, mocker):
        source = ("share/test.txt",)
        spec =  ("jupyter-packaging-test", "share", "**/*")
        target = "jupyter-packaging-test/test.txt"

        pkg_path = make_package_deprecated(data_files=source, data_files_spec=spec)
        os.chdir(pkg_path)
        cmdclass = pkg.create_cmdclass(
            package_data_spec=dict(foo="*.*"),
            data_files_spec=[spec],
            exclude=lambda x: False
        )
        for name in ['build_py', 'handle_files', 'sdist', 'bdist_wheel']:
            assert name in cmdclass

        dist = Distribution()
        cmdclass['handle_files'](dist).run()
        assert dist.data_files == [('jupyter-packaging-test', ['share/test.txt'])]
        assert dist.package_data == {'foo': []}

        # Test installation of data_files in develop mode
        dist = Distribution()
        handler = cmdclass['handle_files'](dist)
        develop = cmdclass['develop'](dist)

        def run_command(name):
            cmdclass[name](dist).run()

        mocker.patch.object(pkg.develop, 'install_for_development')
        develop.run_command = run_command
>       develop.install_for_development()

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:101:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:685: in install_for_development
    self.finalize_options()
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:52: in finalize_options
    easy_install.finalize_options(self)
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:322: in finalize_options
    self.check_site_dir()
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:481: in check_site_dir
    self.cant_write_to_target()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <jupyter_packaging.setupbase._wrap_command.<locals>.WrappedCommand object at 0x7efd64f7d6a0>

    def cant_write_to_target(self):
        msg = self.__cant_write_msg % (sys.exc_info()[1], self.install_dir,)

        if not os.path.exists(self.install_dir):
            msg += '\n' + self.__not_exists_id
        else:
            msg += '\n' + self.__access_msg
>       raise DistutilsError(msg)
E       distutils.errors.DistutilsError: can't create or remove files in install directory
E
E       The following error occurred while trying to add or remove files in the
E       installation directory:
E
E           [Errno 13] Permission denied: '/usr/lib/python3.8/site-packages/test-easy-install-307926.write-test'
E
E       The installation directory you specified (via --install-dir, --prefix, or
E       the distutils default setting) was:
E
E           /usr/lib/python3.8/site-packages/
E
E       Perhaps your account does not have write access to this directory?  If the
E       installation directory is a system-owned directory, you may need to sign in
E       as the administrator or "root" account.  If you do not have administrative
E       access to this machine, you may wish to choose a different installation
E       directory, preferably one that is listed in your PYTHONPATH environment
E       variable.
E
E       For information on other options, you may wish to consult the
E       documentation at:
E
E         https://setuptools.pypa.io/en/latest/deprecated/easy_install.html
E
E       Please make the appropriate changes for your system and try again.

/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:541: DistutilsError
_______________________________________________________________________________ test_install _______________________________________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7efd64dc4a60>, tmp_path = PosixPath('/tmp/pytest-of-tkloczko/pytest-10/test_install0')

    def test_install(make_package, tmp_path):
        name = 'jupyter_packaging_test_foo'
        ensured_targets=[f'{name}/main.py']
        package_dir = make_package(name=name, ensured_targets=ensured_targets)
        try:
            subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
        except subprocess.CalledProcessError:
            pytest.skip("Unable to write to site packages")
        # Get site packages where the package is installed.
        sitepkg = Path(sysconfig.get_paths()["purelib"])
        installed_file = sitepkg / f"{name}/main.py"
>       assert installed_file.exists()
E       AssertionError: assert False
E        +  where False = <bound method Path.exists of PosixPath('/usr/lib/python3.8/site-packages/jupyter_packaging_test_foo/main.py')>()
E        +    where <bound method Path.exists of PosixPath('/usr/lib/python3.8/site-packages/jupyter_packaging_test_foo/main.py')> = PosixPath('/usr/lib/python3.8/site-packages/jupyter_packaging_test_foo/main.py').exists

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_install.py:20: AssertionError
___________________________________________________________________________ test_install_hybrid ____________________________________________________________________________

make_hybrid_package = <function make_package_base.<locals>.do_stuff at 0x7efd64ed8ee0>, tmp_path = PosixPath('/tmp/pytest-of-tkloczko/pytest-10/test_install_hybrid0')

    def test_install_hybrid(make_hybrid_package, tmp_path):
        name = 'jupyter_packaging_test_foo'
        ensured_targets = [f"{name}/main.py", f"{name}/generated.js"]
        package_dir = make_hybrid_package(name=name, ensured_targets=ensured_targets, skip_if_exists=[f"{name}/generated.js"])
        try:
            subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
        except subprocess.CalledProcessError:
            pytest.skip("Unable to write to site packages")
        # Get site packages where the package is installed.
        sitepkg = Path(sysconfig.get_paths()["purelib"])
        installed_py_file = sitepkg / f"{name}/main.py"
        installed_js_file = sitepkg / f"{name}/generated.js"
>       assert installed_py_file.exists()
E       AssertionError: assert False
E        +  where False = <bound method Path.exists of PosixPath('/usr/lib/python3.8/site-packages/jupyter_packaging_test_foo/main.py')>()
E        +    where <bound method Path.exists of PosixPath('/usr/lib/python3.8/site-packages/jupyter_packaging_test_foo/main.py')> = PosixPath('/usr/lib/python3.8/site-packages/jupyter_packaging_test_foo/main.py').exists

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_install.py:39: AssertionError
___________________________________________________________________________ test_install_missing ___________________________________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7efd64dc43a0>, tmp_path = PosixPath('/tmp/pytest-of-tkloczko/pytest-10/test_install_missing0')

    def test_install_missing(make_package, tmp_path):
        name = 'jupyter_packaging_test_foo'
        ensured_targets=[f'{name}/missing.py']
        package_dir = make_package(name=name, ensured_targets=ensured_targets)
        with pytest.raises(subprocess.CalledProcessError):
            subprocess.check_output([shutil.which('pip'), 'install', '--user', '.'], cwd=str(package_dir))
>       subprocess.check_output([shutil.which('pip'), 'install', '--user', '-e', '.'], cwd=str(package_dir))

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_install.py:58:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib64/python3.8/subprocess.py:415: in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

input = None, capture_output = False, timeout = None, check = True, popenargs = (['/usr/bin/pip', 'install', '--user', '-e', '.'],)
kwargs = {'cwd': '/tmp/pytest-of-tkloczko/pytest-10/test_install_missing0/package', 'stdout': -1}, process = <subprocess.Popen object at 0x7efd6503dc70>
stdout = b"Obtaining file:///tmp/pytest-of-tkloczko/pytest-10/test_install_missing0/package\n  Installing build dependencies: s...es/jupyter_packaging_test_foo/\n   from /home/tkloczko/.local/lib/python3.8/site-packages/~upyter_packaging_test_foo\n"
stderr = None, retcode = 1

    def run(*popenargs,
            input=None, capture_output=False, timeout=None, check=False, **kwargs):
        """Run command with arguments and return a CompletedProcess instance.

        The returned instance will have attributes args, returncode, stdout and
        stderr. By default, stdout and stderr are not captured, and those attributes
        will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.

        If check is True and the exit code was non-zero, it raises a
        CalledProcessError. The CalledProcessError object will have the return code
        in the returncode attribute, and output & stderr attributes if those streams
        were captured.

        If timeout is given, and the process takes too long, a TimeoutExpired
        exception will be raised.

        There is an optional argument "input", allowing you to
        pass bytes or a string to the subprocess's stdin.  If you use this argument
        you may not also use the Popen constructor's "stdin" argument, as
        it will be used internally.

        By default, all communication is in bytes, and therefore any "input" should
        be bytes, and the stdout and stderr will be bytes. If in text mode, any
        "input" should be a string, and stdout and stderr will be strings decoded
        according to locale encoding, or by "encoding" if set. Text mode is
        triggered by setting any of text, encoding, errors or universal_newlines.

        The other arguments are the same as for the Popen constructor.
        """
        if input is not None:
            if kwargs.get('stdin') is not None:
                raise ValueError('stdin and input arguments may not both be used.')
            kwargs['stdin'] = PIPE

        if capture_output:
            if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
                raise ValueError('stdout and stderr arguments may not be used '
                                 'with capture_output.')
            kwargs['stdout'] = PIPE
            kwargs['stderr'] = PIPE

        with Popen(*popenargs, **kwargs) as process:
            try:
                stdout, stderr = process.communicate(input, timeout=timeout)
            except TimeoutExpired as exc:
                process.kill()
                if _mswindows:
                    # Windows accumulates the output in a single blocking
                    # read() call run on child threads, with the timeout
                    # being done in a join() on those threads.  communicate()
                    # _after_ kill() is required to collect that and add it
                    # to the exception.
                    exc.stdout, exc.stderr = process.communicate()
                else:
                    # POSIX _communicate already populated the output so
                    # far into the TimeoutExpired exception.
                    process.wait()
                raise
            except:  # Including KeyboardInterrupt, communicate handled that.
                process.kill()
                # We don't call process.wait() as .__exit__ does that for us.
                raise
            retcode = process.poll()
            if check and retcode:
>               raise CalledProcessError(retcode, process.args,
                                         output=stdout, stderr=stderr)
E               subprocess.CalledProcessError: Command '['/usr/bin/pip', 'install', '--user', '-e', '.']' returned non-zero exit status 1.

/usr/lib64/python3.8/subprocess.py:516: CalledProcessError
--------------------------------------------------------------------------- Captured stderr call ---------------------------------------------------------------------------
  ERROR: Command errored out with exit status 1:
   command: /usr/bin/python3 /usr/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py build_wheel /tmp/tmpr1_p5fbw
       cwd: /tmp/pytest-of-tkloczko/pytest-10/test_install_missing0/package
  Complete output (37 lines):
  running bdist_wheel
  running pre_dist
  running ensure_targets
  Traceback (most recent call last):
    File "/usr/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 363, in <module>
      main()
    File "/usr/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 345, in main
      json_out['return_val'] = hook(**hook_input['kwargs'])
    File "/usr/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 261, in build_wheel
      return _build_backend().build_wheel(wheel_directory, config_settings,
    File "/tmp/pip-build-env-_6eh4gia/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 230, in build_wheel
      return self._build_with_temp_dir(['bdist_wheel'], '.whl',
    File "/tmp/pip-build-env-_6eh4gia/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 215, in _build_with_temp_dir
      self.run_setup()
    File "/tmp/pip-build-env-_6eh4gia/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 158, in run_setup
      exec(compile(code, __file__, 'exec'), locals())
    File "setup.py", line 13, in <module>
      setuptools.setup(data_files=data_files, cmdclass=cmdclass, packages=setuptools.find_packages('.'),
    File "/tmp/pip-build-env-_6eh4gia/overlay/lib/python3.8/site-packages/setuptools/__init__.py", line 155, in setup
      return distutils.core.setup(**attrs)
    File "/tmp/pip-build-env-_6eh4gia/overlay/lib/python3.8/site-packages/setuptools/_distutils/core.py", line 148, in setup
      return run_commands(dist)
    File "/tmp/pip-build-env-_6eh4gia/overlay/lib/python3.8/site-packages/setuptools/_distutils/core.py", line 163, in run_commands
      dist.run_commands()
    File "/tmp/pip-build-env-_6eh4gia/overlay/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 967, in run_commands
      self.run_command(cmd)
    File "/tmp/pip-build-env-_6eh4gia/overlay/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 986, in run_command
      cmd_obj.run()
    File "/tmp/pip-build-env-_6eh4gia/overlay/lib/python3.8/site-packages/jupyter_packaging/setupbase.py", line 133, in run
      self.run_command('ensure_targets')
    File "/tmp/pip-build-env-_6eh4gia/overlay/lib/python3.8/site-packages/setuptools/_distutils/cmd.py", line 313, in run_command
      self.distribution.run_command(command)
    File "/tmp/pip-build-env-_6eh4gia/overlay/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 986, in run_command
      cmd_obj.run()
    File "/tmp/pip-build-env-_6eh4gia/overlay/lib/python3.8/site-packages/jupyter_packaging/setupbase.py", line 409, in run
      raise ValueError(('missing files: %s' % missing))
  ValueError: missing files: ['jupyter_packaging_test_foo/missing.py']
  ----------------------------------------
  ERROR: Failed building wheel for jupyter-packaging-test-foo
ERROR: Could not build wheels for jupyter-packaging-test-foo, which is required to install pyproject.toml-based projects
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-10/test_install_missing0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-10/test_install_missing0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix=
         cwd: /tmp/pytest-of-tkloczko/pytest-10/test_install_missing0/package/
    Complete output (32 lines):
    running develop
    /tmp/pip-build-env-fm879vb0/overlay/lib/python3.8/site-packages/setuptools/command/easy_install.py:156: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    WARNING: The user site-packages directory is disabled.
    /tmp/pip-build-env-fm879vb0/overlay/lib/python3.8/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    error: can't create or remove files in install directory

    The following error occurred while trying to add or remove files in the
    installation directory:

        [Errno 13] Permission denied: '/usr/lib/python3.8/site-packages/test-easy-install-313825.write-test'

    The installation directory you specified (via --install-dir, --prefix, or
    the distutils default setting) was:

        /usr/lib/python3.8/site-packages/

    Perhaps your account does not have write access to this directory?  If the
    installation directory is a system-owned directory, you may need to sign in
    as the administrator or "root" account.  If you do not have administrative
    access to this machine, you may wish to choose a different installation
    directory, preferably one that is listed in your PYTHONPATH environment
    variable.

    For information on other options, you may wish to consult the
    documentation at:

      https://setuptools.pypa.io/en/latest/deprecated/easy_install.html

    Please make the appropriate changes for your system and try again.

    ----------------------------------------
ERROR: Command errored out with exit status 1: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-10/test_install_missing0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-10/test_install_missing0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix= Check the logs for full command output.
============================================================================= warnings summary =============================================================================
tests/test_deprecated.py::test_ensure_python
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:58: DeprecatedWarning: ensure_python is deprecated as of 0.7 and will be removed in 1.0. Use `setuptools` `python_requires` instead
    pkg.ensure_python('>=3.6')

tests/test_deprecated.py::test_ensure_python
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:59: DeprecatedWarning: ensure_python is deprecated as of 0.7 and will be removed in 1.0. Use `setuptools` `python_requires` instead
    pkg.ensure_python(['>=3.6', '>=3.5'])

tests/test_deprecated.py::test_ensure_python
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:62: DeprecatedWarning: ensure_python is deprecated as of 0.7 and will be removed in 1.0. Use `setuptools` `python_requires` instead
    pkg.ensure_python('<3.5')

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:78: DeprecatedWarning: create_cmdclass is deprecated as of 0.8 and will be removed in 1.0. "
  Use `wrap_installers` to handle prebuild steps in cmdclass.
  Use `get_data_files` to handle data files.
  Use `include_package_data=True` and `MANIFEST.in` for package data.

    cmdclass = pkg.create_cmdclass(

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:563: DeprecatedWarning: _get_file_handler is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    handle_files = _get_file_handler(package_data_spec, data_files_spec, exclude)

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:564: DeprecatedWarning: _get_develop_handler is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    develop_handler = _get_develop_handler()

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:574: DeprecatedWarning: _wrap_command is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    build_py=wrapper(build_py, strict=is_repo),

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:576: DeprecatedWarning: _wrap_command is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    sdist=wrapper(sdist, strict=True),

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:581: DeprecatedWarning: _wrap_command is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    cmdclass['bdist_wheel'] = wrapper(bdist_wheel, strict=True)

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:583: DeprecatedWarning: _wrap_command is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    cmdclass['develop'] = wrapper(develop_handler, strict=True)

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:666: DeprecatedWarning: _get_package_data is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    files =  _get_package_data(key, patterns)

tests/test_deprecated.py::test_create_cmdclass
  /usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:156: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
    warnings.warn(

tests/test_deprecated.py::test_create_cmdclass
  /usr/lib/python3.8/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
    warnings.warn(

tests/test_deprecated.py::test_command_for_func
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:111: DeprecatedWarning: command_for_func is deprecated as of 0.8 and will be removed in 1.0. Use `BaseCommand` directly instead
    cmd = pkg.command_for_func(func)

tests/test_deprecated.py::test_command_for_func
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:458: DeprecatedWarning: update_package_data is deprecated as of 0.8 and will be removed in 1.0. Use `use_package_data=True` and `MANIFEST.in` instead
    update_package_data(self.distribution)

tests/test_deprecated.py::test_install_npm
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:117: DeprecatedWarning: install_npm is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    builder = pkg.install_npm()

tests/test_deprecated.py::test__wrap_command
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:131: DeprecatedWarning: _wrap_command is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    cmd = pkg._wrap_command(['js'], TestCommand)

tests/test_deprecated.py::test__wrap_command
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:647: DeprecatedWarning: update_package_data is deprecated as of 0.8 and will be removed in 1.0. Use `use_package_data=True` and `MANIFEST.in` instead
    update_package_data(self.distribution)

-- Docs: https://docs.pytest.org/en/stable/warnings.html
========================================================================= short test summary info ==========================================================================
SKIPPED [5] tests/test_datafiles_install.py:72: Unable to write to site packages
SKIPPED [1] tests/test_deprecated.py:65: Tests RuntimeError for Python 3.10+
FAILED tests/test_datafiles_install.py::test_install[source0-spec0-jupyter-packaging-test/test.txt] - AssertionError: assert False
FAILED tests/test_datafiles_install.py::test_install[source1-spec1-jupyter-packaging-test/level1/test.txt] - AssertionError: assert False
FAILED tests/test_datafiles_install.py::test_install[source2-spec2-jupyter-packaging-test/test.txt] - AssertionError: assert False
FAILED tests/test_datafiles_install.py::test_install[source3-spec3-jupyter-packaging-test//level1/level2/test.txt] - AssertionError: assert False
FAILED tests/test_datafiles_install.py::test_install[source4-spec4-jupyter-packaging-test/level2/test/test.txt] - AssertionError: assert False
FAILED tests/test_deprecated.py::test_create_cmdclass - distutils.errors.DistutilsError: can't create or remove files in install directory
FAILED tests/test_install.py::test_install - AssertionError: assert False
FAILED tests/test_install.py::test_install_hybrid - AssertionError: assert False
FAILED tests/test_install.py::test_install_missing - subprocess.CalledProcessError: Command '['/usr/bin/pip', 'install', '--user', '-e', '.']' returned non-zero exit sta...
===================================================== 9 failed, 51 passed, 6 skipped, 18 warnings in 131.54s (0:02:11) =====================================================

Windows Difference of path expansion between pathlib and os

Ok seems that the trouble come from a difference in behavior between pathlib and os.path

os is getting an absolute path like C:\Users\RUNNER~1\AppData\Local\Temp\pip-req-build-vi810dlk
pathlib is expanding the folder name and returns C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-vi810dlk

Originally posted by @fcollonval in jupyterlab/extension-examples#167 (comment)

Unsure what is the best solution, should we migrate the package to pathlib?

python setup.py sdist/bdist_wheel failing

With the latest version of jupyter-packaging, running python setup.py sdist/bdist_wheel will fail because the JS assets will be missing:

running sdist
running ensure_targets
Traceback (most recent call last):
  File "/home/fcollonval/projects/jupyterlab-gitlab/setup.py", line 105, in <module>
    setuptools.setup(**setup_args)
  File "/home/fcollonval/miniconda3/envs/jgit/lib/python3.9/site-packages/setuptools/__init__.py", line 153, in setup
    return distutils.core.setup(**attrs)
  File "/home/fcollonval/miniconda3/envs/jgit/lib/python3.9/distutils/core.py", line 148, in setup
    dist.run_commands()
  File "/home/fcollonval/miniconda3/envs/jgit/lib/python3.9/distutils/dist.py", line 966, in run_commands
    self.run_command(cmd)
  File "/home/fcollonval/miniconda3/envs/jgit/lib/python3.9/distutils/dist.py", line 985, in run_command
    cmd_obj.run()
  File "/home/fcollonval/miniconda3/envs/jgit/lib/python3.9/site-packages/jupyter_packaging/setupbase.py", line 133, in run
    self.run_command('ensure_targets')
  File "/home/fcollonval/miniconda3/envs/jgit/lib/python3.9/distutils/cmd.py", line 313, in run_command
    self.distribution.run_command(command)
  File "/home/fcollonval/miniconda3/envs/jgit/lib/python3.9/distutils/dist.py", line 985, in run_command
    cmd_obj.run()
  File "/home/fcollonval/miniconda3/envs/jgit/lib/python3.9/site-packages/jupyter_packaging/setupbase.py", line 402, in run
    raise ValueError(('missing files: %s' % missing))
ValueError: missing files: ['/home/fcollonval/projects/jupyterlab-gitlab/jupyterlab_gitlab/labextension/package.json', '/home/fcollonval/projects/jupyterlab-gitlab/jupyterlab_gitlab/labextension/static/style.js']

Question about pyproject.toml syntax

The README for this project suggests using:

[build-system]
requires = ["jupyter_packaging~=0.10.0,<2"]
build-backend = "setuptools.build_meta"

However, doesn't ~=0.10.0 imply >=0.10.0,==0.10.*? So not only is the <2 unnecessary, it's also misleading since it suggests that version 0.11.0 or 1.X would work? I'm referring to this syntax specification.

Install failure - AttributeError: 'Distribution' object has no attribute 'set_defaults'

For nix/windows installs I'm running into this error on install:

  File "C:\builds\deps\5d2381d4-86ec-5e0b-90ef-e24dd41d5457\installdir\lib\site-packages\setuptools\config\expand.py", line 415, in __exit__
    self._dist.set_defaults.analyse_name()  # Now we can set a default name
AttributeError: 'Distribution' object has no attribute 'set_defaults'

When using setuptools 61 or greater.

This section of code was introduced at version 61:
https://github.com/pypa/setuptools/blob/4923d1139be9366b3010a6d6e56d4c4980a0ab6e/setuptools/config/expand.py#L407

`pip install .` is not handling any files

Needs a test that makes sure both the python files and any data_files are handled properly on an install and uninstall, and that they are present in an sdist as well.

0.11.1: pytest is failing

I'm trying to package your module as an rpm package. So I'm using the typical build, install and test cycle used on building packages from non-root account.

  • "setup.py build"
  • "setup.py install --root </install/prefix>"
  • "pytest with PYTHONPATH pointing to sitearch and sitelib inside </install/prefix>

Here is pytest output with few units are failing:

+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.12, pytest-6.2.5, py-1.10.0, pluggy-0.13.1
rootdir: /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1
plugins: rerunfailures-9.1.1, cov-2.12.1, forked-1.3.0, xdist-2.3.0, flake8-1.0.7, shutil-1.7.0, virtualenv-1.7.0, trio-0.7.0, mock-3.6.1, timeout-2.0.1
collected 66 items

tests/test_build_api.py ........                                                                                                                                     [ 12%]
tests/test_core_functions.py .......                                                                                                                                 [ 22%]
tests/test_datafiles_install.py FFFFFFFFFF                                                                                                                           [ 37%]
tests/test_datafiles_paths.py ........                                                                                                                               [ 50%]
tests/test_deprecated.py ....sF....                                                                                                                                  [ 65%]
tests/test_install.py FFF                                                                                                                                            [ 69%]
tests/test_is_stale.py ...........                                                                                                                                   [ 86%]
tests/test_main.py .                                                                                                                                                 [ 87%]
tests/test_utility_functions.py ........                                                                                                                             [100%]

================================================================================= FAILURES =================================================================================
_______________________________________________________ test_develop[source0-spec0-jupyter-packaging-test/test.txt] ________________________________________________________

make_package_deprecated = <function make_package_base.<locals>.do_stuff at 0x7f37c6263820>, source = ('share/test.txt',), spec = ('jupyter-packaging-test', 'share', '**/*')
target = 'jupyter-packaging-test/test.txt'

    @fail_if_not_removed
    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_develop(make_package_deprecated, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package_deprecated(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
>       subprocess.check_output([shutil.which('pip'), 'install', '-e', '.'], cwd=str(package_dir))

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:69:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib64/python3.8/subprocess.py:415: in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

input = None, capture_output = False, timeout = None, check = True, popenargs = (['/usr/bin/pip', 'install', '-e', '.'],)
kwargs = {'cwd': '/tmp/pytest-of-tkloczko/pytest-0/test_develop_source0_spec0_jup0/package', 'stdout': -1}, process = <subprocess.Popen object at 0x7f37c62318b0>
stdout = b"Defaulting to user installation because normal site-packages is not writeable\nObtaining file:///tmp/pytest-of-tkloc...Installing collected packages: jupyter-packaging-test-foo\n  Running setup.py develop for jupyter-packaging-test-foo\n"
stderr = None, retcode = 1

    def run(*popenargs,
            input=None, capture_output=False, timeout=None, check=False, **kwargs):
        """Run command with arguments and return a CompletedProcess instance.

        The returned instance will have attributes args, returncode, stdout and
        stderr. By default, stdout and stderr are not captured, and those attributes
        will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.

        If check is True and the exit code was non-zero, it raises a
        CalledProcessError. The CalledProcessError object will have the return code
        in the returncode attribute, and output & stderr attributes if those streams
        were captured.

        If timeout is given, and the process takes too long, a TimeoutExpired
        exception will be raised.

        There is an optional argument "input", allowing you to
        pass bytes or a string to the subprocess's stdin.  If you use this argument
        you may not also use the Popen constructor's "stdin" argument, as
        it will be used internally.

        By default, all communication is in bytes, and therefore any "input" should
        be bytes, and the stdout and stderr will be bytes. If in text mode, any
        "input" should be a string, and stdout and stderr will be strings decoded
        according to locale encoding, or by "encoding" if set. Text mode is
        triggered by setting any of text, encoding, errors or universal_newlines.

        The other arguments are the same as for the Popen constructor.
        """
        if input is not None:
            if kwargs.get('stdin') is not None:
                raise ValueError('stdin and input arguments may not both be used.')
            kwargs['stdin'] = PIPE

        if capture_output:
            if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
                raise ValueError('stdout and stderr arguments may not be used '
                                 'with capture_output.')
            kwargs['stdout'] = PIPE
            kwargs['stderr'] = PIPE

        with Popen(*popenargs, **kwargs) as process:
            try:
                stdout, stderr = process.communicate(input, timeout=timeout)
            except TimeoutExpired as exc:
                process.kill()
                if _mswindows:
                    # Windows accumulates the output in a single blocking
                    # read() call run on child threads, with the timeout
                    # being done in a join() on those threads.  communicate()
                    # _after_ kill() is required to collect that and add it
                    # to the exception.
                    exc.stdout, exc.stderr = process.communicate()
                else:
                    # POSIX _communicate already populated the output so
                    # far into the TimeoutExpired exception.
                    process.wait()
                raise
            except:  # Including KeyboardInterrupt, communicate handled that.
                process.kill()
                # We don't call process.wait() as .__exit__ does that for us.
                raise
            retcode = process.poll()
            if check and retcode:
>               raise CalledProcessError(retcode, process.args,
                                         output=stdout, stderr=stderr)
E               subprocess.CalledProcessError: Command '['/usr/bin/pip', 'install', '-e', '.']' returned non-zero exit status 1.

/usr/lib64/python3.8/subprocess.py:516: CalledProcessError
--------------------------------------------------------------------------- Captured stderr call ---------------------------------------------------------------------------
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source0_spec0_jup0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source0_spec0_jup0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix=
         cwd: /tmp/pytest-of-tkloczko/pytest-0/test_develop_source0_spec0_jup0/package/
    Complete output (42 lines):
    running develop
    /tmp/pytest-of-tkloczko/pytest-0/test_develop_source0_spec0_jup0/package/setup.py:10: DeprecatedWarning: create_cmdclass is deprecated as of 0.8 and will be removed in 1.0. "
    Use `wrap_installers` to handle prebuild steps in cmdclass.
    Use `get_data_files` to handle data files.
    Use `include_package_data=True` and `MANIFEST.in` for package data.

      cmdclass = create_cmdclass('jsdeps', data_files_spec=[('jupyter-packaging-test', 'share', '**/*')], exclude=exclude)
    /tmp/pytest-of-tkloczko/pytest-0/test_develop_source0_spec0_jup0/package/setup.py:11: DeprecatedWarning: install_npm is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
      cmdclass['jsdeps'] = install_npm()
    /usr/lib64/python3.8/distutils/dist.py:274: UserWarning: Unknown distribution option: 'skip_if_exists'
      warnings.warn(msg)
    /tmp/pip-build-env-am0ch5u2/overlay/lib/python3.8/site-packages/setuptools/command/easy_install.py:156: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    WARNING: The user site-packages directory is disabled.
    /tmp/pip-build-env-am0ch5u2/overlay/lib/python3.8/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    error: can't create or remove files in install directory

    The following error occurred while trying to add or remove files in the
    installation directory:

        [Errno 13] Permission denied: '/usr/lib/python3.8/site-packages/test-easy-install-20477.write-test'

    The installation directory you specified (via --install-dir, --prefix, or
    the distutils default setting) was:

        /usr/lib/python3.8/site-packages/

    Perhaps your account does not have write access to this directory?  If the
    installation directory is a system-owned directory, you may need to sign in
    as the administrator or "root" account.  If you do not have administrative
    access to this machine, you may wish to choose a different installation
    directory, preferably one that is listed in your PYTHONPATH environment
    variable.

    For information on other options, you may wish to consult the
    documentation at:

      https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html

    Please make the appropriate changes for your system and try again.

    ----------------------------------------
ERROR: Command errored out with exit status 1: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source0_spec0_jup0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source0_spec0_jup0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix= Check the logs for full command output.
____________________________________________________ test_develop[source1-spec1-jupyter-packaging-test/level1/test.txt] ____________________________________________________

make_package_deprecated = <function make_package_base.<locals>.do_stuff at 0x7f37c6732e50>, source = ('share/test.txt',)
spec = ('jupyter-packaging-test/level1', 'share', '**/[a-z]est.txt'), target = 'jupyter-packaging-test/level1/test.txt'

    @fail_if_not_removed
    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_develop(make_package_deprecated, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package_deprecated(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
>       subprocess.check_output([shutil.which('pip'), 'install', '-e', '.'], cwd=str(package_dir))

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:69:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib64/python3.8/subprocess.py:415: in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

input = None, capture_output = False, timeout = None, check = True, popenargs = (['/usr/bin/pip', 'install', '-e', '.'],)
kwargs = {'cwd': '/tmp/pytest-of-tkloczko/pytest-0/test_develop_source1_spec1_jup0/package', 'stdout': -1}, process = <subprocess.Popen object at 0x7f37c6220670>
stdout = b"Defaulting to user installation because normal site-packages is not writeable\nObtaining file:///tmp/pytest-of-tkloc...Installing collected packages: jupyter-packaging-test-foo\n  Running setup.py develop for jupyter-packaging-test-foo\n"
stderr = None, retcode = 1

    def run(*popenargs,
            input=None, capture_output=False, timeout=None, check=False, **kwargs):
        """Run command with arguments and return a CompletedProcess instance.

        The returned instance will have attributes args, returncode, stdout and
        stderr. By default, stdout and stderr are not captured, and those attributes
        will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.

        If check is True and the exit code was non-zero, it raises a
        CalledProcessError. The CalledProcessError object will have the return code
        in the returncode attribute, and output & stderr attributes if those streams
        were captured.

        If timeout is given, and the process takes too long, a TimeoutExpired
        exception will be raised.

        There is an optional argument "input", allowing you to
        pass bytes or a string to the subprocess's stdin.  If you use this argument
        you may not also use the Popen constructor's "stdin" argument, as
        it will be used internally.

        By default, all communication is in bytes, and therefore any "input" should
        be bytes, and the stdout and stderr will be bytes. If in text mode, any
        "input" should be a string, and stdout and stderr will be strings decoded
        according to locale encoding, or by "encoding" if set. Text mode is
        triggered by setting any of text, encoding, errors or universal_newlines.

        The other arguments are the same as for the Popen constructor.
        """
        if input is not None:
            if kwargs.get('stdin') is not None:
                raise ValueError('stdin and input arguments may not both be used.')
            kwargs['stdin'] = PIPE

        if capture_output:
            if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
                raise ValueError('stdout and stderr arguments may not be used '
                                 'with capture_output.')
            kwargs['stdout'] = PIPE
            kwargs['stderr'] = PIPE

        with Popen(*popenargs, **kwargs) as process:
            try:
                stdout, stderr = process.communicate(input, timeout=timeout)
            except TimeoutExpired as exc:
                process.kill()
                if _mswindows:
                    # Windows accumulates the output in a single blocking
                    # read() call run on child threads, with the timeout
                    # being done in a join() on those threads.  communicate()
                    # _after_ kill() is required to collect that and add it
                    # to the exception.
                    exc.stdout, exc.stderr = process.communicate()
                else:
                    # POSIX _communicate already populated the output so
                    # far into the TimeoutExpired exception.
                    process.wait()
                raise
            except:  # Including KeyboardInterrupt, communicate handled that.
                process.kill()
                # We don't call process.wait() as .__exit__ does that for us.
                raise
            retcode = process.poll()
            if check and retcode:
>               raise CalledProcessError(retcode, process.args,
                                         output=stdout, stderr=stderr)
E               subprocess.CalledProcessError: Command '['/usr/bin/pip', 'install', '-e', '.']' returned non-zero exit status 1.

/usr/lib64/python3.8/subprocess.py:516: CalledProcessError
--------------------------------------------------------------------------- Captured stderr call ---------------------------------------------------------------------------
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source1_spec1_jup0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source1_spec1_jup0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix=
         cwd: /tmp/pytest-of-tkloczko/pytest-0/test_develop_source1_spec1_jup0/package/
    Complete output (42 lines):
    running develop
    /tmp/pytest-of-tkloczko/pytest-0/test_develop_source1_spec1_jup0/package/setup.py:10: DeprecatedWarning: create_cmdclass is deprecated as of 0.8 and will be removed in 1.0. "
    Use `wrap_installers` to handle prebuild steps in cmdclass.
    Use `get_data_files` to handle data files.
    Use `include_package_data=True` and `MANIFEST.in` for package data.

      cmdclass = create_cmdclass('jsdeps', data_files_spec=[('jupyter-packaging-test/level1', 'share', '**/[a-z]est.txt')], exclude=exclude)
    /tmp/pytest-of-tkloczko/pytest-0/test_develop_source1_spec1_jup0/package/setup.py:11: DeprecatedWarning: install_npm is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
      cmdclass['jsdeps'] = install_npm()
    /usr/lib64/python3.8/distutils/dist.py:274: UserWarning: Unknown distribution option: 'skip_if_exists'
      warnings.warn(msg)
    /tmp/pip-build-env-4skow_50/overlay/lib/python3.8/site-packages/setuptools/command/easy_install.py:156: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    WARNING: The user site-packages directory is disabled.
    /tmp/pip-build-env-4skow_50/overlay/lib/python3.8/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    error: can't create or remove files in install directory

    The following error occurred while trying to add or remove files in the
    installation directory:

        [Errno 13] Permission denied: '/usr/lib/python3.8/site-packages/test-easy-install-20499.write-test'

    The installation directory you specified (via --install-dir, --prefix, or
    the distutils default setting) was:

        /usr/lib/python3.8/site-packages/

    Perhaps your account does not have write access to this directory?  If the
    installation directory is a system-owned directory, you may need to sign in
    as the administrator or "root" account.  If you do not have administrative
    access to this machine, you may wish to choose a different installation
    directory, preferably one that is listed in your PYTHONPATH environment
    variable.

    For information on other options, you may wish to consult the
    documentation at:

      https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html

    Please make the appropriate changes for your system and try again.

    ----------------------------------------
ERROR: Command errored out with exit status 1: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source1_spec1_jup0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source1_spec1_jup0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix= Check the logs for full command output.
_______________________________________________________ test_develop[source2-spec2-jupyter-packaging-test/test.txt] ________________________________________________________

make_package_deprecated = <function make_package_base.<locals>.do_stuff at 0x7f37c6263550>, source = ('level1/test/test.txt',)
spec = ('jupyter-packaging-test', 'level1/test', '**/*'), target = 'jupyter-packaging-test/test.txt'

    @fail_if_not_removed
    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_develop(make_package_deprecated, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package_deprecated(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
>       subprocess.check_output([shutil.which('pip'), 'install', '-e', '.'], cwd=str(package_dir))

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:69:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib64/python3.8/subprocess.py:415: in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

input = None, capture_output = False, timeout = None, check = True, popenargs = (['/usr/bin/pip', 'install', '-e', '.'],)
kwargs = {'cwd': '/tmp/pytest-of-tkloczko/pytest-0/test_develop_source2_spec2_jup0/package', 'stdout': -1}, process = <subprocess.Popen object at 0x7f37c620ec70>
stdout = b"Defaulting to user installation because normal site-packages is not writeable\nObtaining file:///tmp/pytest-of-tkloc...Installing collected packages: jupyter-packaging-test-foo\n  Running setup.py develop for jupyter-packaging-test-foo\n"
stderr = None, retcode = 1

    def run(*popenargs,
            input=None, capture_output=False, timeout=None, check=False, **kwargs):
        """Run command with arguments and return a CompletedProcess instance.

        The returned instance will have attributes args, returncode, stdout and
        stderr. By default, stdout and stderr are not captured, and those attributes
        will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.

        If check is True and the exit code was non-zero, it raises a
        CalledProcessError. The CalledProcessError object will have the return code
        in the returncode attribute, and output & stderr attributes if those streams
        were captured.

        If timeout is given, and the process takes too long, a TimeoutExpired
        exception will be raised.

        There is an optional argument "input", allowing you to
        pass bytes or a string to the subprocess's stdin.  If you use this argument
        you may not also use the Popen constructor's "stdin" argument, as
        it will be used internally.

        By default, all communication is in bytes, and therefore any "input" should
        be bytes, and the stdout and stderr will be bytes. If in text mode, any
        "input" should be a string, and stdout and stderr will be strings decoded
        according to locale encoding, or by "encoding" if set. Text mode is
        triggered by setting any of text, encoding, errors or universal_newlines.

        The other arguments are the same as for the Popen constructor.
        """
        if input is not None:
            if kwargs.get('stdin') is not None:
                raise ValueError('stdin and input arguments may not both be used.')
            kwargs['stdin'] = PIPE

        if capture_output:
            if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
                raise ValueError('stdout and stderr arguments may not be used '
                                 'with capture_output.')
            kwargs['stdout'] = PIPE
            kwargs['stderr'] = PIPE

        with Popen(*popenargs, **kwargs) as process:
            try:
                stdout, stderr = process.communicate(input, timeout=timeout)
            except TimeoutExpired as exc:
                process.kill()
                if _mswindows:
                    # Windows accumulates the output in a single blocking
                    # read() call run on child threads, with the timeout
                    # being done in a join() on those threads.  communicate()
                    # _after_ kill() is required to collect that and add it
                    # to the exception.
                    exc.stdout, exc.stderr = process.communicate()
                else:
                    # POSIX _communicate already populated the output so
                    # far into the TimeoutExpired exception.
                    process.wait()
                raise
            except:  # Including KeyboardInterrupt, communicate handled that.
                process.kill()
                # We don't call process.wait() as .__exit__ does that for us.
                raise
            retcode = process.poll()
            if check and retcode:
>               raise CalledProcessError(retcode, process.args,
                                         output=stdout, stderr=stderr)
E               subprocess.CalledProcessError: Command '['/usr/bin/pip', 'install', '-e', '.']' returned non-zero exit status 1.

/usr/lib64/python3.8/subprocess.py:516: CalledProcessError
--------------------------------------------------------------------------- Captured stderr call ---------------------------------------------------------------------------
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source2_spec2_jup0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source2_spec2_jup0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix=
         cwd: /tmp/pytest-of-tkloczko/pytest-0/test_develop_source2_spec2_jup0/package/
    Complete output (42 lines):
    running develop
    /tmp/pytest-of-tkloczko/pytest-0/test_develop_source2_spec2_jup0/package/setup.py:10: DeprecatedWarning: create_cmdclass is deprecated as of 0.8 and will be removed in 1.0. "
    Use `wrap_installers` to handle prebuild steps in cmdclass.
    Use `get_data_files` to handle data files.
    Use `include_package_data=True` and `MANIFEST.in` for package data.

      cmdclass = create_cmdclass('jsdeps', data_files_spec=[('jupyter-packaging-test', 'level1/test', '**/*')], exclude=exclude)
    /tmp/pytest-of-tkloczko/pytest-0/test_develop_source2_spec2_jup0/package/setup.py:11: DeprecatedWarning: install_npm is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
      cmdclass['jsdeps'] = install_npm()
    /usr/lib64/python3.8/distutils/dist.py:274: UserWarning: Unknown distribution option: 'skip_if_exists'
      warnings.warn(msg)
    /tmp/pip-build-env-22g02x5u/overlay/lib/python3.8/site-packages/setuptools/command/easy_install.py:156: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    WARNING: The user site-packages directory is disabled.
    /tmp/pip-build-env-22g02x5u/overlay/lib/python3.8/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    error: can't create or remove files in install directory

    The following error occurred while trying to add or remove files in the
    installation directory:

        [Errno 13] Permission denied: '/usr/lib/python3.8/site-packages/test-easy-install-20559.write-test'

    The installation directory you specified (via --install-dir, --prefix, or
    the distutils default setting) was:

        /usr/lib/python3.8/site-packages/

    Perhaps your account does not have write access to this directory?  If the
    installation directory is a system-owned directory, you may need to sign in
    as the administrator or "root" account.  If you do not have administrative
    access to this machine, you may wish to choose a different installation
    directory, preferably one that is listed in your PYTHONPATH environment
    variable.

    For information on other options, you may wish to consult the
    documentation at:

      https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html

    Please make the appropriate changes for your system and try again.

    ----------------------------------------
ERROR: Command errored out with exit status 1: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source2_spec2_jup0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source2_spec2_jup0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix= Check the logs for full command output.
________________________________________________ test_develop[source3-spec3-jupyter-packaging-test//level1/level2/test.txt] ________________________________________________

make_package_deprecated = <function make_package_base.<locals>.do_stuff at 0x7f37c6343550>, source = ('level1/test/test.txt',)
spec = ('jupyter-packaging-test/level1/level2', 'level1/test', '**/*'), target = 'jupyter-packaging-test//level1/level2/test.txt'

    @fail_if_not_removed
    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_develop(make_package_deprecated, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package_deprecated(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
>       subprocess.check_output([shutil.which('pip'), 'install', '-e', '.'], cwd=str(package_dir))

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:69:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib64/python3.8/subprocess.py:415: in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

input = None, capture_output = False, timeout = None, check = True, popenargs = (['/usr/bin/pip', 'install', '-e', '.'],)
kwargs = {'cwd': '/tmp/pytest-of-tkloczko/pytest-0/test_develop_source3_spec3_jup0/package', 'stdout': -1}, process = <subprocess.Popen object at 0x7f37c6265e20>
stdout = b"Defaulting to user installation because normal site-packages is not writeable\nObtaining file:///tmp/pytest-of-tkloc...Installing collected packages: jupyter-packaging-test-foo\n  Running setup.py develop for jupyter-packaging-test-foo\n"
stderr = None, retcode = 1

    def run(*popenargs,
            input=None, capture_output=False, timeout=None, check=False, **kwargs):
        """Run command with arguments and return a CompletedProcess instance.

        The returned instance will have attributes args, returncode, stdout and
        stderr. By default, stdout and stderr are not captured, and those attributes
        will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.

        If check is True and the exit code was non-zero, it raises a
        CalledProcessError. The CalledProcessError object will have the return code
        in the returncode attribute, and output & stderr attributes if those streams
        were captured.

        If timeout is given, and the process takes too long, a TimeoutExpired
        exception will be raised.

        There is an optional argument "input", allowing you to
        pass bytes or a string to the subprocess's stdin.  If you use this argument
        you may not also use the Popen constructor's "stdin" argument, as
        it will be used internally.

        By default, all communication is in bytes, and therefore any "input" should
        be bytes, and the stdout and stderr will be bytes. If in text mode, any
        "input" should be a string, and stdout and stderr will be strings decoded
        according to locale encoding, or by "encoding" if set. Text mode is
        triggered by setting any of text, encoding, errors or universal_newlines.

        The other arguments are the same as for the Popen constructor.
        """
        if input is not None:
            if kwargs.get('stdin') is not None:
                raise ValueError('stdin and input arguments may not both be used.')
            kwargs['stdin'] = PIPE

        if capture_output:
            if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
                raise ValueError('stdout and stderr arguments may not be used '
                                 'with capture_output.')
            kwargs['stdout'] = PIPE
            kwargs['stderr'] = PIPE

        with Popen(*popenargs, **kwargs) as process:
            try:
                stdout, stderr = process.communicate(input, timeout=timeout)
            except TimeoutExpired as exc:
                process.kill()
                if _mswindows:
                    # Windows accumulates the output in a single blocking
                    # read() call run on child threads, with the timeout
                    # being done in a join() on those threads.  communicate()
                    # _after_ kill() is required to collect that and add it
                    # to the exception.
                    exc.stdout, exc.stderr = process.communicate()
                else:
                    # POSIX _communicate already populated the output so
                    # far into the TimeoutExpired exception.
                    process.wait()
                raise
            except:  # Including KeyboardInterrupt, communicate handled that.
                process.kill()
                # We don't call process.wait() as .__exit__ does that for us.
                raise
            retcode = process.poll()
            if check and retcode:
>               raise CalledProcessError(retcode, process.args,
                                         output=stdout, stderr=stderr)
E               subprocess.CalledProcessError: Command '['/usr/bin/pip', 'install', '-e', '.']' returned non-zero exit status 1.

/usr/lib64/python3.8/subprocess.py:516: CalledProcessError
--------------------------------------------------------------------------- Captured stderr call ---------------------------------------------------------------------------
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source3_spec3_jup0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source3_spec3_jup0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix=
         cwd: /tmp/pytest-of-tkloczko/pytest-0/test_develop_source3_spec3_jup0/package/
    Complete output (42 lines):
    running develop
    /tmp/pytest-of-tkloczko/pytest-0/test_develop_source3_spec3_jup0/package/setup.py:10: DeprecatedWarning: create_cmdclass is deprecated as of 0.8 and will be removed in 1.0. "
    Use `wrap_installers` to handle prebuild steps in cmdclass.
    Use `get_data_files` to handle data files.
    Use `include_package_data=True` and `MANIFEST.in` for package data.

      cmdclass = create_cmdclass('jsdeps', data_files_spec=[('jupyter-packaging-test/level1/level2', 'level1/test', '**/*')], exclude=exclude)
    /tmp/pytest-of-tkloczko/pytest-0/test_develop_source3_spec3_jup0/package/setup.py:11: DeprecatedWarning: install_npm is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
      cmdclass['jsdeps'] = install_npm()
    /usr/lib64/python3.8/distutils/dist.py:274: UserWarning: Unknown distribution option: 'skip_if_exists'
      warnings.warn(msg)
    /tmp/pip-build-env-d7ipludc/overlay/lib/python3.8/site-packages/setuptools/command/easy_install.py:156: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    WARNING: The user site-packages directory is disabled.
    /tmp/pip-build-env-d7ipludc/overlay/lib/python3.8/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    error: can't create or remove files in install directory

    The following error occurred while trying to add or remove files in the
    installation directory:

        [Errno 13] Permission denied: '/usr/lib/python3.8/site-packages/test-easy-install-20587.write-test'

    The installation directory you specified (via --install-dir, --prefix, or
    the distutils default setting) was:

        /usr/lib/python3.8/site-packages/

    Perhaps your account does not have write access to this directory?  If the
    installation directory is a system-owned directory, you may need to sign in
    as the administrator or "root" account.  If you do not have administrative
    access to this machine, you may wish to choose a different installation
    directory, preferably one that is listed in your PYTHONPATH environment
    variable.

    For information on other options, you may wish to consult the
    documentation at:

      https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html

    Please make the appropriate changes for your system and try again.

    ----------------------------------------
ERROR: Command errored out with exit status 1: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source3_spec3_jup0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source3_spec3_jup0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix= Check the logs for full command output.
_________________________________________________ test_develop[source4-spec4-jupyter-packaging-test/level2/test/test.txt] __________________________________________________

make_package_deprecated = <function make_package_base.<locals>.do_stuff at 0x7f37c61f19d0>, source = ('level1/level2/test/test.txt',)
spec = ('jupyter-packaging-test', 'level1', '**/*'), target = 'jupyter-packaging-test/level2/test/test.txt'

    @fail_if_not_removed
    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_develop(make_package_deprecated, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package_deprecated(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
>       subprocess.check_output([shutil.which('pip'), 'install', '-e', '.'], cwd=str(package_dir))

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:69:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib64/python3.8/subprocess.py:415: in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

input = None, capture_output = False, timeout = None, check = True, popenargs = (['/usr/bin/pip', 'install', '-e', '.'],)
kwargs = {'cwd': '/tmp/pytest-of-tkloczko/pytest-0/test_develop_source4_spec4_jup0/package', 'stdout': -1}, process = <subprocess.Popen object at 0x7f37c60d22b0>
stdout = b"Defaulting to user installation because normal site-packages is not writeable\nObtaining file:///tmp/pytest-of-tkloc...Installing collected packages: jupyter-packaging-test-foo\n  Running setup.py develop for jupyter-packaging-test-foo\n"
stderr = None, retcode = 1

    def run(*popenargs,
            input=None, capture_output=False, timeout=None, check=False, **kwargs):
        """Run command with arguments and return a CompletedProcess instance.

        The returned instance will have attributes args, returncode, stdout and
        stderr. By default, stdout and stderr are not captured, and those attributes
        will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.

        If check is True and the exit code was non-zero, it raises a
        CalledProcessError. The CalledProcessError object will have the return code
        in the returncode attribute, and output & stderr attributes if those streams
        were captured.

        If timeout is given, and the process takes too long, a TimeoutExpired
        exception will be raised.

        There is an optional argument "input", allowing you to
        pass bytes or a string to the subprocess's stdin.  If you use this argument
        you may not also use the Popen constructor's "stdin" argument, as
        it will be used internally.

        By default, all communication is in bytes, and therefore any "input" should
        be bytes, and the stdout and stderr will be bytes. If in text mode, any
        "input" should be a string, and stdout and stderr will be strings decoded
        according to locale encoding, or by "encoding" if set. Text mode is
        triggered by setting any of text, encoding, errors or universal_newlines.

        The other arguments are the same as for the Popen constructor.
        """
        if input is not None:
            if kwargs.get('stdin') is not None:
                raise ValueError('stdin and input arguments may not both be used.')
            kwargs['stdin'] = PIPE

        if capture_output:
            if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
                raise ValueError('stdout and stderr arguments may not be used '
                                 'with capture_output.')
            kwargs['stdout'] = PIPE
            kwargs['stderr'] = PIPE

        with Popen(*popenargs, **kwargs) as process:
            try:
                stdout, stderr = process.communicate(input, timeout=timeout)
            except TimeoutExpired as exc:
                process.kill()
                if _mswindows:
                    # Windows accumulates the output in a single blocking
                    # read() call run on child threads, with the timeout
                    # being done in a join() on those threads.  communicate()
                    # _after_ kill() is required to collect that and add it
                    # to the exception.
                    exc.stdout, exc.stderr = process.communicate()
                else:
                    # POSIX _communicate already populated the output so
                    # far into the TimeoutExpired exception.
                    process.wait()
                raise
            except:  # Including KeyboardInterrupt, communicate handled that.
                process.kill()
                # We don't call process.wait() as .__exit__ does that for us.
                raise
            retcode = process.poll()
            if check and retcode:
>               raise CalledProcessError(retcode, process.args,
                                         output=stdout, stderr=stderr)
E               subprocess.CalledProcessError: Command '['/usr/bin/pip', 'install', '-e', '.']' returned non-zero exit status 1.

/usr/lib64/python3.8/subprocess.py:516: CalledProcessError
--------------------------------------------------------------------------- Captured stderr call ---------------------------------------------------------------------------
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source4_spec4_jup0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source4_spec4_jup0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix=
         cwd: /tmp/pytest-of-tkloczko/pytest-0/test_develop_source4_spec4_jup0/package/
    Complete output (42 lines):
    running develop
    /tmp/pytest-of-tkloczko/pytest-0/test_develop_source4_spec4_jup0/package/setup.py:10: DeprecatedWarning: create_cmdclass is deprecated as of 0.8 and will be removed in 1.0. "
    Use `wrap_installers` to handle prebuild steps in cmdclass.
    Use `get_data_files` to handle data files.
    Use `include_package_data=True` and `MANIFEST.in` for package data.

      cmdclass = create_cmdclass('jsdeps', data_files_spec=[('jupyter-packaging-test', 'level1', '**/*')], exclude=exclude)
    /tmp/pytest-of-tkloczko/pytest-0/test_develop_source4_spec4_jup0/package/setup.py:11: DeprecatedWarning: install_npm is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
      cmdclass['jsdeps'] = install_npm()
    /usr/lib64/python3.8/distutils/dist.py:274: UserWarning: Unknown distribution option: 'skip_if_exists'
      warnings.warn(msg)
    /tmp/pip-build-env-1wj4wxah/overlay/lib/python3.8/site-packages/setuptools/command/easy_install.py:156: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    WARNING: The user site-packages directory is disabled.
    /tmp/pip-build-env-1wj4wxah/overlay/lib/python3.8/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    error: can't create or remove files in install directory

    The following error occurred while trying to add or remove files in the
    installation directory:

        [Errno 13] Permission denied: '/usr/lib/python3.8/site-packages/test-easy-install-20613.write-test'

    The installation directory you specified (via --install-dir, --prefix, or
    the distutils default setting) was:

        /usr/lib/python3.8/site-packages/

    Perhaps your account does not have write access to this directory?  If the
    installation directory is a system-owned directory, you may need to sign in
    as the administrator or "root" account.  If you do not have administrative
    access to this machine, you may wish to choose a different installation
    directory, preferably one that is listed in your PYTHONPATH environment
    variable.

    For information on other options, you may wish to consult the
    documentation at:

      https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html

    Please make the appropriate changes for your system and try again.

    ----------------------------------------
ERROR: Command errored out with exit status 1: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source4_spec4_jup0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-0/test_develop_source4_spec4_jup0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix= Check the logs for full command output.
_______________________________________________________ test_install[source0-spec0-jupyter-packaging-test/test.txt] ________________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7f37c60478b0>, source = ('share/test.txt',), spec = ('jupyter-packaging-test', 'share', '**/*')
target = 'jupyter-packaging-test/test.txt'

    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_install(make_package, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
        subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
>       assert target_path.exists()
E       AssertionError: assert False
E        +  where False = <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/test.txt')>()
E        +    where <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/test.txt')> = PosixPath('/usr/jupyter-packaging-test/test.txt').exists

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:89: AssertionError
____________________________________________________ test_install[source1-spec1-jupyter-packaging-test/level1/test.txt] ____________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7f37c5f370d0>, source = ('share/test.txt',)
spec = ('jupyter-packaging-test/level1', 'share', '**/[a-z]est.txt'), target = 'jupyter-packaging-test/level1/test.txt'

    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_install(make_package, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
        subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
>       assert target_path.exists()
E       AssertionError: assert False
E        +  where False = <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/level1/test.txt')>()
E        +    where <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/level1/test.txt')> = PosixPath('/usr/jupyter-packaging-test/level1/test.txt').exists

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:89: AssertionError
_______________________________________________________ test_install[source2-spec2-jupyter-packaging-test/test.txt] ________________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7f37c5f37c10>, source = ('level1/test/test.txt',)
spec = ('jupyter-packaging-test', 'level1/test', '**/*'), target = 'jupyter-packaging-test/test.txt'

    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_install(make_package, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
        subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
>       assert target_path.exists()
E       AssertionError: assert False
E        +  where False = <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/test.txt')>()
E        +    where <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/test.txt')> = PosixPath('/usr/jupyter-packaging-test/test.txt').exists

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:89: AssertionError
________________________________________________ test_install[source3-spec3-jupyter-packaging-test//level1/level2/test.txt] ________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7f37c5f37a60>, source = ('level1/test/test.txt',)
spec = ('jupyter-packaging-test/level1/level2', 'level1/test', '**/*'), target = 'jupyter-packaging-test//level1/level2/test.txt'

    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_install(make_package, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
        subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
>       assert target_path.exists()
E       AssertionError: assert False
E        +  where False = <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/level1/level2/test.txt')>()
E        +    where <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/level1/level2/test.txt')> = PosixPath('/usr/jupyter-packaging-test/level1/level2/test.txt').exists

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:89: AssertionError
_________________________________________________ test_install[source4-spec4-jupyter-packaging-test/level2/test/test.txt] __________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7f37c5f37ee0>, source = ('level1/level2/test/test.txt',)
spec = ('jupyter-packaging-test', 'level1', '**/*'), target = 'jupyter-packaging-test/level2/test/test.txt'

    @pytest.mark.parametrize(
        'source,spec,target',
        data_files_combinations
    )
    def test_install(make_package, source,spec,target):
        name = 'jupyter_packaging_test_foo'
        package_dir = make_package(name=name, data_files=source, data_files_spec=[spec])
        target_path = pathlib.Path(sys.prefix).joinpath(target)
        if target_path.exists():
            shutil.rmtree(str(target_path.parent))
        subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
>       assert target_path.exists()
E       AssertionError: assert False
E        +  where False = <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/level2/test/test.txt')>()
E        +    where <bound method Path.exists of PosixPath('/usr/jupyter-packaging-test/level2/test/test.txt')> = PosixPath('/usr/jupyter-packaging-test/level2/test/test.txt').exists

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_datafiles_install.py:89: AssertionError
___________________________________________________________________________ test_create_cmdclass ___________________________________________________________________________

self = <jupyter_packaging.setupbase._wrap_command.<locals>.WrappedCommand object at 0x7f37c61d4ca0>

    def check_site_dir(self):  # noqa: C901  # is too complex (12)  # FIXME
        """Verify that self.install_dir is .pth-capable dir, if needed"""

        instdir = normalize_path(self.install_dir)
        pth_file = os.path.join(instdir, 'easy-install.pth')

        if not os.path.exists(instdir):
            try:
                os.makedirs(instdir)
            except (OSError, IOError):
                self.cant_write_to_target()

        # Is it a configured, PYTHONPATH, implicit, or explicit site dir?
        is_site_dir = instdir in self.all_site_dirs

        if not is_site_dir and not self.multi_version:
            # No?  Then directly test whether it does .pth file processing
            is_site_dir = self.check_pth_processing()
        else:
            # make sure we can write to target dir
            testfile = self.pseudo_tempname() + '.write-test'
            test_exists = os.path.exists(testfile)
            try:
                if test_exists:
                    os.unlink(testfile)
>               open(testfile, 'w').close()
E               PermissionError: [Errno 13] Permission denied: '/usr/lib/python3.8/site-packages/test-easy-install-20261.write-test'

/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:471: PermissionError

During handling of the above exception, another exception occurred:

make_package_deprecated = <function make_package_base.<locals>.do_stuff at 0x7f37c6200b80>, mocker = <pytest_mock.plugin.MockerFixture object at 0x7f37c6347ac0>

    def test_create_cmdclass(make_package_deprecated, mocker):
        source = ("share/test.txt",)
        spec =  ("jupyter-packaging-test", "share", "**/*")
        target = "jupyter-packaging-test/test.txt"

        pkg_path = make_package_deprecated(data_files=source, data_files_spec=spec)
        os.chdir(pkg_path)
        cmdclass = pkg.create_cmdclass(
            package_data_spec=dict(foo="*.*"),
            data_files_spec=[spec],
            exclude=lambda x: False
        )
        for name in ['build_py', 'handle_files', 'sdist', 'bdist_wheel']:
            assert name in cmdclass

        dist = Distribution()
        cmdclass['handle_files'](dist).run()
        assert dist.data_files == [('jupyter-packaging-test', ['share/test.txt'])]
        assert dist.package_data == {'foo': []}

        # Test installation of data_files in develop mode
        dist = Distribution()
        handler = cmdclass['handle_files'](dist)
        develop = cmdclass['develop'](dist)

        def run_command(name):
            cmdclass[name](dist).run()

        mocker.patch.object(pkg.develop, 'install_for_development')
        develop.run_command = run_command
>       develop.install_for_development()

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:101:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:685: in install_for_development
    self.finalize_options()
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:52: in finalize_options
    easy_install.finalize_options(self)
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:315: in finalize_options
    self.check_site_dir()
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:474: in check_site_dir
    self.cant_write_to_target()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <jupyter_packaging.setupbase._wrap_command.<locals>.WrappedCommand object at 0x7f37c61d4ca0>

    def cant_write_to_target(self):
        msg = self.__cant_write_msg % (sys.exc_info()[1], self.install_dir,)

        if not os.path.exists(self.install_dir):
            msg += '\n' + self.__not_exists_id
        else:
            msg += '\n' + self.__access_msg
>       raise DistutilsError(msg)
E       distutils.errors.DistutilsError: can't create or remove files in install directory
E
E       The following error occurred while trying to add or remove files in the
E       installation directory:
E
E           [Errno 13] Permission denied: '/usr/lib/python3.8/site-packages/test-easy-install-20261.write-test'
E
E       The installation directory you specified (via --install-dir, --prefix, or
E       the distutils default setting) was:
E
E           /usr/lib/python3.8/site-packages/
E
E       Perhaps your account does not have write access to this directory?  If the
E       installation directory is a system-owned directory, you may need to sign in
E       as the administrator or "root" account.  If you do not have administrative
E       access to this machine, you may wish to choose a different installation
E       directory, preferably one that is listed in your PYTHONPATH environment
E       variable.
E
E       For information on other options, you may wish to consult the
E       documentation at:
E
E         https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html
E
E       Please make the appropriate changes for your system and try again.

/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:534: DistutilsError
_______________________________________________________________________________ test_install _______________________________________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7f37c6200c10>, tmp_path = PosixPath('/tmp/pytest-of-tkloczko/pytest-0/test_install0')

    def test_install(make_package, tmp_path):
        name = 'jupyter_packaging_test_foo'
        ensured_targets=[f'{name}/main.py']
        package_dir = make_package(name=name, ensured_targets=ensured_targets)
        subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
        # Get site packages where the package is installed.
        sitepkg = Path(sysconfig.get_paths()["purelib"])
        installed_file = sitepkg / f"{name}/main.py"
>       assert installed_file.exists()
E       AssertionError: assert False
E        +  where False = <bound method Path.exists of PosixPath('/usr/lib/python3.8/site-packages/jupyter_packaging_test_foo/main.py')>()
E        +    where <bound method Path.exists of PosixPath('/usr/lib/python3.8/site-packages/jupyter_packaging_test_foo/main.py')> = PosixPath('/usr/lib/python3.8/site-packages/jupyter_packaging_test_foo/main.py').exists

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_install.py:18: AssertionError
___________________________________________________________________________ test_install_hybrid ____________________________________________________________________________

make_hybrid_package = <function make_package_base.<locals>.do_stuff at 0x7f37c600ff70>, tmp_path = PosixPath('/tmp/pytest-of-tkloczko/pytest-0/test_install_hybrid0')

    def test_install_hybrid(make_hybrid_package, tmp_path):
        name = 'jupyter_packaging_test_foo'
        ensured_targets = [f"{name}/main.py", f"{name}/generated.js"]
        package_dir = make_hybrid_package(name=name, ensured_targets=ensured_targets, skip_if_exists=[f"{name}/generated.js"])
>       subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_install.py:29:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib64/python3.8/subprocess.py:415: in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

input = None, capture_output = False, timeout = None, check = True, popenargs = (['/usr/bin/pip', 'install', '.'],)
kwargs = {'cwd': '/tmp/pytest-of-tkloczko/pytest-0/test_install_hybrid0/package', 'stdout': -1}, process = <subprocess.Popen object at 0x7f37c631b9a0>
stdout = b"Defaulting to user installation because normal site-packages is not writeable\nProcessing /tmp/pytest-of-tkloczko/py...upyter-packaging-test-foo (pyproject.toml): finished with status 'error'\nFailed to build jupyter-packaging-test-foo\n"
stderr = None, retcode = 1

    def run(*popenargs,
            input=None, capture_output=False, timeout=None, check=False, **kwargs):
        """Run command with arguments and return a CompletedProcess instance.

        The returned instance will have attributes args, returncode, stdout and
        stderr. By default, stdout and stderr are not captured, and those attributes
        will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.

        If check is True and the exit code was non-zero, it raises a
        CalledProcessError. The CalledProcessError object will have the return code
        in the returncode attribute, and output & stderr attributes if those streams
        were captured.

        If timeout is given, and the process takes too long, a TimeoutExpired
        exception will be raised.

        There is an optional argument "input", allowing you to
        pass bytes or a string to the subprocess's stdin.  If you use this argument
        you may not also use the Popen constructor's "stdin" argument, as
        it will be used internally.

        By default, all communication is in bytes, and therefore any "input" should
        be bytes, and the stdout and stderr will be bytes. If in text mode, any
        "input" should be a string, and stdout and stderr will be strings decoded
        according to locale encoding, or by "encoding" if set. Text mode is
        triggered by setting any of text, encoding, errors or universal_newlines.

        The other arguments are the same as for the Popen constructor.
        """
        if input is not None:
            if kwargs.get('stdin') is not None:
                raise ValueError('stdin and input arguments may not both be used.')
            kwargs['stdin'] = PIPE

        if capture_output:
            if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
                raise ValueError('stdout and stderr arguments may not be used '
                                 'with capture_output.')
            kwargs['stdout'] = PIPE
            kwargs['stderr'] = PIPE

        with Popen(*popenargs, **kwargs) as process:
            try:
                stdout, stderr = process.communicate(input, timeout=timeout)
            except TimeoutExpired as exc:
                process.kill()
                if _mswindows:
                    # Windows accumulates the output in a single blocking
                    # read() call run on child threads, with the timeout
                    # being done in a join() on those threads.  communicate()
                    # _after_ kill() is required to collect that and add it
                    # to the exception.
                    exc.stdout, exc.stderr = process.communicate()
                else:
                    # POSIX _communicate already populated the output so
                    # far into the TimeoutExpired exception.
                    process.wait()
                raise
            except:  # Including KeyboardInterrupt, communicate handled that.
                process.kill()
                # We don't call process.wait() as .__exit__ does that for us.
                raise
            retcode = process.poll()
            if check and retcode:
>               raise CalledProcessError(retcode, process.args,
                                         output=stdout, stderr=stderr)
E               subprocess.CalledProcessError: Command '['/usr/bin/pip', 'install', '.']' returned non-zero exit status 1.

/usr/lib64/python3.8/subprocess.py:516: CalledProcessError
--------------------------------------------------------------------------- Captured stderr call ---------------------------------------------------------------------------
  ERROR: Command errored out with exit status 1:
   command: /usr/bin/python3 /usr/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py build_wheel /tmp/tmp52zj7g6v
       cwd: /tmp/pytest-of-tkloczko/pytest-0/test_install_hybrid0/package
  Complete output (36 lines):
  running bdist_wheel
  running pre_dist
  `npm` unavailable.  If you're running this command using sudo, make sure `npm` is available to sudo
  running ensure_targets
  Traceback (most recent call last):
    File "/usr/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 363, in <module>
      main()
    File "/usr/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 345, in main
      json_out['return_val'] = hook(**hook_input['kwargs'])
    File "/usr/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 261, in build_wheel
      return _build_backend().build_wheel(wheel_directory, config_settings,
    File "/tmp/pip-build-env-0bvi_ope/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 230, in build_wheel
      return self._build_with_temp_dir(['bdist_wheel'], '.whl',
    File "/tmp/pip-build-env-0bvi_ope/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 215, in _build_with_temp_dir
      self.run_setup()
    File "/tmp/pip-build-env-0bvi_ope/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 158, in run_setup
      exec(compile(code, __file__, 'exec'), locals())
    File "setup.py", line 13, in <module>
      setuptools.setup(data_files=data_files, cmdclass=cmdclass, packages=setuptools.find_packages('.'),
    File "/tmp/pip-build-env-0bvi_ope/overlay/lib/python3.8/site-packages/setuptools/__init__.py", line 159, in setup
      return distutils.core.setup(**attrs)
    File "/usr/lib64/python3.8/distutils/core.py", line 148, in setup
      dist.run_commands()
    File "/usr/lib64/python3.8/distutils/dist.py", line 966, in run_commands
      self.run_command(cmd)
    File "/usr/lib64/python3.8/distutils/dist.py", line 985, in run_command
      cmd_obj.run()
    File "/tmp/pip-build-env-0bvi_ope/overlay/lib/python3.8/site-packages/jupyter_packaging/setupbase.py", line 133, in run
      self.run_command('ensure_targets')
    File "/usr/lib64/python3.8/distutils/cmd.py", line 313, in run_command
      self.distribution.run_command(command)
    File "/usr/lib64/python3.8/distutils/dist.py", line 985, in run_command
      cmd_obj.run()
    File "/tmp/pip-build-env-0bvi_ope/overlay/lib/python3.8/site-packages/jupyter_packaging/setupbase.py", line 409, in run
      raise ValueError(('missing files: %s' % missing))
  ValueError: missing files: ['jupyter_packaging_test_foo/generated.js']
  ----------------------------------------
  ERROR: Failed building wheel for jupyter-packaging-test-foo
ERROR: Could not build wheels for jupyter-packaging-test-foo, which is required to install pyproject.toml-based projects
___________________________________________________________________________ test_install_missing ___________________________________________________________________________

make_package = <function make_package_base.<locals>.do_stuff at 0x7f37c6282040>, tmp_path = PosixPath('/tmp/pytest-of-tkloczko/pytest-0/test_install_missing0')

    def test_install_missing(make_package, tmp_path):
        name = 'jupyter_packaging_test_foo'
        ensured_targets=[f'{name}/missing.py']
        package_dir = make_package(name=name, ensured_targets=ensured_targets)
        with pytest.raises(subprocess.CalledProcessError):
            subprocess.check_output([shutil.which('pip'), 'install', '.'], cwd=str(package_dir))
>       subprocess.check_output([shutil.which('pip'), 'install', '-e', '.'], cwd=str(package_dir))

/home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_install.py:53:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib64/python3.8/subprocess.py:415: in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

input = None, capture_output = False, timeout = None, check = True, popenargs = (['/usr/bin/pip', 'install', '-e', '.'],)
kwargs = {'cwd': '/tmp/pytest-of-tkloczko/pytest-0/test_install_missing0/package', 'stdout': -1}, process = <subprocess.Popen object at 0x7f37c622a8e0>
stdout = b"Defaulting to user installation because normal site-packages is not writeable\nObtaining file:///tmp/pytest-of-tkloc...es/jupyter_packaging_test_foo/\n   from /home/tkloczko/.local/lib/python3.8/site-packages/~upyter_packaging_test_foo\n"
stderr = None, retcode = 1

    def run(*popenargs,
            input=None, capture_output=False, timeout=None, check=False, **kwargs):
        """Run command with arguments and return a CompletedProcess instance.

        The returned instance will have attributes args, returncode, stdout and
        stderr. By default, stdout and stderr are not captured, and those attributes
        will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.

        If check is True and the exit code was non-zero, it raises a
        CalledProcessError. The CalledProcessError object will have the return code
        in the returncode attribute, and output & stderr attributes if those streams
        were captured.

        If timeout is given, and the process takes too long, a TimeoutExpired
        exception will be raised.

        There is an optional argument "input", allowing you to
        pass bytes or a string to the subprocess's stdin.  If you use this argument
        you may not also use the Popen constructor's "stdin" argument, as
        it will be used internally.

        By default, all communication is in bytes, and therefore any "input" should
        be bytes, and the stdout and stderr will be bytes. If in text mode, any
        "input" should be a string, and stdout and stderr will be strings decoded
        according to locale encoding, or by "encoding" if set. Text mode is
        triggered by setting any of text, encoding, errors or universal_newlines.

        The other arguments are the same as for the Popen constructor.
        """
        if input is not None:
            if kwargs.get('stdin') is not None:
                raise ValueError('stdin and input arguments may not both be used.')
            kwargs['stdin'] = PIPE

        if capture_output:
            if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
                raise ValueError('stdout and stderr arguments may not be used '
                                 'with capture_output.')
            kwargs['stdout'] = PIPE
            kwargs['stderr'] = PIPE

        with Popen(*popenargs, **kwargs) as process:
            try:
                stdout, stderr = process.communicate(input, timeout=timeout)
            except TimeoutExpired as exc:
                process.kill()
                if _mswindows:
                    # Windows accumulates the output in a single blocking
                    # read() call run on child threads, with the timeout
                    # being done in a join() on those threads.  communicate()
                    # _after_ kill() is required to collect that and add it
                    # to the exception.
                    exc.stdout, exc.stderr = process.communicate()
                else:
                    # POSIX _communicate already populated the output so
                    # far into the TimeoutExpired exception.
                    process.wait()
                raise
            except:  # Including KeyboardInterrupt, communicate handled that.
                process.kill()
                # We don't call process.wait() as .__exit__ does that for us.
                raise
            retcode = process.poll()
            if check and retcode:
>               raise CalledProcessError(retcode, process.args,
                                         output=stdout, stderr=stderr)
E               subprocess.CalledProcessError: Command '['/usr/bin/pip', 'install', '-e', '.']' returned non-zero exit status 1.

/usr/lib64/python3.8/subprocess.py:516: CalledProcessError
--------------------------------------------------------------------------- Captured stderr call ---------------------------------------------------------------------------
  ERROR: Command errored out with exit status 1:
   command: /usr/bin/python3 /usr/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py build_wheel /tmp/tmpis447da5
       cwd: /tmp/pytest-of-tkloczko/pytest-0/test_install_missing0/package
  Complete output (35 lines):
  running bdist_wheel
  running pre_dist
  running ensure_targets
  Traceback (most recent call last):
    File "/usr/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 363, in <module>
      main()
    File "/usr/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 345, in main
      json_out['return_val'] = hook(**hook_input['kwargs'])
    File "/usr/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 261, in build_wheel
      return _build_backend().build_wheel(wheel_directory, config_settings,
    File "/tmp/pip-build-env-ddyf2q8l/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 230, in build_wheel
      return self._build_with_temp_dir(['bdist_wheel'], '.whl',
    File "/tmp/pip-build-env-ddyf2q8l/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 215, in _build_with_temp_dir
      self.run_setup()
    File "/tmp/pip-build-env-ddyf2q8l/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 158, in run_setup
      exec(compile(code, __file__, 'exec'), locals())
    File "setup.py", line 13, in <module>
      setuptools.setup(data_files=data_files, cmdclass=cmdclass, packages=setuptools.find_packages('.'),
    File "/tmp/pip-build-env-ddyf2q8l/overlay/lib/python3.8/site-packages/setuptools/__init__.py", line 159, in setup
      return distutils.core.setup(**attrs)
    File "/usr/lib64/python3.8/distutils/core.py", line 148, in setup
      dist.run_commands()
    File "/usr/lib64/python3.8/distutils/dist.py", line 966, in run_commands
      self.run_command(cmd)
    File "/usr/lib64/python3.8/distutils/dist.py", line 985, in run_command
      cmd_obj.run()
    File "/tmp/pip-build-env-ddyf2q8l/overlay/lib/python3.8/site-packages/jupyter_packaging/setupbase.py", line 133, in run
      self.run_command('ensure_targets')
    File "/usr/lib64/python3.8/distutils/cmd.py", line 313, in run_command
      self.distribution.run_command(command)
    File "/usr/lib64/python3.8/distutils/dist.py", line 985, in run_command
      cmd_obj.run()
    File "/tmp/pip-build-env-ddyf2q8l/overlay/lib/python3.8/site-packages/jupyter_packaging/setupbase.py", line 409, in run
      raise ValueError(('missing files: %s' % missing))
  ValueError: missing files: ['jupyter_packaging_test_foo/missing.py']
  ----------------------------------------
  ERROR: Failed building wheel for jupyter-packaging-test-foo
ERROR: Could not build wheels for jupyter-packaging-test-foo, which is required to install pyproject.toml-based projects
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-0/test_install_missing0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-0/test_install_missing0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix=
         cwd: /tmp/pytest-of-tkloczko/pytest-0/test_install_missing0/package/
    Complete output (32 lines):
    running develop
    /tmp/pip-build-env-3ujs3lv4/overlay/lib/python3.8/site-packages/setuptools/command/easy_install.py:156: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    WARNING: The user site-packages directory is disabled.
    /tmp/pip-build-env-3ujs3lv4/overlay/lib/python3.8/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
      warnings.warn(
    error: can't create or remove files in install directory

    The following error occurred while trying to add or remove files in the
    installation directory:

        [Errno 13] Permission denied: '/usr/lib/python3.8/site-packages/test-easy-install-20965.write-test'

    The installation directory you specified (via --install-dir, --prefix, or
    the distutils default setting) was:

        /usr/lib/python3.8/site-packages/

    Perhaps your account does not have write access to this directory?  If the
    installation directory is a system-owned directory, you may need to sign in
    as the administrator or "root" account.  If you do not have administrative
    access to this machine, you may wish to choose a different installation
    directory, preferably one that is listed in your PYTHONPATH environment
    variable.

    For information on other options, you may wish to consult the
    documentation at:

      https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html

    Please make the appropriate changes for your system and try again.

    ----------------------------------------
ERROR: Command errored out with exit status 1: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pytest-of-tkloczko/pytest-0/test_install_missing0/package/setup.py'"'"'; __file__='"'"'/tmp/pytest-of-tkloczko/pytest-0/test_install_missing0/package/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps --user --prefix= Check the logs for full command output.
============================================================================= warnings summary =============================================================================
tests/test_deprecated.py::test_ensure_python
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:58: DeprecatedWarning: ensure_python is deprecated as of 0.7 and will be removed in 1.0. Use `setuptools` `python_requires` instead
    pkg.ensure_python('>=3.6')

tests/test_deprecated.py::test_ensure_python
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:59: DeprecatedWarning: ensure_python is deprecated as of 0.7 and will be removed in 1.0. Use `setuptools` `python_requires` instead
    pkg.ensure_python(['>=3.6', '>=3.5'])

tests/test_deprecated.py::test_ensure_python
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:62: DeprecatedWarning: ensure_python is deprecated as of 0.7 and will be removed in 1.0. Use `setuptools` `python_requires` instead
    pkg.ensure_python('<3.5')

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:78: DeprecatedWarning: create_cmdclass is deprecated as of 0.8 and will be removed in 1.0. "
  Use `wrap_installers` to handle prebuild steps in cmdclass.
  Use `get_data_files` to handle data files.
  Use `include_package_data=True` and `MANIFEST.in` for package data.

    cmdclass = pkg.create_cmdclass(

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:563: DeprecatedWarning: _get_file_handler is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    handle_files = _get_file_handler(package_data_spec, data_files_spec, exclude)

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:564: DeprecatedWarning: _get_develop_handler is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    develop_handler = _get_develop_handler()

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:574: DeprecatedWarning: _wrap_command is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    build_py=wrapper(build_py, strict=is_repo),

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:576: DeprecatedWarning: _wrap_command is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    sdist=wrapper(sdist, strict=True),

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:581: DeprecatedWarning: _wrap_command is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    cmdclass['bdist_wheel'] = wrapper(bdist_wheel, strict=True)

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:583: DeprecatedWarning: _wrap_command is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    cmdclass['develop'] = wrapper(develop_handler, strict=True)

tests/test_deprecated.py::test_create_cmdclass
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:666: DeprecatedWarning: _get_package_data is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    files =  _get_package_data(key, patterns)

tests/test_deprecated.py::test_create_cmdclass
  /usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:156: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
    warnings.warn(

tests/test_deprecated.py::test_create_cmdclass
  /usr/lib/python3.8/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
    warnings.warn(

tests/test_deprecated.py::test_command_for_func
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:111: DeprecatedWarning: command_for_func is deprecated as of 0.8 and will be removed in 1.0. Use `BaseCommand` directly instead
    cmd = pkg.command_for_func(func)

tests/test_deprecated.py::test_command_for_func
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:458: DeprecatedWarning: update_package_data is deprecated as of 0.8 and will be removed in 1.0. Use `use_package_data=True` and `MANIFEST.in` instead
    update_package_data(self.distribution)

tests/test_deprecated.py::test_install_npm
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:117: DeprecatedWarning: install_npm is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    builder = pkg.install_npm()

tests/test_deprecated.py::test__wrap_command
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.11.1/tests/test_deprecated.py:131: DeprecatedWarning: _wrap_command is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    cmd = pkg._wrap_command(['js'], TestCommand)

tests/test_deprecated.py::test__wrap_command
  /home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.11.1-2.fc35.x86_64/usr/lib/python3.8/site-packages/jupyter_packaging/setupbase.py:647: DeprecatedWarning: update_package_data is deprecated as of 0.8 and will be removed in 1.0. Use `use_package_data=True` and `MANIFEST.in` instead
    update_package_data(self.distribution)

tests/test_utility_functions.py::test_get_version
  <string>:421: DeprecationWarning: invalid escape sequence \d

-- Docs: https://docs.pytest.org/en/stable/warnings.html
========================================================================= short test summary info ==========================================================================
SKIPPED [1] tests/test_deprecated.py:65: Tests RuntimeError for Python 3.10+
FAILED tests/test_datafiles_install.py::test_develop[source0-spec0-jupyter-packaging-test/test.txt] - subprocess.CalledProcessError: Command '['/usr/bin/pip', 'install',...
FAILED tests/test_datafiles_install.py::test_develop[source1-spec1-jupyter-packaging-test/level1/test.txt] - subprocess.CalledProcessError: Command '['/usr/bin/pip', 'in...
FAILED tests/test_datafiles_install.py::test_develop[source2-spec2-jupyter-packaging-test/test.txt] - subprocess.CalledProcessError: Command '['/usr/bin/pip', 'install',...
FAILED tests/test_datafiles_install.py::test_develop[source3-spec3-jupyter-packaging-test//level1/level2/test.txt] - subprocess.CalledProcessError: Command '['/usr/bin/p...
FAILED tests/test_datafiles_install.py::test_develop[source4-spec4-jupyter-packaging-test/level2/test/test.txt] - subprocess.CalledProcessError: Command '['/usr/bin/pip'...
FAILED tests/test_datafiles_install.py::test_install[source0-spec0-jupyter-packaging-test/test.txt] - AssertionError: assert False
FAILED tests/test_datafiles_install.py::test_install[source1-spec1-jupyter-packaging-test/level1/test.txt] - AssertionError: assert False
FAILED tests/test_datafiles_install.py::test_install[source2-spec2-jupyter-packaging-test/test.txt] - AssertionError: assert False
FAILED tests/test_datafiles_install.py::test_install[source3-spec3-jupyter-packaging-test//level1/level2/test.txt] - AssertionError: assert False
FAILED tests/test_datafiles_install.py::test_install[source4-spec4-jupyter-packaging-test/level2/test/test.txt] - AssertionError: assert False
FAILED tests/test_deprecated.py::test_create_cmdclass - distutils.errors.DistutilsError: can't create or remove files in install directory
FAILED tests/test_install.py::test_install - AssertionError: assert False
FAILED tests/test_install.py::test_install_hybrid - subprocess.CalledProcessError: Command '['/usr/bin/pip', 'install', '.']' returned non-zero exit status 1.
FAILED tests/test_install.py::test_install_missing - subprocess.CalledProcessError: Command '['/usr/bin/pip', 'install', '-e', '.']' returned non-zero exit status 1.
==================================================== 14 failed, 51 passed, 1 skipped, 19 warnings in 243.86s (0:04:03) =====================================================

Bug in ensure_python

ensure_python does not work for Python 3.10:

Python 3.10.0b2 (default, Jun  1 2021, 00:00:00) [GCC 11.1.1 20210428 (Red Hat 11.1.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import jupyter_packaging.setupbase as pkg
>>> pkg.ensure_python(">=3.6")
<stdin>:1: DeprecatedWarning: ensure_python is deprecated as of 0.7 and will be removed in 1.0. Use `setuptools` `python_requires` instead
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/lbalhar/.virtualenvs/tmp-5c2b09dccbe8317/lib/python3.10/site-packages/deprecation.py", line 260, in _inner
    return function(*args, **kwargs)
  File "/home/lbalhar/Software/jupyter-packaging/jupyter_packaging/setupbase.py", line 474, in ensure_python
    raise ValueError('Python version %s unsupported' % part)
ValueError: Python version 3.10 unsupported

I know it's deprecated but the 3.10 might be released sooner than the function disappears.

How is this repo intended to be used?

@ian-r-rose and I are looking to release jupyterlab-latex which is python 3.6+ only.

While I was building some of the version checking based on the IPython repo, Ian pointed out that this repo existed and we might be able to use common tooling. He pointed out that a few repos use a setupbase.py similar to the one here.

Currently the README says to pip install jupyter-packaging and then doesn't quite say how to use the package after it has been installed. We looked at the __main__ and noticed that that would seem to do the necessary copying so that

The contents of jupyter_packaging.py are copied locally to setupbase.py so they are available to run the setup.py script itself

But then, after installing from pypi, python -m jupyter_packaging did seemingly nothing.

It could be possible that we're supposed to copy the setupbase.py directly… but in that case I can't tell what the advantage of having jupyter-packaging in a package is.

Could we get some guidance on how to use this?

Nested folders in data_files are not working

The following config does not work:

data_files_spec = [
    ('etc/jupyter/jupyter_server_config.d',
     'jupyter-config/jupyter_server_config.d', 'jupyterlab.json'),
]

The file does not get copied. We need our tests to include nested folders in the second argument and account for them.

Entry point for setupbase copying

It would be nice if this package registered an entry point (or maybe a __main__.py) which copied the setupbase to the current directory. Then it would also be easier to automate this task, e.g. with a custom local script:

$ pip install -u jupyter-packaging

$ python -m jupyter-packaging
OR
$ jupyter-package-init ./

Remove data_files on uninstall

In #35 we added a develop_handler to handle data_files for a develop install.

Currently we do not remove data_files during an uninstall. uninstall is an option given to the develop target. We can use the presence of that option to remove those files.

0.12.3: pytest deprecation errors

Looks like with setuptools 68.0.0 and pytest 7.4.0 test suite is failing with deprecation errors

+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.12.3-4.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.12.3-4.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra -m 'not network'
============================= test session starts ==============================
platform linux -- Python 3.8.17, pytest-7.4.0, pluggy-1.0.0
rootdir: /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.12.3
configfile: pyproject.toml
testpaths: tests/
plugins: mock-3.11.1, timeout-2.1.0
timeout: 300.0s
timeout method: signal
timeout func_only: False
collected 13 items / 14 errors

==================================== ERRORS ====================================
___________________ ERROR collecting tests/test_build_api.py ___________________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/doctest.py:547: in collect
    module = import_path(
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_build_api.py:7: in <module>
    from jupyter_packaging.build_api import build_sdist, build_wheel
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
___________________ ERROR collecting tests/test_build_api.py ___________________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/python.py:536: in collect
    self._inject_setup_module_fixture()
/usr/lib/python3.8/site-packages/_pytest/python.py:550: in _inject_setup_module_fixture
    self.obj, ("setUpModule", "setup_module")
/usr/lib/python3.8/site-packages/_pytest/python.py:315: in obj
    self._obj = obj = self._getobj()
/usr/lib/python3.8/site-packages/_pytest/python.py:533: in _getobj
    return self._importtestmodule()
/usr/lib/python3.8/site-packages/_pytest/python.py:622: in _importtestmodule
    mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_build_api.py:7: in <module>
    from jupyter_packaging.build_api import build_sdist, build_wheel
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
________________ ERROR collecting tests/test_core_functions.py _________________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/doctest.py:547: in collect
    module = import_path(
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_core_functions.py:6: in <module>
    from jupyter_packaging.setupbase import npm_builder, wrap_installers
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
________________ ERROR collecting tests/test_core_functions.py _________________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/python.py:536: in collect
    self._inject_setup_module_fixture()
/usr/lib/python3.8/site-packages/_pytest/python.py:550: in _inject_setup_module_fixture
    self.obj, ("setUpModule", "setup_module")
/usr/lib/python3.8/site-packages/_pytest/python.py:315: in obj
    self._obj = obj = self._getobj()
/usr/lib/python3.8/site-packages/_pytest/python.py:533: in _getobj
    return self._importtestmodule()
/usr/lib/python3.8/site-packages/_pytest/python.py:622: in _importtestmodule
    mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_core_functions.py:6: in <module>
    from jupyter_packaging.setupbase import npm_builder, wrap_installers
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
________________ ERROR collecting tests/test_datafiles_paths.py ________________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/doctest.py:547: in collect
    module = import_path(
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_datafiles_paths.py:1: in <module>
    from jupyter_packaging.setupbase import get_data_files
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
________________ ERROR collecting tests/test_datafiles_paths.py ________________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/python.py:536: in collect
    self._inject_setup_module_fixture()
/usr/lib/python3.8/site-packages/_pytest/python.py:550: in _inject_setup_module_fixture
    self.obj, ("setUpModule", "setup_module")
/usr/lib/python3.8/site-packages/_pytest/python.py:315: in obj
    self._obj = obj = self._getobj()
/usr/lib/python3.8/site-packages/_pytest/python.py:533: in _getobj
    return self._importtestmodule()
/usr/lib/python3.8/site-packages/_pytest/python.py:622: in _importtestmodule
    mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_datafiles_paths.py:1: in <module>
    from jupyter_packaging.setupbase import get_data_files
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
__________________ ERROR collecting tests/test_deprecated.py ___________________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/doctest.py:547: in collect
    module = import_path(
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_deprecated.py:9: in <module>
    import jupyter_packaging.setupbase as pkg
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
__________________ ERROR collecting tests/test_deprecated.py ___________________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/python.py:536: in collect
    self._inject_setup_module_fixture()
/usr/lib/python3.8/site-packages/_pytest/python.py:550: in _inject_setup_module_fixture
    self.obj, ("setUpModule", "setup_module")
/usr/lib/python3.8/site-packages/_pytest/python.py:315: in obj
    self._obj = obj = self._getobj()
/usr/lib/python3.8/site-packages/_pytest/python.py:533: in _getobj
    return self._importtestmodule()
/usr/lib/python3.8/site-packages/_pytest/python.py:622: in _importtestmodule
    mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_deprecated.py:9: in <module>
    import jupyter_packaging.setupbase as pkg
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
___________________ ERROR collecting tests/test_is_stale.py ____________________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/doctest.py:547: in collect
    module = import_path(
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_is_stale.py:1: in <module>
    from jupyter_packaging.setupbase import is_stale
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
___________________ ERROR collecting tests/test_is_stale.py ____________________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/python.py:536: in collect
    self._inject_setup_module_fixture()
/usr/lib/python3.8/site-packages/_pytest/python.py:550: in _inject_setup_module_fixture
    self.obj, ("setUpModule", "setup_module")
/usr/lib/python3.8/site-packages/_pytest/python.py:315: in obj
    self._obj = obj = self._getobj()
/usr/lib/python3.8/site-packages/_pytest/python.py:533: in _getobj
    return self._importtestmodule()
/usr/lib/python3.8/site-packages/_pytest/python.py:622: in _importtestmodule
    mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_is_stale.py:1: in <module>
    from jupyter_packaging.setupbase import is_stale
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
_____________________ ERROR collecting tests/test_main.py ______________________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/doctest.py:547: in collect
    module = import_path(
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_main.py:1: in <module>
    from jupyter_packaging.__main__ import main
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
_____________________ ERROR collecting tests/test_main.py ______________________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/python.py:536: in collect
    self._inject_setup_module_fixture()
/usr/lib/python3.8/site-packages/_pytest/python.py:550: in _inject_setup_module_fixture
    self.obj, ("setUpModule", "setup_module")
/usr/lib/python3.8/site-packages/_pytest/python.py:315: in obj
    self._obj = obj = self._getobj()
/usr/lib/python3.8/site-packages/_pytest/python.py:533: in _getobj
    return self._importtestmodule()
/usr/lib/python3.8/site-packages/_pytest/python.py:622: in _importtestmodule
    mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_main.py:1: in <module>
    from jupyter_packaging.__main__ import main
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
_______________ ERROR collecting tests/test_utility_functions.py _______________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/doctest.py:547: in collect
    module = import_path(
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_utility_functions.py:6: in <module>
    import jupyter_packaging.setupbase as pkg
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
_______________ ERROR collecting tests/test_utility_functions.py _______________
/usr/lib/python3.8/site-packages/_pytest/runner.py:341: in from_call
    result: Optional[TResult] = func()
/usr/lib/python3.8/site-packages/_pytest/runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
/usr/lib/python3.8/site-packages/_pytest/python.py:536: in collect
    self._inject_setup_module_fixture()
/usr/lib/python3.8/site-packages/_pytest/python.py:550: in _inject_setup_module_fixture
    self.obj, ("setUpModule", "setup_module")
/usr/lib/python3.8/site-packages/_pytest/python.py:315: in obj
    self._obj = obj = self._getobj()
/usr/lib/python3.8/site-packages/_pytest/python.py:533: in _getobj
    return self._importtestmodule()
/usr/lib/python3.8/site-packages/_pytest/python.py:622: in _importtestmodule
    mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:565: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:178: in exec_module
    exec(co, module.__dict__)
tests/test_utility_functions.py:6: in <module>
    import jupyter_packaging.setupbase as pkg
jupyter_packaging/__init__.py:6: in <module>
    from .setupbase import *  # noqa
jupyter_packaging/setupbase.py:44: in <module>
    from setuptools.command.develop import develop
/usr/lib/python3.8/site-packages/setuptools/command/develop.py:8: in <module>
    from setuptools.command.easy_install import easy_install
/usr/lib/python3.8/site-packages/setuptools/command/easy_install.py:48: in <module>
    from setuptools.sandbox import run_setup
/usr/lib/python3.8/site-packages/setuptools/sandbox.py:13: in <module>
    import pkg_resources
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:118: in <module>
    warnings.warn(
E   DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
=========================== short test summary info ============================
ERROR tests/test_build_api.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
ERROR tests/test_build_api.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
ERROR tests/test_core_functions.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
ERROR tests/test_core_functions.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
ERROR tests/test_datafiles_paths.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
ERROR tests/test_datafiles_paths.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
ERROR tests/test_deprecated.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
ERROR tests/test_deprecated.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
ERROR tests/test_is_stale.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
ERROR tests/test_is_stale.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
ERROR tests/test_main.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
ERROR tests/test_main.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
ERROR tests/test_utility_functions.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
ERROR tests/test_utility_functions.py - DeprecationWarning: pkg_resources is deprecated as an API. See https://setu...
!!!!!!!!!!!!!!!!!!! Interrupted: 14 errors during collection !!!!!!!!!!!!!!!!!!!
============================== 14 errors in 3.30s ==============================

Feat: move to hatchling?

I am aware that @blink1073 has been looking into using hatch for building e.g. nbconvert.

I've also used it to write my own build plugin, and it's very easy to use. Given that hatch already supports PEP 621, PEP 517, PEP 660 et al, we'd be getting a lot of nice features up front.

Relevant Issues:

Add more declarative config

Ideally we shouldn't need a setup.py file.

  • We can use from importlib_metadata import version; version('<name>') anywhere where we're using python setup.py --version, and we can get the name from setup.cfg or pyproject.toml if available, and fall back on python setup.py --name.
  • We can add data_files config using our better tuple and glob handling
  • We should also handle ensured_targets
  • Ideally we could replace all of jupyterlab/setup.py

Running pytest fails if pip doesn't have permissions to install packages

The problem seems to be in tests/test_datafiles_install.py which tries to execute a bare pip install .

A somewhat easy workaround would be to set up a temporary directory and export PIP_TARGET=/path/to/tmp/staging before running each test that tries to pip install.

UPDATE: Also seems to affect tests/test_install.py.

`data_files` vs `package_data`

I see that the current code updates data_files with the static files generated, and not package_data. What is the reasoning behind this? I also see that jupyterlab has a pretty neat solution for updating package_data:

def update_package_data(distribution):
    """update build_py options to get package_data changes"""
    build_py = distribution.get_command_obj('build_py')
    build_py.finalize_options()

Would it be a decent (i.e. general) fix to add a call to such a function at the end of WrappedCommand.run()?

0.12.0: tests/ files are installed and pytest warnings

Just started testing 0.12.0 and found two minor issues:

  • tests/ files are installed

This can be fixed by patch

--- a/setup.cfg~        2022-03-24 23:56:48.000000000 +0000
+++ b/setup.cfg 2022-03-26 13:00:47.005702412 +0000
@@ -41,3 +41,7 @@

 [bdist_wheel]
 universal=1
+
+[options.packages.find]
+exclude =
+    tests
  • pytest is showing few warnings
+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.12.0-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-jupyter-packaging-0.12.0-2.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.12, pytest-7.1.1, pluggy-1.0.0
rootdir: /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.12.0
plugins: mock-3.7.0, cov-3.0.0
collected 66 items

tests/test_build_api.py ........                                                                                                                                     [ 12%]
tests/test_core_functions.py .......                                                                                                                                 [ 22%]
tests/test_datafiles_install.py ssssssssss                                                                                                                           [ 37%]
tests/test_datafiles_paths.py ........                                                                                                                               [ 50%]
tests/test_deprecated.py ....ss....                                                                                                                                  [ 65%]
tests/test_install.py sss                                                                                                                                            [ 69%]
tests/test_is_stale.py ...........                                                                                                                                   [ 86%]
tests/test_main.py .                                                                                                                                                 [ 87%]
tests/test_utility_functions.py ........                                                                                                                             [100%]

============================================================================= warnings summary =============================================================================
tests/test_core_functions.py::test_npm_builder_missing_yarn
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.12.0/jupyter_packaging/setupbase.py:201: DeprecationWarning: The 'warn' method is deprecated, use 'warning' instead
    log.warn("yarn not found, ignoring yarn.lock file")

tests/test_deprecated.py::test_ensure_python
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.12.0/tests/test_deprecated.py:67: DeprecatedWarning: ensure_python is deprecated as of 0.7 and will be removed in 1.0. Use `setuptools` `python_requires` instead
    pkg.ensure_python(">=3.6")

tests/test_deprecated.py::test_ensure_python
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.12.0/tests/test_deprecated.py:68: DeprecatedWarning: ensure_python is deprecated as of 0.7 and will be removed in 1.0. Use `setuptools` `python_requires` instead
    pkg.ensure_python([">=3.6", ">=3.5"])

tests/test_deprecated.py::test_ensure_python
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.12.0/tests/test_deprecated.py:71: DeprecatedWarning: ensure_python is deprecated as of 0.7 and will be removed in 1.0. Use `setuptools` `python_requires` instead
    pkg.ensure_python("<3.5")

tests/test_deprecated.py::test_command_for_func
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.12.0/tests/test_deprecated.py:124: DeprecatedWarning: command_for_func is deprecated as of 0.8 and will be removed in 1.0. Use `BaseCommand` directly instead
    cmd = pkg.command_for_func(func)

tests/test_deprecated.py::test_command_for_func
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.12.0/jupyter_packaging/setupbase.py:498: DeprecatedWarning: update_package_data is deprecated as of 0.8 and will be removed in 1.0. Use `use_package_data=True` and `MANIFEST.in` instead
    update_package_data(self.distribution)

tests/test_deprecated.py::test_install_npm
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.12.0/tests/test_deprecated.py:130: DeprecatedWarning: install_npm is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    builder = pkg.install_npm()

tests/test_deprecated.py::test__wrap_command
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.12.0/tests/test_deprecated.py:145: DeprecatedWarning: _wrap_command is deprecated as of 0.8 and will be removed in 1.0. Use `npm_builder` and `wrap_installers`
    cmd = pkg._wrap_command(["js"], TestCommand)

tests/test_deprecated.py::test__wrap_command
  /home/tkloczko/rpmbuild/BUILD/jupyter-packaging-0.12.0/jupyter_packaging/setupbase.py:731: DeprecatedWarning: update_package_data is deprecated as of 0.8 and will be removed in 1.0. Use `use_package_data=True` and `MANIFEST.in` instead
    update_package_data(self.distribution)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
========================================================================= short test summary info ==========================================================================
SKIPPED [5] tests/test_datafiles_install.py:56: Site Packages are Read-only
SKIPPED [5] tests/test_datafiles_install.py:80: Site Packages are Read-only
SKIPPED [1] tests/test_deprecated.py:74: Tests RuntimeError for Python 3.10+
SKIPPED [1] tests/test_deprecated.py:82: Site Packages are Read-only
SKIPPED [1] tests/test_install.py:11: Site Packages are Read-only
SKIPPED [1] tests/test_install.py:31: Site Packages are Read-only
SKIPPED [1] tests/test_install.py:64: Site Packages are Read-only
=============================================================== 51 passed, 15 skipped, 9 warnings in 44.47s ================================================================

JUPYTER_PACKAGING_SKIP_NPM environment variable versus --skip-npm option

tried with: jupyter-jsmol version 2022.1.0 and jupyter-packaging 0.12.2
downstream issue: https://trac.sagemath.org/ticket/34421

When setting JUPYTER_PACKAGING_SKIP_NPM=1 in the shell and launching pip install --no-binary ':all:' jupyter-jsmol, the setup process correctly ignores npm install. However, it ends up with

  Skipping npm install as requested.
  Traceback (most recent call last):
    File "[...]/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 363, in <module>
      main()
    File "[...]/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 345, in main
      json_out['return_val'] = hook(**hook_input['kwargs'])
    File "[...]/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 164, in prepare_metadata_for_build_wheel
      return hook(metadata_directory, config_settings)
    File "[...]/python3.10/site-packages/setuptools/build_meta.py", line 188, in prepare_metadata_for_build_wheel
      self.run_setup()
    File "[...]/python3.10/site-packages/setuptools/build_meta.py", line 174, in run_setup
      exec(code, locals())
    File "<string>", line 8, in <module>
    File "[...]/python3.10/site-packages/jupyter_packaging/__init__.py", line 6, in <module>
      from .setupbase import *  # noqa
    File "[...]/python3.10/site-packages/jupyter_packaging/setupbase.py", line 77, in <module>
      sys.argv.remove("--skip-npm")
  ValueError: list.remove(x): x not in list

Version 0.12.0 installs tests directly into site-packages

It seems that because tests folder is now a Python package (see the new __init__.py in d56a2de) the folder is included in the release. This means that the tests are also installed and they are installed directly into site-packages folder, which is not correct I'd say.

$ ls lib/python3.10/site-packages/tests 
conftest.py        test_core_functions.py     test_install.py            utils.py
__init__.py        test_datafiles_install.py  test_is_stale.py
__pycache__        test_datafiles_paths.py    test_main.py
test_build_api.py  test_deprecated.py         test_utility_functions.py

Is there any reason to have tests being a part of the released code? If so, would it make sense to move them somewhere else?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.