Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Q: how to build install and test flit in isolated network? #406

Closed
kloczek opened this issue Apr 17, 2021 · 22 comments
Closed

Q: how to build install and test flit in isolated network? #406

kloczek opened this issue Apr 17, 2021 · 22 comments

Comments

@kloczek
Copy link

kloczek commented Apr 17, 2021

I'm trying to build flit in isolated network and really struggling with doing that.
I'm trying to use build module like with few other modulke and to be hones I'm stuck

+ cd flit-3.2.0
+ cd flit_core
+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core/flit_core:/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core/flit
+ FLIT_NO_NETWORK=1
+ /usr/bin/python3 -m build --no-isolation
+ cd -
/home/tkloczko/rpmbuild/BUILD/flit-3.2.0
+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core:/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit
+ /usr/bin/python3 -m build --no-isolation
Traceback (most recent call last):
  File "/usr/lib64/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib64/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit/build.py", line 12, in <module>
    from .config import read_flit_config, ConfigError
ImportError: attempted relative import with no known parent package

May I ask for some hints/advices or help?

@takluyver
Copy link
Member

I think you've made a mistake with PYTHONPATH. You've put the flit package directory (containing __init__.py) in PYTHONPATH. So it's finding part of flit when it tries to import build, instead of the build package you're trying to use. I think you're making a similar mistake when building flit_core, but by luck it works anyway there.

Try something like this:

cd flit-3.2.0
cd flit_core
/usr/bin/python3 -m build --no-isolation

cd ..
PYTHONPATH=$PWD/flit_core /usr/bin/python3 -m build --no-isolation

@kloczek
Copy link
Author

kloczek commented Apr 18, 2021

It works. Thank you :)

Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.o68bet
+ umask 022
+ cd /home/tkloczko/rpmbuild/BUILD
+ cd flit-3.2.0
+ cd flit_core
+ FLIT_NO_NETWORK=1
+ /usr/bin/python3 -m build --no-isolation
+ cd -
/home/tkloczko/rpmbuild/BUILD/flit-3.2.0
+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core
+ /usr/bin/python3 -m build --no-isolation
+ RPM_EC=0
++ jobs -p
+ exit 0

