System lib search fails on openSUSE

The installer is only looking for rpm in the noarch site-packages, whereas on openSUSE there is only a package in the arch site-packages.
> rpm -ql python2-rpm
/usr/lib64/python2.7/site-packages/rpm
/usr/lib64/python2.7/site-packages/rpm-<IP_ADDRESS>-py2.7.egg-info
/usr/lib64/python2.7/site-packages/rpm/__init__.py
/usr/lib64/python2.7/site-packages/rpm/__init__.pyc
/usr/lib64/python2.7/site-packages/rpm/__init__.pyo
/usr/lib64/python2.7/site-packages/rpm/_rpm.so
/usr/lib64/python2.7/site-packages/rpm/_rpmb.so
/usr/lib64/python2.7/site-packages/rpm/_rpms.so
/usr/lib64/python2.7/site-packages/rpm/transaction.py
/usr/lib64/python2.7/site-packages/rpm/transaction.pyc
/usr/lib64/python2.7/site-packages/rpm/transaction.pyo
> python2 -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib())'
/usr/lib/python2.7/site-packages

https://build.opensuse.org/package/view_file/home:jayvdb:rpm/python-rpm-py-installer/fix-rpm-installed-check.patch?expand=1 fixes it for me, but will that also work on all other systems?
Can rpm bindings be installed without a sitearch package?

Thanks for the info.
Can you send me the pull-request? And which version of the openSUSE are you using?

Also welcome to pull-request to add openSUSE case to Travis CI too!

https://build.opensuse.org/package/view_file/home:jayvdb:rpm/python-rpm-py-installer/fix-rpm-installed-check.patch?expand=1 fixes it for me, but will that also work on all other systems?
Can rpm bindings be installed without a sitearch package?

I appreciate you manage the RPM package of rpm-py-installer on openSUSE.
Right now I am not sure for your question.
What is "he arch site-packages" or "a sitearch package"?
I also need to understand your below modification.
https://build.opensuse.org/package/view_file/home:jayvdb:rpm/python-rpm-py-installer/fix-rpm-installed-check.patch?expand=1

> python2 -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib())'
/usr/lib/python2.7/site-packages
> python2 -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib(plat_specific=True))'
/usr/lib64/python2.7/site-packages

As rpm uses a .so, it should go into lib64 (or lib32), so I would expect that it always appears in get_python_lib(plat_specific=True) , and so my change would be safe for everyone.
I believe a .so appearing under /usr/lib/python2.7/site-packages would be a bug in the rpm packaging, or a result of a bug in pip/setuptools/etc.
But to be safe, both should be checked for the presense of an rpm sub-directory.

Thank you for the explanation. I understood it.
As rpm-py-installer would like to support any cases as much as possible including old platforms: CentOS6, Ubuntu trusty and etc.
I am thinking the inclusive way to search it.

