MikrofonSensor und TemperaturSenor die zwei Python programme funktionieren. mit den jeweiligen 2 json Datein. Beim TemperaturSensor wird im Terminal keine Wertre ausgegeben aber in der json Datei kann man die Temp und Hum sehen.

This commit is contained in:
Chiara 2025-05-28 14:53:44 +02:00
parent 4c654ec969
commit 1751076592
2614 changed files with 349009 additions and 0 deletions

View file

@ -0,0 +1,23 @@
"""Wrappers to call pyproject.toml-based build backend hooks.
"""
from ._impl import (
BackendInvalid,
BackendUnavailable,
BuildBackendHookCaller,
HookMissing,
UnsupportedOperation,
default_subprocess_runner,
quiet_subprocess_runner,
)
__version__ = '1.0.0'
__all__ = [
'BackendUnavailable',
'BackendInvalid',
'HookMissing',
'UnsupportedOperation',
'default_subprocess_runner',
'quiet_subprocess_runner',
'BuildBackendHookCaller',
]

View file

@ -0,0 +1,8 @@
__all__ = ("tomllib",)
import sys
if sys.version_info >= (3, 11):
import tomllib
else:
from pip._vendor import tomli as tomllib

View file

@ -0,0 +1,330 @@
import json
import os
import sys
import tempfile
from contextlib import contextmanager
from os.path import abspath
from os.path import join as pjoin
from subprocess import STDOUT, check_call, check_output
from ._in_process import _in_proc_script_path
def write_json(obj, path, **kwargs):
with open(path, 'w', encoding='utf-8') as f:
json.dump(obj, f, **kwargs)
def read_json(path):
with open(path, encoding='utf-8') as f:
return json.load(f)
class BackendUnavailable(Exception):
"""Will be raised if the backend cannot be imported in the hook process."""
def __init__(self, traceback):
self.traceback = traceback
class BackendInvalid(Exception):
"""Will be raised if the backend is invalid."""
def __init__(self, backend_name, backend_path, message):
super().__init__(message)
self.backend_name = backend_name
self.backend_path = backend_path
class HookMissing(Exception):
"""Will be raised on missing hooks (if a fallback can't be used)."""
def __init__(self, hook_name):
super().__init__(hook_name)
self.hook_name = hook_name
class UnsupportedOperation(Exception):
"""May be raised by build_sdist if the backend indicates that it can't."""
def __init__(self, traceback):
self.traceback = traceback
def default_subprocess_runner(cmd, cwd=None, extra_environ=None):
"""The default method of calling the wrapper subprocess.
This uses :func:`subprocess.check_call` under the hood.
"""
env = os.environ.copy()
if extra_environ:
env.update(extra_environ)
check_call(cmd, cwd=cwd, env=env)
def quiet_subprocess_runner(cmd, cwd=None, extra_environ=None):
"""Call the subprocess while suppressing output.
This uses :func:`subprocess.check_output` under the hood.
"""
env = os.environ.copy()
if extra_environ:
env.update(extra_environ)
check_output(cmd, cwd=cwd, env=env, stderr=STDOUT)
def norm_and_check(source_tree, requested):
"""Normalise and check a backend path.
Ensure that the requested backend path is specified as a relative path,
and resolves to a location under the given source tree.
Return an absolute version of the requested path.
"""
if os.path.isabs(requested):
raise ValueError("paths must be relative")
abs_source = os.path.abspath(source_tree)
abs_requested = os.path.normpath(os.path.join(abs_source, requested))
# We have to use commonprefix for Python 2.7 compatibility. So we
# normalise case to avoid problems because commonprefix is a character
# based comparison :-(
norm_source = os.path.normcase(abs_source)
norm_requested = os.path.normcase(abs_requested)
if os.path.commonprefix([norm_source, norm_requested]) != norm_source:
raise ValueError("paths must be inside source tree")
return abs_requested
class BuildBackendHookCaller:
"""A wrapper to call the build backend hooks for a source directory.
"""
def __init__(
self,
source_dir,
build_backend,
backend_path=None,
runner=None,
python_executable=None,
):
"""
:param source_dir: The source directory to invoke the build backend for
:param build_backend: The build backend spec
:param backend_path: Additional path entries for the build backend spec
:param runner: The :ref:`subprocess runner <Subprocess Runners>` to use
:param python_executable:
The Python executable used to invoke the build backend
"""
if runner is None:
runner = default_subprocess_runner
self.source_dir = abspath(source_dir)
self.build_backend = build_backend
if backend_path:
backend_path = [
norm_and_check(self.source_dir, p) for p in backend_path
]
self.backend_path = backend_path
self._subprocess_runner = runner
if not python_executable:
python_executable = sys.executable
self.python_executable = python_executable
@contextmanager
def subprocess_runner(self, runner):
"""A context manager for temporarily overriding the default
:ref:`subprocess runner <Subprocess Runners>`.
.. code-block:: python
hook_caller = BuildBackendHookCaller(...)
with hook_caller.subprocess_runner(quiet_subprocess_runner):
...
"""
prev = self._subprocess_runner
self._subprocess_runner = runner
try:
yield
finally:
self._subprocess_runner = prev
def _supported_features(self):
"""Return the list of optional features supported by the backend."""
return self._call_hook('_supported_features', {})
def get_requires_for_build_wheel(self, config_settings=None):
"""Get additional dependencies required for building a wheel.
:returns: A list of :pep:`dependency specifiers <508>`.
:rtype: list[str]
.. admonition:: Fallback
If the build backend does not defined a hook with this name, an
empty list will be returned.
"""
return self._call_hook('get_requires_for_build_wheel', {
'config_settings': config_settings
})
def prepare_metadata_for_build_wheel(
self, metadata_directory, config_settings=None,
_allow_fallback=True):
"""Prepare a ``*.dist-info`` folder with metadata for this project.
:returns: Name of the newly created subfolder within
``metadata_directory``, containing the metadata.
:rtype: str
.. admonition:: Fallback
If the build backend does not define a hook with this name and
``_allow_fallback`` is truthy, the backend will be asked to build a
wheel via the ``build_wheel`` hook and the dist-info extracted from
that will be returned.
"""
return self._call_hook('prepare_metadata_for_build_wheel', {
'metadata_directory': abspath(metadata_directory),
'config_settings': config_settings,
'_allow_fallback': _allow_fallback,
})
def build_wheel(
self, wheel_directory, config_settings=None,
metadata_directory=None):
"""Build a wheel from this project.
:returns:
The name of the newly created wheel within ``wheel_directory``.
.. admonition:: Interaction with fallback
If the ``build_wheel`` hook was called in the fallback for
:meth:`prepare_metadata_for_build_wheel`, the build backend would
not be invoked. Instead, the previously built wheel will be copied
to ``wheel_directory`` and the name of that file will be returned.
"""
if metadata_directory is not None:
metadata_directory = abspath(metadata_directory)
return self._call_hook('build_wheel', {
'wheel_directory': abspath(wheel_directory),
'config_settings': config_settings,
'metadata_directory': metadata_directory,
})
def get_requires_for_build_editable(self, config_settings=None):
"""Get additional dependencies required for building an editable wheel.
:returns: A list of :pep:`dependency specifiers <508>`.
:rtype: list[str]
.. admonition:: Fallback
If the build backend does not defined a hook with this name, an
empty list will be returned.
"""
return self._call_hook('get_requires_for_build_editable', {
'config_settings': config_settings
})
def prepare_metadata_for_build_editable(
self, metadata_directory, config_settings=None,
_allow_fallback=True):
"""Prepare a ``*.dist-info`` folder with metadata for this project.
:returns: Name of the newly created subfolder within
``metadata_directory``, containing the metadata.
:rtype: str
.. admonition:: Fallback
If the build backend does not define a hook with this name and
``_allow_fallback`` is truthy, the backend will be asked to build a
wheel via the ``build_editable`` hook and the dist-info
extracted from that will be returned.
"""
return self._call_hook('prepare_metadata_for_build_editable', {
'metadata_directory': abspath(metadata_directory),
'config_settings': config_settings,
'_allow_fallback': _allow_fallback,
})
def build_editable(
self, wheel_directory, config_settings=None,
metadata_directory=None):
"""Build an editable wheel from this project.
:returns:
The name of the newly created wheel within ``wheel_directory``.
.. admonition:: Interaction with fallback
If the ``build_editable`` hook was called in the fallback for
:meth:`prepare_metadata_for_build_editable`, the build backend
would not be invoked. Instead, the previously built wheel will be
copied to ``wheel_directory`` and the name of that file will be
returned.
"""
if metadata_directory is not None:
metadata_directory = abspath(metadata_directory)
return self._call_hook('build_editable', {
'wheel_directory': abspath(wheel_directory),
'config_settings': config_settings,
'metadata_directory': metadata_directory,
})
def get_requires_for_build_sdist(self, config_settings=None):
"""Get additional dependencies required for building an sdist.
:returns: A list of :pep:`dependency specifiers <508>`.
:rtype: list[str]
"""
return self._call_hook('get_requires_for_build_sdist', {
'config_settings': config_settings
})
def build_sdist(self, sdist_directory, config_settings=None):
"""Build an sdist from this project.
:returns:
The name of the newly created sdist within ``wheel_directory``.
"""
return self._call_hook('build_sdist', {
'sdist_directory': abspath(sdist_directory),
'config_settings': config_settings,
})
def _call_hook(self, hook_name, kwargs):
extra_environ = {'PEP517_BUILD_BACKEND': self.build_backend}
if self.backend_path:
backend_path = os.pathsep.join(self.backend_path)
extra_environ['PEP517_BACKEND_PATH'] = backend_path
with tempfile.TemporaryDirectory() as td:
hook_input = {'kwargs': kwargs}
write_json(hook_input, pjoin(td, 'input.json'), indent=2)
# Run the hook in a subprocess
with _in_proc_script_path() as script:
python = self.python_executable
self._subprocess_runner(
[python, abspath(str(script)), hook_name, td],
cwd=self.source_dir,
extra_environ=extra_environ
)
data = read_json(pjoin(td, 'output.json'))
if data.get('unsupported'):
raise UnsupportedOperation(data.get('traceback', ''))
if data.get('no_backend'):
raise BackendUnavailable(data.get('traceback', ''))
if data.get('backend_invalid'):
raise BackendInvalid(
backend_name=self.build_backend,
backend_path=self.backend_path,
message=data.get('backend_error', '')
)
if data.get('hook_missing'):
raise HookMissing(data.get('missing_hook_name') or hook_name)
return data['return_val']