Sorry for maybe dumb questions (I'm still learning how to use build modules about which there is no to much documentation).
Now I need to perform install all necessary files in separated directory to be able assemble rpm package and if it is possible execute some package test suite.
Do you know how to do that?
I don't see anything about install and testing in python3 -m build --help output.

@kloczek
Copy link
Author

kloczek commented Apr 18, 2021

OK looks like testting can be done using pytest/tox.
However I found small issue in test suite when pytest is used.

+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-flit-3.2.0-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-flit-3.2.0-2.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/python3 -Bm pytest -ra
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.9, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: /home/tkloczko/rpmbuild/BUILD/flit-3.2.0
plugins: forked-1.3.0, shutil-1.7.0, virtualenv-1.7.0, asyncio-0.14.0, expect-1.1.0, cov-2.11.1, mock-3.5.1, httpbin-1.0.0, xdist-2.2.1, flake8-1.0.7, timeout-1.4.2, betamax-0.8.1, pyfakefs-4.4.0, freezegun-0.4.2, flaky-3.7.0, cases-3.4.6, hypothesis-6.10.0
collected 169 items

flit_core/flit_core/tests/test_build_thyself.py ...                                                                                                                  [  1%]
flit_core/flit_core/tests/test_buildapi.py .......                                                                                                                   [  5%]
flit_core/flit_core/tests/test_common.py ................                                                                                                            [ 15%]
flit_core/flit_core/tests/test_config.py ............................................                                                                                [ 41%]
flit_core/flit_core/tests/test_sdist.py .....                                                                                                                        [ 44%]
flit_core/flit_core/tests/test_versionno.py .                                                                                                                        [ 44%]
flit_core/flit_core/tests/test_wheel.py .                                                                                                                            [ 45%]
tests/test_build.py ....                                                                                                                                             [ 47%]
tests/test_command.py ..                                                                                                                                             [ 49%]
tests/test_config.py .                                                                                                                                               [ 49%]
tests/test_find_python_executable.py ...F...                                                                                                                         [ 53%]
tests/test_init.py .................                                                                                                                                 [ 63%]
tests/test_install.py ...................                                                                                                                            [ 75%]
tests/test_sdist.py ..........                                                                                                                                       [ 81%]
tests/test_tomlify.py .                                                                                                                                              [ 81%]
tests/test_upload.py ....                                                                                                                                            [ 84%]
tests/test_validate.py ...............                                                                                                                               [ 92%]
tests/test_vcs.py .                                                                                                                                                  [ 93%]
tests/test_wheel.py ...........                                                                                                                                      [100%]

================================================================================= FAILURES =================================================================================
____________________________________________________________________________ test_find_in_path _____________________________________________________________________________

    def test_find_in_path():
>       assert os.path.isabs(find_python_executable("python"))

tests/test_find_python_executable.py:23:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

python = 'python'

    def find_python_executable(python: Optional[str] = None) -> str:
        """Returns an absolute filepath to the executable of Python to use."""
        if not python:
            python = os.environ.get("FLIT_INSTALL_PYTHON")
        if not python:
            return sys.executable
        if os.path.isabs(python):  # sys.executable is absolute too
            return python
        # get absolute filepath of {python}
        # shutil.which may give a different result to the raw subprocess call
        # see https://github.com/takluyver/flit/pull/300 and https://bugs.python.org/issue38905
        resolved_python = shutil.which(python)
        if resolved_python is None:
>           raise PythonNotFoundError("Unable to resolve Python executable {!r}".format(python))
E           flit.PythonNotFoundError: Unable to resolve Python executable 'python'

flit/__init__.py:36: PythonNotFoundError
========================================================================= short test summary info ==========================================================================
FAILED tests/test_find_python_executable.py::test_find_in_path - flit.PythonNotFoundError: Unable to resolve Python executable 'python'
====================================================================== 1 failed, 168 passed in 2.67s =======================================================================

I always preffer to use pytest over tox as tox has less dependencies.
On use tox there is no that error so I ssupose that it is possible to pass python executable name over some env variable however I don't see any hints in tox.ini about how to do that.

Nevertheless still did not figure out how to install all flibt files in some base directory tree to be able package all those files.

@takluyver
Copy link
Member

No problem - build is still quite new and people are getting used to it. Flit is also a bit trickier than most packages because it has to be bootstrapped with flit_core.

Installation: at the moment, the canonical way is to install wheels is to use pip - something like pip install --no-deps dist/flit-3.2.0-py3-none-any.whl, using the --prefix and --root options as necessary to control where it gets installed. There is a work-in-progress low-level installer package which is meant to complement build, but it's even less mature than build.

Test failures: The tests assume that python will be found on PATH when they are run, and it looks like that's not the case in your build environment. You can either make the assumption valid - by changing PATH or adding a symlink - or patch that test out.

@kloczek
Copy link
Author

kloczek commented Apr 18, 2021

There is a work-in-progress low-level installer package which is meant to complement build, but it's even less mature than build.

OK will try to package installer module :)
Thank you for the hint.
I'm building all my packages in dedicated build envs with installed only what is needed to build exact package, and by that I'm trying to not use pip because it drags alot of dependencies :/

Test failures: The tests assume that python will be found on PATH when they are run, and it looks like that's not the case in your build environment. You can either make the assumption valid - by changing PATH or adding a symlink - or patch that test out.

I have only python3 and no python.

[tkloczko@barrel SPECS]$ type python
-bash: type: python: not found
[tkloczko@barrel SPECS]$ type python3
python3 is /usr/bin/python3

I patch for myself that unit but maybe it is some other generic metbid finding python executable which could be usied in that unit?
Interesiting is that tox passes that without problems. But looks like tox is not executing tests/test_find_python_executable.py unit.

+ /usr/bin/python3 -Bm tox --skip-missing-interpreters
py39 create: /home/tkloczko/rpmbuild/BUILD/flit-3.2.0/.tox/py39
SKIPPED: InterpreterNotFound: python3.9
py38 create: /home/tkloczko/rpmbuild/BUILD/flit-3.2.0/.tox/py38
py38 installdeps: requests, requests_download, testpath, responses, docutils, toml, pytest>=2.7.3, pytest-cov
py38 installed: attrs==20.3.0,certifi==2020.12.5,chardet==4.0.0,coverage==5.5,docutils==0.17.1,idna==2.10,iniconfig==1.1.1,packaging==20.9,pluggy==0.13.1,py==1.10.0,pyparsing==2.4.7,pytest==6.2.3,pytest-cov==2.11.1,requests==2.25.1,requests-download==0.1.2,responses==0.13.2,six==1.15.0,testpath==0.4.4,toml==0.10.2,urllib3==1.26.4
py38 run-test-pre: PYTHONHASHSEED='687411366'
py38 run-test: commands[0] | python -m pytest --cov=flit --cov=flit_core/flit_core
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.9, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
cachedir: .tox/py38/.pytest_cache
rootdir: /home/tkloczko/rpmbuild/BUILD/flit-3.2.0
plugins: cov-2.11.1
collected 169 items