@jayvdb I have a question.
On my environment Fedora 29, both get_python_lib(plat_specific=True) and get_python_lib() are same directory. It is because the configure script options to build Python?
$ /usr/local/python-3.6.5/bin/python3
Python 3.6.5 (v3.6.5:f59c0932b4, Apr 23 2018, 20:38:55)
[GCC 7.3.1 20180130 (Red Hat 7.3.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from distutils.sysconfig import get_python_lib
>>> get_python_lib(plat_specific=True)
'/usr/local/python-3.6.5/lib/python3.6/site-packages'
>>> get_python_lib()
'/usr/local/python-3.6.5/lib/python3.6/site-packages'

$ /usr/local/python-2.7.13/bin/python
Python 2.7.13 (default, Feb  2 2017, 00:43:19)
[GCC 6.3.1 20161221 (Red Hat 6.3.1-1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from distutils.sysconfig import get_python_lib
[48273 refs]
>>> get_python_lib(plat_specific=True)
'/usr/local/python-2.7.13/lib/python2.7/site-packages'
[48275 refs]
>>> get_python_lib()
'/usr/local/python-2.7.13/lib/python2.7/site-packages'
[48275 refs]

Anyway, I fixed it and merged it to the master branch.

@jayvdb Now I released the new version 0.9.9, maybe that fixed this issue. Could you check it?
Thank you.

Thanks.
The build step now passes, but there are 22 test failures.
The s390x log is probably the best one, as it violates more of the expectations of the test suite.
https://build.opensuse.org/package/live_build_log/home:jayvdb:branches:Base:SystemRpm/python-rpm-py-installer/openSUSE_Factory_zSystems/s390x
Ideally any test which requires the internet should have a @pytest.mark.internet (or similar name) then I can add -k 'not internet' to not run them inside rpmbuild where internet is disabled.
I'll be happy to change my builds to use a github branch, and give you admin rights on that OBS workspace, so you can test on those workers without needing to do releases.  Let me know branch name, and or OBS username.
You'll find some other tweaks in https://build.opensuse.org/package/view_file/home:jayvdb:branches:Base:SystemRpm/python-rpm-py-installer/python-rpm-py-installer.spec?expand=1 , like naming of install.py , fixing the mock import , etc.
Also, a LICENSE file will be needed in the sdist uploaded to PyPI, and tests in the sdist, so then the RPM builds from the sdist instead of the GitHub archive.

@jayvdb sure. I will add the mark for internet to the unit tests. And also good timing to consider the multi arch not only x86_64.

I'll be happy to change my builds to use a github branch, and give you admin rights on that OBS workspace, so you can test on those workers without needing to do releases. Let me know branch name, and or OBS username.

I do not understand what you are saying. A github branch? This repository's github branch?

Yes.  We could work on a feature branch in GitHub to resolve these issues, and i'll set up the OBS workspace to track that branch, so we can get it right before you do a release.

@jayvdb I think we do not have to create that kind of branch.
because I like testing the disabled internet case for every pull-request.
Maybe we can add the new disabled internet case to Travis CI.
such as running systemctl stop netowrk as a initial command.

The failures are not only because of no internet.
Marking the internet accessing tests only helps eliminate them.  Then there are distro (openSUSE) and arch (s390x) specific bugs we need to fix.

For the specific issue for openSuSE, you can see this repository has CI cases for Fedora, CentOS and Ubuntu. I like to add the openSuSE case to the CI cases.
For s390x specific case, there is a way to test multi arch except x86_64 on Travis CI with QEMU.
Here is the example.
https://github.com/junaruga/ci-multi-arch-test
I like to look for the way.
Or after adding no-internet tests, I want to create the specific feature branch "temporary" to fix it.
Because I do not want to manage the feature branch continuously. It's costy for me to sync the feature branch with master branch regularly.
Once the tests are passed for openSuSE build, you can set the branch "master" as a branch to check the RPM build.
Is it fine for you?

Do you know below service? Recently I knew it. It is to check downstream RPM build (Fedora project) on the upstream project repository at the timing of the pull-request.
I wish openSuSE starts to use this kind of technology in the future.
https://github.com/packit-service/packit

Ya, I know about packit.  I've been slowly getting the fedora packages related to rpm management working on openSUSE.  They are appearing at https://build.opensuse.org/project/show/home:jayvdb:rpm/ once I have them roughly working.  fedpkg & koji is still not working. I can put more emphasis on fedpkg, but iirc it has a long dependency list still not working on openSUSE.
Anyways, yes I only intended for a temporary feature branch while we iterate through the problems.  I can also set up the workarea to track master, I guess since this repo isnt too busy.  I guess I was mostly trying to avoid you doing lots of releases fixing one thing at a time, which is a waste of effort.
https://github.com/junaruga/ci-multi-arch-test looks very nice.  One place which desperately needs it is psutil.
e.g. https://github.com/giampaolo/psutil/pull/1364 , and https://github.com/giampaolo/psutil/issues/1414 / https://github.com/giampaolo/psutil/issues/1226  They are also closing 32bit-only bugs as unsupported, because they dont have a test rig for that.  I'll see if I can add openSUSE to https://github.com/junaruga/ci-multi-arch-test .  Give me a few days on that.

Sure. The temporary feature branch is okay for me. At first, I like to implement non-internet test case. Then I will create the feature branch.
For the 32bit only bugs, here are the actual case used. I think these cases help the psutil project people to imagine the implementation.

The way using the container like what I showed.
https://github.com/ged/ruby-pg/blob/master/.travis.yml#L9-L18 (i386 is 32-bit)
The way using setarch command the 32-bit package.
https://github.com/ruby/ruby/blob/trunk/.travis.yml#L194-L223 (i686 is 32-bit)

I know pipenv has an automatic network detect routine which then disables their internet tests.  Might be worth looking into.
I also submitted a few issues for pytest plugins to do this, but no response yet.  https://github.com/miketheman/pytest-socket/issues/25 and https://github.com/kevin1024/vcrpy/issues/425 and https://github.com/venmo/nose-detecthttp/issues/9 .

@jayvdb
I prepared the no internet tests. You can run like this.
pytest -m 'not network'

I also prepared the temporary branch to fix SuSE's arch specific issue.
You can refer it from your build system.
https://github.com/junaruga/rpm-py-installer/tree/feature/tmp-suse

Results appearing at https://build.opensuse.org/package/show/home:jayvdb:branches:Base:SystemRpm/python-rpm-py-installer . One failure so far, on i586 (32bit).

The six failures at https://build.opensuse.org/package/live_build_log/home:jayvdb:branches:Base:SystemRpm/python-rpm-py-installer/openSUSE_Factory/i586 are a good place to start.  Copied here in case you havent got an account on OBS yet - for reasons unknown the build logs are hidden behind user login, which is easy to create.
[  111s] =================================== FAILURES ===================================
[  111s] __________________________ test_rpm_init_is_ok[True] ___________________________
[  111s]
[  111s] is_dnf = True, sys_rpm_path = '/usr/bin/rpm'
[  111s]
[  111s]     @pytest.mark.parametrize('is_dnf', [True, False])
[  111s]     @pytest.mark.skipif(pytest.helpers.helper_is_debian(),
[  111s]                         reason='Only Linux Fedora.')
[  111s]     def test_rpm_init_is_ok(is_dnf, sys_rpm_path):
[  111s]         with mock.patch.object(Cmd, 'which') as mock_which:
[  111s]             mock_which.return_value = is_dnf
[  111s]             rpm = FedoraRpm(sys_rpm_path)
[  111s]             assert mock_which.called
[  111s]             assert rpm.rpm_path == sys_rpm_path
[  111s]             assert rpm.is_dnf is is_dnf
[  111s] >           assert rpm.arch == 'x86_64'
[  111s] E           AssertionError: assert 'i686' == 'x86_64'
[  111s] E             - i686
[  111s] E             + x86_64
[  111s]
[  111s] tests/test_install.py:370: AssertionError
[  111s] __________________________ test_rpm_init_is_ok[False] __________________________
[  111s]
[  111s] is_dnf = False, sys_rpm_path = '/usr/bin/rpm'
[  111s]
[  111s]     @pytest.mark.parametrize('is_dnf', [True, False])
[  111s]     @pytest.mark.skipif(pytest.helpers.helper_is_debian(),
[  111s]                         reason='Only Linux Fedora.')
[  111s]     def test_rpm_init_is_ok(is_dnf, sys_rpm_path):
[  111s]         with mock.patch.object(Cmd, 'which') as mock_which:
[  111s]             mock_which.return_value = is_dnf
[  111s]             rpm = FedoraRpm(sys_rpm_path)
[  111s]             assert mock_which.called
[  111s]             assert rpm.rpm_path == sys_rpm_path
[  111s]             assert rpm.is_dnf is is_dnf
[  111s] >           assert rpm.arch == 'x86_64'
[  111s] E           AssertionError: assert 'i686' == 'x86_64'
[  111s] E             - i686
[  111s] E             + x86_64
[  111s]
[  111s] tests/test_install.py:370: AssertionError
[  111s] ____________________________ test_rpm_lib_dir_is_ok ____________________________
[  111s]
[  111s] sys_rpm = <install.FedoraRpm object at 0xb6a3796c>, is_debian = False
[  111s]
[  111s]     def test_rpm_lib_dir_is_ok(sys_rpm, is_debian):
[  111s]         if is_debian:
[  111s]             assert sys_rpm.lib_dir == '/usr/lib/x86_64-linux-gnu'
[  111s]         else:
[  111s] >           assert sys_rpm.lib_dir == '/usr/lib64'
[  111s]
[  111s] tests/test_install.py:438:
[  111s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[  111s] install.py:1536: in lib_dir
[  111s]     out = Cmd.sh_e_out(cmd)
[  111s] install.py:1768: in sh_e_out
[  111s]     return cls.sh_e(cmd, **cmd_kwargs)[0]
[  112s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[  112s]
[  112s] cls = <class 'install.Cmd'>, cmd = '/usr/bin/rpm -ql rpm-libs'
[  112s] kwargs = {'stdout': -1}
[  112s] cmd_kwargs = {'env': {'COLORTERM': '1', 'CPU': 'i686', 'CSHEDIT': 'emacs', 'FORCE_SOURCE_DATE': '1', ...}, 'shell': True, 'stderr': -1, 'stdout': -1}
[  112s] env = {'COLORTERM': '1', 'CPU': 'i686', 'CSHEDIT': 'emacs', 'FORCE_SOURCE_DATE': '1', ...}
[  112s] proc = <subprocess.Popen object at 0xb6a3780c>
[  112s] stdout = 'package rpm-libs is not installed
[  112s] ', stderr = '', returncode = 1
[  112s] message_format = 'CMD Return Code: [{0}], Stdout: [{1}], Stderr: [{2}]'
[  112s]
[  112s]     @classmethod
[  112s]     def sh_e(cls, cmd, **kwargs):
[  112s]         """Run the command. It behaves like "sh -e".
[  112s]
[  112s]         It raises InstallError if the command failed.
[  112s]         """
[  112s]         Log.debug('CMD: {0}'.format(cmd))
[  112s]         cmd_kwargs = {
[  112s]             'shell': True,
[  112s]         }
[  112s]         cmd_kwargs.update(kwargs)
[  112s]
[  112s]         env = os.environ.copy()
[  112s]         # Better to parse English output
[  112s]         env['LC_ALL'] = 'en_US.utf-8'
[  112s]         if 'env' in kwargs:
[  112s]             env.update(kwargs['env'])
[  112s]         cmd_kwargs['env'] = env
[  112s]         # Capture stderr to show it on error message.
[  112s]         cmd_kwargs['stderr'] = subprocess.PIPE
[  112s]
[  112s]         proc = None
[  112s]         try:
[  112s]             proc = subprocess.Popen(cmd, **cmd_kwargs)
[  112s]             stdout, stderr = proc.communicate()
[  112s]             returncode = proc.returncode
[  112s]             message_format = (
[  112s]                 'CMD Return Code: [{0}], Stdout: [{1}], Stderr: [{2}]'
[  112s]             )
[  112s]             Log.debug(message_format.format(returncode, stdout, stderr))
[  112s]
[  112s]             if stdout is not None:
[  112s]                 stdout = stdout.decode('utf-8')
[  112s]             if stderr is not None:
[  112s]                 stderr = stderr.decode('utf-8')
[  112s]
[  112s]             if returncode != 0:
[  112s]                 message = 'CMD: [{0}], Return Code: [{1}] at [{2}]'.format(
[  112s]                     cmd, returncode, os.getcwd())
[  112s]                 if stderr is not None:
[  112s]                     message += ' Stderr: [{0}]'.format(stderr)
[  112s]                 ie = CmdError(message)
[  112s]                 ie.stdout = stdout
[  112s]                 ie.stderr = stderr
[  112s]                 raise ie
[  112s]
[  112s]             return (stdout, stderr)
[  112s]         except Exception as e:
[  112s]             try:
[  112s]                 proc.kill()
[  112s]             except Exception:
[  112s]                 pass
[  112s] >           raise e
[  112s] E           CmdError: CMD: [/usr/bin/rpm -ql rpm-libs], Return Code: [1] at [/home/abuild/rpmbuild/BUILD/rpm-py-installer-feature-tmp-suse] Stderr: []
[  112s]
[  112s] install.py:1759: CmdError
[  112s] ____________________________ test_rpm_extract_is_ok ____________________________
[  112s]
[  112s] sys_rpm = <install.FedoraRpm object at 0xb6b1fd2c>
[  112s] rpm_files = ['/home/abuild/rpmbuild/BUILD/rpm-py-installer-feature-tmp-suse/tests/fixtures/rpm/rpm-build-libs-<IP_ADDRESS>-2.fc25.i686.../home/abuild/rpmbuild/BUILD/rpm-py-installer-feature-tmp-suse/tests/fixtures/rpm/rpm-devel-<IP_ADDRESS>-2.fc25.x86_64.rpm']
[  112s]
[  112s]     @pytest.mark.skipif(pytest.helpers.helper_is_debian(),
[  112s]                         reason='Only Linux Fedora.')
[  112s]     def test_rpm_extract_is_ok(sys_rpm, rpm_files):
[  112s]         with pytest.helpers.work_dir():
[  112s]             for rpm_file in rpm_files:
[  112s]                 shutil.copy(rpm_file, '.')
[  112s]
[  112s]             sys_rpm.extract('rpm-build-libs')
[  112s] >           files = os.listdir('./usr/lib64')
[  112s] E           OSError: [Errno 2] No such file or directory: './usr/lib64'
[  112s]
[  112s] tests/test_install.py:506: OSError
[  112s] ______________ test_installer_run_raises_error_for_rpm_build_libs ______________
[  112s]
[  112s] installer = <install.FedoraInstaller object at 0xb6b6654c>
[  112s]
[  112s]     @pytest.mark.skipif(pytest.helpers.helper_is_debian(),
[  112s]                         reason='Only Linux Fedora.')
[  112s]     def test_installer_run_raises_error_for_rpm_build_libs(installer):
[  112s]         installer.rpm.has_composed_rpm_bulid_libs = mock.MagicMock(
[  112s]             return_value=True
[  112s]         )
[  112s]         installer._is_rpm_all_lib_include_files_installed = mock.MagicMock(
[  112s]             return_value=False
[  112s]         )
[  112s]         installer.rpm.is_downloadable = mock.MagicMock(
[  112s]             return_value=False
[  112s]         )
[  112s]         installer._is_rpm_build_libs_installed = mock.MagicMock(
[  112s]             return_value=False
[  112s]         )
[  112s]
[  112s]         with pytest.raises(InstallError) as ei:
[  112s]             installer.run()
[  112s]         expected_message = '''
[  112s]     Install failed without rpm-devel package by below reason.
[  112s]     Can you install the RPM package, and run this installer again?
[  112s]
[  112s]     Required RPM not installed: [rpm-build-libs],
[  112s]     when a RPM download plugin not installed.
[  112s]     '''
[  112s] >       assert expected_message == str(ei.value)
[  112s] E       AssertionError: assert '\nInstall fa... installed.\n' == '\nInstall fai...e] Stderr: []'
[  112s] E
[  112s] E           Install failed without rpm-devel package by below reason.
[  112s] E           Can you install the RPM package, and run this installer again?
[  112s] E         + CMD: [/usr/bin/rpm -ql rpm-libs], Return Code: [1] at [/home/abuild/rpmbuild/BUILD/rpm-py-installer-feature-tmp-suse] Stderr: []
[  112s] E         -
[  112s] E         - Required RPM not installed: [rpm-build-libs],
[  112s] E         - when a RPM download plugin not installed.
[  112s]
[  112s] tests/test_install.py:987: AssertionError
[  112s] _____ test_app_verify_system_status_is_ok_on_sys_py_and_sys_installed_true _____
[  112s]
[  112s] app = <install.Application object at 0xb6b1282c>
[  112s]
[  112s]     def test_app_verify_system_status_is_ok_on_sys_py_and_sys_installed_true(app):
[  112s]         app.python.is_system_python = mock.MagicMock(return_value=True)
[  112s]         app.python.is_python_binding_installed = mock.MagicMock(return_value=False)
[  112s]         app.linux.sys_installed = mock.MagicMock(return_value=True)
[  112s] >       app.linux.verify_system_status()
[  112s]
[  112s] tests/test_install.py:1123:
[  112s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[  112s] install.py:1217: in verify_system_status
[  112s]     self.verify_package_status()
[  112s] install.py:1237: in verify_package_status
[  112s]     self.rpm.verify_packages_installed(['rpm-libs'])
[  112s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[  112s]
[  112s] self = <install.FedoraRpm object at 0xb6b12d4c>, package_names = ['rpm-libs']
[  112s]
[  112s]         def verify_packages_installed(self, package_names):
[  112s]             """Check if the RPM packages are installed.
[  112s]
[  112s]             Raise InstallError if any of the packages is not installed.
[  112s]             """
[  112s]             if not package_names:
[  112s]                 raise ValueError('package_names required.')
[  112s]
[  112s]             missing_packages = []
[  112s]             for package_name in package_names:
[  112s]                 if not self.is_package_installed(package_name):
[  112s]                     missing_packages.append(package_name)
[  112s]
[  112s]             if missing_packages:
[  112s]                 comma_packages = ', '.join(missing_packages)
[  112s]                 message = '''
[  112s]     Required RPM not installed: [{0}].
[  112s]     Install the RPM package.
[  112s]     '''.format(comma_packages)
[  112s] >               raise InstallError(message)
[  112s] E               InstallError:
[  112s] E               Required RPM not installed: [rpm-libs].
[  112s] E               Install the RPM package.
[  112s]
[  112s] install.py:1498: InstallError

@jayvdb sorry for late response. I updated this repository's "master" branch and "feature/tmp-suse" branch. I think now the update supports multi arch and 32-bit environment. I expect it also works on "i586 (32bit)" of your build system.
Could you try "feature/tmp-suse" or "master" branch when you have time?
Thanks.

 It behaves like "sh -e".
[   71s]
[   71s]         It raises InstallError if the command failed.
[   71s]         """
[   71s]         Log.debug('CMD: {0}'.format(cmd))
[   71s]         cmd_kwargs = {
[   71s]             'shell': True,
[   71s]         }
[   71s]         cmd_kwargs.update(kwargs)
[   71s]
[   71s]         env = os.environ.copy()
[   71s]         # Better to parse English output
[   71s]         env['LC_ALL'] = 'en_US.utf-8'
[   71s]         if 'env' in kwargs:
[   71s]             env.update(kwargs['env'])
[   71s]         cmd_kwargs['env'] = env
[   71s]         # Capture stderr to show it on error message.
[   71s]         cmd_kwargs['stderr'] = subprocess.PIPE
[   71s]
[   71s]         proc = None
[   71s]         try:
[   71s]             proc = subprocess.Popen(cmd, **cmd_kwargs)
[   71s]             stdout, stderr = proc.communicate()
[   71s]             returncode = proc.returncode
[   71s]             message_format = (
[   71s]                 'CMD Return Code: [{0}], Stdout: [{1}], Stderr: [{2}]'
[   71s]             )
[   71s]             Log.debug(message_format.format(returncode, stdout, stderr))
[   71s]
[   71s]             if stdout is not None:
[   71s]                 stdout = stdout.decode('utf-8')
[   71s]             if stderr is not None:
[   71s]                 stderr = stderr.decode('utf-8')
[   71s]
[   71s]             if returncode != 0:
[   71s]                 message = 'CMD: [{0}], Return Code: [{1}] at [{2}]'.format(
[   71s]                     cmd, returncode, os.getcwd())
[   71s]                 if stderr is not None:
[   71s]                     message += ' Stderr: [{0}]'.format(stderr)
[   71s]                 ie = CmdError(message)
[   71s]                 ie.stdout = stdout
[   71s]                 ie.stderr = stderr
[   71s]                 raise ie
[   71s]
[   71s]             return (stdout, stderr)
[   71s]         except Exception as e:
[   71s]             try:
[   71s]                 proc.kill()
[   71s]             except Exception:
[   71s]                 pass
[   71s] >           raise e
[   71s] E           CmdError: CMD: [/usr/bin/rpm -ql rpm-libs], Return Code: [1] at [/home/abuild/rpmbuild/BUILD/rpm-py-installer-master] Stderr: []
[   71s]
[   71s] install.py:1761: CmdError
[   71s] ______________ test_installer_run_raises_error_for_rpm_build_libs ______________
[   71s]
[   71s] installer = <install.FedoraInstaller object at 0x7f2adb117810>
[   71s]
[   71s]     @pytest.mark.skipif(pytest.helpers.helper_is_debian(),
[   71s]                         reason='Only Linux Fedora.')
[   71s]     def test_installer_run_raises_error_for_rpm_build_libs(installer):
[   71s]         installer.rpm.has_composed_rpm_bulid_libs = mock.MagicMock(
[   71s]             return_value=True
[   71s]         )
[   71s]         installer._is_rpm_all_lib_include_files_installed = mock.MagicMock(
[   71s]             return_value=False
[   71s]         )
[   71s]         installer.rpm.is_downloadable = mock.MagicMock(
[   71s]             return_value=False
[   71s]         )
[   71s]         installer._is_rpm_build_libs_installed = mock.MagicMock(
[   71s]             return_value=False
[   71s]         )
[   71s]
[   71s]         with pytest.raises(InstallError) as ei:
[   71s]             installer.run()
[   71s]         expected_message = '''
[   71s]     Install failed without rpm-devel package by below reason.
[   71s]     Can you install the RPM package, and run this installer again?
[   71s]
[   71s]     Required RPM not installed: [rpm-build-libs],
[   71s]     when a RPM download plugin not installed.
[   71s]     '''
[   71s] >       assert expected_message == str(ei.value)
[   71s] E       AssertionError: assert '\nInstall fa... installed.\n' == '\nInstall fai...r] Stderr: []'
[   71s] E
[   71s] E           Install failed without rpm-devel package by below reason.
[   71s] E           Can you install the RPM package, and run this installer again?
[   71s] E         + CMD: [/usr/bin/rpm -ql rpm-libs], Return Code: [1] at [/home/abuild/rpmbuild/BUILD/rpm-py-installer-master] Stderr: []
[   71s] E         -
[   71s] E         - Required RPM not installed: [rpm-build-libs],
[   71s] E         - when a RPM download plugin not installed.
[   71s]
[   71s] tests/test_install.py:991: AssertionError
[   71s] _____ test_app_verify_system_status_is_ok_on_sys_py_and_sys_installed_true _____
[   71s]
[   71s] app = <install.Application object at 0x7f2adb53e590>
[   71s]
[   71s]     def test_app_verify_system_status_is_ok_on_sys_py_and_sys_installed_true(app):
[   71s]         app.python.is_system_python = mock.MagicMock(return_value=True)
[   71s]         app.python.is_python_binding_installed = mock.MagicMock(return_value=False)
[   71s]         app.linux.sys_installed = mock.MagicMock(return_value=True)
[   71s] >       app.linux.verify_system_status()
[   71s]
[   71s] tests/test_install.py:1127:
[   71s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[   71s] install.py:1217: in verify_system_status
[   71s]     self.verify_package_status()
[   71s] install.py:1237: in verify_package_status
[   71s]     self.rpm.verify_packages_installed(['rpm-libs'])
[   71s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[   71s]
[   71s] self = <install.FedoraRpm object at 0x7f2adb53e510>
[   71s] package_names = ['rpm-libs']
[   71s]
[   71s]         def verify_packages_installed(self, package_names):
[   71s]             """Check if the RPM packages are installed.
[   71s]
[   71s]             Raise InstallError if any of the packages is not installed.
[   71s]             """
[   71s]             if not package_names:
[   71s]                 raise ValueError('package_names required.')
[   71s]
[   71s]             missing_packages = []
[   71s]             for package_name in package_names:
[   71s]                 if not self.is_package_installed(package_name):
[   71s]                     missing_packages.append(package_name)
[   71s]
[   71s]             if missing_packages:
[   71s]                 comma_packages = ', '.join(missing_packages)
[   71s]                 message = '''
[   71s]     Required RPM not installed: [{0}].
[   71s]     Install the RPM package.
[   71s]     '''.format(comma_packages)
[   71s] >               raise InstallError(message)
[   71s] E               InstallError:
[   71s] E               Required RPM not installed: [rpm-libs].
[   71s] E               Install the RPM package.
[   71s]
[   71s] install.py:1498: InstallError
[   71s] ======== 3 failed, 92 passed, 2 skipped, 22 deselected in 3.76 seconds =========
[   71s] error: Bad exit status from /var/tmp/rpm-tmp.e87sWg (%check)

e.g. i586 extra error
[   42s] __________________________ test_rpm_init_is_ok[True] ___________________________
[   42s]
[   42s] is_dnf = True, sys_rpm_path = '/usr/bin/rpm', arch = 'i686'
[   42s]
[   42s]     @pytest.mark.parametrize('is_dnf', [True, False])
[   42s]     @pytest.mark.skipif(pytest.helpers.helper_is_debian(),
[   42s]                         reason='Only Linux Fedora.')
[   42s]     def test_rpm_init_is_ok(is_dnf, sys_rpm_path, arch):
[   42s]         with mock.patch.object(Cmd, 'which') as mock_which:
[   42s]             mock_which.return_value = is_dnf
[   42s]             rpm = FedoraRpm(sys_rpm_path)
[   42s]             assert mock_which.called
[   42s]             assert rpm.rpm_path == sys_rpm_path
[   42s]             assert rpm.is_dnf is is_dnf
[   42s] >           assert rpm.arch == arch
[   42s] E           AssertionError: assert 'i586' == 'i686'
[   42s] E             - i586
[   42s] E             ?  ^
[   42s] E             + i686
[   42s] E             ?  ^

All logs at https://build.opensuse.org/package/show/home:jayvdb:branches:Base:SystemRpm/python-rpm-py-installer

@jayvdb thank you for the log files.
I want to ask you to add below 4 commands in python-rpm-py-installer.spec to see the results.
rpm -ql rpm-libs
command -v dnf
uname -m
rpm -q rpm --qf "%{arch}\n"

In the log, it seems rpm -ql rpm-libs returns error exit status.
On Fedora the package rpm-libs is required to run rpm. And I expected it is already installed.
I expected dnf was installed and used on opensuse. But I was wrong.
I assume zypper is installed and used right? (I am not familiar with opensuse).
Right now zypper is not considered for rpm-py-installer.
Maybe I need to add opensuse case to this repository's CI.
https://github.com/rpm-software-management/rpmlint/tree/master/test
https://hub.docker.com/_/opensuse

In the log, it seems rpm -ql rpm-libs returns error exit status.
On Fedora the package rpm-libs is required to run rpm. And I expected it is already installed.

Oh seeing opensuse's rpm.spec, there is no rpm-libs sub package in it.
https://build.opensuse.org/package/view_file/Base:System/rpm/rpm.spec?expand=1

@junaruga regarding packit, this is hardcoded fedora jenkins stuff as far as I see. But we can setup a CI build in build.opensuse.org and you could add a webhook in github. So a package could build for all opensuse (and also fedora, debian, ArchLinux, ...) always based on latest master, if you like.
However, someone would need to help with the non-suse build descriptions, but shouldn't be too hard ...

@adrianschroeter Thanks. But at first I am planing to to add OpenSuSE x86_64 case and (Intel 32-bit or ARM 32-bit) case to this repository using container like other distributions' test cases. Then I think that we can fix every issues for the OpenSuSE CI.

I released new version rpm-py-installer 1.0.0 including this feature now. :)

Note that I removed the feature/tmp-suse branch. I think we do not use it any more.


Added fdatasync to fs api

fixes #45

Coverage remained the same at 92.157% when pulling 722faf2d6c95dc88193b23cce90e20aad0857bd2 on axit-rasmus:master into efad0c55ad5a2b82d6860a4cc90183eb46fb2dd4 on normalize:master.

fs.js 100644 → 100755

You, probably accidentally, changed the file to be executable, could you please revert that change? Thanks

Coverage remained the same at 92.157% when pulling bf6dd4aae44a9820023c32251978a85c9e5e3736 on axit-rasmus:master into efad0c55ad5a2b82d6860a4cc90183eb46fb2dd4 on normalize:master.

Good catch, didn't notice. Fixed

If anyone can make a release, please feel free to merge and release, otherwise I will fix it when I'm not at work 👌

LGTM

2.6.0

Thank you!


Implement cycle-handling

I'm beginning to appreciate the idea of this feature because implementing it maens

parity with itchyny/mmv
more protection on file movement, which is nice and smart
more practice for me 💪🏻

Problem
There is no check for the existence of cycles in sources and destinations. Overwriting files can happen, and we aren't fond of that idea. Where we used to simply leave it up to the user, we now would like to provide protections in those instances where the user behaves as humans do.
Solution
We should use our ordered sets to capture the destination names provided by the user, compare them to the source set, and handle various situations accordingly. Given that the two sets should always be the same size and have the same number of entries, we should (we think) be able to compare the hashes (indices of insertion) of the dest set to the source set to find cycles. For example, if we have
file1.txt -> file2.txt
file2.txt -> file3.txt
file3.txt -> file1.txt

We should be able to compare the first destination, just for example, to the source set and see that there is a match, because file2.txt is in both. From there, we should use some checks to see if file2.txt is being renamed and, if

true: move it to a temporary location, then to its final destination
false: enforce the user provide another name or something to that effect

Closed by #15, implemented in 3f8e6e520e819f36236d80a490019ad9d6d6fdf0


List Config disappears

I saved my configuration in my Azure DevOps Project.  Tested it.  It works wonderfully.  Then, two days later configuration reverted to the default config.  Not sure what is happening or what I am not doing.  Please help.  I save a backup now to quickly replace.  This has happened twice.

This happens to me as well.  I've also had several others in our organization test it and every single time someone logs in from their phone, it's set back to default config.  This is something that we really love and need to use, but being the person who has to write the JSON... you get it.  You know you get it.

I am also having this same issue and have to fix this 3 times now.  I am unsure of the root cause but I know that I spent a lot of time setting up the configuration only to have it 'stop working' days later and find that the configuration has been reset back to its default value.
Please find a fix for this and sort it as this is becoming extremely annoying.

Is this fixed then? How can update this new change to Azure devops.

Is this resolved?  If so do I need to remove and install this extension again?  Looking for help to fix this issue.

Is This fixed?

I have had to rebuild my config once this week.  Is there something I need to do?
From: Vcods<EMAIL_ADDRESS>Sent: Tuesday, January 14, 2020 4:01 AM
To: microsoft/azure-devops-extension-cascading-picklist<EMAIL_ADDRESS>Cc: Thomas Brelinski<EMAIL_ADDRESS>Author<EMAIL_ADDRESS>Subject: Re: [microsoft/azure-devops-extension-cascading-picklist] List Config disappears (#29)
Is This fixed?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHubhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fmicrosoft%2Fazure-devops-extension-cascading-picklist%2Fissues%2F29%3Femail_source%3Dnotifications%26email_token%3DAMBAKNWKYKZ5KB2RASPBIUDQ5WSQFA5CNFSM4JEX3HP2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEI4LJTA%23issuecomment-574141644&data=02|01|Thomas.Brelinski%40microsoft.com|2f06595b7b4a4fece3e008d798e9705e|72f988bf86f141af91ab2d7cd011db47|1|0|637146000697241824&sdata=luqpgCQi1V0e8DNtrcGs0Fm48OKH7I%2FbD6GpnfJxpPs%3D&reserved=0, or unsubscribehttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAMBAKNUOKAMLA7S74WUDBETQ5WSQFANCNFSM4JEX3HPQ&data=02|01|Thomas.Brelinski%40microsoft.com|2f06595b7b4a4fece3e008d798e9705e|72f988bf86f141af91ab2d7cd011db47|1|0|637146000697241824&sdata=qhDQQ%2BAAa%2BcW48Tn%2FM6Uj2Wg%2B8Owf2Op03Z8Qg10Cqs%3D&reserved=0.


Fixed: Gradle eclipse target produces duplicate build path entries in .classpath (OFBIZ-12888)

Removes the groovyScripts source set, the compileGroovyScriptsGroovy task configuration and changes the pre-push hook to "checkstyleMain codenarcMain codenarcTest" instead of "checkstyleMain codenarcGroovyScripts".

It's only a matter of performance for the hook. I'd like to have @danwatford's opinon about removing the compileGroovyScriptsGroovy Gradle task...

It's only a matter of performance for the hook. I'd like to have @danwatford's opinon about removing the compileGroovyScriptsGroovy Gradle task...

Yes - the groovyScripts source set should be removed along with the changes to the compileGroovyScriptsGroovy task.
This PR should be merged, with corresponding changes to the OFBiz buildbot definition to prevent build failure due to the absence of the build/reports/codenarc/groovyScripts.html file. Explanation given in comments here - https://issues.apache.org/jira/browse/OFBIZ-12888.


New prop setOGTypeArticle sets og:type to "article" for posts

...and "website" for every other page.

😅 Looks like the deployment failed. My apologies, this is my first pull request. I'm not sure what I did wrong, this change works fine on my website.

Thank you!


[cache] fix transaction iterator

There are a few things to fix with the transaction iterator

Iterating a transactdion should not yield entry state, only key & value.
It should work in a for of -- this means it can't accept parameters.
It should iterate local entries.

Right now localEntries is implemented by calling the tx iterator itself but it should be the other way around.
// iterating the tx itself should be fine and should semantically be the same
// as iterating tx.localEntries()
let (for [key, value] of tx) {
  console.log('tx updates', key, value);
}

I realize iterating the cache entry state was in the original design -- this was a design mistake.


fix cellid property name and netcoreapp2.0 switch

@yatli i just have a try, we do need the netcoreapp2.0 switch for ‘DefineConstants', since if build unittest with 'dotnet' command, we have to pass TargetFramework=netcoreapp2.0, then lost the 'NETSTANDARD2_0' definition, this will cause build error for FanoutSearch project.

alright. I also touched the CellID issue, let me push first, and then merge your PR onto it.

@chaosddp you're through! :D


FetchContent and install path updates

I've added a couple of updates that might be helpful, feel free to use them if you wish, or not:

Added a new option use_default_install_location to disable the overload of CMAKE_INSTALL_PREFIX if the default path is used. This allows people to pull the package in via FetchContent without it overriding the install path of their outer project.
Updated the install paths so that they install to include/MUMPS and lib/MUMPS (rather than include/ and lib/) so that they don't directly pollute system paths.

There are a lot of formatting changes because of my auto-formatter that might confuse things - the only actual changes are to the argument of the DESTINATION keyword of each install() call.

Thanks--I should have realized that install prefix would be a problem for FetchContent consumers.
I changed in ae7e258c32d4c60c896c58ba4f3cc7c926e49f88 to NOT do this problematic cache override.

With regard to forcing relative install paths like lib/MUMPS and include/MUMPS, I think this is a matter of different practices by different projects. Instead of relative install paths, I have been using distinct install prefixes like:
cmake -B build -DCMAKE_INSTALL_PREFIX=~/local/mumps

and then set environment variables like:
export MUMPS_ROOT=~/local/mumps

So I really appreciate you letting me know about the FetchContent install prefix override issue, I will also check other projects of ours for the same problem.
With regard to install relative paths, I would like to retain the current Mumps approach of using distinct install prefixes. For our work, we often test across library versions, compiler vendors and compiler versions, and using distinct install prefixes has been a better fit for us.

Thanks--I should have realized that install prefix would be a problem for FetchContent consumers.
I changed in ae7e258c32d4c60c896c58ba4f3cc7c926e49f88 to NOT do this problematic cache override.

Excellent, thanks for sorting this out so quickly.

With regard to forcing relative install paths like lib/MUMPS and include/MUMPS, I think this is a matter of different practices by different projects. Instead of relative install paths, I have been using distinct install prefixes like:

cmake -B build -DCMAKE_INSTALL_PREFIX=~/local/mumps

and then set environment variables like:

export MUMPS_ROOT=~/local/mumps

Ah, I see! It makes sense for the project I'm working on to have its own project subdirectory as it installs so many files. I have made another update in my forked repo to adjust the FindMUMPS.cmake script with the new install locations if you wanted to use the format I mentioned. :)

So I really appreciate you letting me know about the FetchContent install prefix override issue, I will also check other projects of ours for the same problem.
With regard to install relative paths, I would like to retain the current Mumps approach of using distinct install prefixes. For our work, we often test across library versions, compiler vendors and compiler versions, and using distinct install prefixes has been a better fit for us.

Not a problem, glad I could help! Thanks for doing such a great job of exporting the package, it has otherwise made it incredibly easy to import the solver into my library.


Unicorn-Micro – Define the HW requirements

Task description
We want to evaluate the possibility build a new low-power compact board to control a LED lamp over Bluetooth and/or WiFi.
The board must be powered by battery.
Definition of Done

[ ] HW Requirements are well defined
[ ] Estimate the total cost production

❓ Some Queestions

How many batteries?
Which micro-controller?
What are the functional requirements?
Do we have to develop an adapter-board for programming?

❌ Absolutely to avoid

No LEDs on board
No Variable voltage regulator on board
No more than 6 GPIOs Exposed to the user (maybe only the one for programming?)

✅ Absolutely to have

USB-C connector for powering and charging (and programming?)
All the components must be SMD
Battery connector or +/- holes for soldering the battery wires

I want to drop here just a couple of info/links found on the web:
We could power the microcontrolled w/ a 3.7 LiPo:

https://forum.arduino.cc/t/atmega328-powered-by-3-7v-lipo/84931

Todo this we'd need for a Step-Up Power Module integrated on our PCB:

https://en.wikipedia.org/wiki/Boost_converter
ANGEEK-0-9-5V-Step-Up-Voltage-Converter

/remind 8th April 2024 Let's start this activity!


ScrollViewer not working on Microsoft surface touch device

Which version of the app?
WinUI 3 Gallery
Description
"I have an existing UWP app that works as expected on non-touch devices and utilizes the Data Grid control, ScrollViewer, and ListView control from Microsoft.Toolkit.Uwp.UI.Controls. While I can scroll and click the scroll buttons using the mouse, I’m unable to scroll using the scrollbar controls on touch screen devices; it seems that this functionality is disabled for touch input. Could you please provide guidance or solutions to enable scrolling with the scrollbar and scroll buttons on touch screens? Any configuration tips or solutions would be greatly appreciated. Thank you!"
Screenshots
No response
Windows version
Windows 10 22H2 (19045)
Additional context
No response

DataGrid.zip
ScrollBarWIthButton.zip
Please refer to the attached two sample applications:

The application works fine with a mouse, but when used on a Microsoft Surface or other touch devices, scrolling using the scrollbar is not possible (swipe functionality is working , but required to work scrollbar with touch).

Data Grid Demo App - Scrolling using the scrollbar does not work on touch screens. While the scrollbar's color changes when using a mouse, it appears to be non-interactive when on  touch device."

Please review the application and let me know the option to enable scrolling on touch devices.


Ungapped prefilter died during GPU-accelerated search

When I ran my scrpit below to generate MSA against uniref90 by MMseqs2 GPU-accelerated searching, it reported an error as follows. However, when I replaced the targetDB uniref90 with a smaller one (consisit of about thousands of sequences), such error would not appear. My Linux system contains:

40 CPUs,
400+ GB ram,
4 GPUs,
enough storage.

Could you please help me figure this out? Thanks in advance for your expert help.
Error
ungappedprefilter /a100_nas/ai4s/MSA/queries/testDB /a100_nas/ai4s/MSA/uniref90DB_gpu.idx /a100_nas/ai4s/MSA/tmp/15602816422822286028/pref_0 --sub-mat 'aa:blosum62.out,nucl:nucleotide.out' -c 0 -e 0.001 --cov-mode 0 --comp-bias-corr 1 --comp-bias-corr-scale 1 --min-ungapped-score 15 --max-seqs 300 --db-load-mode 2 --gpu 1 --gpu-server 1 --prefilter-mode 1 --threads 42 --compressed 0 -v 3

Index version: 16
Generated by:  16.747c6
ScoreMatrix:  VTML80.out
--gpu-server /dev/shm/8478586279687262130 does not existError: Ungapped prefilter died

part of my script
mmseqs createdb $UNIREFFASTA $UNIREFDB
mmseqs makepaddedseqdb $UNIREFDB $UNIREFDB_GPU

QUERY_DB="${QUERY_DIR}/testDB"
mmseqs createdb $QUERY $QUERY_DB

# searching with GPU
mmseqs createindex $UNIREFDB_GPU $TMP --index-subset 2
mmseqs gpuserver $UNIREFDB_GPU --gpu 1 &
PID=$!
mmseqs search $QUERY_DB $UNIREFDB_GPU $RESULTS/aln_test $TMP --gpu 1 --gpu-server 1 --db-load-mode 2 --remove-tmp-files 1 --max-seq 10000
kill $PID

hello, it seems i have the same problem with you.I wanna know that if you  used the command mmseqs makepaddedseqdb and it  returns the segment error?

hello, it seems i have the same problem with you.I wanna know that if you used the command mmseqs makepaddedseqdb for the targetdb and it returns the segment error?

Hello, I definitely used mmseqs makepaddedseqdb command, and it succeeded and no error occurred. How large is your targetDB?

Nearly 43GB.It is uniclust30-hhsuite and  used mmseqs createdb to get the targetdb.


TFlite model loading and detecting in Flutter

Hi, cuz I'm using in flutter
referring by this: https://pub.dev/packages/tflite
I just used below command in flutter
res = await Tflite.loadModel(
          model: "assets/yolov4-416-fp32.tflite",
          labels: "assets/coco.txt",
        );

var recognitions = await Tflite.detectObjectOnImage(
        path: image.path,
        model: "YOLO",
        threshold: 0.3,
        imageMean: 0.0,
        imageStd: 255.0,
        numResultsPerClass: 1);

But there was an error.

Caused by: java.lang.IllegalArgumentException: Cannot copy from a TensorFlowLite tensor (Identity) with shape [1, 2535, 4] to a Java object with shape [1, 13, 13, 425]

something more i type correctly in Tflite.detectObjectOnFrame?

Did you e

Hi, cuz I'm using in flutter
referring by this: https://pub.dev/packages/tflite
I just used below command in flutter
res = await Tflite.loadModel(
          model: "assets/yolov4-416-fp32.tflite",
          labels: "assets/coco.txt",
        );

var recognitions = await Tflite.detectObjectOnImage(
        path: image.path,
        model: "YOLO",
        threshold: 0.3,
        imageMean: 0.0,
        imageStd: 255.0,
        numResultsPerClass: 1);

But there was an error.
Caused by: java.lang.IllegalArgumentException: Cannot copy from a TensorFlowLite tensor (Identity) with shape [1, 2535, 4] to a Java object with shape [1, 13, 13, 425]
something more i type correctly in Tflite.detectObjectOnFrame?

Did you get it to work on flutter? Looking to get yolov4 model to work on flutter too

@TexMexMax
TFlite for flutter does not appear to support custom neural networks, so you must modify the TFlite package directly if you want to support the scutum neural network. Or changing the language to an environment where tensorflow lite, such as java lights, is well supported. The issue was described below. After converting my own neural network into TFlite based on java, I import directly to java and have succeeded in input and neural network load and run connection. But I couldn't do anything about drawing a rectangle in the video through the output tensor because I'm used to Python only and can hardly code Java.
https://github.TFlite does not appear to support custom neural networks, so you must modify the TFlite package directly if you want to support the scutum neural network. The issue was described below.
https://github.com/shaqian/flutter_tflite/issues/42
https://github.com/shaqian/flutter_tflite/issues/44

Actually, if you use the tflite plugin, it doesn't. However, there is another flutter plugin called tflite_flutter. It uses the C bindings for the TensorFlow lite C API. This guy basically created an entire API for Dart. It is actually better than the Tensorflow lite Java API since the C API has less latency. The plugin is located in the link below:
https://pub.dev/packages/tflite_flutter
This guy even wrote a support library for this plugin called tflite_flutter_helper. The link is below:
https://pub.dev/packages/tflite_flutter_helper
I build an app that uses a yolov4 model by merely looking at the functions getDetectionsForFull(...) and getDetectionsForTiny(...) in this repository as well as looking at this repository made by the guy who made the above plugins.
https://github.com/am15h/object_detection_flutter/blob/master/lib/tflite/classifier.dart
Just tweaked the that class a bit and it worked.
This is the resulting code:
``
import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as imageLib;
import 'package:object_detection/tflite/recognition.dart';
import 'package:tflite_flutter/tflite_flutter.dart';
import 'package:tflite_flutter_helper/tflite_flutter_helper.dart';
import 'stats.dart';
/// Classifier
class Classifier {
/// Instance of Interpreter
Interpreter _interpreter;
/// Labels file loaded as list
List _labels;
static const String MODEL_FILE_NAME = "yolov4-416-fp32.tflite";
static const String LABEL_FILE_NAME = "coco.txt";
/// Input size of image (height = width = 300)
static const int INPUT_SIZE = 300;
/// Result score threshold
static const double THRESHOLD = 0.5;
/// [ImageProcessor] used to pre-process the image
ImageProcessor imageProcessor;
/// Padding the image to transform into square
int padSize;
/// Shapes of output tensors
List<List> _outputShapes;
/// Types of output tensors
List _outputTypes;
/// Number of results to show
static const int NUM_RESULTS = 10;
Classifier({
Interpreter interpreter,
List labels,
}) {
loadModel(interpreter: interpreter);
loadLabels(labels: labels);
}
/// Loads interpreter from asset
void loadModel({Interpreter interpreter}) async {
try {
_interpreter = interpreter ??
await Interpreter.fromAsset(
MODEL_FILE_NAME,
options: InterpreterOptions()..threads = 4,
);
  var outputTensors = _interpreter.getOutputTensors();
  print("the length of the ouput Tensors is ${outputTensors.length}");
  _outputShapes = [];
  _outputTypes = [];
  outputTensors.forEach((tensor) {
    print(tensor.toString());
    _outputShapes.add(tensor.shape);
    _outputTypes.add(tensor.type);
  });
} catch (e) {
  print("Error while creating interpreter: $e");
}

}
/// Loads labels from assets
void loadLabels({List labels}) async {
try {
_labels =
labels ?? await FileUtil.loadLabels("assets/" + LABEL_FILE_NAME);
} catch (e) {
print("Error while loading labels: $e");
}
}
/// Pre-process the image
TensorImage getProcessedImage(TensorImage inputImage) {
padSize = max(inputImage.height, inputImage.width);
if (imageProcessor == null) {
imageProcessor = ImageProcessorBuilder()
.add(ResizeWithCropOrPadOp(padSize, padSize))
.add(ResizeOp(INPUT_SIZE, INPUT_SIZE, ResizeMethod.BILINEAR))
.build();
}
inputImage = imageProcessor.process(inputImage);
return inputImage;
}
/// Runs object detection on the input image
Map<String, dynamic> predict(imageLib.Image image) {
var predictStartTime = DateTime.now().millisecondsSinceEpoch;
if (_interpreter == null) {
  print("Interpreter not initialized");
  return null;
}

var preProcessStart = DateTime.now().millisecondsSinceEpoch;

// Create TensorImage from image
TensorImage inputImage = TensorImage.fromImage(image);

// Pre-process TensorImage
inputImage = getProcessedImage(inputImage);

var preProcessElapsedTime =
    DateTime.now().millisecondsSinceEpoch - preProcessStart;

// TensorBuffers for output tensors
TensorBuffer outputLocations = TensorBufferFloat(
    _outputShapes[0]); // The location of each detected object
TensorBuffer outputClassesScore = TensorBufferFloat(_outputShapes[
    1]); // The scores of all the classes for each detected object
//TensorBuffer outputScores = TensorBufferFloat(_outputShapes[2]);
//TensorBuffer numLocations = TensorBufferFloat(_outputShapes[3]);

// Inputs object for runForMultipleInputs
// Use [TensorImage.buffer] or [TensorBuffer.buffer] to pass by reference
List<Object> inputs = [inputImage.buffer];

// Outputs map
Map<int, Object> outputs = {
  0: outputLocations.buffer,
  1: outputClassesScore.buffer,
};

var inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;

// run inference
_interpreter.runForMultipleInputs(inputs, outputs);

var inferenceTimeElapsed =
    DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;

// Maximum number of results to show
int resultsCount = min(NUM_RESULTS, outputLocations.getFlatSize());

//List<List<List<double>>> locations = outputs[0]; // The location of each detected object.
List<List<List<double>>> outScores =
    outputs[1]; // The output scores of each class for each detected Object

// Using labelOffset = 1 as ??? at index 0
//int labelOffset = 0;

// Using bounding box utils for easy conversion of tensorbuffer to List<Rect>
List<Rect> locations = BoundingBoxUtils.convert(
  tensor: outputLocations,
  valueIndex: [1, 0, 3, 2],
  boundingBoxAxis: 2,
  boundingBoxType: BoundingBoxType.BOUNDARIES,
  coordinateType: CoordinateType.RATIO,
  height: INPUT_SIZE,
  width: INPUT_SIZE,
);

List<Recognition> recognitions = [];

for (int i = 0; i < resultsCount; i++) {
  // Since we are given a list of scores for each class for
  // each detected Object, we are interested in finding the class
  // with the highest output score

  var maxClass = 0.00;
  var labelIndex = -1;

  for (int c = 0; c < _labels.length; ++c) {
    // output[0][i][c] is the confidence score of c class
    if (outScores[0][i][c] > maxClass) {
      labelIndex = c;
      maxClass = outScores[0][i][c];
    }
  }
  // Prediction score
  var score = maxClass;

  // Label string
  var label = _labels.elementAt(labelIndex);

  // Makes sure the confidence is above the
  // minimum threshold score for each object.
  if (score > THRESHOLD) {
    // inverse of rect
    // [locations] corresponds to the image size 300 X 300
    // inverseTransformRect transforms it our [inputImage]
    Rect transformedRect = imageProcessor.inverseTransformRect(
        locations[i], image.height, image.width);

    recognitions.add(
      Recognition(i, label, score, transformedRect),
    );
  }
}

var predictElapsedTime =
    DateTime.now().millisecondsSinceEpoch - predictStartTime;

return {
  "recognitions": recognitions,
  "stats": Stats(
      totalPredictTime: predictElapsedTime,
      inferenceTime: inferenceTimeElapsed,
      preProcessingTime: preProcessElapsedTime)
};

}
/// Gets the interpreter instance
Interpreter get interpreter => _interpreter;
/// Gets the loaded labels
List get labels => _labels;
}
``

Thank you very much. I just started working at the company and I was mainly used Python, when I want to use neural network to the app, it was very difficult because it required knowledge of Android API and Java grammar. That's why I was the first to see flutter, but I was frustrated that flutter also needed some low code to connect the neural network, and I tried a little bit in JAVA... I finished model converting, loading, inputting but I didn't know how to display the outputs of neural network in display, because I don't know well in java data formats... (I was actually trying OCR... Also recently I was worked another task in company so I paused above things)
Thank you for the answer above and I will study the above code using C API. Thank you!

Actually, if you use the tflite plugin, it doesn't. However, there is another flutter plugin called tflite_flutter. It uses the C bindings for the TensorFlow lite C API. This guy basically created an entire API for Dart. It is actually better than the Tensorflow lite Java API since the C API has less latency. The plugin is located in the link below:
https://pub.dev/packages/tflite_flutter
This guy even wrote a support library for this plugin called tflite_flutter_helper. The link is below:
https://pub.dev/packages/tflite_flutter_helper
I build an app that uses a yolov4 model by merely looking at the functions getDetectionsForFull(...) and getDetectionsForTiny(...) in this repository as well as looking at this repository made by the guy who made the above plugins.
https://github.com/am15h/object_detection_flutter/blob/master/lib/tflite/classifier.dart
Just tweaked the that class a bit and it worked.
This is the resulting code:
``
import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as imageLib;
import 'package:object_detection/tflite/recognition.dart';
import 'package:tflite_flutter/tflite_flutter.dart';
import 'package:tflite_flutter_helper/tflite_flutter_helper.dart';
import 'stats.dart';
/// Classifier
class Classifier {
/// Instance of Interpreter
Interpreter _interpreter;
/// Labels file loaded as list
List _labels;
static const String MODEL_FILE_NAME = "yolov4-416-fp32.tflite";
static const String LABEL_FILE_NAME = "coco.txt";
/// Input size of image (height = width = 300)
static const int INPUT_SIZE = 300;
/// Result score threshold
static const double THRESHOLD = 0.5;
/// [ImageProcessor] used to pre-process the image
ImageProcessor imageProcessor;
/// Padding the image to transform into square
int padSize;
/// Shapes of output tensors
List _outputShapes;
/// Types of output tensors
List _outputTypes;
/// Number of results to show
static const int NUM_RESULTS = 10;
Classifier({
Interpreter interpreter,
List labels,
}) {
loadModel(interpreter: interpreter);
loadLabels(labels: labels);
}
/// Loads interpreter from asset
void loadModel({Interpreter interpreter}) async {
try {
_interpreter = interpreter ??
await Interpreter.fromAsset(
MODEL_FILE_NAME,
options: InterpreterOptions()..threads = 4,
);
  var outputTensors = _interpreter.getOutputTensors();
  print("the length of the ouput Tensors is ${outputTensors.length}");
  _outputShapes = [];
  _outputTypes = [];
  outputTensors.forEach((tensor) {
    print(tensor.toString());
    _outputShapes.add(tensor.shape);
    _outputTypes.add(tensor.type);
  });
} catch (e) {
  print("Error while creating interpreter: $e");
}

}
/// Loads labels from assets
void loadLabels({List labels}) async {
try {
_labels =
labels ?? await FileUtil.loadLabels("assets/" + LABEL_FILE_NAME);
} catch (e) {
print("Error while loading labels: $e");
}
}
/// Pre-process the image
TensorImage getProcessedImage(TensorImage inputImage) {
padSize = max(inputImage.height, inputImage.width);
if (imageProcessor == null) {
imageProcessor = ImageProcessorBuilder()
.add(ResizeWithCropOrPadOp(padSize, padSize))
.add(ResizeOp(INPUT_SIZE, INPUT_SIZE, ResizeMethod.BILINEAR))
.build();
}
inputImage = imageProcessor.process(inputImage);
return inputImage;
}
/// Runs object detection on the input image
Map<String, dynamic> predict(imageLib.Image image) {
var predictStartTime = DateTime.now().millisecondsSinceEpoch;
if (_interpreter == null) {
  print("Interpreter not initialized");
  return null;
}

var preProcessStart = DateTime.now().millisecondsSinceEpoch;

// Create TensorImage from image
TensorImage inputImage = TensorImage.fromImage(image);

// Pre-process TensorImage
inputImage = getProcessedImage(inputImage);

var preProcessElapsedTime =
    DateTime.now().millisecondsSinceEpoch - preProcessStart;

// TensorBuffers for output tensors
TensorBuffer outputLocations = TensorBufferFloat(
    _outputShapes[0]); // The location of each detected object
TensorBuffer outputClassesScore = TensorBufferFloat(_outputShapes[
    1]); // The scores of all the classes for each detected object
//TensorBuffer outputScores = TensorBufferFloat(_outputShapes[2]);
//TensorBuffer numLocations = TensorBufferFloat(_outputShapes[3]);

// Inputs object for runForMultipleInputs
// Use [TensorImage.buffer] or [TensorBuffer.buffer] to pass by reference
List<Object> inputs = [inputImage.buffer];

// Outputs map
Map<int, Object> outputs = {
  0: outputLocations.buffer,
  1: outputClassesScore.buffer,
};

var inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;

// run inference
_interpreter.runForMultipleInputs(inputs, outputs);

var inferenceTimeElapsed =
    DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;

// Maximum number of results to show
int resultsCount = min(NUM_RESULTS, outputLocations.getFlatSize());

//List<List<List<double>>> locations = outputs[0]; // The location of each detected object.
List<List<List<double>>> outScores =
    outputs[1]; // The output scores of each class for each detected Object

// Using labelOffset = 1 as ??? at index 0
//int labelOffset = 0;

// Using bounding box utils for easy conversion of tensorbuffer to List<Rect>
List<Rect> locations = BoundingBoxUtils.convert(
  tensor: outputLocations,
  valueIndex: [1, 0, 3, 2],
  boundingBoxAxis: 2,
  boundingBoxType: BoundingBoxType.BOUNDARIES,
  coordinateType: CoordinateType.RATIO,
  height: INPUT_SIZE,
  width: INPUT_SIZE,
);

List<Recognition> recognitions = [];

for (int i = 0; i < resultsCount; i++) {
  // Since we are given a list of scores for each class for
  // each detected Object, we are interested in finding the class
  // with the highest output score

  var maxClass = 0.00;
  var labelIndex = -1;

  for (int c = 0; c < _labels.length; ++c) {
    // output[0][i][c] is the confidence score of c class
    if (outScores[0][i][c] > maxClass) {
      labelIndex = c;
      maxClass = outScores[0][i][c];
    }
  }
  // Prediction score
  var score = maxClass;

  // Label string
  var label = _labels.elementAt(labelIndex);

  // Makes sure the confidence is above the
  // minimum threshold score for each object.
  if (score > THRESHOLD) {
    // inverse of rect
    // [locations] corresponds to the image size 300 X 300
    // inverseTransformRect transforms it our [inputImage]
    Rect transformedRect = imageProcessor.inverseTransformRect(
        locations[i], image.height, image.width);

    recognitions.add(
      Recognition(i, label, score, transformedRect),
    );
  }
}

var predictElapsedTime =
    DateTime.now().millisecondsSinceEpoch - predictStartTime;

return {
  "recognitions": recognitions,
  "stats": Stats(
      totalPredictTime: predictElapsedTime,
      inferenceTime: inferenceTimeElapsed,
      preProcessingTime: preProcessElapsedTime)
};

}
/// Gets the interpreter instance
Interpreter get interpreter => _interpreter;
/// Gets the loaded labels
List get labels => _labels;
}
``

Could you post your whole working project on GitHub? I'm trying to run yolov4 on phone as well and couldn't get your or original code to work. Thanks!

@TexMexMax I changed the original classifier.dart to your code (since my custom model is also yolov4), changed the names of the two files and it does not work. The app compiles but nothing is happening, not even the text "Inference Time", "Total prediction time". Does not work nor with yolov4.tflite nor with yolov4-fp16.tflite.
This is my AndroidStudio Console output:
Performing hot restart...
Syncing files to device WAS LX1...
Restarted application in 1.967ms.
I/CameraManagerGlobal(12654): do not need hide aux camera, device number: 2
I/CameraDevice-JV-0(12654): close camera: 0, package name: com.example.object_detection
I/HwSystemManager(12654): pkgName = com.example.object_detection pid = 12654uidOf3RdApk = 10162permType = 0permCfg=0
I/BackgroundPermManager(12654): pkgName: com.example.object_detection,pid: 12654 ,uidOf3RdApk: 10162 ,permType: 0 ,permCfg: 0
I/CameraManagerGlobal(12654): do not need hide aux camera, device number: 2
I/CameraManagerGlobal(12654): do not need hide aux camera, device number: 2
I/CameraDevice-JV-0(12654): Camera now idle
E/BufferQueueProducer(12654): [] Can not get hwsched service
E/BufferQueueProducer(12654): [] Can not get hwsched service
E/BufferQueueProducer(12654): [] Can not get hwsched service
I/PermissionManager(12654): camera remind result:true
I/CameraManager(12654): open camera: 0, package name: com.example.object_detection
I/HwSystemManager(12654): pkgName = com.example.object_detection pid = 12654uidOf3RdApk = 10162permType = 0permCfg=1
I/BackgroundPermManager(12654): pkgName: com.example.object_detection,pid: 12654 ,uidOf3RdApk: 10162 ,permType: 0 ,permCfg: 1
I/CameraManagerGlobal(12654): do not need hide aux camera, device number: 2
I/CameraManagerGlobal(12654): do not need hide aux camera, device number: 2
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
I/flutter (12654): the length of the ouput Tensors is 2
I/flutter (12654): Tensor{_tensor: Pointer: address=0x78a8f4aef0, name: Identity, type: TfLiteType.float32, shape: [1, 10647, 4], data:  170352
I/flutter (12654): Tensor{_tensor: Pointer: address=0x78a8f4a5c0, name: Identity_1, type: TfLiteType.float32, shape: [1, 10647, 12], data:  511056
I/CameraDevice-JV-0(12654): Camera now idle
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
W/GrallocMapperPassthrough(12654): buffer descriptor with invalid usage bits 0x2080000
I/flutter (12654): the length of the ouput Tensors is 2
I/flutter (12654): Tensor{_tensor: Pointer: address=0x78a8f4aef0, name: Identity, type: TfLiteType.float32, shape: [1, 10647, 4], data:  170352
I/flutter (12654): Tensor{_tensor: Pointer: address=0x78a8f4a5c0, name: Identity_1, type: TfLiteType.float32, shape: [1, 10647, 12], data:  511056
E/flutter (12654): [ERROR:flutter/runtime/dart_isolate.cc(882)] Unhandled exception:
E/flutter (12654): Bad state: failed precondition
E/flutter (12654): #0      checkState (package:quiver/check.dart:71:5)
E/flutter (12654): #1      Tensor.setTo (package:tflite_flutter/src/tensor.dart:150:5)
E/flutter (12654): #2      Interpreter.runForMultipleInputs (package:tflite_flutter/src/interpreter.dart:194:33)
E/flutter (12654): #3      Classifier.predict (package:object_detection/tflite/classifier.dart:140:18)
E/flutter (12654): #4      IsolateUtils.entryPoint (package:object_detection/utils/isolate_utils.dart:45:51)
E/flutter (12654): #5      _RootZone.runUnary (dart:async/zone.dart:1450:54)
E/flutter (12654): #6      _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
E/flutter (12654): #7      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
E/flutter (12654): #8      Future._propagateToListeners (dart:async/future_impl.dart:725:32)
E/flutter (12654): #9      Future._complete (dart:async/future_impl.dart:519:7)
E/flutter (12654): #10     _StreamIterator._onData (dart:async/stream_impl.dart:1070:20)
E/flutter (12654): #11     _RootZone.runUnaryGuarded (dart:async/zone.dart:1384:10)
E/flutter (12654): #12     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:357:11)
E/flutter (12654): #13     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:285:7)
E/flutter (12654): #14     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:808:19)
E/flutter (12654): #15     _StreamController._add (dart:async/stream_controller.dart:682:7)
E/flutter (12654): #16     _StreamController.add (dart:async/stream_controller.dart:624:5)
E/flutter (12654): #17     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

@Liisjak I had messed up and pasted the wrong version of the code above by accident. Anyways, the code below is my current code, but I have found some logic errors like the non-max suppression failing to work properly. Still debugging my code. You are more than welcome to tested it with this. It should output bounding boxes and the confidence scores.
CODE: classifierYolov4.dart
import 'dart:math';
import 'dart:ui';
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as imageLib;
import 'package:object_detection/tflite/recognition.dart';
import 'package:tflite_flutter/tflite_flutter.dart';
import 'package:tflite_flutter_helper/tflite_flutter_helper.dart';
import 'stats.dart';
/// Classifier
class Classifier {
/// Instance of Interpreter
Interpreter _interpreter;
//Interpreter Options (Settings)
final int numThreads = 6;
final bool isNNAPI = false;
final bool isGPU = true;
/// Labels file loaded as list
List _labels;
static const String MODEL_FILE_NAME = "yolov4-416-fp32.tflite";
static const String LABEL_FILE_NAME = "coco.txt";
/// Input size of image (height = width = 300)
static const int INPUT_SIZE = 416;
/// Confidence Probabilty score threshold
static const double THRESHOLD = 0.5;
/// Non-maximum suppression threshold
static double mNmsThresh = 0.6;
/// [ImageProcessor] used to pre-process the image
ImageProcessor imageProcessor;
/// Padding the image to transform into square
int padSize;
/// Shapes of output tensors
List<List> _outputShapes;
/// Types of output tensors
List _outputTypes;
/// Number of results to show
static const int NUM_RESULTS = 10;
Classifier({
Interpreter interpreter,
List labels,
}) {
loadModel(interpreter: interpreter);
loadLabels(labels: labels);
}
/// Loads interpreter from asset
void loadModel({Interpreter interpreter}) async {
try {
//Still working on it
/InterpreterOptions myOptions = new InterpreterOptions();
myOptions.threads = numThreads;
if (isNNAPI) {
NnApiDelegate nnApiDelegate;
bool androidApiThresholdMet = true;
if (androidApiThresholdMet) {
nnApiDelegate = new NnApiDelegate();
myOptions.addDelegate(nnApiDelegate);
myOptions.useNnApiForAndroid = true;
}
}
if (isGPU) {
GpuDelegateV2 gpuDelegateV2 = new GpuDelegateV2();
myOptions.addDelegate(gpuDelegateV2);
}/
  _interpreter = interpreter ??
      await Interpreter.fromAsset(
        MODEL_FILE_NAME,
        options: InterpreterOptions()..threads = numThreads, //myOptions,
      );

  var outputTensors = _interpreter.getOutputTensors();
  print("the length of the ouput Tensors is ${outputTensors.length}");
  _outputShapes = [];
  _outputTypes = [];
  outputTensors.forEach((tensor) {
    print(tensor.toString());
    _outputShapes.add(tensor.shape);
    _outputTypes.add(tensor.type);
  });
} catch (e) {
  print("Error while creating interpreter: $e");
}

}
/// Loads labels from assets
void loadLabels({List labels}) async {
try {
_labels =
labels ?? await FileUtil.loadLabels("assets/" + LABEL_FILE_NAME);
} catch (e) {
print("Error while loading labels: $e");
}
}
/// Pre-process the image
TensorImage getProcessedImage(TensorImage inputImage) {
padSize = max(inputImage.height, inputImage.width);
if (imageProcessor == null) {
imageProcessor = ImageProcessorBuilder()
.add(ResizeWithCropOrPadOp(padSize, padSize))
.add(ResizeOp(INPUT_SIZE, INPUT_SIZE, ResizeMethod.BILINEAR))
.build();
}
inputImage = imageProcessor.process(inputImage);
return inputImage;
}
// non-maximum suppression
List nms(
List list) // Turned from Java's ArrayList to Dart's List.
{
List nmsList = new List();
for (int k = 0; k < labels.length; k++) {
  // 1.find max confidence per class
  PriorityQueue<Recognition> pq = new HeapPriorityQueue<Recognition>();
  for (int i = 0; i < list.length; ++i) {
    print("${list[i].label}  == ${labels[k]}");
    print("${list[i].label == labels[k]}");
    if (list[i].label == labels[k]) {
      // Changed from comparing #th class to class to string to string
      pq.add(list[i]);
    }
  }
  List<Recognition> babe = pq.toList();
  for (int v = 0; v < babe.length; v++) {
    print("pq[$v] = ${babe.elementAt(v)}");
  }

  // 2.do non maximum suppression
  while (pq.length > 0) {
    // insert detection with max confidence
    List<Recognition> detections = pq.toList(); //In Java: pq.toArray(a)
    Recognition max = detections[0];
    nmsList.add(max);
    pq.clear();
    for (int j = 1; j < detections.length; j++) {
      Recognition detection = detections[j];
      Rect b = detection.location;
      if (boxIou(max.location, b) < mNmsThresh) {
        pq.add(detection);
      }
    }
  }
}

return nmsList;

}
double boxIou(Rect a, Rect b) {
Rect inter = a.intersect(b);
if (inter.width > 0 || inter.height > 0) {
return 0;
}
double area = inter.width * inter.height;
return area / boxUnion(a, b);
//return boxIntersection(a, b) / boxUnion(a, b);
}
double boxIntersection(Rect a, Rect b) {
Rect inter = a.intersect(b);
if (inter.width < 0 || inter.height > 0) {
return 0;
}
double area = inter.width * inter.height;
return area;
//Original code (Dart version of hunglc007 yolov4 tensorflow projct)
/*double w = overlap((a.left + a.right) / 2, a.right - a.left,
    (b.left + b.right) / 2, b.right - b.left);
double h = overlap((a.top + a.bottom) / 2, a.bottom - a.top,
    (b.top + b.bottom) / 2, b.bottom - b.top);
if ((w < 0) || (h < 0)) {
  return 0;
}
double area = (w * h);
return area;*/

}
double boxUnion(Rect a, Rect b) {
double i = boxIntersection(a, b);
double u = ((((a.right - a.left) * (a.bottom - a.top)) +
((b.right - b.left) * (b.bottom - b.top))) -
i);
return u;
}
/double overlap(double x1, double w1, double x2, double w2) {
double l1 = (x1 - (w1 / 2));
double l2 = (x2 - (w2 / 2));
double left = ((l1 > l2) ? l1 : l2);
double r1 = (x1 + (w1 / 2));
double r2 = (x2 + (w2 / 2));
double right = ((r1 < r2) ? r1 : r2);
return right - left;
}/
/// Runs object detection on the input image
Map<String, dynamic> predict(imageLib.Image image) {
var predictStartTime = DateTime.now().millisecondsSinceEpoch;
if (_interpreter == null) {
  return null;
}

var preProcessStart = DateTime.now().millisecondsSinceEpoch;

// Initliazing TensorImage as the needed model input type
// of TfLiteType.float32. Then, creating TensorImage from image
TensorImage inputImage = TensorImage(TfLiteType.float32);
inputImage.loadImage(image);
// Do not use static methods, fromImage(Image) or fromFile(File),
// of TensorImage unless the desired input TfLiteDataType is Uint8.
// Create TensorImage from image
//inputImage = TensorImage.fromImage(image);

// Pre-process TensorImage
inputImage = getProcessedImage(inputImage);

var preProcessElapsedTime =
    DateTime.now().millisecondsSinceEpoch - preProcessStart;

// TensorBuffers for output tensors
TensorBuffer outputLocations = TensorBufferFloat(
    _outputShapes[0]); // The location of each detected object

List<List<List<double>>> outputClassScores = new List.generate(
    _outputShapes[1][0],
    (_) => new List.generate(_outputShapes[1][1],
        (_) => new List.filled(_outputShapes[1][2], 0.0),
        growable: false),
    growable: false);

// Inputs object for runForMultipleInputs
// Use [TensorImage.buffer] or [TensorBuffer.buffer] to pass by reference
List<Object> inputs = [inputImage.buffer];

// Outputs map
Map<int, Object> outputs = {
  0: outputLocations.buffer,
  1: outputClassScores,
};

var inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;

print("Running inference");
// run inference
_interpreter.runForMultipleInputs(inputs, outputs);

print("Done running inference");

var inferenceTimeElapsed =
    DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;

// Using bounding box utils for easy conversion of tensorbuffer to List<Rect>
List<Rect> locations = BoundingBoxUtils.convert(
  tensor: outputLocations,
  //valueIndex: [1, 0, 3, 2], Commented out because default order is needed.
  boundingBoxAxis: 2,
  boundingBoxType: BoundingBoxType.CENTER,
  coordinateType: CoordinateType.PIXEL,
  height: INPUT_SIZE,
  width: INPUT_SIZE,
);

print(locations.length);

List<Recognition> recognitions = [];

var gridWidth = _outputShapes[0][1];
//print("gridWidth = $gridWidth");

for (int i = 0; i < gridWidth; i++) {
  // Since we are given a list of scores for each class for
  // each detected Object, we are interested in finding the class
  // with the highest output score

  var maxClassScore = 0.00;
  var labelIndex = -1;

  for (int c = 0; c < _labels.length; c++) {
    // output[0][i][c] is the confidence score of c class
    if (outputClassScores[0][i][c] > maxClassScore) {
      labelIndex = c;
      maxClassScore = outputClassScores[0][i][c];
    }
  }
  // Prediction score
  var score = maxClassScore;

  var label;
  if (labelIndex != -1) {
    // Label string
    label = _labels.elementAt(labelIndex);
  } else {
    label = null;
  }

  print("label = $label\tscore=$score");
  // Makes sure the confidence is above the
  // minimum threshold score for each object.
  if (score > THRESHOLD) {
    // inverse of rect
    // [locations] corresponds to the image size 300 X 300
    // inverseTransformRect transforms it our [inputImage]

    Rect rectAti = Rect.fromLTRB(
        max(0, locations[i].left),
        max(0, locations[i].top),
        min(INPUT_SIZE + 0.0, locations[i].right),
        min(INPUT_SIZE + 0.0, locations[i].bottom));

    Rect transformedRect = imageProcessor.inverseTransformRect(
        rectAti, image.height, image.width);

    recognitions.add(
      Recognition(i, label, score, transformedRect),
    );
  }
} // End of for loop and added all recognitions
List<Recognition> recognitionsNMS = nms(recognitions);
var predictElapsedTime =
    DateTime.now().millisecondsSinceEpoch - predictStartTime;

return {
  "recognitions": recognitionsNMS,
  "stats": Stats(
      totalPredictTime: predictElapsedTime,
      inferenceTime: inferenceTimeElapsed,
      preProcessingTime: preProcessElapsedTime)
};

}
/// Gets the interpreter instance
Interpreter get interpreter => _interpreter;
/// Gets the loaded labels
List get labels => _labels;
}
Also, change the code below in camera_view.dart:
cameraController = CameraController(cameras[0], ResolutionPreset.low, enableAudio:false);
to
cameraController = CameraController(cameras[0], ResolutionPreset.low, enableAudio:false);
This is assuming your custom yolov4 model wants a 416x416 size image. In addition, I'd really appreciate if you reply with whether it works. Maybe you or someone can figure out what the error is. Currently, testing with the yolov4 tflite model and label asset .txt file from this repository. Keeps identifying my laptop as a sofa. If I find something else, I'll certainly post here.

@TexMexMax Hey! Your code compiled after I removed some unnecessary slash symbols. However, I could NOT get it to work properly. I keep getting:
Error while creating interpreter: Invalid argument(s): Failed to lookup symbol (undefined symbol: TfLiteGpuDelegateV2Create)
Would you mind creating a repo and posting code there? Also, you told me to replace a line in camera_view.dart with the same exact line.
Cheers

@Liisjak @SungmanHong I finally made a repository and fixed everything wrong with the models. The program works better than this version.
Here is the link:
https://github.com/TexMexMax/object_detection_flutter.git

@TexMexMax I can only say Great work! Very well done, thank you!

@TexMexMax Any ideas on how to change your code so that it works on a single image (taken from camera or image from Assets folder)?

@TexMexMax  thank u sir i will try , even i get confused haha

@TexMexMax Thank you for this wonderful work. When I run it without changing anything in the code, it randomly draws a box on the screen. When I give my tflite model, which normally works in the android/java part, it still draws a random box or not at all. Where is the problem? I would be very grateful if you could help.

@furkan1023 I am not sure why that would be the case. Is the model a Yolov4 tflite model?

@TexMexMax i actually tried your repo on multiple devices(phones) with multiple flutter versions, outcome is still same. when you cover the camera it randomly draws boxes with "sofa" label or randomly draws boxes with random labels. I wanted to test your "pre-built apk" but its broken. Let me remind you again i did no changes on your repo, not a single scratch, it simply doesn't work. If you would like to see the outcome i made a screen recording of the app. You're my only hope with yolov4-flutter.
Video : https://www.youtube.com/watch?v=9h8xWF9Hss8&ab_channel=furkanxxx

Are you using your very own model and labels? What is MODEL_FILE_NAME and LABEL_FILE_NAME set as?

@furkan1023 Are you using your very own model and labels? What is MODEL_FILE_NAME and LABEL_FILE_NAME set as?

@TexMexMax  These model and label are  from your repo
static const String MODEL_FILE_NAME = "yolov4-416-fp32.tflite";
static const String LABEL_FILE_NAME = "coco.txt";
But as i said, i didn't change anything. i have just run install.bat from the link you shared on your repo and executed the main.dart.

@furkan1023 I'm sorry for the late response. I've been really busy. Anyways, I think you might be messing something up. I can confirm it worked with me, and I tested it on the day you send me the video. Make sure you follow the instructions in the README.MD. Make sure you replace the image_conversions file of tflite_flutter_helper with the one I provide. This might be the issue.

i found out . that was actually my problem. it was solved with replace the image_conversions file of tflite_flutter_helper with the one you provide

Facing similar issue
Error:
Cannot copy from a TensorFlowLite tensor (Identity) with shape [1, 2535, 4] to a Java object with shape [1, 2].
Tried all most all the github links for tflite in flutter for object detection still not working.
They are our customised weights, your weights are working but not ours.
yolov4-tinny-.tflite-416.
So please can you help us??

Does it matter which version of tflite_flutter_helper you are using.  I replaced the image_conversion.dart file in my tflite_flutter_helper 0.3.0 with yours and that caused my app to fail to build.  Does it only work with tflite_flutter_helper 0.1.2?

@furkan1023 I'm sorry for the late response. I've been really busy. Anyways, I think you might be messing something up. I can confirm it worked with me, and I tested it on the day you send me the video. Make sure you follow the instructions in the README.MD. Make sure you replace the image_conversions file of tflite_flutter_helper with the one I provide. This might be the issue.

How do i try to capture and upload from gallery functionality i see most object detections do on real-time only ?

@TexMexMax Any ideas on how to change your code so that it works on a single image (taken from camera or image from Assets folder)?

Any idea what changes need to be done in the code so that the model can work on a single image

@LiisjakEu errei e colei a versão errada do código acima por acidente. De qualquer forma, o código abaixo é o meu código atual, mas encontrei alguns erros de lógica, como a supressão não-máxima, não funcionando corretamente. Ainda depurando meu código. Você é mais do que bem-vindo para testá-lo com isso. Ele deve gerar caixas delimitadoras e as pontuações de confiança. CÓDIGO: classifierYolov4.dart import 'dart:math'; import 'dart:ui'; import 'pacote:coleção/coleção.dart'; import 'package:flutter/material.dart'; import 'package:image/image.dart' como imageLib; import 'package:object_detection/tflite/recognition.dart'; import 'pacote:tflite_flutter/tflite_flutter.dart'; import 'pacote:
importar 'stats.dart';
/// Classifier class Classifier { /// Instância do intérprete Interpreter _interpreter;
//Opções do Interpretador (Configurações) final int numThreads = 6; final bool isNNAPI = false; final bool isGPU = true;
/// Arquivos de rótulos carregados como list List _labels;
static const String MODEL_FILE_NAME = "yolov4-416-fp32.tflite"; static const String LABEL_FILE_NAME = "coco.txt";
/// Tamanho de entrada da imagem (altura = largura = 300) static const int INPUT_SIZE = 416;
/// Limite de pontuação de probabilidade de confiança static const double THRESHOLD = 0.5;
/// Limite de supressão não máximo static double mNmsThresh = 0.6;
/// [ImageProcessor] usado para pré-processar a imagem ImageProcessor imageProcessor;
/// Preenchendo a imagem para transformar em quadrado int padSize;
/// Formas de tensores de saída List _outputShapes;
/// Tipos de tensores de saída List _outputTypes;
/// Número de resultados para mostrar static const int NUM_RESULTS = 10;
Classifier({ Interpreter interpreter, List labels, }) { loadModel(interpreter: interpreter); loadLabels(rótulos: rótulos); }
/// Carrega o interpretador do ativo void loadModel({Interpreter interpreter}) async { try { //Ainda trabalhando nele / InterpreterOptions myOptions = new InterpreterOptions(); minhasOpções.threads = numThreads; if (isNNAPI) { NnApiDelegate nnApiDelegate; bool androidApiThresholdMet = true; if (androidApiThresholdMet) { nnApiDelegate = new NnApiDelegate(); myOptions.addDelegate(nnApiDelegate); myOptions.useNnApiForAndroid = true; } } if (isGPU) { GpuDelegateV2 gpuDelegateV2 = new GpuDelegateV2(); myOptions.addDelegate(gpuDelegateV2); } /
  _interpreter = interpreter ??
      await Interpreter.fromAsset(
        MODEL_FILE_NAME,
        options: InterpreterOptions()..threads = numThreads, //myOptions,
      );

  var outputTensors = _interpreter.getOutputTensors();
  print("the length of the ouput Tensors is ${outputTensors.length}");
  _outputShapes = [];
  _outputTypes = [];
  outputTensors.forEach((tensor) {
    print(tensor.toString());
    _outputShapes.add(tensor.shape);
    _outputTypes.add(tensor.type);
  });
} catch (e) {
  print("Error while creating interpreter: $e");
}

}
/// Carrega rótulos de ativos void loadLabels({List labels}) async { try { _labels = labels ?? await FileUtil.loadLabels("assets/" + LABEL_FILE_NAME); } catch (e) { print("Erro ao carregar etiquetas: $e"); } }
/// Pré-processa a imagem TensorImage getProcessedImage(TensorImage inputImage) { padSize = max(inputImage.height, inputImage.width); if (imageProcessor == null) { imageProcessor = ImageProcessorBuilder() .add(ResizeWithCropOrPadOp(padSize, padSize)) .add(ResizeOp(INPUT_SIZE, INPUT_SIZE, ResizeMethod.BILINEAR)) .build(); } inputImage = imageProcessor.process(inputImage); return imagem de entrada; }
// supressão não máxima List nms( List list) // Passado de ArrayList de Java para List de Dart. { Lista nmsLista = new Lista();
for (int k = 0; k < labels.length; k++) {
  // 1.find max confidence per class
  PriorityQueue<Recognition> pq = new HeapPriorityQueue<Recognition>();
  for (int i = 0; i < list.length; ++i) {
    print("${list[i].label}  == ${labels[k]}");
    print("${list[i].label == labels[k]}");
    if (list[i].label == labels[k]) {
      // Changed from comparing #th class to class to string to string
      pq.add(list[i]);
    }
  }
  List<Recognition> babe = pq.toList();
  for (int v = 0; v < babe.length; v++) {
    print("pq[$v] = ${babe.elementAt(v)}");
  }

  // 2.do non maximum suppression
  while (pq.length > 0) {
    // insert detection with max confidence
    List<Recognition> detections = pq.toList(); //In Java: pq.toArray(a)
    Recognition max = detections[0];
    nmsList.add(max);
    pq.clear();
    for (int j = 1; j < detections.length; j++) {
      Recognition detection = detections[j];
      Rect b = detection.location;
      if (boxIou(max.location, b) < mNmsThresh) {
        pq.add(detection);
      }
    }
  }
}

return nmsList;

}
double boxIou(Ret a, Rect b) { Rect inter = a.intersect(b); if (inter.width > 0 || inter.height > 0) { return 0; } double area = inter.width * inter.height; área de retorno / boxUnion(a, b); //retorna boxIntersection(a, b) / boxUnion(a, b); }
double boxIntersection(Ret a, Rect b) { Rect inter = a.intersect(b); if (inter.width < 0 || inter.height > 0) { return 0; } double area = inter.width * inter.height; área de retorno;
//Original code (Dart version of hunglc007 yolov4 tensorflow projct)
/*double w = overlap((a.left + a.right) / 2, a.right - a.left,
    (b.left + b.right) / 2, b.right - b.left);
double h = overlap((a.top + a.bottom) / 2, a.bottom - a.top,
    (b.top + b.bottom) / 2, b.bottom - b.top);
if ((w < 0) || (h < 0)) {
  return 0;
}
double area = (w * h);
return area;*/

}
double boxUnion(Ret a, Rect b) { double i = boxIntersection(a, b); double u = ((((a.right - a.left) * (a.bottom - a.top)) + ((b.right - b.left) * (b.bottom - b.top))) - eu); devolva você; }
/ double sobreposição(double x1, double w1, double x2, double w2) { double l1 = (x1 - (w1 / 2)); duplo l2 = (x2 - (w2/2)); double left = ((l1 > l2) ? l1 : l2); duplo r1 = (x1 + (w1/2)); duplo r2 = (x2 + (w2/2)); direito duplo = ((r1 < r2) ? r1 : r2); retornar direita - esquerda; } /
/// Runs object detection on the input image Map<String, dynamic> predict(imageLib.Image image) { var predictStartTime = DateTime.now().millisecondsSinceEpoch;
if (_interpreter == null) {
  return null;
}

var preProcessStart = DateTime.now().millisecondsSinceEpoch;

// Initliazing TensorImage as the needed model input type
// of TfLiteType.float32. Then, creating TensorImage from image
TensorImage inputImage = TensorImage(TfLiteType.float32);
inputImage.loadImage(image);
// Do not use static methods, fromImage(Image) or fromFile(File),
// of TensorImage unless the desired input TfLiteDataType is Uint8.
// Create TensorImage from image
//inputImage = TensorImage.fromImage(image);

// Pre-process TensorImage
inputImage = getProcessedImage(inputImage);

var preProcessElapsedTime =
    DateTime.now().millisecondsSinceEpoch - preProcessStart;

// TensorBuffers for output tensors
TensorBuffer outputLocations = TensorBufferFloat(
    _outputShapes[0]); // The location of each detected object

List<List<List<double>>> outputClassScores = new List.generate(
    _outputShapes[1][0],
    (_) => new List.generate(_outputShapes[1][1],
        (_) => new List.filled(_outputShapes[1][2], 0.0),
        growable: false),
    growable: false);

// Inputs object for runForMultipleInputs
// Use [TensorImage.buffer] or [TensorBuffer.buffer] to pass by reference
List<Object> inputs = [inputImage.buffer];

// Outputs map
Map<int, Object> outputs = {
  0: outputLocations.buffer,
  1: outputClassScores,
};

var inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;

print("Running inference");
// run inference
_interpreter.runForMultipleInputs(inputs, outputs);

print("Done running inference");

var inferenceTimeElapsed =
    DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;

// Using bounding box utils for easy conversion of tensorbuffer to List<Rect>
List<Rect> locations = BoundingBoxUtils.convert(
  tensor: outputLocations,
  //valueIndex: [1, 0, 3, 2], Commented out because default order is needed.
  boundingBoxAxis: 2,
  boundingBoxType: BoundingBoxType.CENTER,
  coordinateType: CoordinateType.PIXEL,
  height: INPUT_SIZE,
  width: INPUT_SIZE,
);

print(locations.length);

List<Recognition> recognitions = [];

var gridWidth = _outputShapes[0][1];
//print("gridWidth = $gridWidth");

for (int i = 0; i < gridWidth; i++) {
  // Since we are given a list of scores for each class for
  // each detected Object, we are interested in finding the class
  // with the highest output score

  var maxClassScore = 0.00;
  var labelIndex = -1;

  for (int c = 0; c < _labels.length; c++) {
    // output[0][i][c] is the confidence score of c class
    if (outputClassScores[0][i][c] > maxClassScore) {
      labelIndex = c;
      maxClassScore = outputClassScores[0][i][c];
    }
  }
  // Prediction score
  var score = maxClassScore;

  var label;
  if (labelIndex != -1) {
    // Label string
    label = _labels.elementAt(labelIndex);
  } else {
    label = null;
  }

  print("label = $label\tscore=$score");
  // Makes sure the confidence is above the
  // minimum threshold score for each object.
  if (score > THRESHOLD) {
    // inverse of rect
    // [locations] corresponds to the image size 300 X 300
    // inverseTransformRect transforms it our [inputImage]

    Rect rectAti = Rect.fromLTRB(
        max(0, locations[i].left),
        max(0, locations[i].top),
        min(INPUT_SIZE + 0.0, locations[i].right),
        min(INPUT_SIZE + 0.0, locations[i].bottom));

    Rect transformedRect = imageProcessor.inverseTransformRect(
        rectAti, image.height, image.width);

    recognitions.add(
      Recognition(i, label, score, transformedRect),
    );
  }
} // End of for loop and added all recognitions
List<Recognition> recognitionsNMS = nms(recognitions);
var predictElapsedTime =
    DateTime.now().millisecondsSinceEpoch - predictStartTime;

return {
  "recognitions": recognitionsNMS,
  "stats": Stats(
      totalPredictTime: predictElapsedTime,
      inferenceTime: inferenceTimeElapsed,
      preProcessingTime: preProcessElapsedTime)
};

}
/// Gets the interpreter instance Interpreter get interpreter => _interpreter;
/// Gets the loaded labels List get labels => _labels; }
Also, change the code below in camera_view.dart: cameraController = CameraController(cameras[0], ResolutionPreset.low, enableAudio:false); to cameraController = CameraController(cameras[0], ResolutionPreset.low, enableAudio:false);
This is assuming your custom yolov4 model wants a 416x416 size image. In addition, I'd really appreciate if you reply with whether it works. Maybe you or someone can figure out what the error is. Currently, testing with the yolov4 tflite model and label asset .txt file from this repository. Keeps identifying my laptop as a sofa. If I find something else, I'll certainly post here.

Hi bro, this classification does it work correctly?


SNMP documentation to include ACL support

Change Summary

Types of changes

[ ] Bug fix (non-breaking change which fixes an issue)
[ ] New feature (non-breaking change which adds functionality)
[x] Breaking change (fix or feature that would cause existing functionality to change)
[ ] Code style update (formatting, renaming)
[ ] Refactoring (no functional changes)
[x] Documentation content changes
[ ] Other (please describe):

Related Issue(s)

Fixes documentation missing on #377
Fixes #377

Component(s) name
Proposed changes

How to test

Checklist:

[ ] My code has been rebased from devel before I start
[ ] I have read the CONTRIBUTING document.
[ ] My change requires a change to the documentation.
[ ] I have updated the documentation accordingly.
[ ] I have updated molecule CI testing accordingly
[ ] All new and existing tests passed (pre-commit, make linting and make sanity-lint).

Please, review. Since ACLs on SNMP were not considered as per VRF, this is a breaking change.

Please, review. Since ACLs on SNMP were not considered as per VRF, this is a breaking change.

LGTM!

LGTM!

Doing rebase before merging

Doing rebase before merging


Bluetooth: Controller: Fix regression in BT_RX_STACK_SIZE use

Fix regression in BT_RX_STACK_SIZE use due to
commit b91728619c05 ("Bluetooth: host: remove
CONFIG_BT_RECV_BLOCKING").
Fixes #71062.

@jhedberg Would it be possible for you to test the mesh_demo on BBC:microbit v1 for regressions?

@jhedberg Would it be possible for you to test the mesh_demo on BBC:microbit v1 for regressions?

I did a quick build+flash+boot, resulting in this:
*** Booting Zephyr OS build v3.6.0-2343-gf707156f7ae8 ***
Initializing...
Unicast address: 0x0b0c
Bluetooth init failed (err -45)

-45 is EDEADLK

For the record, the same happens with latest main branch, i.e. not related to this PR:
*** Booting Zephyr OS build v3.6.0-2435-g289c7e16475b ***
Initializing...
Unicast address: 0x0b0c
Bluetooth init failed (err -45)

-45 is EDEADLK

Only realistic option is that it's coming from here:
subsys/fs/nvs/nvs.c:            rc = -EDEADLK;

I.e. this might just be related how the flash on my device has been formatted.

There we go, instead of west flash I just copied zephyr.bin over to the USB mass storage drive, and the sample now successfully boots:
*** Booting Zephyr OS build v3.6.0-2435-g289c7e16475b ***
Initializing...
Unicast address: 0x0b0c
Bluetooth initialized
Mesh initialized
Loading stored settings
Provisioning completed
Configuring...
Configuration complete
Subscribing to heartbeat messages

The odd thing is that in either case (main or this PR) there are no build errors of not fitting within the available memory.

I was trying to use the shell yesterday (w/o this patch) on 52840 (and 833) and it was stack-overflowing pretty hard.

The odd thing is that in either case (main or this PR) there are no build errors of not fitting within the available memory.

@jhedberg Thank you for testing. Yes, both main and PR do not fail to build, its the Controller's Rx thead stack that would be low on main and during (extended scanning, which mesh demo does not use) scanning that the sample could crash/hang with stack overflow.
@jori-nordic Thank you for testing.