opensafely 2.1.0__tar.gz → 2.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {opensafely-2.1.0 → opensafely-2.1.2}/PKG-INFO +1 -1
- opensafely-2.1.2/opensafely/VERSION +1 -0
- opensafely-2.1.2/opensafely/_vendor/pipeline/constants.py +19 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/pipeline/features.py +2 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/pipeline/loading.py +1 -1
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/pipeline/models.py +23 -86
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/pipeline/validation.py +52 -42
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely.egg-info/PKG-INFO +1 -1
- opensafely-2.1.0/opensafely/VERSION +0 -1
- opensafely-2.1.0/opensafely/_vendor/pipeline/constants.py +0 -21
- {opensafely-2.1.0 → opensafely-2.1.2}/LICENSE +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/README.md +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/certifi/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/certifi/__main__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/certifi/cacert.pem +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/certifi/core.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/certifi/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/charset_normalizer/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/charset_normalizer/__main__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/charset_normalizer/api.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/charset_normalizer/cd.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/charset_normalizer/cli/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/charset_normalizer/cli/__main__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/charset_normalizer/constant.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/charset_normalizer/legacy.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/charset_normalizer/md.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/charset_normalizer/models.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/charset_normalizer/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/charset_normalizer/utils.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/charset_normalizer/version.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/distro/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/distro/__main__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/distro/distro.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/distro/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/idna/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/idna/__main__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/idna/cli.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/idna/codec.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/idna/compat.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/idna/core.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/idna/idnadata.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/idna/intranges.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/idna/package_data.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/idna/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/idna/uts46data.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/_logs/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/_logs/_internal/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/_logs/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/_logs/severity/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/attributes/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/attributes/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/baggage/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/baggage/propagation/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/baggage/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/context/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/context/context.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/context/contextvars_context.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/context/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/environment_variables/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/environment_variables/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/metrics/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/metrics/_internal/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/metrics/_internal/instrument.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/metrics/_internal/observation.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/metrics/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/propagate/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/propagate/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/propagators/_envcarrier.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/propagators/composite.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/propagators/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/propagators/textmap.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/trace/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/trace/propagation/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/trace/propagation/tracecontext.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/trace/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/trace/span.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/trace/status.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/util/_decorator.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/util/_importlib_metadata.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/util/_once.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/util/_providers.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/util/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/util/re.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/util/types.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/version/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/version/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/pipeline/__init__.py +1 -1
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/pipeline/__main__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/pipeline/exceptions.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/pipeline/legacy.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/pipeline/main.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/pipeline/outputs.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/pipeline.pyi +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/__version__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/_internal_utils.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/_types.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/adapters.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/api.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/auth.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/certs.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/compat.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/cookies.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/exceptions.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/help.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/hooks.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/models.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/packages.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/sessions.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/status_codes.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/structures.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/requests/utils.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/anchor.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/comments.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/compat.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/composer.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/configobjwalker.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/constructor.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/cyaml.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/dumper.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/emitter.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/error.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/events.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/loader.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/main.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/nodes.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/parser.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/reader.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/representer.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/resolver.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/scalarbool.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/scalarfloat.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/scalarint.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/scalarstring.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/scanner.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/serializer.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/timestamp.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/tokens.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/ruyaml/util.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/typing_extensions.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/typing_extensions.pyi +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/_base_connection.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/_collections.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/_request_methods.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/_version.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/connection.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/connectionpool.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/contrib/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/contrib/emscripten/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/contrib/emscripten/connection.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/contrib/emscripten/fetch.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/contrib/emscripten/request.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/contrib/emscripten/response.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/contrib/pyopenssl.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/contrib/socks.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/exceptions.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/fields.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/filepost.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/http2/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/http2/connection.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/http2/probe.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/poolmanager.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/py.typed +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/response.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/util/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/util/connection.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/util/proxy.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/util/request.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/util/response.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/util/retry.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/util/ssl_.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/util/ssl_match_hostname.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/util/ssltransport.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/util/timeout.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/util/url.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/util/util.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/urllib3/util/wait.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/clean.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/codelists.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/execute.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/info.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/actions.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/cli/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/cli/local_run.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/cli/migrate.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/config.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/create_or_update_jobs.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/executors/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/executors/local.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/executors/volumes.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/job_executor.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/lib/__init__.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/lib/database.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/lib/docker.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/lib/git.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/lib/github_validators.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/lib/log_utils.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/lib/lru_dict.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/lib/path_utils.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/lib/string_utils.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/lib/subprocess_utils.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/lib/yaml_utils.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/models.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/queries.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/reusable_actions.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/run.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jobrunner/tracing.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/jupyter.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/launch.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/pull.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/rstudio.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/unzip.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/upgrade.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely/utils.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely.egg-info/SOURCES.txt +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely.egg-info/dependency_links.txt +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely.egg-info/entry_points.txt +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely.egg-info/requires.txt +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/opensafely.egg-info/top_level.txt +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/pyproject.toml +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/setup.cfg +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/tests/test_clean.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/tests/test_codelists.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/tests/test_execute.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/tests/test_info.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/tests/test_init.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/tests/test_launch.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/tests/test_packaging.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/tests/test_pull.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/tests/test_unzip.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/tests/test_upgrade.py +0 -0
- {opensafely-2.1.0 → opensafely-2.1.2}/tests/test_utils.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
v2.1.2
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# The magic action name which means "run every action"
|
|
2
|
+
RUN_ALL_COMMAND = "run_all"
|
|
3
|
+
|
|
4
|
+
LEVEL4_FILE_TYPES = {
|
|
5
|
+
# tables
|
|
6
|
+
".csv",
|
|
7
|
+
# images
|
|
8
|
+
".jpg",
|
|
9
|
+
".jpeg",
|
|
10
|
+
".png",
|
|
11
|
+
".svg",
|
|
12
|
+
".svgz",
|
|
13
|
+
# reports
|
|
14
|
+
".html",
|
|
15
|
+
".txt",
|
|
16
|
+
".log",
|
|
17
|
+
".json",
|
|
18
|
+
".md",
|
|
19
|
+
}
|
|
@@ -80,7 +80,7 @@ def parse_yaml_file(data: str | Path, filename: str | None = None) -> dict[str,
|
|
|
80
80
|
if FAST_PARSER is not None: # pragma: no cover
|
|
81
81
|
try:
|
|
82
82
|
return FAST_PARSER.load(data) # type: ignore[no-any-return]
|
|
83
|
-
except Exception:
|
|
83
|
+
except Exception: # noqa: S110, BLE001
|
|
84
84
|
pass
|
|
85
85
|
|
|
86
86
|
try:
|
|
@@ -4,16 +4,15 @@ import pathlib
|
|
|
4
4
|
import re
|
|
5
5
|
import shlex
|
|
6
6
|
import warnings
|
|
7
|
-
from collections import defaultdict
|
|
8
7
|
from dataclasses import dataclass
|
|
9
8
|
from typing import Any
|
|
10
9
|
|
|
11
10
|
from .constants import RUN_ALL_COMMAND
|
|
12
11
|
from .exceptions import InvalidPatternError, ValidationError
|
|
13
|
-
from .features import LATEST_VERSION, get_feature_flags_for_version
|
|
12
|
+
from .features import LATEST_VERSION, MINIMUM_VERSION, get_feature_flags_for_version
|
|
14
13
|
from .validation import (
|
|
15
14
|
validate_action_config,
|
|
16
|
-
|
|
15
|
+
validate_actions_config,
|
|
17
16
|
validate_ehrql_outputs,
|
|
18
17
|
validate_glob_pattern,
|
|
19
18
|
validate_no_kwargs,
|
|
@@ -21,6 +20,7 @@ from .validation import (
|
|
|
21
20
|
validate_not_latest_tag,
|
|
22
21
|
validate_not_run_all_action,
|
|
23
22
|
validate_type,
|
|
23
|
+
validate_unique_output_paths,
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
|
|
@@ -28,7 +28,6 @@ from .validation import (
|
|
|
28
28
|
DB_COMMANDS = {
|
|
29
29
|
"ehrql": ("generate-dataset", "generate-measures"),
|
|
30
30
|
"sqlrunner": "*", # all commands are valid
|
|
31
|
-
"cohortextractor": ("generate_cohort", "generate_codelist_report"),
|
|
32
31
|
"databuilder": ("generate-dataset",),
|
|
33
32
|
}
|
|
34
33
|
|
|
@@ -54,26 +53,6 @@ def is_database_action(args: list[str]) -> bool:
|
|
|
54
53
|
return args[1] in db_commands
|
|
55
54
|
|
|
56
55
|
|
|
57
|
-
@dataclass(frozen=True)
|
|
58
|
-
class Expectations:
|
|
59
|
-
population_size: int
|
|
60
|
-
|
|
61
|
-
@classmethod
|
|
62
|
-
def build(
|
|
63
|
-
cls,
|
|
64
|
-
population_size: Any = None,
|
|
65
|
-
**kwargs: Any,
|
|
66
|
-
) -> Expectations:
|
|
67
|
-
validate_no_kwargs(kwargs, "project `expectations` section")
|
|
68
|
-
try:
|
|
69
|
-
population_size = int(population_size)
|
|
70
|
-
except (TypeError, ValueError):
|
|
71
|
-
raise ValidationError(
|
|
72
|
-
"Project expectations population size must be a number",
|
|
73
|
-
)
|
|
74
|
-
return cls(population_size)
|
|
75
|
-
|
|
76
|
-
|
|
77
56
|
@dataclass(frozen=True)
|
|
78
57
|
class Outputs:
|
|
79
58
|
highly_sensitive: dict[str, str] | None
|
|
@@ -95,7 +74,7 @@ class Outputs:
|
|
|
95
74
|
and minimally_sensitive is None
|
|
96
75
|
):
|
|
97
76
|
raise ValidationError(
|
|
98
|
-
|
|
77
|
+
"must specify at least one output of: highly_sensitive, moderately_sensitive, minimally_sensitive"
|
|
99
78
|
)
|
|
100
79
|
|
|
101
80
|
validate_no_kwargs(kwargs, f"`outputs` section for action {action_id}")
|
|
@@ -210,10 +189,11 @@ class Action:
|
|
|
210
189
|
)
|
|
211
190
|
action = cls(action_id, outputs, run, needs, config, dummy_data_file)
|
|
212
191
|
|
|
213
|
-
if re.match(
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
192
|
+
if match := re.match(
|
|
193
|
+
r"(ehrql|databuilder):\S+ generate[-_](?P<ehrql_type>dataset|measures)",
|
|
194
|
+
run.raw,
|
|
195
|
+
):
|
|
196
|
+
validate_ehrql_outputs(action_id, action, match.group("ehrql_type"))
|
|
217
197
|
|
|
218
198
|
return action
|
|
219
199
|
|
|
@@ -249,17 +229,14 @@ class Action:
|
|
|
249
229
|
class Pipeline:
|
|
250
230
|
version: float
|
|
251
231
|
actions: dict[str, Action]
|
|
252
|
-
expectations: Expectations | None
|
|
253
232
|
|
|
254
233
|
@classmethod
|
|
255
234
|
def build(
|
|
256
235
|
cls,
|
|
257
236
|
version: Any = None,
|
|
258
237
|
actions: Any = None,
|
|
259
|
-
expectations: Any = None,
|
|
260
238
|
**kwargs: Any,
|
|
261
239
|
) -> Pipeline:
|
|
262
|
-
validate_no_kwargs(kwargs, "project")
|
|
263
240
|
if version is None:
|
|
264
241
|
raise ValidationError(
|
|
265
242
|
f"Project file must have a `version` attribute specifying which "
|
|
@@ -271,84 +248,44 @@ class Pipeline:
|
|
|
271
248
|
version = float(version)
|
|
272
249
|
except (TypeError, ValueError):
|
|
273
250
|
raise ValidationError(
|
|
274
|
-
f"`version` must be a number between
|
|
251
|
+
f"`version` must be a number between {MINIMUM_VERSION} and {LATEST_VERSION}"
|
|
275
252
|
)
|
|
276
253
|
else:
|
|
254
|
+
if version < MINIMUM_VERSION:
|
|
255
|
+
raise ValidationError(
|
|
256
|
+
f"Your project file is using a deprecated version ({version}); update to at least version {MINIMUM_VERSION}"
|
|
257
|
+
)
|
|
277
258
|
if version != LATEST_VERSION:
|
|
278
259
|
warnings.warn(
|
|
279
260
|
f"ProjectWarning: Your project file is using an old version ({version}); consider updating to version {LATEST_VERSION}",
|
|
280
261
|
stacklevel=2,
|
|
281
262
|
)
|
|
282
263
|
|
|
264
|
+
validate_no_kwargs(kwargs, "project")
|
|
265
|
+
|
|
283
266
|
feat = get_feature_flags_for_version(version)
|
|
284
267
|
|
|
285
268
|
validate_type(actions, dict, "Project `actions` section")
|
|
286
269
|
|
|
287
|
-
_actions =
|
|
270
|
+
_actions = {}
|
|
288
271
|
for action_id, action_config in actions.items():
|
|
289
272
|
validate_not_run_all_action(action_id, feat)
|
|
290
273
|
validate_action_config(action_id, action_config)
|
|
291
274
|
_actions[action_id] = Action.build(action_id, **action_config)
|
|
292
275
|
actions = _actions
|
|
293
276
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
validate_not_cohort_extractor_action(config)
|
|
277
|
+
for config in actions.values():
|
|
278
|
+
validate_not_cohort_extractor_action(config)
|
|
297
279
|
|
|
298
280
|
if feat.REMOVE_SUPPORT_FOR_LATEST_TAG:
|
|
299
281
|
for config in actions.values():
|
|
300
282
|
validate_not_latest_tag(config)
|
|
301
283
|
|
|
302
|
-
|
|
303
|
-
for name, config in actions.items():
|
|
304
|
-
run = config.run
|
|
305
|
-
if run in seen:
|
|
306
|
-
raise ValidationError(
|
|
307
|
-
f"Action {name} has the same 'run' command as other actions: {' ,'.join(seen[run])}"
|
|
308
|
-
)
|
|
309
|
-
seen[run].append(name)
|
|
310
|
-
|
|
311
|
-
if feat.UNIQUE_OUTPUT_PATH:
|
|
312
|
-
# find duplicate paths defined in the outputs section
|
|
313
|
-
seen_files = []
|
|
314
|
-
for config in actions.values():
|
|
315
|
-
for output in config.outputs.dict().values():
|
|
316
|
-
for filename in output.values():
|
|
317
|
-
if filename in seen_files:
|
|
318
|
-
raise ValidationError(
|
|
319
|
-
f"Output path {filename} is not unique"
|
|
320
|
-
)
|
|
321
|
-
|
|
322
|
-
seen_files.append(filename)
|
|
323
|
-
|
|
324
|
-
for a in actions.values():
|
|
325
|
-
for n in a.needs:
|
|
326
|
-
if n not in actions:
|
|
327
|
-
raise ValidationError(
|
|
328
|
-
f"Action `{a.action_id}` references an unknown action in its `needs` list: {n}"
|
|
329
|
-
)
|
|
330
|
-
|
|
331
|
-
if feat.REMOVE_SUPPORT_FOR_COHORT_EXTRACTOR:
|
|
332
|
-
if expectations is not None:
|
|
333
|
-
raise ValidationError(
|
|
334
|
-
"Project includes `expectations` section, which is not supported in this version. "
|
|
335
|
-
"This section is only applicable to deprecated cohortextractor actions; you can safely remove it."
|
|
336
|
-
)
|
|
337
|
-
elif feat.EXPECTATIONS_POPULATION:
|
|
338
|
-
if expectations is None:
|
|
339
|
-
raise ValidationError("Project must include `expectations` section")
|
|
340
|
-
else:
|
|
341
|
-
expectations = {"population_size": 1000}
|
|
284
|
+
validate_actions_config(actions)
|
|
342
285
|
|
|
343
|
-
|
|
344
|
-
validate_type(expectations, dict, "Project `expectations` section")
|
|
345
|
-
if "population_size" not in expectations:
|
|
346
|
-
raise ValidationError(
|
|
347
|
-
"Project `expectations` section must include `population_size` section",
|
|
348
|
-
)
|
|
349
|
-
expectations = Expectations.build(**expectations)
|
|
286
|
+
validate_unique_output_paths(actions)
|
|
350
287
|
|
|
351
|
-
return cls(version, actions
|
|
288
|
+
return cls(version, actions)
|
|
352
289
|
|
|
353
290
|
@property
|
|
354
291
|
def all_actions(self) -> list[str]:
|
|
@@ -360,7 +297,7 @@ class Pipeline:
|
|
|
360
297
|
We use a list comprehension rather than set operators as previously so we preserve
|
|
361
298
|
the original order.
|
|
362
299
|
"""
|
|
363
|
-
return [action for action in self.actions
|
|
300
|
+
return [action for action in self.actions if action != RUN_ALL_COMMAND]
|
|
364
301
|
|
|
365
302
|
@property
|
|
366
303
|
def action_images(self) -> set[str]:
|
|
@@ -3,17 +3,17 @@ from __future__ import annotations
|
|
|
3
3
|
import fnmatch
|
|
4
4
|
import posixpath
|
|
5
5
|
import warnings
|
|
6
|
+
from collections import defaultdict
|
|
6
7
|
from pathlib import Path, PurePath, PurePosixPath, PureWindowsPath
|
|
7
8
|
from types import SimpleNamespace
|
|
8
9
|
from typing import TYPE_CHECKING, Any
|
|
9
10
|
|
|
10
11
|
from .constants import LEVEL4_FILE_TYPES
|
|
11
12
|
from .exceptions import InvalidPatternError, ValidationError
|
|
12
|
-
from .outputs import get_output_dirs
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
if TYPE_CHECKING: # pragma: no cover
|
|
16
|
-
from .models import Action
|
|
16
|
+
from .models import Action, Command
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def validate_type(val: Any, exp_type: type, loc: str, optional: bool = False) -> None:
|
|
@@ -59,11 +59,10 @@ def validate_glob_pattern(pattern: str, privacy_level: str) -> None:
|
|
|
59
59
|
"output paths must have a file type extension at the end"
|
|
60
60
|
)
|
|
61
61
|
|
|
62
|
-
if privacy_level == "moderately_sensitive":
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
)
|
|
62
|
+
if privacy_level == "moderately_sensitive" and path.suffix not in LEVEL4_FILE_TYPES:
|
|
63
|
+
raise InvalidPatternError(
|
|
64
|
+
f"{path} is not an allowed file type for moderately_sensitive outputs"
|
|
65
|
+
)
|
|
67
66
|
|
|
68
67
|
# Check that the path is in normal form
|
|
69
68
|
if posixpath.normpath(pattern) != pattern:
|
|
@@ -92,6 +91,29 @@ def validate_action_config(action_id: str, action_config: Any) -> None:
|
|
|
92
91
|
)
|
|
93
92
|
|
|
94
93
|
|
|
94
|
+
def validate_actions_config(actions: dict[str, Action]) -> None:
|
|
95
|
+
"""
|
|
96
|
+
Validates that actions are consistent and valid with respect to other actions
|
|
97
|
+
- run commands are not duplicated
|
|
98
|
+
- Specified `needs` are valid actions
|
|
99
|
+
"""
|
|
100
|
+
seen: dict[Command, list[str]] = defaultdict(list)
|
|
101
|
+
for name, config in actions.items():
|
|
102
|
+
run = config.run
|
|
103
|
+
if run in seen:
|
|
104
|
+
raise ValidationError(
|
|
105
|
+
f"Action {name} has the same 'run' command as other actions: {' ,'.join(seen[run])}"
|
|
106
|
+
)
|
|
107
|
+
seen[run].append(name)
|
|
108
|
+
|
|
109
|
+
for a in actions.values():
|
|
110
|
+
for n in a.needs:
|
|
111
|
+
if n not in actions:
|
|
112
|
+
raise ValidationError(
|
|
113
|
+
f"Action `{a.action_id}` references an unknown action in its `needs` list: {n}"
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
95
117
|
def validate_not_cohort_extractor_action(action: Action) -> None:
|
|
96
118
|
if action.run.parts[0].startswith("cohortextractor"):
|
|
97
119
|
raise ValidationError(
|
|
@@ -121,49 +143,30 @@ def validate_not_latest_tag(action: Action) -> None:
|
|
|
121
143
|
)
|
|
122
144
|
|
|
123
145
|
|
|
124
|
-
def
|
|
146
|
+
def validate_unique_output_paths(actions: dict[str, Action]) -> None:
|
|
125
147
|
"""
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
We can't validate outputs in the Action or Outputs models because we need
|
|
129
|
-
to look up other fields (eg run).
|
|
148
|
+
Validates that paths defined in the outputs section are unique
|
|
130
149
|
"""
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
)
|
|
150
|
+
seen_files = []
|
|
151
|
+
for config in actions.values():
|
|
152
|
+
for output in config.outputs.dict().values():
|
|
153
|
+
for filename in output.values():
|
|
154
|
+
if filename in seen_files:
|
|
155
|
+
raise ValidationError(f"Output path {filename} is not unique")
|
|
138
156
|
|
|
139
|
-
|
|
140
|
-
if len(output_dirs) == 1:
|
|
141
|
-
return
|
|
142
|
-
|
|
143
|
-
# If we detect multiple output directories but the command explicitly
|
|
144
|
-
# specifies an output directory then we assume the user knows what
|
|
145
|
-
# they're doing and don't attempt to modify the output directory or
|
|
146
|
-
# throw an error
|
|
147
|
-
flag = "--output-dir"
|
|
148
|
-
has_output_dir = any(
|
|
149
|
-
arg == flag or arg.startswith(f"{flag}=") for arg in action.run.parts
|
|
150
|
-
)
|
|
151
|
-
if not has_output_dir:
|
|
152
|
-
raise ValidationError(
|
|
153
|
-
f"generate_cohort command should produce output in only one "
|
|
154
|
-
f"directory, found {len(output_dirs)}:\n"
|
|
155
|
-
+ "\n".join([f" - {d}/" for d in output_dirs])
|
|
156
|
-
)
|
|
157
|
+
seen_files.append(filename)
|
|
157
158
|
|
|
158
159
|
|
|
159
|
-
def validate_ehrql_outputs(action_id: str, action: Action) -> None:
|
|
160
|
+
def validate_ehrql_outputs(action_id: str, action: Action, ehrql_type: str) -> None:
|
|
160
161
|
"""
|
|
161
162
|
Check ehrQL's output config is valid for this command
|
|
162
163
|
|
|
163
164
|
We can't validate outputs in the Action or Outputs models because we need
|
|
164
165
|
to look up other fields (eg run).
|
|
165
166
|
"""
|
|
166
|
-
if
|
|
167
|
+
if ehrql_type == "dataset" and (
|
|
168
|
+
action.outputs.moderately_sensitive or action.outputs.minimally_sensitive
|
|
169
|
+
):
|
|
167
170
|
raise ValidationError(
|
|
168
171
|
f"`{action_id}` action uses `generate-dataset` and so all outputs must "
|
|
169
172
|
f"be labelled `highly_sensitive`"
|
|
@@ -173,11 +176,18 @@ def validate_ehrql_outputs(action_id: str, action: Action) -> None:
|
|
|
173
176
|
if not output_spec:
|
|
174
177
|
raise ValidationError(
|
|
175
178
|
f"`{action_id}` action does not provide an `--output` argument specifying "
|
|
176
|
-
f"where the results of `generate-
|
|
179
|
+
f"where the results of `generate-{ehrql_type}` should be stored"
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
if ehrql_type == "dataset":
|
|
183
|
+
output_patterns = list((action.outputs.highly_sensitive or {}).values())
|
|
184
|
+
else:
|
|
185
|
+
assert ehrql_type == "measures"
|
|
186
|
+
output_patterns = list((action.outputs.highly_sensitive or {}).values()) + list(
|
|
187
|
+
(action.outputs.moderately_sensitive or {}).values()
|
|
177
188
|
)
|
|
178
189
|
|
|
179
|
-
|
|
180
|
-
if not output_patterns_match_spec(output_spec, list(output_patterns)):
|
|
190
|
+
if not output_patterns_match_spec(output_spec, output_patterns):
|
|
181
191
|
expected = expected_pattern_for_spec(output_spec)
|
|
182
192
|
formatted_patterns = " \n".join(output_patterns)
|
|
183
193
|
raise ValidationError(
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
v2.1.0
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# The magic action name which means "run every action"
|
|
2
|
-
RUN_ALL_COMMAND = "run_all"
|
|
3
|
-
|
|
4
|
-
LEVEL4_FILE_TYPES = set(
|
|
5
|
-
[
|
|
6
|
-
# tables
|
|
7
|
-
".csv",
|
|
8
|
-
# images
|
|
9
|
-
".jpg",
|
|
10
|
-
".jpeg",
|
|
11
|
-
".png",
|
|
12
|
-
".svg",
|
|
13
|
-
".svgz",
|
|
14
|
-
# reports
|
|
15
|
-
".html",
|
|
16
|
-
".txt",
|
|
17
|
-
".log",
|
|
18
|
-
".json",
|
|
19
|
-
".md",
|
|
20
|
-
]
|
|
21
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/_logs/_internal/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/_logs/severity/__init__.py
RENAMED
|
File without changes
|
{opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/attributes/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/metrics/_internal/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/propagate/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/propagators/_envcarrier.py
RENAMED
|
File without changes
|
{opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/propagators/composite.py
RENAMED
|
File without changes
|
|
File without changes
|
{opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/propagators/textmap.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/trace/propagation/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opensafely-2.1.0 → opensafely-2.1.2}/opensafely/_vendor/opentelemetry/util/_importlib_metadata.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|