flit_core/flit_core/tests/test_build_thyself.py ...                                                                                                                  [  1%]
flit_core/flit_core/tests/test_buildapi.py .......                                                                                                                   [  5%]
flit_core/flit_core/tests/test_common.py ................                                                                                                            [ 15%]
flit_core/flit_core/tests/test_config.py ............................................                                                                                [ 41%]
flit_core/flit_core/tests/test_sdist.py .....                                                                                                                        [ 44%]
flit_core/flit_core/tests/test_versionno.py .                                                                                                                        [ 44%]
flit_core/flit_core/tests/test_wheel.py .                                                                                                                            [ 45%]
tests/test_build.py ....                                                                                                                                             [ 47%]
tests/test_command.py ..                                                                                                                                             [ 49%]
tests/test_config.py .                                                                                                                                               [ 49%]
tests/test_find_python_executable.py .......                                                                                                                         [ 53%]
tests/test_init.py .................                                                                                                                                 [ 63%]
tests/test_install.py ...................                                                                                                                            [ 75%]
tests/test_sdist.py ..........                                                                                                                                       [ 81%]
tests/test_tomlify.py .                                                                                                                                              [ 81%]
tests/test_upload.py ....                                                                                                                                            [ 84%]
tests/test_validate.py ...............                                                                                                                               [ 92%]
tests/test_vcs.py .                                                                                                                                                  [ 93%]
tests/test_wheel.py ...........                                                                                                                                      [100%]

----------- coverage: platform linux, python 3.8.9-final-0 -----------
Name                                   Stmts   Miss  Cover
----------------------------------------------------------
flit/__init__.py                          89     23    74%
flit/__main__.py                           3      0   100%
flit/_get_dirs.py                         14      9    36%
flit/build.py                             45      2    96%
flit/buildapi.py                           1      1     0%
flit/config.py                            11      1    91%
flit/init.py                             155     14    91%
flit/install.py                          262     32    88%
flit/log.py                               49     27    45%
flit/logo.py                               2      2     0%
flit/sdist.py                            120     10    92%
flit/tomlify.py                           56      4    93%
flit/upload.py                           115     31    73%
flit/validate.py                         174     13    93%
flit/vcs/__init__.py                      11      0   100%
flit/vcs/git.py                            9      0   100%
flit/vcs/hg.py                            23      0   100%
flit/vendorized/__init__.py                0      0   100%
flit/vendorized/readme/__init__.py         0      0   100%
flit/vendorized/readme/clean.py            1      0   100%
flit/vendorized/readme/rst.py             36     12    67%
flit/wheel.py                              7      0   100%
flit_core/flit_core/__init__.py            1      0   100%
flit_core/flit_core/build_thyself.py      44      5    89%
flit_core/flit_core/buildapi.py           41      0   100%
flit_core/flit_core/common.py            229      6    97%
flit_core/flit_core/config.py            343     21    94%
flit_core/flit_core/sdist.py             122      5    96%
flit_core/flit_core/versionno.py          45      2    96%
flit_core/flit_core/wheel.py             165     28    83%
----------------------------------------------------------
TOTAL                                   2173    248    89%


=========================================================================== 169 passed in 4.76s ============================================================================

@takluyver
Copy link
Member

but maybe it is some other generic metbid finding python executable which could be usied in that unit?

It's testing a function that finds a Python executable, so there isn't an easy way around that...

Interesiting is that tox passes that without problems.

Tox creates a virtualenv to run the tests, and inside the virtualenv there will be a python executable on PATH.

@kloczek
Copy link
Author

kloczek commented Apr 18, 2021

I think that I'll try patch that sibgle line in test unit to use python3. At least it will solve usimg that unit in case of my build procedure implementrd in rpm spec file.
I've still not finished packaging installer as it have some other dependencies which I must apackage as well :)
Neverttheless I think that with details which you shared I would be able to finish packaging flit module :P

If you have nothing more to add or maybe correct in flit code feel free to close that ticket.
Thank you very much for your time :)