View file

@ -0,0 +1,18 @@
"""This is a subpackage because the directory is on sys.path for _in_process.py
The subpackage should stay as empty as possible to avoid shadowing modules that
the backend might import.
"""
import importlib.resources as resources
try:
resources.files
except AttributeError:
# Python 3.8 compatibility
def _in_proc_script_path():
return resources.path(__package__, '_in_process.py')
else:
def _in_proc_script_path():
return resources.as_file(
resources.files(__package__).joinpath('_in_process.py'))

View file

@ -0,0 +1,353 @@
"""This is invoked in a subprocess to call the build backend hooks.
It expects:
- Command line args: hook_name, control_dir
- Environment variables:
PEP517_BUILD_BACKEND=entry.point:spec
PEP517_BACKEND_PATH=paths (separated with os.pathsep)
- control_dir/input.json:
- {"kwargs": {...}}
Results:
- control_dir/output.json
- {"return_val": ...}
"""
import json
import os
import os.path
import re
import shutil
import sys
import traceback
from glob import glob
from importlib import import_module
from os.path import join as pjoin
# This file is run as a script, and `import wrappers` is not zip-safe, so we
# include write_json() and read_json() from wrappers.py.
def write_json(obj, path, **kwargs):
with open(path, 'w', encoding='utf-8') as f:
json.dump(obj, f, **kwargs)
def read_json(path):
with open(path, encoding='utf-8') as f:
return json.load(f)
class BackendUnavailable(Exception):
"""Raised if we cannot import the backend"""
def __init__(self, traceback):
self.traceback = traceback
class BackendInvalid(Exception):
"""Raised if the backend is invalid"""
def __init__(self, message):
self.message = message
class HookMissing(Exception):
"""Raised if a hook is missing and we are not executing the fallback"""
def __init__(self, hook_name=None):
super().__init__(hook_name)
self.hook_name = hook_name
def contained_in(filename, directory):
"""Test if a file is located within the given directory."""
filename = os.path.normcase(os.path.abspath(filename))
directory = os.path.normcase(os.path.abspath(directory))
return os.path.commonprefix([filename, directory]) == directory
def _build_backend():
"""Find and load the build backend"""
# Add in-tree backend directories to the front of sys.path.
backend_path = os.environ.get('PEP517_BACKEND_PATH')
if backend_path:
extra_pathitems = backend_path.split(os.pathsep)
sys.path[:0] = extra_pathitems
ep = os.environ['PEP517_BUILD_BACKEND']
mod_path, _, obj_path = ep.partition(':')
try:
obj = import_module(mod_path)
except ImportError:
raise BackendUnavailable(traceback.format_exc())
if backend_path:
if not any(
contained_in(obj.__file__, path)
for path in extra_pathitems
):
raise BackendInvalid("Backend was not loaded from backend-path")
if obj_path:
for path_part in obj_path.split('.'):
obj = getattr(obj, path_part)
return obj
def _supported_features():
"""Return the list of options features supported by the backend.
Returns a list of strings.
The only possible value is 'build_editable'.
"""
backend = _build_backend()
features = []
if hasattr(backend, "build_editable"):
features.append("build_editable")
return features
def get_requires_for_build_wheel(config_settings):
"""Invoke the optional get_requires_for_build_wheel hook
Returns [] if the hook is not defined.
"""
backend = _build_backend()
try:
hook = backend.get_requires_for_build_wheel
except AttributeError:
return []
else:
return hook(config_settings)
def get_requires_for_build_editable(config_settings):
"""Invoke the optional get_requires_for_build_editable hook
Returns [] if the hook is not defined.
"""
backend = _build_backend()
try:
hook = backend.get_requires_for_build_editable
except AttributeError:
return []
else:
return hook(config_settings)
def prepare_metadata_for_build_wheel(
metadata_directory, config_settings, _allow_fallback):
"""Invoke optional prepare_metadata_for_build_wheel
Implements a fallback by building a wheel if the hook isn't defined,
unless _allow_fallback is False in which case HookMissing is raised.
"""
backend = _build_backend()
try:
hook = backend.prepare_metadata_for_build_wheel
except AttributeError:
if not _allow_fallback:
raise HookMissing()
else:
return hook(metadata_directory, config_settings)
# fallback to build_wheel outside the try block to avoid exception chaining
# which can be confusing to users and is not relevant
whl_basename = backend.build_wheel(metadata_directory, config_settings)
return _get_wheel_metadata_from_wheel(whl_basename, metadata_directory,
config_settings)
def prepare_metadata_for_build_editable(
metadata_directory, config_settings, _allow_fallback):
"""Invoke optional prepare_metadata_for_build_editable
Implements a fallback by building an editable wheel if the hook isn't
defined, unless _allow_fallback is False in which case HookMissing is
raised.
"""
backend = _build_backend()
try:
hook = backend.prepare_metadata_for_build_editable
except AttributeError:
if not _allow_fallback:
raise HookMissing()
try:
build_hook = backend.build_editable
except AttributeError:
raise HookMissing(hook_name='build_editable')
else:
whl_basename = build_hook(metadata_directory, config_settings)
return _get_wheel_metadata_from_wheel(whl_basename,
metadata_directory,
config_settings)
else:
return hook(metadata_directory, config_settings)
WHEEL_BUILT_MARKER = 'PEP517_ALREADY_BUILT_WHEEL'
def _dist_info_files(whl_zip):
"""Identify the .dist-info folder inside a wheel ZipFile."""
res = []
for path in whl_zip.namelist():
m = re.match(r'[^/\\]+-[^/\\]+\.dist-info/', path)
if m:
res.append(path)
if res:
return res
raise Exception("No .dist-info folder found in wheel")
def _get_wheel_metadata_from_wheel(
whl_basename, metadata_directory, config_settings):
"""Extract the metadata from a wheel.
Fallback for when the build backend does not
define the 'get_wheel_metadata' hook.
"""
from zipfile import ZipFile
with open(os.path.join(metadata_directory, WHEEL_BUILT_MARKER), 'wb'):
pass # Touch marker file
whl_file = os.path.join(metadata_directory, whl_basename)
with ZipFile(whl_file) as zipf:
dist_info = _dist_info_files(zipf)
zipf.extractall(path=metadata_directory, members=dist_info)
return dist_info[0].split('/')[0]
def _find_already_built_wheel(metadata_directory):
"""Check for a wheel already built during the get_wheel_metadata hook.
"""
if not metadata_directory:
return None
metadata_parent = os.path.dirname(metadata_directory)
if not os.path.isfile(pjoin(metadata_parent, WHEEL_BUILT_MARKER)):
return None
whl_files = glob(os.path.join(metadata_parent, '*.whl'))
if not whl_files:
print('Found wheel built marker, but no .whl files')
return None
if len(whl_files) > 1:
print('Found multiple .whl files; unspecified behaviour. '
'Will call build_wheel.')
return None
# Exactly one .whl file
return whl_files[0]
def build_wheel(wheel_directory, config_settings, metadata_directory=None):
"""Invoke the mandatory build_wheel hook.
If a wheel was already built in the
prepare_metadata_for_build_wheel fallback, this
will copy it rather than rebuilding the wheel.
"""
prebuilt_whl = _find_already_built_wheel(metadata_directory)
if prebuilt_whl:
shutil.copy2(prebuilt_whl, wheel_directory)
return os.path.basename(prebuilt_whl)
return _build_backend().build_wheel(wheel_directory, config_settings,
metadata_directory)
def build_editable(wheel_directory, config_settings, metadata_directory=None):
"""Invoke the optional build_editable hook.
If a wheel was already built in the
prepare_metadata_for_build_editable fallback, this
will copy it rather than rebuilding the wheel.
"""
backend = _build_backend()
try:
hook = backend.build_editable
except AttributeError:
raise HookMissing()
else:
prebuilt_whl = _find_already_built_wheel(metadata_directory)
if prebuilt_whl:
shutil.copy2(prebuilt_whl, wheel_directory)
return os.path.basename(prebuilt_whl)
return hook(wheel_directory, config_settings, metadata_directory)
def get_requires_for_build_sdist(config_settings):
"""Invoke the optional get_requires_for_build_wheel hook
Returns [] if the hook is not defined.
"""
backend = _build_backend()
try:
hook = backend.get_requires_for_build_sdist
except AttributeError:
return []
else:
return hook(config_settings)
class _DummyException(Exception):
"""Nothing should ever raise this exception"""
class GotUnsupportedOperation(Exception):
"""For internal use when backend raises UnsupportedOperation"""
def __init__(self, traceback):
self.traceback = traceback
def build_sdist(sdist_directory, config_settings):
"""Invoke the mandatory build_sdist hook."""
backend = _build_backend()
try:
return backend.build_sdist(sdist_directory, config_settings)
except getattr(backend, 'UnsupportedOperation', _DummyException):
raise GotUnsupportedOperation(traceback.format_exc())
HOOK_NAMES = {
'get_requires_for_build_wheel',
'prepare_metadata_for_build_wheel',
'build_wheel',
'get_requires_for_build_editable',
'prepare_metadata_for_build_editable',
'build_editable',
'get_requires_for_build_sdist',
'build_sdist',
'_supported_features',
}
def main():
if len(sys.argv) < 3:
sys.exit("Needs args: hook_name, control_dir")
hook_name = sys.argv[1]
control_dir = sys.argv[2]
if hook_name not in HOOK_NAMES:
sys.exit("Unknown hook: %s" % hook_name)
hook = globals()[hook_name]
hook_input = read_json(pjoin(control_dir, 'input.json'))
json_out = {'unsupported': False, 'return_val': None}
try:
json_out['return_val'] = hook(**hook_input['kwargs'])
except BackendUnavailable as e:
json_out['no_backend'] = True
json_out['traceback'] = e.traceback
except BackendInvalid as e:
json_out['backend_invalid'] = True
json_out['backend_error'] = e.message
except GotUnsupportedOperation as e:
json_out['unsupported'] = True
json_out['traceback'] = e.traceback
except HookMissing as e:
json_out['hook_missing'] = True
json_out['missing_hook_name'] = e.hook_name or hook_name
write_json(json_out, pjoin(control_dir, 'output.json'), indent=2)
if __name__ == '__main__':
main()