@takluyver
Copy link
Member

Thanks!

@kloczek
Copy link
Author

kloczek commented May 29, 2021

Sorry to bother you one more time.
I've been asked to do other things in meantime and only now I found time to finish packaging flint and installer however when now I'm trying to build flint using spec which have been working last time it does not work :/

Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.tIpYVU
+ umask 022
+ cd /home/tkloczko/rpmbuild/BUILD
+ cd flit-3.2.0
+ cd flit_core
+ FLIT_NO_NETWORK=1
+ /usr/bin/python3 -Bm build --no-isolation
+ cd -
/home/tkloczko/rpmbuild/BUILD/flit-3.2.0
+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core
+ /usr/bin/python3 -m build --no-isolation
ERROR Missing dependencies:
        flit_core >=3.2.0,<3.3

Seems only thing which I've updated in mean time is builder module to version 0.4.0.
strace shows me that definitely flint_core is red from build tree

[tkloczko@barrel flit-3.2.0]$ PYTHONPATH=/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core strace -fe trace=openat /usr/bin/python3 -m build --no-isolation -s 2>&1 |grep core
openat(AT_FDCWD, "/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
[pid 2235140] openat(AT_FDCWD, "/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
[pid 2235140] openat(AT_FDCWD, "/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core/flit_core/__pycache__/__init__.cpython-38.pyc", O_RDONLY|O_CLOEXEC) = 3
[pid 2235140] openat(AT_FDCWD, "/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core/flit_core", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
[pid 2235140] openat(AT_FDCWD, "/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core/flit_core/__pycache__/buildapi.cpython-38.pyc", O_RDONLY|O_CLOEXEC) = 3
[pid 2235140] openat(AT_FDCWD, "/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core/flit_core/__pycache__/common.cpython-38.pyc", O_RDONLY|O_CLOEXEC) = 3
[pid 2235140] openat(AT_FDCWD, "/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core/flit_core/__pycache__/versionno.cpython-38.pyc", O_RDONLY|O_CLOEXEC) = 3
[pid 2235140] openat(AT_FDCWD, "/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core/flit_core/__pycache__/config.cpython-38.pyc", O_RDONLY|O_CLOEXEC) = 3
[pid 2235140] openat(AT_FDCWD, "/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core/flit_core/__pycache__/wheel.cpython-38.pyc", O_RDONLY|O_CLOEXEC) = 3
[pid 2235140] openat(AT_FDCWD, "/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core/flit_core/__pycache__/sdist.cpython-38.pyc", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/home/tkloczko/rpmbuild/BUILD/flit-3.2.0/flit_core", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
        flit_core >=3.2.0,<3.3

@takluyver
Copy link
Member

It looks like the build package now checks for dependencies, rather than attempting the build and trusting you that dependencies are in place (you're setting PYTHONPATH to ensure that, but the checks for installed distributions are separate from the import mechanism, so the check doesn't 'see' flit_core).

I can see two possible approaches to deal with that:

  • After building a wheel of flit_core, install that wheel in the build environment (with pip or the WIP installer package). Then build should accept that it's present.
  • Or suppress the check with --skip-dependency-check

@kloczek
Copy link
Author

kloczek commented May 30, 2021

OK good to know that it nothing wrong with my build env :)
Looking on flit_core version and however theoretically should be fulfilled (?)

And another though .. IIRC I saw few modules which effectively have been installing more than one directory in python tree and everything was handled by single setup.py so if I'm right IMO something like this should be possible to do using build. If I'm right in such case checking dependencies between flit and flit_core could be dropped and everything should be possible to code in single pyproject.toml.

Just tested build with --skip-dependency-check and it works.
However as now I have installed much more pytest extensions than previously I see that pytest is failing (tox still is OK).
It maybe false positive error but may be not. Could you please have look on below log? (because some of those extensions may be pointing on something which could be corrected)
Here is the log:

+ /usr/bin/python3 -Bm pytest -ra
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.9, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /home/tkloczko/rpmbuild/BUILD/flit-3.2.0
plugins: forked-1.3.0, shutil-1.7.0, virtualenv-1.7.0, expect-1.1.0, cov-2.11.1, httpbin-1.0.0, xdist-2.2.1, flake8-1.0.7, timeout-1.4.2, betamax-0.8.1, pyfakefs-4.4.0, freezegun-0.4.2, cases-3.4.6, case-1.5.3, isort-1.3.0, aspectlib-1.5.2, asyncio-0.15.1, toolbox-0.5, xprocess-0.17.1, flaky-3.7.0, aiohttp-0.3.0, checkdocs-2.7.0, mock-3.6.1, rerunfailures-9.1.1, requests-mock-1.9.3, hypothesis-6.13.7
collected 190 items

. .                                                                                                                                                                  [  0%]
flit_core/flit_core/tests/test_build_thyself.py ...                                                                                                                  [  2%]
flit_core/flit_core/tests/test_buildapi.py .......                                                                                                                   [  6%]
flit_core/flit_core/tests/test_common.py ................                                                                                                            [ 15%]
flit_core/flit_core/tests/test_config.py ............................................                                                                                [ 41%]
flit_core/flit_core/tests/test_sdist.py .....                                                                                                                        [ 44%]
flit_core/flit_core/tests/test_versionno.py .                                                                                                                        [ 45%]
flit_core/flit_core/tests/test_wheel.py .                                                                                                                            [ 45%]
tests/test_build.py ....                                                                                                                                             [ 48%]
tests/test_command.py FF                                                                                                                                             [ 49%]
tests/test_config.py .                                                                                                                                               [ 50%]
tests/test_find_python_executable.py .......                                                                                                                         [ 54%]
tests/test_init.py .................                                                                                                                                 [ 64%]
tests/test_install.py ...................                                                                                                                            [ 75%]
tests/test_sdist.py ..........                                                                                                                                       [ 81%]
tests/test_tomlify.py .                                                                                                                                              [ 81%]
tests/test_upload.py ....                                                                                                                                            [ 84%]
tests/test_validate.py ...............                                                                                                                               [ 92%]
tests/test_vcs.py .                                                                                                                                                  [ 93%]
tests/test_wheel.py ...........                                                                                                                                      [100%]

================================================================================= FAILURES =================================================================================
______________________________________________________________________________ test_flit_help ______________________________________________________________________________

    def test_flit_help():
        p = Popen([sys.executable, '-m', 'flit', '--help'], stdout=PIPE, stderr=STDOUT)
        out, _ = p.communicate()
>       assert 'Build wheel' in out.decode('utf-8', 'replace')
E       assert 'Build wheel' in 'Traceback (most recent call last):\n  File "/usr/lib64/python3.8/runpy.py", line 185, in _run_module_as_main\n    mod...\n    from flit_core import common\nImportError: cannot import name \'common\' from \'flit_core\' (unknown location)\n'
E        +  where 'Traceback (most recent call last):\n  File "/usr/lib64/python3.8/runpy.py", line 185, in _run_module_as_main\n    mod...\n    from flit_core import common\nImportError: cannot import name \'common\' from \'flit_core\' (unknown location)\n' = <built-in method decode of bytes object at 0x561c18f8a0f0>('utf-8', 'replace')
E        +    where <built-in method decode of bytes object at 0x561c18f8a0f0> = b'Traceback (most recent call last):\n  File "/usr/lib64/python3.8/runpy.py", line 185, in _run_module_as_main\n    mo...\n    from flit_core import common\nImportError: cannot import name \'common\' from \'flit_core\' (unknown location)\n'.decode

tests/test_command.py:7: AssertionError
_____________________________________________________________________________ test_flit_usage ______________________________________________________________________________

    def test_flit_usage():
        p = Popen([sys.executable, '-m', 'flit'], stdout=PIPE, stderr=STDOUT)
        out, _ = p.communicate()
>       assert 'Build wheel' in out.decode('utf-8', 'replace')
E       assert 'Build wheel' in 'Traceback (most recent call last):\n  File "/usr/lib64/python3.8/runpy.py", line 185, in _run_module_as_main\n    mod...\n    from flit_core import common\nImportError: cannot import name \'common\' from \'flit_core\' (unknown location)\n'
E        +  where 'Traceback (most recent call last):\n  File "/usr/lib64/python3.8/runpy.py", line 185, in _run_module_as_main\n    mod...\n    from flit_core import common\nImportError: cannot import name \'common\' from \'flit_core\' (unknown location)\n' = <built-in method decode of bytes object at 0x561c18f90c80>('utf-8', 'replace')
E        +    where <built-in method decode of bytes object at 0x561c18f90c80> = b'Traceback (most recent call last):\n  File "/usr/lib64/python3.8/runpy.py", line 185, in _run_module_as_main\n    mo...\n    from flit_core import common\nImportError: cannot import name \'common\' from \'flit_core\' (unknown location)\n'.decode

tests/test_command.py:12: AssertionError
========================================================================= short test summary info ==========================================================================
FAILED tests/test_command.py::test_flit_help - assert 'Build wheel' in 'Traceback (most recent call last):\n  File "/usr/lib64/python3.8/runpy.py", line 185, in _run_mod...
FAILED tests/test_command.py::test_flit_usage - assert 'Build wheel' in 'Traceback (most recent call last):\n  File "/usr/lib64/python3.8/runpy.py", line 185, in _run_mo...
====================================================================== 2 failed, 168 passed in 4.46s =======================================================================

FYI to be able to use tox/pytest with /usr/bin/python3 I've added below patch:

--- a/tests/test_find_python_executable.py~     2021-03-21 21:18:18.000000000 +0000
+++ b/tests/test_find_python_executable.py      2021-05-30 19:17:45.840724117 +0100
@@ -16,14 +16,14 @@


 def test_abs():
-    assert find_python_executable("/usr/bin/python") == "/usr/bin/python"
+    assert find_python_executable("/usr/bin/python3") == "/usr/bin/python3"


 def test_find_in_path():
-    assert os.path.isabs(find_python_executable("python"))
+    assert os.path.isabs(find_python_executable("python3"))


-@pytest.mark.parametrize("bad_python_name", ["pyhton", "ls", "."])
+@pytest.mark.parametrize("bad_python_name", ["pyhton3", "ls", "."])
 def test_exception(bad_python_name: str):
     """Test that an appropriate exception (that contains the error string) is raised."""
     with pytest.raises(PythonNotFoundError, match=re.escape(bad_python_name)):

@kloczek
Copy link
Author

kloczek commented May 30, 2021

And yet another small question (if I can) ,.

I'm packaging all my python modules adding documentation in form of roff man pages (if it is only possible).
Usually when setuptools is used as build framework it ia possible to use setup.py build_sphinx -b man.
Q: is it possible to build such documentation using build module?

@kloczek
Copy link
Author

kloczek commented May 30, 2021

And yet another observation.
Trying to build roff man pages I found that it uses sphinx extension:

+ sphinx-build -b man -d python-flit doc .
Running Sphinx v4.0.2

Extension error:
Could not import extension sphinxcontrib_github_alt (exception: No module named 'sphinxcontrib_github_alt')

That extension looks like has some substantial set of dependencies. As flint is quite high on list of growing dependencies I think I think that it would be good to use in conf.py just raw sphinx because building flint with documentation probably will create few addition loops in graph of dependencies.

@takluyver
Copy link
Member

Looking on flit_core version and however theoretically should be fulfilled (?)

Adding it to PYTHONPATH makes it importable, but it doesn't show up as an installed distribution for the requirements check. That mechanism is based on .dist-info folders which are created when you build a package (PEP 376).

checking dependencies between flit and flit_core could be dropped and everything should be possible to code in single pyproject.toml.

I've split it into two pieces precisely because I want it to be possible to install them separately. Every package which is built with Flit will have flit_core as a build dependency, but when building them automatically, it shouldn't be necessary to install flit as well. This means I can use dependencies and newer Python versions more readily in the non-core part of Flit.

I see that pytest is failing...

That looks like when it runs python -m flit as a subprocess, it can't import flit_core. I'm not sure at the moment if that's an issue with the tests themselves, or the way you're running them.

Usually when setuptools is used as build framework it ia possible to use setup.py build_sphinx -b man. Q: is it possible to build such documentation using build module?

Definitely not at present, and I'd guess it's not going to be. The idea of build is to be tightly focussed on one thing - building distributions of Python code. Building documentation is a separate question. From my perspective, the canonical way to build Sphinx documentation is to cd to the docs folder and run make html (replacing html with whatever output format you want).

As flint is quite high on list of growing dependencies I think I think that it would be good to use in conf.py just raw sphinx because building flint with documentation probably will create few addition loops in graph of dependencies.

Using Flit to build other packages shouldn't require that Flit's docs are built first. It shouldn't even require the whole of Flit, just flit_core. I don't know how you need to arrange this in your packaging system, though.

@kloczek
Copy link
Author

kloczek commented May 31, 2021

Thank you for your comments :)

The idea of build is to be tightly focussed on one thing - building distributions of Python code

Working +20 years on packaging software I know how important is not only building and installing (which still is not integrated part of the build) but testing and preparing other resources like end user documentation.
Hopefully that build is still in kind of WIP state and framework for that parts will be added in the future.

Using Flit to build other packages shouldn't require that Flit's docs are built first. It shouldn't even require the whole of Flit, just flit_core. I don't know how you need to arrange this in your packaging system, though.

So far I've added to my package patch which is removing history from the documentation (only that part requires that sphinx extension):

--- a/doc/conf.py~      2021-05-30 20:16:03.000000000 +0100
+++ b/doc/conf.py       2021-05-30 20:16:28.697651673 +0100
@@ -30,7 +30,6 @@
 # ones.
 extensions = [
     'sphinx.ext.autodoc',
-    'sphinxcontrib_github_alt',
     'sphinx_rtd_theme',
 ]

--- a/doc/index.rst~    2021-03-21 21:18:18.000000000 +0000
+++ b/doc/index.rst     2021-05-30 20:16:37.874664255 +0100
@@ -23,7 +23,6 @@
    :maxdepth: 1

    development
-   history

 Indices and tables
 ==================

Than with that I'm able to generate man page using sphinx-build -b man -d %{name} doc .
For now I thin that should be enough.
Yesterday I've finished packaging installer. After that checking automatically generated dependencies I found that this module has substantial list of dependencies.

python3.8dist(distlib)
python3.8dist(packagebuilder)
python3.8dist(packaging)
python3.8dist(pip-shims)
python3.8dist(requirementslib)
python3.8dist(setuptools)
python3.8dist(vistir)
python3.8dist(vistir[spinner])

It is quite long list for something like only unpacking .whl file which is just zip file and transform *..dist-info directory to (probably) *.info-egg. Such low level operation IMO should be possible to do without additional dependencies. Probably will try to talk wit builder maintainer and ask about installation process (and generate documentation as well).
Still installer has waaay shorter list of dependencies than pip but IMO even that is not enough :/
Do you have maybe some other suggestions which I can try to implement? to install generated by 'builder` .whl files?

And again .. thanks for your comments because now I have better understanding of some details.

@takluyver
Copy link
Member

Working +20 years on packaging software I know how important is not only building and installing (which still is not integrated part of the build) but testing and preparing other resources like end user documentation.

I'm not saying they're not important, just that I don't think the build package needs to do all those things.

So far I've added to my package patch which is removing history from the documentation

I'd rather you either built the docs entirely, or left them out and pointed people to the online docs, rather than building part of the docs with no sign that you've cut part out.

Sphinx has 16 direct dependencies and likely several more indirect ones, so it's not exactly straightforward or lightweight just because you've removed one small extension. I don't think any of Sphinx's dependencies are packaged with Flit at present, but there's no reason they couldn't be.

Yesterday I've finished packaging installer. After that checking automatically generated dependencies I found that this module has substantial list of dependencies.

Do you mean build? 🤔 installer appears to require nothing on Python 3.7 and above:

https://github.com/pradyunsg/installer/blob/0c302c2488485a68ec68afb07408d3c49b0cf482/pyproject.toml#L13-L16

@kloczek
Copy link
Author

kloczek commented Jun 1, 2021

OK in case of sphinx dependencies you are right.

Do you mean build? 🤔 installer appears to require nothing on Python 3.7 and above

Nope installer
Here is the content of the /usr/lib/python3.8/site-packages/installer-0.1.1-py3.8.egg-info/requires.txt from the package which I've done:

packaging
packagebuilder
pip-shims
requirementslib
setuptools
vistir[spinner]

[tests]
pytest-timeout
pytest-xdist
pytest-cov
pytest

[virtualenv]
mork
virtualenv

rpm automatically process that file to autogenerate generated package requires dependencies ([tests] and [virtualenv] are not proced). So as you see that list is not empty.

Still I cannot install that package because I must package all what installed needs.

[tkloczko@barrel .git]$ sudo dnf install 'python3dist(installer)'
Last metadata expiration check: 0:32:48 ago on Tue 01 Jun 2021 11:09:56 BST.
Error:
 Problem: conflicting requests
  - nothing provides python3.8dist(packagebuilder) needed by python-installer-0.1.1-2.fc35.noarch
  - nothing provides python3.8dist(pip-shims) needed by python-installer-0.1.1-2.fc35.noarch
  - nothing provides python3.8dist(requirementslib) needed by python-installer-0.1.1-2.fc35.noarch
  - nothing provides python3.8dist(vistir) needed by python-installer-0.1.1-2.fc35.noarch
  - nothing provides python3.8dist(vistir[spinner]) needed by python-installer-0.1.1-2.fc35.noarch
(try to add '--skip-broken' to skip uninstallable packages)

@kloczek
Copy link
Author

kloczek commented Jun 1, 2021

BTW just checked builder requires dependencies:

python3.8dist(packaging) >= 19
python3.8dist(pep517) >= 0.9.1
python3.8dist(setuptools)
python3.8dist(toml) >= 0.10

Is it true that builder suppose to be setuptools "replacement"? If yes looks like it has some setuptools dependencies.

@takluyver
Copy link
Member

Here is the content of the /usr/lib/python3.8/site-packages/installer-0.1.1-py3.8.egg-info/requires.txt

It looks like the name installer was first used for this project, which now has a notice that it is abandoned, and it was replaced by this project, which has fewer dependencies. installer 0.2 onwards is the project I was looking at.

However, it is packaged with flit_core, so you'll need some workaround to get at least one of those installed.

Is it true that builder suppose to be setuptools "replacement"?

Not really, no. Since PEP 517, we separate these tools into 'backends', like setuptools or flit, which a project chooses to define how to make packages, and 'frontends', like pip & build, which the user can choose.

The picture is a bit muddy because many of the tools predate PEP 517 and so do bits of both frontend & backend things. E.g. setup.py commands run setuptools directly (more or less) rather than as a PEP 517 backend. In flit, this distinction is the difference between flit_core (the backend) and flit (command line tools).

@kloczek
Copy link
Author

kloczek commented Jun 17, 2021

Thanks for all your help. I've manage to package all basic module and flit as well.
I still have one more thing which bothers me and which is related to flit as well.

I found that many modules which no longer have setup.py and instead they have project.toml file in sdist dist tarballs have generated in that tar ball setup.py are using distutils instead setuptools.
IMO it is kind of step back becaue setuptools provides generic way to generate doscumentation like /usr/bin/python3 setup.py build_sphinx -b man which I've started using on massive scale to build mnodules documentation in form of roff man pages (at the moment I have more than 200 modules which is using that trick).
Recently I found that few packages are using distuils.core instead setuptools and distutils does not offer building build_sphinx command so I've started even patching some setup.py files. However when I fould that those files have been genetrated I've started tracind where actually it is hardcoded generate use distutils.
I just found that flint as well uses distutils

[tkloczko@barrel SRPMS]$ grep -r distutils /usr/lib/python3.8/site-packages/flit | grep py$
/usr/lib/python3.8/site-packages/flit/sdist.py:# Our generated setup.py deliberately loads distutils, not setuptools, to
/usr/lib/python3.8/site-packages/flit/sdist.py:from distutils.core import setup
/usr/lib/python3.8/site-packages/flit/sdist.py:    # Undocumented distutils feature: the empty string matches all package names
/usr/lib/python3.8/site-packages/flit/upload.py:This is cribbed heavily from distutils.command.(upgrade|register), which as part
/usr/lib/python3.8/site-packages/flit/upload.py:    names = cp.get('distutils', 'index-servers', fallback='pypi').split()

IMO using distutils instead setuptools is kind of step back from point of functionality.
For example pep517 (https://github.com/takluyver/pep517/) has in tree doc/ directory and documentation cannot be generated in that generic way OOTB using sdist tar ball. Looks like in absence of what provides setuptools it wa necessary to add in that project doc/Makefile

Is it intentional that flint and other are using distutils instead setuptools?
If it is why not use everywhere setuptools?
As I wrote from popint of people like me which are packaging stuff IMO using distutils is kind of step back :/

Sorry for asking you again but looks like you are quite close to developing all build/install/test python frameworks so you are the person which could be best suited to address that kind of question :)
I've been trying to find some details about setuptools vs distutils and was not able to find anything which could answer on my dilemas/questions ..

@takluyver
Copy link
Member

The setup.py files are - from my perspective - a short-term workaround for older versions of pip which didn't support PEP 517. I don't intend people to run them directly. They will be going away - there's already an option to skip generating setup.py, and at some point it will become the default (#391). So I would advise you not to rely on them.

@takluyver
Copy link
Member

(To be clear, I mean that setup.py files generated by flit are going away. Lots of projects which aren't packaged with Flit will continue to use setup.py files.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants