text:
The "standard" installation use pyproject.toml in UV rather than dynamic dependencies via build hooks (comparing to PIP)

When you install packages using remote url and specify extras, the --editable version of extras are used, rather than the dependencies used in wheel. While I don't think it's very well specified which dependencies should be used
uv pip install 'apache-airflow[aiobotocore,amazon,async,celery,cncf-kubernetes,common-io, \
docker,elasticsearch,ftp,google,google-auth,graphviz,grpc,hashicorp,http,ldap,microsoft-azure, \
mysql,odbc,openlineage,pandas,postgres,redis,sendgrid,sftp,slack,snowflake, \
ssh,statsd,uv,virtualenv] @ https://github.com/apache/airflow/archive/main.tar.gz'

Here is the output of `uv pip install` output

Resolved 359 packages in 2.94s

Downloaded 154 packages in 2.44s
Installed 257 packages in 700ms

adal==1.2.7
adlfs==2024.2.0
aiobotocore==2.12.0
aiofiles==23.2.1
aiohttp==3.9.3
aioitertools==0.11.0
aiosignal==1.3.1
amqp==5.2.0
annotated-types==0.6.0
apispec==6.5.0
asn1crypto==1.5.1
async-timeout==4.0.3
asyncssh==2.14.2
authlib==1.3.0
aws-sam-translator==1.85.0
aws-xray-sdk==2.12.1
azure-batch==14.1.0
azure-common==1.1.28
azure-core==1.30.1
azure-cosmos==4.5.1
azure-datalake-store==0.0.53
azure-identity==1.15.0
azure-keyvault-secrets==4.8.0
azure-kusto-data==4.3.1
azure-mgmt-containerinstance==10.1.0
azure-mgmt-containerregistry==10.3.0
azure-mgmt-core==1.4.0
azure-mgmt-cosmosdb==9.4.0
azure-mgmt-datafactory==5.0.0
azure-mgmt-datalake-nspkg==3.0.1
azure-mgmt-datalake-store==0.5.0
azure-mgmt-nspkg==3.0.2
azure-mgmt-resource==23.0.1
azure-mgmt-storage==21.1.0
azure-nspkg==3.0.2
azure-servicebus==7.11.4
azure-storage-blob==12.19.0
azure-storage-file-datalake==12.14.0
azure-storage-file-share==12.15.0
azure-synapse-artifacts==0.18.0
azure-synapse-spark==0.7.0
babel==2.14.0
bcrypt==4.1.2
beautifulsoup4==4.12.3
billiard==4.2.0
boto3==1.34.51
botocore==1.34.51
cachetools==5.3.3
cattrs==23.2.3
celery==5.3.6
cfn-lint==0.85.3
chardet==5.2.0
click-didyoumean==0.3.0
click-plugins==1.1.1
click-repl==0.3.0
colorama==0.4.6

cryptography==42.0.5

cryptography==41.0.7
db-dtypes==1.2.0
decorator==5.1.1
distlib==0.3.8
dnspython==2.6.1
docker==7.0.0
elastic-transport==8.12.0
elasticsearch==8.12.1
email-validator==1.3.1
eventlet==0.35.2
filelock==3.13.1
flask-appbuilder==4.3.11
flask-babel==2.0.0
flask-jwt-extended==4.6.0
flask-limiter==3.5.1
flask-login==0.6.3
flask-sqlalchemy==2.5.1
flower==2.0.1
frozenlist==1.4.1
gcloud-aio-auth==4.2.3
gcloud-aio-bigquery==7.1.0
gcloud-aio-storage==9.2.0
gcsfs==2024.2.0
gevent==24.2.1
google-ads==23.1.0
google-analytics-admin==0.22.6
google-api-core==2.17.1
google-api-python-client==2.120.0
google-auth==2.28.1
google-auth-httplib2==0.2.0
google-auth-oauthlib==1.2.0
google-cloud-aiplatform==1.43.0
google-cloud-appengine-logging==1.4.2
google-cloud-audit-log==0.2.5
google-cloud-automl==2.13.2
google-cloud-batch==0.17.12
google-cloud-bigquery==3.17.2
google-cloud-bigquery-datatransfer==3.15.0
google-cloud-bigquery-storage==2.24.0
google-cloud-bigtable==2.23.0
google-cloud-build==3.23.2
google-cloud-compute==1.17.0
google-cloud-container==2.41.0
google-cloud-core==2.4.1
google-cloud-datacatalog==3.18.2
google-cloud-dataflow-client==0.8.9
google-cloud-dataform==0.5.8
google-cloud-dataplex==1.12.2
google-cloud-dataproc==5.9.2
google-cloud-dataproc-metastore==1.15.2
google-cloud-dlp==3.15.2
google-cloud-kms==2.21.2
google-cloud-language==2.13.2
google-cloud-logging==3.9.0
google-cloud-memcache==1.9.2
google-cloud-monitoring==2.19.2
google-cloud-orchestration-airflow==1.12.0
google-cloud-os-login==2.14.2
google-cloud-pubsub==2.19.7
google-cloud-redis==2.15.2
google-cloud-resource-manager==1.12.2
google-cloud-run==0.10.4
google-cloud-secret-manager==2.18.2
google-cloud-spanner==3.42.0
google-cloud-speech==2.25.0
google-cloud-storage==2.14.0
google-cloud-storage-transfer==1.11.2
google-cloud-tasks==2.16.2
google-cloud-texttospeech==2.16.2
google-cloud-translate==3.15.2
google-cloud-videointelligence==2.13.2
google-cloud-vision==3.7.1
google-cloud-workflows==1.14.2
google-crc32c==1.5.0
google-resumable-media==2.7.0
graphql-core==3.2.3
graphviz==0.20.1
greenlet==3.0.3
grpc-google-iam-v1==0.13.0
grpc-interceptor==0.15.4
grpcio-gcp==0.2.2
grpcio-status==1.62.0
httplib2==0.22.0
humanize==4.9.0
hvac==2.1.0
ijson==3.2.3
isodate==0.6.1
jmespath==1.0.1
joserfc==0.9.0
jschema-to-python==1.2.3
json-merge-patch==0.2
jsondiff==2.0.0
jsonpatch==1.33
jsonpath-ng==1.6.1
jsonpickle==3.0.3
jsonpointer==2.4
jsonschema-path==0.3.2
junit-xml==1.9
kombu==5.3.5
kubernetes==29.0.0
kubernetes-asyncio==29.0.0
ldap3==2.9.1
limits==3.9.0
looker-sdk==24.2.0
lxml==5.1.0
marshmallow-sqlalchemy==0.26.1
more-itertools==10.2.0
moto==5.0.2
mpmath==1.3.0
msal==1.27.0
msal-extensions==1.1.0
msrest==0.7.1
msrestazure==0.6.4
multidict==6.0.5
mypy-boto3-appflow==1.34.0
mypy-boto3-rds==1.34.50
mypy-boto3-redshift-data==1.34.0
mypy-boto3-s3==1.34.14
mysql-connector-python==8.3.0
mysqlclient==2.2.4
networkx==3.1
numpy==1.24.4
oauthlib==3.2.2
openapi-schema-validator==0.6.2
openapi-spec-validator==0.7.1
openlineage-integration-common==1.9.1
openlineage-python==1.9.1
openlineage-sql==1.9.1
ordered-set==4.1.0
pandas==2.0.3
pandas-gbq==0.21.0
paramiko==3.4.0
pathable==0.4.3
pbr==6.0.0
platformdirs==3.11.0
ply==3.11
portalocker==2.8.2
prison==0.2.1
prometheus-client==0.20.0
prompt-toolkit==3.0.43
proto-plus==1.23.0
psycopg2-binary==2.9.9
py-partiql-parser==0.5.1
pyarrow==15.0.0
pyasn1==0.5.1
pyasn1-modules==0.3.0
pyathena==3.3.0
pydantic==2.6.3
pydantic-core==2.16.3
pydata-google-auth==1.8.2
pynacl==1.5.0
pyodbc==5.1.0
pyopenssl==24.0.0
pyparsing==3.1.1
pyspnego==0.10.2
python-dotenv==1.0.1
python-http-client==3.3.7
python-ldap==3.4.4
pywinrm==0.4.3
redis==4.6.0
redshift-connector==2.1.0

referencing==0.33.0

referencing==0.31.1
regex==2023.12.25
requests-ntlm==1.2.0
requests-oauthlib==1.3.1
requests-toolbelt==1.0.0
responses==0.25.0
rsa==4.9
s3fs==2024.2.0
s3transfer==0.10.0
sarif-om==1.0.4
scramp==1.4.4
sendgrid==6.11.0
shapely==2.0.3
slack-sdk==3.27.1
snowflake-connector-python==3.7.1
snowflake-sqlalchemy==1.5.1
sortedcontainers==2.4.0
soupsieve==2.5
sqlalchemy-bigquery==1.10.0
sqlalchemy-redshift==0.8.14
sqlalchemy-spanner==1.6.2
sqlalchemy-utils==0.41.1
sqlparse==0.4.4
sshtunnel==0.4.0
starkbank-ecdsa==2.2.0
statsd==4.0.1
sympy==1.12
tomlkit==0.12.4
tornado==6.4
uritemplate==4.1.1

urllib3==2.2.1

urllib3==1.26.18
vine==5.1.0
virtualenv==20.25.1
watchtower==3.0.1
wcwidth==0.2.13
websocket-client==1.7.0
xmltodict==0.13.0
yarl==1.9.4
zope-event==5.0
zope-interface==6.2

Compare it with the equivalent pip result:
uv pip install 'apache-airflow[aiobotocore,amazon,async,celery,cncf-kubernetes,common-io, \
docker,elasticsearch,ftp,google,google-auth,graphviz,grpc,hashicorp,http,ldap,microsoft-azure, \
mysql,odbc,openlineage,pandas,postgres,redis,sendgrid,sftp,slack,snowflake, \
ssh,statsd,uv,virtualenv] @ https://github.com/apache/airflow/archive/main.tar.gz'

Result of `pip install`

Installing collected packages: wcwidth, unicodecsv, text-unidecode, statsd, starkbank-ecdsa, sortedcontainers, pytz, ply, lockfile, json-merge-patch, ijson, distlib, cron-descriptor, colorlog, azure-nspkg, azure-common, asn1crypto, zope.interface, zope.event, zipp, wrapt, websocket-client, vine, urllib3, uritemplate, uc-micro-py, tzdata, typing-extensions, tornado, tomlkit, termcolor, tenacity, tabulate, sqlparse, sqlalchemy, soupsieve, sniffio, slack_sdk, six, setproctitle, scramp, rpds-py, PyYAML, python-slugify, python-http-client, python-dotenv, pyparsing, pyodbc, pyjwt, pygments, pycparser, pyasn1, psycopg2-binary, psutil, protobuf, prompt-toolkit, prometheus-client, portalocker, pluggy, platformdirs, pkgutil-resolve-name, pathspec, packaging, ordered-set, opentelemetry-semantic-conventions, openlineage-sql, oauthlib, numpy, mysqlclient, mysql-connector-python, multidict, more-itertools, mdurl, markupsafe, lxml, lazy-object-proxy, jsonpath_ng, jmespath, itsdangerous, inflection, idna, humanize, h11, grpcio, greenlet, graphviz, google-re2, google-crc32c, fsspec, frozenlist, filelock, exceptiongroup, docutils, dnspython, dill, decorator, configupdater, colorama, click, charset-normalizer, chardet, certifi, cachetools, cachelib, blinker, billiard, bcrypt, backports.zoneinfo, backoff, Babel, azure-mgmt-nspkg, attrs, async-timeout, argcomplete, aiofiles, yarl, wtforms, werkzeug, virtualenv, universal-pathlib, sqlalchemy-utils, sqlalchemy_redshift, sqlalchemy-jsonfield, shapely, sendgrid, rsa, rfc3339-validator, requests, referencing, redis, python-dateutil, python-daemon, pyasn1-modules, pyarrow, proto-plus, prison, opentelemetry-proto, marshmallow, markdown-it-py, Mako, linkify-it-py, ldap3, jinja2, isodate, importlib-resources, importlib-metadata, httplib2, httpcore, gunicorn, grpcio-gcp, grpc-interceptor, googleapis-common-protos, google-resumable-media, gevent, eventlet, email-validator, elastic-transport, deprecated, clickclick, click-repl, click-plugins, click-didyoumean, cffi, cattrs, beautifulsoup4, azure-mgmt-datalake-nspkg, asgiref, apispec, anyio, amqp, aiosignal, aioitertools, time-machine, rich, requests_toolbelt, requests-oauthlib, python-nvd3, python-ldap, pynacl, pandas, opentelemetry-exporter-otlp-proto-common, opentelemetry-api, openlineage-python, mdit-py-plugins, marshmallow-sqlalchemy, marshmallow-oneofschema, looker-sdk, limits, kombu, jsonschema-specifications, hvac, httpx, grpcio-status, google-cloud-audit-log, google-auth, flask, elasticsearch, docker, cryptography, croniter, botocore, azure-core, alembic, aiohttp, s3transfer, rich-argparse, PyOpenSSL, pendulum, paramiko, opentelemetry-sdk, openlineage-integration-common, msrest, kubernetes_asyncio, kubernetes, jsonschema, grpc-google-iam-v1, google-auth-oauthlib, google-auth-httplib2, google-api-core, gcloud-aio-auth, flask-wtf, Flask-SQLAlchemy, flask-session, flask-login, Flask-Limiter, Flask-JWT-Extended, flask-caching, Flask-Babel, db-dtypes, celery, azure-storage-file-share, azure-storage-blob, azure-servicebus, azure-mgmt-core, azure-keyvault-secrets, azure-cosmos, authlib, asyncssh, aiobotocore, adal, sshtunnel, snowflake-connector-python, pydata-google-auth, opentelemetry-exporter-otlp-proto-http, opentelemetry-exporter-otlp-proto-grpc, msrestazure, msal, google-cloud-core, google-api-python-client, google-ads, gcloud-aio-storage, gcloud-aio-bigquery, flower, flask-appbuilder, connexion, boto3, azure-synapse-spark, azure-synapse-artifacts, azure-storage-file-datalake, azure-mgmt-storage, azure-mgmt-resource, azure-mgmt-datafactory, azure-mgmt-cosmosdb, azure-mgmt-containerregistry, azure-mgmt-containerinstance, watchtower, snowflake-sqlalchemy, redshift_connector, PyAthena, opentelemetry-exporter-otlp, msal-extensions, google-cloud-workflows, google-cloud-vision, google-cloud-videointelligence, google-cloud-translate, google-cloud-texttospeech, google-cloud-tasks, google-cloud-storage-transfer, google-cloud-storage, google-cloud-speech, google-cloud-spanner, google-cloud-secret-manager, google-cloud-run, google-cloud-resource-manager, google-cloud-redis, google-cloud-pubsub, google-cloud-os-login, google-cloud-orchestration-airflow, google-cloud-monitoring, google-cloud-memcache, google-cloud-language, google-cloud-kms, google-cloud-dlp, google-cloud-dataproc-metastore, google-cloud-dataproc, google-cloud-dataplex, google-cloud-dataform, google-cloud-dataflow-client, google-cloud-datacatalog, google-cloud-container, google-cloud-compute, google-cloud-build, google-cloud-bigtable, google-cloud-bigquery-storage, google-cloud-bigquery-datatransfer, google-cloud-bigquery, google-cloud-batch, google-cloud-automl, google-cloud-appengine-logging, google-analytics-admin, azure-mgmt-datalake-store, azure-datalake-store, azure-batch, sqlalchemy-spanner, sqlalchemy-bigquery, pandas-gbq, google-cloud-logging, google-cloud-aiplatform, gcsfs, azure-identity, azure-kusto-data, adlfs, apache-airflow-providers-smtp, apache-airflow-providers-imap, apache-airflow-providers-http, apache-airflow-providers-ftp, apache-airflow-providers-fab, apache-airflow-providers-common-sql, apache-airflow-providers-common-io, apache-airflow-providers-sqlite, apache-airflow-providers-ssh, apache-airflow-providers-snowflake, apache-airflow-providers-slack, apache-airflow-providers-sftp, apache-airflow-providers-sendgrid, apache-airflow-providers-redis, apache-airflow-providers-postgres, apache-airflow-providers-openlineage, apache-airflow-providers-odbc, apache-airflow-providers-mysql, apache-airflow-providers-microsoft-azure, apache-airflow-providers-hashicorp, apache-airflow-providers-grpc, apache-airflow-providers-google, apache-airflow-providers-elasticsearch, apache-airflow-providers-docker, apache-airflow-providers-cncf-kubernetes, apache-airflow-providers-celery, apache-airflow-providers-amazon

Note - all the apache-airflow-providers-* packages missing in case of uv pip install.
The problem is likely that the installation uses directly pyproject.toml to install dependencies, however for such remote installation (and without --editable install at that - but even if it would be specified, --editable makes no sense for remote install) the dependencies should be the same as in packaged .whl file and it makes the installation of uv in this case non-compliant with PEP 517.
A bit more context: Airlfow uses hatchling build backend, and utilzes PEP 517 compliant build_hooks (https://peps.python.org/pep-0517/#build-wheel) to modify the --editable  extras into wheel extras on the flight. So for example [celery] requirement in pyproject.toml ( https://github.com/apache/airflow/blob/main/pyproject.toml#L641) is this:
celery = [ # source: airflow/providers/celery/provider.yaml
  "celery>=5.3.0,<6,!=5.3.3,!=5.3.2",
  "flower>=1.0.0",
  "google-re2>=1.0",
]

However the hatchling build hook of ours, when preparing wheel package, replaces this extra with:
"apache-airflow-providers-celery"

This is the way how we are dealing with our monorepo where --editable "extra" just installs dependencies of our providers, while the "wheel" extra install actual provider (and transitively dependencies of that provider).
I believe that PEP-517 compliant way of installing a package from remote URL should actually build the wheel file first using the build backend the project has defined in pyproject.toml and only then install such a wheel file (this is exactly what pip does under the hood when installing package from remote url - treating it the same way as installind an sdist package (which the remote URL is equivalent of).

I have an update.
I realized that the problem could be, because we were not really PEP 621 compliant with Airflow becaused we mixed "dynamic" and "static project properties in Airflow. The pyproject.toml contained  the "dependencies" and "optional-dependencies" but also build hooks modified them.
However as of today we fixed it in `apache-airflow'  in https://github.com/apache/airflow/pull/38439 and the problem remains.
Both "dependencies" and "optional-dependencies" are set as dynamic in pyproject.toml: https://github.com/apache/airflow/blob/main/pyproject.toml#L64 👍
dynamic = ["version", "optional-dependencies", "dependencies"]

It looks like uv - unlike pip does not use build hooks to determine "standard" dynamic properties as defined in pyproject.toml - only uses the hooks to determine editable dependencies
PIP case

With pip - they are both properly set dynamically by PEP 517 compliant build hooks (via hatchling) - https://github.com/apache/airflow/blob/main/hatch_build.py - you can check it by checking out the repo and running those commands (I separated out the relevant installed packages to show the difference)

pip install "apache-airflow[aws] @ file:///Users/jarek/code/airflow" -> correctly installs "wheel" version of airflow with wheel [aws] variant of extra - including apache-airflow-providers-amazon - but not including devel deps like moto.

Output

Successfully installed Babel-2.14.0 Flask-Babel-2.0.0 Flask-JWT-Extended-4.6.0 Flask-Limiter-3.5.1 Flask-SQLAlchemy-2.5.1 Mako-1.3.2 PyAthena-3.5.1 PyYAML-6.0.1 WTForms-3.1.2 aiohttp-3.9.3 aiosignal-1.3.1 alembic-1.13.1 anyio-4.3.0 apache-airflow-2.9.0.dev0

apache-airflow-providers-amazon-8.19.0

apache-airflow-providers-common-io-1.3.0 apache-airflow-providers-common-sql-1.11.1 apache-airflow-providers-fab-1.0.2.dev2 apache-airflow-providers-ftp-3.7.0 apache-airflow-providers-http-4.10.0 apache-airflow-providers-imap-3.5.0 apache-airflow-providers-smtp-1.6.1 apache-airflow-providers-sqlite-3.7.1 apispec-6.6.0 argcomplete-3.2.3 asgiref-3.8.1 asn1crypto-1.5.1 attrs-23.2.0 beautifulsoup4-4.12.3 blinker-1.7.0 boto3-1.34.69 botocore-1.34.69 cachelib-0.9.0 certifi-2024.2.2 cffi-1.16.0 charset-normalizer-3.3.2 click-8.1.7 clickclick-20.10.2 colorama-0.4.6 colorlog-4.8.0 configupdater-3.2 connexion-2.14.2 cron-descriptor-1.4.3 croniter-2.0.3 cryptography-42.0.5 deprecated-1.2.14 dill-0.3.8 dnspython-2.6.1 docutils-0.20.1 email-validator-2.1.1 flask-2.2.5 flask-appbuilder-4.4.1 flask-caching-2.1.0 flask-login-0.6.3 flask-session-0.5.0 flask-wtf-1.2.1 frozenlist-1.4.1 fsspec-2024.3.1 google-re2-1.1 googleapis-common-protos-1.63.0 grpcio-1.62.1 gunicorn-21.2.0 h11-0.14.0 httpcore-1.0.4 httpx-0.27.0 idna-3.6 importlib-metadata-6.11.0 importlib-resources-6.4.0 inflection-0.5.1 itsdangerous-2.1.2 jinja2-3.1.3 jmespath-1.0.1 jsonpath_ng-1.6.1 jsonschema-4.21.1 jsonschema-specifications-2023.12.1 lazy-object-proxy-1.10.0 limits-3.10.1 linkify-it-py-2.0.3 lockfile-0.12.2 lxml-5.1.0 markdown-it-py-3.0.0 markupsafe-2.1.5 marshmallow-3.21.1 marshmallow-oneofschema-3.1.1 marshmallow-sqlalchemy-0.28.2 mdit-py-plugins-0.4.0 mdurl-0.1.2 more-itertools-10.2.0 multidict-6.0.5 opentelemetry-api-1.23.0 opentelemetry-exporter-otlp-1.23.0 opentelemetry-exporter-otlp-proto-common-1.23.0 opentelemetry-exporter-otlp-proto-grpc-1.23.0 opentelemetry-exporter-otlp-proto-http-1.23.0 opentelemetry-proto-1.23.0 opentelemetry-sdk-1.23.0 opentelemetry-semantic-conventions-0.44b0 ordered-set-4.1.0 packaging-24.0 pathspec-0.12.1 pendulum-3.0.0 pluggy-1.4.0 ply-3.11 prison-0.2.1 protobuf-4.25.3 psutil-5.9.8 pycparser-2.21 pygments-2.17.2 pyjwt-2.8.0 python-daemon-3.0.1 python-dateutil-2.9.0.post0 python-nvd3-0.15.0 python-slugify-8.0.4 pytz-2024.1 redshift_connector-2.1.0 referencing-0.34.0 requests-2.31.0 requests_toolbelt-1.0.0 rfc3339-validator-0.1.4 rich-13.7.1 rich-argparse-1.4.0 rpds-py-0.18.0 s3transfer-0.10.1 scramp-1.4.4 setproctitle-1.3.3 six-1.16.0 sniffio-1.3.1 soupsieve-2.5 sqlalchemy-1.4.52 sqlalchemy-jsonfield-1.0.2 sqlalchemy-utils-0.41.2 sqlalchemy_redshift-0.8.14 sqlparse-0.4.4 tabulate-0.9.0 tenacity-8.2.3 termcolor-2.4.0 text-unidecode-1.3 time-machine-2.14.1 typing-extensions-4.10.0 tzdata-2024.1 uc-micro-py-1.0.3 unicodecsv-0.14.1 universal-pathlib-0.2.2 urllib3-2.2.1 watchtower-3.1.0 werkzeug-2.2.3 wrapt-1.16.0 yarl-1.9.4 zipp-3.18.1

pip install -e "/Users/jarek/code/airflow[aws]" -> correctly install "editable" version of airflow with editable version of [aws] variant of extra - not includoing apaxhe-airflow-providers-amazon

Output

Successfully installed Mako-1.3.2 PyAthena-3.5.1 PyYAML-6.0.1 aiobotocore-2.12.1 aiohttp-3.9.3 aioitertools-0.11.0 aiosignal-1.3.1 alembic-1.13.1 annotated-types-0.6.0 anyio-4.3.0 apache-airflow-2.9.0.dev0 argcomplete-3.2.3 asgiref-3.8.1 asn1crypto-1.5.1 attrs-23.2.0 aws-sam-translator-1.86.0 aws_xray_sdk-2.13.0 beautifulsoup4-4.12.3 blinker-1.7.0 boto3-1.34.51 botocore-1.34.51 cachelib-0.9.0 certifi-2024.2.2 cffi-1.16.0 cfn-lint-0.86.1 charset-normalizer-3.3.2 click-8.1.7 clickclick-20.10.2 colorlog-4.8.0 configupdater-3.2 connexion-2.14.2 cron-descriptor-1.4.3 croniter-2.0.3 cryptography-42.0.5 deprecated-1.2.14 dill-0.3.8 docker-7.0.0 docutils-0.20.1 flask-2.2.5 flask-caching-2.1.0 flask-session-0.5.0 flask-wtf-1.2.1 frozenlist-1.4.1 fsspec-2024.3.1 google-re2-1.1 googleapis-common-protos-1.63.0 graphql-core-3.2.3 grpcio-1.62.1 gunicorn-21.2.0 h11-0.14.0 httpcore-1.0.4 httpx-0.27.0 idna-3.6 importlib-metadata-6.11.0 inflection-0.5.1 itsdangerous-2.1.2 jinja2-3.1.3 jmespath-1.0.1 joserfc-0.9.0 jschema-to-python-1.2.3 jsondiff-2.0.0 jsonpatch-1.33 jsonpath_ng-1.6.1 jsonpickle-3.0.3 jsonpointer-2.4 jsonschema-4.21.1 jsonschema-path-0.3.2 jsonschema-specifications-2023.12.1 junit-xml-1.9 lazy-object-proxy-1.10.0 linkify-it-py-2.0.3 lockfile-0.12.2 lxml-5.1.0 markdown-it-py-3.0.0 markupsafe-2.1.5 marshmallow-3.21.1 marshmallow-oneofschema-3.1.1 mdit-py-plugins-0.4.0 mdurl-0.1.2 more-itertools-10.2.0

moto-5.0.3

mpmath-1.3.0 multidict-6.0.5 mypy-boto3-appflow-1.34.0 mypy-boto3-rds-1.34.65 mypy-boto3-redshift-data-1.34.0 mypy-boto3-s3-1.34.65 networkx-3.2.1 openapi-schema-validator-0.6.2 openapi-spec-validator-0.7.1 opentelemetry-api-1.23.0 opentelemetry-exporter-otlp-1.23.0 opentelemetry-exporter-otlp-proto-common-1.23.0 opentelemetry-exporter-otlp-proto-grpc-1.23.0 opentelemetry-exporter-otlp-proto-http-1.23.0 opentelemetry-proto-1.23.0 opentelemetry-sdk-1.23.0 opentelemetry-semantic-conventions-0.44b0 packaging-24.0 pathable-0.4.3 pathspec-0.12.1 pbr-6.0.0 pendulum-3.0.0 pluggy-1.4.0 ply-3.11 protobuf-4.25.3 psutil-5.9.8 py-partiql-parser-0.5.1 pycparser-2.21 pydantic-2.6.4 pydantic-core-2.16.3 pygments-2.17.2 pyjwt-2.8.0 pyparsing-3.1.2 python-daemon-3.0.1 python-dateutil-2.9.0.post0 python-nvd3-0.15.0 python-slugify-8.0.4 pytz-2024.1 redshift_connector-2.1.0 referencing-0.31.1 regex-2023.12.25 requests-2.31.0 requests_toolbelt-1.0.0 responses-0.25.0 rfc3339-validator-0.1.4 rich-13.7.1 rich-argparse-1.4.0 rpds-py-0.18.0 s3fs-2024.3.1 s3transfer-0.10.1 sarif-om-1.0.4 scramp-1.4.4 setproctitle-1.3.3 six-1.16.0 sniffio-1.3.1 soupsieve-2.5 sqlalchemy-1.4.52 sqlalchemy-jsonfield-1.0.2 sqlalchemy_redshift-0.8.14 sqlparse-0.4.4 sympy-1.12 tabulate-0.9.0 tenacity-8.2.3 termcolor-2.4.0 text-unidecode-1.3 time-machine-2.14.1 typing-extensions-4.10.0 tzdata-2024.1 uc-micro-py-1.0.3 unicodecsv-0.14.1 universal-pathlib-0.2.2 urllib3-2.0.7 watchtower-3.1.0 werkzeug-2.2.3 wrapt-1.16.0 wtforms-3.1.2 xmltodict-0.13.0 yarl-1.9.4 zipp-3.18.1

Similarly - remote installtion via URL uses "wheel" dependency versions: pip install "apache-airflow[aws] @ https://github.com/apache/airflow/archive/main.tar.gz":

Ouput

Successfully installed Babel-2.14.0 Flask-Babel-2.0.0 Flask-JWT-Extended-4.6.0 Flask-Limiter-3.5.1 Flask-SQLAlchemy-2.5.1 Mako-1.3.2 PyAthena-3.5.1 PyYAML-6.0.1 WTForms-3.1.2 aiohttp-3.9.3 aiosignal-1.3.1 alembic-1.13.1 anyio-4.3.0

apache-airflow-providers-amazon-8.19.0

apache-airflow-providers-common-io-1.3.0 apache-airflow-providers-common-sql-1.11.1 apache-airflow-providers-fab-1.0.2.dev2 apache-airflow-providers-ftp-3.7.0 apache-airflow-providers-http-4.10.0 apache-airflow-providers-imap-3.5.0 apache-airflow-providers-smtp-1.6.1 apache-airflow-providers-sqlite-3.7.1 apispec-6.6.0 argcomplete-3.2.3 asgiref-3.8.1 asn1crypto-1.5.1 attrs-23.2.0 beautifulsoup4-4.12.3 blinker-1.7.0 boto3-1.34.69 botocore-1.34.69 cachelib-0.9.0 certifi-2024.2.2 cffi-1.16.0 charset-normalizer-3.3.2 click-8.1.7 clickclick-20.10.2 colorama-0.4.6 colorlog-4.8.0 configupdater-3.2 connexion-2.14.2 cron-descriptor-1.4.3 croniter-2.0.3 cryptography-42.0.5 deprecated-1.2.14 dill-0.3.8 dnspython-2.6.1 docutils-0.20.1 email-validator-2.1.1 flask-2.2.5 flask-appbuilder-4.4.1 flask-caching-2.1.0 flask-login-0.6.3 flask-session-0.5.0 flask-wtf-1.2.1 frozenlist-1.4.1 fsspec-2024.3.1 google-re2-1.1 googleapis-common-protos-1.63.0 grpcio-1.62.1 gunicorn-21.2.0 h11-0.14.0 httpcore-1.0.4 httpx-0.27.0 idna-3.6 importlib-metadata-6.11.0 importlib-resources-6.4.0 inflection-0.5.1 itsdangerous-2.1.2 jinja2-3.1.3 jmespath-1.0.1 jsonpath_ng-1.6.1 jsonschema-4.21.1 jsonschema-specifications-2023.12.1 lazy-object-proxy-1.10.0 limits-3.10.1 linkify-it-py-2.0.3 lockfile-0.12.2 lxml-5.1.0 markdown-it-py-3.0.0 markupsafe-2.1.5 marshmallow-3.21.1 marshmallow-oneofschema-3.1.1 marshmallow-sqlalchemy-0.28.2 mdit-py-plugins-0.4.0 mdurl-0.1.2 more-itertools-10.2.0 multidict-6.0.5 opentelemetry-api-1.23.0 opentelemetry-exporter-otlp-1.23.0 opentelemetry-exporter-otlp-proto-common-1.23.0 opentelemetry-exporter-otlp-proto-grpc-1.23.0 opentelemetry-exporter-otlp-proto-http-1.23.0 opentelemetry-proto-1.23.0 opentelemetry-sdk-1.23.0 opentelemetry-semantic-conventions-0.44b0 ordered-set-4.1.0 packaging-24.0 pathspec-0.12.1 pendulum-3.0.0 pluggy-1.4.0 ply-3.11 prison-0.2.1 protobuf-4.25.3 psutil-5.9.8 pycparser-2.21 pygments-2.17.2 pyjwt-2.8.0 python-daemon-3.0.1 python-dateutil-2.9.0.post0 python-nvd3-0.15.0 python-slugify-8.0.4 pytz-2024.1 redshift_connector-2.1.0 referencing-0.34.0 requests-2.31.0 requests_toolbelt-1.0.0 rfc3339-validator-0.1.4 rich-13.7.1 rich-argparse-1.4.0 rpds-py-0.18.0 s3transfer-0.10.1 scramp-1.4.4 setproctitle-1.3.3 six-1.16.0 sniffio-1.3.1 soupsieve-2.5 sqlalchemy-1.4.52 sqlalchemy-jsonfield-1.0.2 sqlalchemy-utils-0.41.2 sqlalchemy_redshift-0.8.14 sqlparse-0.4.4 tabulate-0.9.0 tenacity-8.2.3 termcolor-2.4.0 text-unidecode-1.3 time-machine-2.14.1 typing-extensions-4.10.0 tzdata-2024.1 uc-micro-py-1.0.3 unicodecsv-0.14.1 universal-pathlib-0.2.2 urllib3-2.2.1 watchtower-3.1.0 werkzeug-2.2.3 wrapt-1.16.0 yarl-1.9.4 zipp-3.18.1

UV case
The same exercise with uv produced very different (incorrect) results:
I run it with the latest as of today uv version:  0.1.24.

uv pip install "apache-airflow[aws] @ file:///Users/jarek/code/airflow"

This wrongly installs just airflow package and misses both - dynamic "dependenciess" and dynamic "optional-dependencies" that should be derived from running the biild hook.

Output

Resolved 1 package in 0.42ms
Built apache-airflow @ file:///Users/jarek/code/airflow                                                                                > Downloaded 1 package in 5.89s
Installed 1 package in 10ms

apache-airflow==2.9.0.dev0 (from file:///Users/jarek/code/airflow)

uv pip install -e "/Users/jarek/code/airflow[aws]"

This correctly installs dynamically derived both "dependencies" and "optional-dependencies". See  (expected) lack of "apache-airflow-providers-amazon" and presence of "moto" - both indicate that aws extra was correctly calculated with the build hook.

Output

uv pip install -e "/Users/jarek/code/airflow[aws]"
Built file:///Users/jarek/code/airflow                                                                                > Built 1 editable in 4.90s
Resolved 161 packages in 6.94s
Built python-nvd3==0.15.0
Built lazy-object-proxy==1.10.0
Built unicodecsv==0.14.1                                                                                > Downloaded 156 packages in 14.87s
Installed 160 packages in 219ms

aiobotocore==2.12.1
aiohttp==3.9.3
aioitertools==0.11.0
aiosignal==1.3.1
alembic==1.13.1
annotated-types==0.6.0
anyio==4.3.0
apache-airflow==2.9.0.dev0 (from file:///Users/jarek/code/airflow)
argcomplete==3.2.3
asgiref==3.8.1
asn1crypto==1.5.1
attrs==23.2.0
aws-sam-translator==1.86.0
aws-xray-sdk==2.13.0
beautifulsoup4==4.12.3
blinker==1.7.0
boto3==1.34.51
botocore==1.34.51
cachelib==0.9.0
certifi==2024.2.2
cffi==1.16.0
cfn-lint==0.86.1
charset-normalizer==3.3.2
click==8.1.7
clickclick==20.10.2
colorlog==4.8.0
configupdater==3.2
connexion==2.14.2
cron-descriptor==1.4.3
croniter==2.0.3
cryptography==42.0.5
deprecated==1.2.14
dill==0.3.8
docker==7.0.0
docutils==0.20.1
flask==2.2.5
flask-caching==2.1.0
flask-session==0.5.0
flask-wtf==1.2.1
frozenlist==1.4.1
fsspec==2024.3.1
google-re2==1.1
googleapis-common-protos==1.63.0
graphql-core==3.2.3
grpcio==1.62.1
gunicorn==21.2.0
h11==0.14.0
httpcore==1.0.4
httpx==0.27.0
idna==3.6
importlib-metadata==6.11.0
inflection==0.5.1
itsdangerous==2.1.2
jinja2==3.1.3
jmespath==1.0.1
joserfc==0.9.0
jschema-to-python==1.2.3
jsondiff==2.0.0
jsonpatch==1.33
jsonpath-ng==1.6.1
jsonpickle==3.0.3
jsonpointer==2.4
v + jsonschema==4.21.1
jsonschema-path==0.3.2
jsonschema-specifications==2023.12.1
junit-xml==1.9
lazy-object-proxy==1.10.0
linkify-it-py==2.0.3
lockfile==0.12.2
lxml==5.1.0
mako==1.3.2
markdown-it-py==3.0.0
markupsafe==2.1.5
marshmallow==3.21.1
marshmallow-oneofschema==3.1.1
mdit-py-plugins==0.4.0
mdurl==0.1.2
more-itertools==10.2.0

+ moto==5.0.3

mpmath==1.3.0
multidict==6.0.5
mypy-boto3-appflow==1.34.0
mypy-boto3-rds==1.34.65
mypy-boto3-redshift-data==1.34.0
mypy-boto3-s3==1.34.65
networkx==3.2.1
openapi-schema-validator==0.6.2
openapi-spec-validator==0.7.1
opentelemetry-api==1.23.0
opentelemetry-exporter-otlp==1.23.0
opentelemetry-exporter-otlp-proto-common==1.23.0
opentelemetry-exporter-otlp-proto-grpc==1.23.0
opentelemetry-exporter-otlp-proto-http==1.23.0
opentelemetry-proto==1.23.0
opentelemetry-sdk==1.23.0
opentelemetry-semantic-conventions==0.44b0
packaging==24.0
pathable==0.4.3
pathspec==0.12.1
pbr==6.0.0
pendulum==3.0.0
pluggy==1.4.0
ply==3.11
protobuf==4.25.3
psutil==5.9.8
py-partiql-parser==0.5.1
pyathena==3.5.1
pycparser==2.21
pydantic==2.6.4
pydantic-core==2.16.3
pygments==2.17.2
pyjwt==2.8.0
pyparsing==3.1.2
python-daemon==3.0.1
python-dateutil==2.9.0.post0
python-nvd3==0.15.0
python-slugify==8.0.4
pytz==2024.1
pyyaml==6.0.1
redshift-connector==2.1.0
referencing==0.31.1
regex==2023.12.25
requests==2.31.0
requests-toolbelt==1.0.0
responses==0.25.0
rfc3339-validator==0.1.4
rich==13.7.1
rich-argparse==1.4.0
rpds-py==0.18.0
s3fs==2024.3.1
s3transfer==0.10.1
sarif-om==1.0.4
scramp==1.4.4
setproctitle==1.3.3
six==1.16.0
sniffio==1.3.1
soupsieve==2.5
sqlalchemy==1.4.52
sqlalchemy-jsonfield==1.0.2
sqlalchemy-redshift==0.8.14
sqlparse==0.4.4
sympy==1.12
tabulate==0.9.0
tenacity==8.2.3
termcolor==2.4.0
text-unidecode==1.3
time-machine==2.14.1
typing-extensions==4.10.0
tzdata==2024.1
uc-micro-py==1.0.3
unicodecsv==0.14.1
universal-pathlib==0.2.2
urllib3==2.0.7
watchtower==3.1.0
werkzeug==2.2.3
wrapt==1.16.0
wtforms==3.1.2
xmltodict==0.13.0
yarl==1.9.4
zipp==3.18.1

Finally installing from URL: uv pip install "apache-airflow[aws] @ https://github.com/apache/airflow/archive/main.tar.gz"

Output

Resolved 1 package in 589ms
Built apache-airflow @ https://github.com/apache/airflow/archive/main.tar.gz                                                                                > Downloaded 1 package in 1.06s
Installed 1 package in 9ms

apache-airflow==2.9.0.dev0 (from file:///Users/jarek/code/airflow)

apache-airflow==2.9.0.dev0 (from https://github.com/apache/airflow/archive/main.tar.gz)

There's something happening here but I don't quite understand what yet.

(We do run the PEP 517 build hooks in all cases here.)

Just to add maybe a hypothesis/lead:
It could be that this is somehow interacting with the way how the "hatch_build.py" interacts with hatchling backeng build. I had a bit hard time to guess how to properly update both dependencies and optional-dependencies in the hook. And I settled with this way (which works as I described above + it nicely generates the .whl packages):
So what i settled with:

Updating "dependencies" is as easy as setting "dependencies" tnery in the "build_data" dict passed to the initialize  https://github.com/apache/airflow/blob/20cb9f1770c819f31e48748fc9fb86527f739d6e/hatch_build.py#L748

modifying protected `_optional_dependencies"  dictionary  in the hook, as I could not find a better way (documentation is a bit sparse and looking at the source code did not help me to understand how else I can do it).
https://github.com/apache/airflow/blob/20cb9f1770c819f31e48748fc9fb86527f739d6e/hatch_build.py#L754

While the "optional-dependencies" might be somewhat hacky, the "dependencies" seem to be perfectly justified way. And they also nicely work for "editable" case.
Hypothesis - maybe the version is not set to "standard" when you run the hook ?  That could cause the behaviour observd.

So, this only installs airflow:
rm -rf foo && cargo run venv && cargo run pip install "apache-airflow[aws] @ https://github.com/apache/airflow/archive/main.tar.gz" --pre --cache-dir foo

But if I run again without clearing the cache...
cargo run venv && cargo run pip install "apache-airflow[aws] @ https://github.com/apache/airflow/archive/main.tar.gz" --cache-dir foo --pre

Then I get all 150 dependencies.

Yes. the build hook is run properly. Just run it with a little exception just before existing inistialization to debug and it seems all good - at least for the  clean run of:
uv pip install "apache-airflow[aws] @ file:///Users/jarek/code/airflow"

result:
[jarek:~/code/airflow] [test-3.11] main(+1/-0)+ 2 ± uv pip install "apache-airflow[aws] @ file:///Users/jarek/code/airflow"
Resolved 1 package in 0.48ms
error: Failed to download distributions
  Caused by: Failed to fetch wheel: apache-airflow @ file:///Users/jarek/code/airflow
  Caused by: Failed to build: apache-airflow @ file:///Users/jarek/code/airflow
  Caused by: Build backend failed to build wheel through `build_wheel()` with exit status: 1
--- stdout:

--- stderr:
Traceback (most recent call last):
  File "<string>", line 11, in <module>
  File "/Users/jarek/Library/Caches/uv/.tmpaYi2WU/.venv/lib/python3.11/site-packages/hatchling/build.py", line 58, in build_wheel
    return os.path.basename(next(builder.build(directory=wheel_directory, versions=['standard'])))
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jarek/Library/Caches/uv/.tmpaYi2WU/.venv/lib/python3.11/site-packages/hatchling/builders/plugin/interface.py", line 147, in build
    build_hook.initialize(version, build_data)
  File "/Users/jarek/IdeaProjects/airflow/hatch_build.py", line 750, in initialize
    raise Exception(build_data)
Exception: {'infer_tag': False, 'pure_python': True, 'dependencies': ['alembic>=1.13.1, <2.0', 'argcomplete>=1.10', 'asgiref', 'attrs>=22.1.0', 'blinker>=1.6.2', 'colorlog>=4.0.2, <5.0', 'configupdater>=3.1.1', 'connexion[flask]>=2.10.0,<3.0', 'cron-descriptor>=1.2.24', 'croniter>=2.0.2', 'cryptography>=39.0.0', 'deprecated>=1.2.13', 'dill>=0.2.2', 'flask-caching>=1.5.0', 'flask-session>=0.4.0,<0.6', 'flask-wtf>=0.15', 'flask>=2.2,<2.3', 'fsspec>=2023.10.0', 'google-re2>=1.0', 'gunicorn>=20.1.0', 'httpx', 'importlib_metadata>=1.7;python_version<"3.9"', 'importlib_resources>=5.2,!=6.2.0,!=6.3.0,!=6.3.1;python_version<"3.9"', 'itsdangerous>=2.0', 'jinja2>=3.0.0', 'jsonschema>=4.18.0', 'lazy-object-proxy', 'linkify-it-py>=2.0.0', 'lockfile>=0.12.2', 'markdown-it-py>=2.1.0', 'markupsafe>=1.1.1', 'marshmallow-oneofschema>=2.0.1', 'mdit-py-plugins>=0.3.0', 'opentelemetry-api>=1.15.0', 'opentelemetry-exporter-otlp', 'packaging>=14.0', 'pathspec>=0.9.0', 'pendulum>=2.1.2,<4.0', 'pluggy>=1.0', 'psutil>=4.2.0', 'pygments>=2.0.1', 'pyjwt>=2.0.0', 'python-daemon>=3.0.0', 'python-dateutil>=2.3', 'python-nvd3>=0.15.0', 'python-slugify>=5.0', 'requests>=2.27.0,<3', 'rfc3339-validator>=0.1.4', 'rich-argparse>=1.0.0', 'rich>=12.4.4', 'setproctitle>=1.1.8', 'sqlalchemy>=1.4.36,<2.0', 'sqlalchemy-jsonfield>=1.0', 'tabulate>=0.7.5', 'tenacity>=6.2.0,!=8.2.0', 'termcolor>=1.1.0', 'unicodecsv>=0.14.1', 'universal-pathlib>=0.2.2', 'werkzeug>=2.0,<3', 'apache-airflow-providers-common-io', 'apache-airflow-providers-common-sql', 'apache-airflow-providers-fab>=1.0.2dev0', 'apache-airflow-providers-ftp', 'apache-airflow-providers-http', 'apache-airflow-providers-imap', 'apache-airflow-providers-smtp', 'apache-airflow-providers-sqlite'], 'force_include_editable': {}, 'extra_metadata': {}, 'artifacts': [], 'force_include': {}, 'build_hooks': ('custom',)}

Still, when I remove the exception:
Resolved 1 package in 0.45ms
   Built apache-airflow @ file:///Users/jarek/code/airflow                                                                                Downloaded 1 package in 5.84s
Installed 1 package in 10ms
 + apache-airflow==2.9.0.dev0 (from file:///Users/jarek/code/airflow)

Hmm, it seems related to our use of prepare_metadata_for_build_wheel. The metadata returned by that hook isn't including any requirements.

Maybe I should set it differently in hatchling, but:
a) no idea how and at least "dependencies" seem to be the right way of doing it
b) pip works correctly with both dependencies" and optional-dependencies c) it seems to work fine with --editablebuuld even inuv`
So it looks like something on the uv side :( ?

Editable with exception:
uv pip install -e "/Users/jarek/code/airflow[aws]"
error: Failed to build editables
  Caused by: Failed to build editable: file:///Users/jarek/code/airflow
  Caused by: Build backend failed to build wheel through `build_editable()` with exit status: 1
--- stdout:

--- stderr:
Traceback (most recent call last):
  File "<string>", line 11, in <module>
  File "/Users/jarek/Library/Caches/uv/.tmpFU2vBA/.venv/lib/python3.11/site-packages/hatchling/build.py", line 83, in build_editable
    return os.path.basename(next(builder.build(directory=wheel_directory, versions=['editable'])))
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jarek/Library/Caches/uv/.tmpFU2vBA/.venv/lib/python3.11/site-packages/hatchling/builders/plugin/interface.py", line 147, in build
    build_hook.initialize(version, build_data)
  File "/Users/jarek/IdeaProjects/airflow/hatch_build.py", line 750, in initialize
    raise Exception(build_data)
Exception: {'infer_tag': False, 'pure_python': True, 'dependencies': ['alembic>=1.13.1, <2.0', 'argcomplete>=1.10', 'asgiref', 'attrs>=22.1.0', 'blinker>=1.6.2', 'colorlog>=4.0.2, <5.0', 'configupdater>=3.1.1', 'connexion[flask]>=2.10.0,<3.0', 'cron-descriptor>=1.2.24', 'croniter>=2.0.2', 'cryptography>=39.0.0', 'deprecated>=1.2.13', 'dill>=0.2.2', 'flask-caching>=1.5.0', 'flask-session>=0.4.0,<0.6', 'flask-wtf>=0.15', 'flask>=2.2,<2.3', 'fsspec>=2023.10.0', 'google-re2>=1.0', 'gunicorn>=20.1.0', 'httpx', 'importlib_metadata>=1.7;python_version<"3.9"', 'importlib_resources>=5.2,!=6.2.0,!=6.3.0,!=6.3.1;python_version<"3.9"', 'itsdangerous>=2.0', 'jinja2>=3.0.0', 'jsonschema>=4.18.0', 'lazy-object-proxy', 'linkify-it-py>=2.0.0', 'lockfile>=0.12.2', 'markdown-it-py>=2.1.0', 'markupsafe>=1.1.1', 'marshmallow-oneofschema>=2.0.1', 'mdit-py-plugins>=0.3.0', 'opentelemetry-api>=1.15.0', 'opentelemetry-exporter-otlp', 'packaging>=14.0', 'pathspec>=0.9.0', 'pendulum>=2.1.2,<4.0', 'pluggy>=1.0', 'psutil>=4.2.0', 'pygments>=2.0.1', 'pyjwt>=2.0.0', 'python-daemon>=3.0.0', 'python-dateutil>=2.3', 'python-nvd3>=0.15.0', 'python-slugify>=5.0', 'requests>=2.27.0,<3', 'rfc3339-validator>=0.1.4', 'rich-argparse>=1.0.0', 'rich>=12.4.4', 'setproctitle>=1.1.8', 'sqlalchemy>=1.4.36,<2.0', 'sqlalchemy-jsonfield>=1.0', 'tabulate>=0.7.5', 'tenacity>=6.2.0,!=8.2.0', 'termcolor>=1.1.0', 'unicodecsv>=0.14.1', 'universal-pathlib>=0.2.2', 'werkzeug>=2.0,<3'], 'force_include_editable': {}, 'extra_metadata': {}, 'artifacts': [], 'force_include': {}, 'build_hooks': ('custom',)}

After removing the exception:
[jarek:~/code/airflow] [test-3.11] main(+1/-1)+ 2 ± uv pip install -e "/Users/jarek/code/airflow[aws]"
   Built file:///Users/jarek/code/airflow                                                                                Built 1 editable in 4.63s
Resolved 161 packages in 5.82s
   Built python-nvd3==0.15.0
   Built lazy-object-proxy==1.10.0
   Built unicodecsv==0.14.1                                                                                Downloaded 151 packages in 1.82s
Installed 154 packages in 254ms
 + aiobotocore==2.12.1
 + aiohttp==3.9.3
 + aioitertools==0.11.0
 + aiosignal==1.3.1
 + alembic==1.13.1
 + annotated-types==0.6.0
 + anyio==4.3.0
 + apache-airflow==2.9.0.dev0 (from file:///Users/jarek/code/airflow)
 + argcomplete==3.2.3
 + asgiref==3.8.1
 + asn1crypto==1.5.1
 + attrs==23.2.0
 + aws-sam-translator==1.86.0
.....  and son ....

Perhaps we can ask Ofek if he has any ideas why the generated metadata is different here.

cc: @ofek ?

(I think the reason it works the second invocation that the wheel is built, and we read the metadata from the wheel if it's available. But in the first invocation, during resolution, we do prepare_metadata_for_build_wheel, since the wheel isn't available yet.)

(I think the reason it works the second invocation that the wheel is built, and we read the metadata from the wheel if it's available. But in the first invocation, during resolution, we do prepare_metadata_for_build_wheel, since the wheel isn't available yet.)

I believe this is what pip is always doing - preparing the  wheel first and only then installing it.

I'm pretty sure that the metadata returned by prepare_metadata_for_build_wheel should be the same as that returned by building the wheel though.

Hmmm. Then we need @ofek to chime-in :).
BTW. Just to add the sense of priority - it's not super important to handle. I workarounded it in our CI image building proces. so I donwload and unpack the https://github.com/apache/airflow/archive/main.tar.gz for our own caching, unpack it and instal it in --editable mode, which is actually even better for our process, because this way we could remove the devel-ci extra from wheel (so it is likely going to stay like that). but it would be nice to solve it for "prime-time" of uv for our users who might want to also install airflow via the GitHub URL in some cases.
It works for pip and pip is for now our recommended user-installation build frontent, so this does not impact us much

Does it work if you explicitly gate by the value of this e.g. wheel? https://hatch.pypa.io/latest/plugins/build-hook/reference/#hatchling.builders.hooks.plugin.interface.BuildHookInterface.target_name
Both built-in targets wheel and sdist have a version named standard just like your custom build target:

https://hatch.pypa.io/latest/plugins/builder/wheel/#versions
https://hatch.pypa.io/latest/plugins/builder/sdist/#versions

I'm just getting up to speed on the issue and don't immediately see what's happening.

Oh, nevermind I see the issue I think: https://github.com/pypa/hatch/blob/hatchling-v1.22.4/backend/src/hatchling/build.py#L86-L99
Charlie, let me know how you would like me to fix. I think I have to account for your code base now as well.

I'm just getting up to speed on the issue and don't immediately see what's happening.

In short:

airflow has rather complex build_hooks writen via hatchling's hatch_build.py https://github.com/apache/airflow/blob/main/hatch_build.py

I just merged PR yesterday (https://github.com/apache/airflow/pull/38437)  to fix it for a bit of abuse of PEP 517 (partially based on your discussions in https://github.com/pypa/hatch/issues/1331 and comment from pfmoore about  non-standard compliant mixing of dynamic properties  with static data in pyproject.toml. I turned both dependencies and optional-dependencies into a truly dynamic property in this PR and in the hook I am updating them after calculating them (though I must admit optional-dependencies are updated in rather hacky way as I have not found a better way via the hatchling hook (see those few lines in https://github.com/apache/airflow/blob/main/hatch_build.py#L748)

the problem - it seems all work perfectly fine in pip for both installing an "editable" install and also a standard install from airflow sources (either via "file:///" or  "http:" - with all the bells-and-whistles (i.e. extras are resolving as I wanted them to resolve). But the "standard" builds don't work with uv.

Oh, nevermind I see the issue I think: https://github.com/pypa/hatch/blob/hatchling-v1.22.4/backend/src/hatchling/build.py#L86-L99

Charlie, let me know how you would like me to fix. I think I have to account for your code base now as well.

AAARGH...
If pip then.... 🤯

BTW. @ofek -> since I got your attention... Is there a better way to dynamically set optional-dependencies than what I (hackishly) figured out ?
        # unfortunately hatchling currently does not have a way to override optional_dependencies
        # via build_data (or so it seem) so we need to modify internal _optional_dependencies
        # field in core.metadata until this is possible
        self.metadata.core._optional_dependencies = self.optional_dependencies

I think I have to account for your code base now as well.

BTW. Shouldn't it work for any PEP-compliant frontend (just sayin :D )

I know that seems hacky but I swear that was only the way to satisfy everyone 😅 I honestly thought a lot about that fix.

Is there a better way to dynamically set optional-dependencies than what I (hackishly) figured out ?

Yes there is a metadata hook https://hatch.pypa.io/latest/plugins/metadata-hook/custom/

Ah ok, so am I correct that Hatchling detects if pip is calling it, and disables the prepare_metadata_for_build_wheel hooks in that case?

Yes, for precisely this issue!

Yes there is a metadata hook https://hatch.pypa.io/latest/plugins/metadata-hook/custom/

Thank you 🙇♂. I think after all the things I've done for Airlfow It's time to contribute back some docs to Hatchling from the "user" perspective :). Will likely do so soon.

That would be awesome, thanks 🙂 Here is the meta-issue: https://github.com/pypa/hatch/issues/1245
In short, please prioritize how-to documents!

Yes there is a metadata hook https://hatch.pypa.io/latest/plugins/metadata-hook/custom/

Hmm. Just tried it but it does not seem to allow me to distinguish between editable/standard build. I want to really have quite a different set of those for editable standard build in a single hatch_build.py

Then please open a feature request to the build hook interface.

Then please open a feature request to the build hook interface.

Cool.

@ofek -- I assume there's no way for uv or for Hatch to detect when the hook can be trusted vs. not? E.g., could uv just avoid calling this when requirements are declared as "dynamic"?

That could work also I think.

Is this unique to Hatch since it supports extensions? Would other build backends need similar gating?

setuptools would have the same issue in theory for very dynamic builds.

Ok, I'll add that gate in uv for now.

Do you have any advice for writing a test for this? This is what I have, but it's passing when I want it to fail based on the above: https://github.com/astral-sh/uv/compare/charlie/proj...charlie/dynamic

Does this work?
scripts/packages/hatch_dynamic/pyproject.toml:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "hatch-dynamic"
version = "1.0.0"
dynamic = ["dependencies"]

[tool.hatch.build.targets.wheel.hooks.custom]

scripts/packages/hatch_dynamic/hatch_build.py:
from hatchling.builders.hooks.plugin.interface import BuildHookInterface

class LiteraryBuildHook(BuildHookInterface):
    def initialize(self, version, build_data):
        build_data['dependencies'].append('foo')

Trying, thank you.

Yes, thanks.

It looks like the example use-case from the Hatch issue (https://github.com/pypa/hatch/issues/532) doesn't use dynamic dependencies. I was hoping I could instead do something even more specific, like look for the presence of Hatch plugins ([tool.hatch.build.targets.wheel.hooks], etc.), but that example also doesn't seem to use that, it registers a custom entrypoint.

So I'm not really sure how to detect it :/

Hmm, good point actually only metadata hooks have anything to do with dynamic I'm seeing. At the end of the day, build hooks can do anything to the metadata because even if they don't use the standard fields that the system might provide to change things they could also do a post hook to actually rewrite the contents of the wheel e.g. for example if there was a plugin that ran auditwheel/delocate/delvewheel to fix up extension modules.
If you want to check hooks then you would have to search for the following:

[tool.hatch.build.hooks.*]
[tool.hatch.build.targets. *.hooks.*]

I'd find it worrying if a trends develops for frontends to special case for specific backends, or backends to special case for specific frontends.

I'd find it worrying if a trends develops for frontends to special case for specific backends, or backends to special case for specific frontends.

Agree. I think we have to find a solution that is generic in both directions. Maybe something to discuss in Pittsburgh :)

Just a sanity check, does everyone here understand why I do this? https://github.com/pypa/hatch/blob/hatchling-v1.22.4/backend/src/hatchling/build.py#L86-L99
I'm open to feedback but basically for extremely dynamic metadata you don't want frontends caching like that before dynamic stuff happens i.e. this issue.

I think I understand it, though I'm not familiar enough with Hatch to know why my first test case (using the requirements.txt plugin) worked without issue.
I do think it's non-standards compliant though, in two ways, at least based on what I saw in the linked issue:

Projects that don't mark fields as "dynamic" can still produce dynamic metadata. In theory this could be considered a user configuration error?
The metadata returned by prepare_metadata_for_build_wheel is incorrect and Hatch doesn't adhere to the contract in the standards, so it's then sniffing for callers that would be impacted by the incorrectness.

I'm honestly somewhat hesitant to add custom workarounds for Hatch here, though it also seems like a huge shame to skip prepare_metadata_for_build_wheel in all cases when it would be totally valid most of the time.
I know it's easier said than done, but I feel like the standards-compliant thing would be something like:

Require "dynamic" for any field that is actually dynamic, and have Hatch enforce that after all the hooks run. (No idea if this is possible.)
Do the detection within Hatch to figure out whether prepare_metadata_for_build_wheel is safe (e.g., are there any build hooks?), and return None when it's not.

I think I understand it, though I'm not familiar enough with Hatch to know why my first test case (using the requirements.txt plugin) worked without issue.

Metadata resolution is the very first step and that component doesn't take into account what kind of builds are happening so it works perfectly in that case.

Projects that don't mark fields as "dynamic" can still produce dynamic metadata. In theory this could be considered a user configuration error?

That is unrelated to what's happening here but you're correct that I should produce an error for build hooks modifying static metadata just like I do for metadata hooks. I'll work on that soon.

The metadata returned by prepare_metadata_for_build_wheel is incorrect and Hatch doesn't adhere to the contract in the standards, so it's then sniffing for callers that would be impacted by the incorrectness.

I understand why you might think that but the issue is that backends that offer a dynamic functionality must make a trade-off. There are three options:

Don't implement that method at all which would preclude certain performance optimizations for some tools.
Only provide an implementation conditionally, deliberately excluding situations where it is undesirable. (This is the current approach.)
Provide a constant implementation, which would break for workloads that require dynamic things happening during builds.

Do the detection within Hatch to figure out whether prepare_metadata_for_build_wheel is safe (e.g., are there any build hooks?), and return None when it's not.

Is that part of the standard? It appears to me that you either implement it or you don't: https://peps.python.org/pep-0517/#prepare-metadata-for-build-wheel

That is unrelated to what's happening here but you're correct that I should produce an error for build hooks modifying static metadata just like I do for metadata hooks. I'll work on that soon.

Yeah makes sense. This more spun out of my idea to detect dynamic fields and limit the call to non-dynamic cases.

Is that part of the standard? It appears to me that you either implement it or you don't: https://peps.python.org/pep-0517/#prepare-metadata-for-build-wheel

I think you're right. Our implementation allows the backend to return None but I think that's just an implementation detail on our side, I don't see that in the standard.

Only provide an implementation conditionally, deliberately excluding situations where it is undesirable. (This is the current approach.)

This seems like a reasonable outcome. The problem is that the "conditionally" is based on detecting the build front-end. Like, this wouldn't just be a problem for uv, it'd be a problem for any other installer too. Though I understand why it's hard to do anything differently here given the limitations of the spec.

I understand why you might think that but the issue is that backends that offer a dynamic functionality must make a trade-off.

Yeah, I understand. But it's still out of compliance with the standard, right? I'm not sure what to suggest other than that the standard needs to evolve in some way, but I'm not familiar enough with build backends to understand how.

It's possible that breaks other frontends though, I'm not sure >.<

I have https://github.com/astral-sh/uv/pull/2645 open for now.

I suppose I'll use your implementation's hack and return None.

My read is that this won't work for pip:
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)

(Though I know you omit pip anyway altogether.)

I would say just leave it for now, there's no need to make any urgent changes.

I ended up special-casing hatchling in https://github.com/astral-sh/uv/pull/2645. We should figure out a better solution together.

authors: charliermarsh ofek potiuk sbidoul


text:
uv run should only resolve when lockfile is out-of-sync

As long as the lockfile satisfies the requirements, we should accept it (even if dependencies are outdated). Updating the lockfile should be done via uv update or uv lock or comparable.

I'm looking into this now.

There are two parts to this:

Statically extracting the requirements for the workspace.
Comparing the extracted requirements to the lockfile.

I am working on (1). It's not totally trivial, we currently defer that extraction to the resolver.
There are several things that make (2) hard:

The markers might've been normalized when writing to the lockfile, so they may not match the requirements as defined by the user. We could also have multiple requirements from (1) that map to a single requirement in (2), if it's (e.g.) a single requirement repeated with different markers (which would get OR'd when writing to the lockfile).
We have to check workspace dependencies recursively.
We need to ensure that there are no entries in the lockfile that no longer exist as requirements -- otherwise, we'll install too many packages. So it's not just checking that each requirement is present; we also need to check that nothing is present that isn't a requirement. We need to be able to map from requirement to lock entry, but also the other way around.

@ibraheemdev and I discussed this in Discord. A summary:

We think that the right way to solve this is to enable the resolver to read from the lockfile directly. Then, this could be reframed as: can we solve the graph with just the lockfile? (Overlaps heavily with https://github.com/astral-sh/uv/issues/3925.) If we can implement resolution atop the lockfile, all of the challenges that I described above go away.
Separately, we may want to read from the lockfile directly during "normal" resolution, but to implement this ticket, we could just do a first-pass where we try to solve from only the lockfile. So there could be additional follow-up work for #3925 later.
Another idea we discussed was: write a hash or checksum of the requirements somewhere in the cache, and avoid re-resolving if they line up with the lockfile. This would be conceptually similar to writing a hash to the lockfile to capture its inputs, but we would write it out-of-band (to the cache) to avoid causing merge conflicts, etc. (This would only work locally after performing at least one resolution.) But we weren't sure if this would be necessary once we do the "resolve from the lockfile" idea. Either way, we'd need to read the lockfile from disk; and either way, we'd need to then validate that the virtual environment satisfies the requirements (unless we used the hash / checksum to skip this too, which could work, but risks getting out-of-sync when the user modifies the environment manually). So we opted not do to that for now, and to instead focus on the harder thing.

There's something confusing in https://github.com/astral-sh/uv/issues/3925 though... In the lockfile, we don't actually store the version constraints, we just store the locked version. That might be fine? But if we translate that back to a requirement, we will have to translate to an == requirement. I haven't thought through the implications of that.

To add more motivation here: When running uv lock transformers with all extras with a fitting lock, we take 100ms on main, but 60ms with https://github.com/astral-sh/uv/pull/4495.
One thing we lose by doing this is the check for yanked releases, those versions that are part of the lock file but have yanked since.

source: gharchive/issue

authors: charliermarsh konstin

repo: astral-sh/uv

license_type: permissive

license_source: github-api


text:
uv sync issue Build backend failed to build editable through build_editable()

platform: macOS m1
uv version: uv 0.4.5 (42b6bfbad 2024-09-04)
error:
❯ uv sync
Resolved 143 packages in 2ms
error: Failed to prepare distributions
  Caused by: Failed to fetch wheel: backend @ file:///Users/steve/projects/recipeyak/backend
  Caused by: Build backend failed to build editable through `build_editable()` with exit status: 1
--- stdout:

--- stderr:
Traceback (most recent call last):
  File "<string>", line 11, in <module>
  File "/Users/steve/.cache/uv/builds-v0/.tmp0olTuB/lib/python3.11/site-packages/hatchling/build.py", line 83, in build_editable
    return os.path.basename(next(builder.build(directory=wheel_directory, versions=['editable'])))
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/steve/.cache/uv/builds-v0/.tmp0olTuB/lib/python3.11/site-packages/hatchling/builders/plugin/interface.py", line 90, in build
    self.metadata.validate_fields()
  File "/Users/steve/.cache/uv/builds-v0/.tmp0olTuB/lib/python3.11/site-packages/hatchling/metadata/core.py", line 266, in validate_fields
    self.core.validate_fields()
  File "/Users/steve/.cache/uv/builds-v0/.tmp0olTuB/lib/python3.11/site-packages/hatchling/metadata/core.py", line 1376, in validate_fields
    getattr(self, attribute)
  File "/Users/steve/.cache/uv/builds-v0/.tmp0olTuB/lib/python3.11/site-packages/hatchling/metadata/core.py", line 833, in authors
    raise TypeError(message)
TypeError: Author #1 of field `project.authors` must be an inline table
---

pyproject.toml:
[project]
name = "backend"
version = "0.1.0"
description = ""
authors = ["foo", "bar"]

requires-python = ">=3.10"
dependencies = [
    "django~=3.2.9",
    "dj-database-url==0.4.2",
    "gunicorn==20.1.0",
    "django-user-sessions~=1.6",
    "python-dotenv==0.21.0",
    "djangorestframework-types~=0.2.0",
    "orjson==3.8.1",
    "psycopg2-binary~=2.9.3",
    "boto3~=1.24.44",
    "yarl~=1.8.1",
    "advocate~=1.0.0",
    "pillow~=9.3.0",
    "httpx~=0.23.1",
    "asyncpg~=0.27.0",
    "asyncpg-stubs~=0.27.0",
    "typer~=0.7.0",
    "structlog~=22.3.0",
    "types-pillow~=9.3.0",
    "pillow-heif~=0.9.0",
    "tldextract~=3.4.0",
    "sentry-sdk~=1.35.0",
    "ably~=2.0.1",
    "recipe-scrapers~=14.52.0",
    "algoliasearch~=3.0.0",
    "async-timeout~=4.0.3",
    "aiohttp~=3.9.1",
    "ruamel-yaml~=0.18.5",
    "pydantic-settings~=2.1.0",
    "jsonref~=1.1.0",
    "pywatchman~=2.0.0",
    "pydantic[email]~=2.5.3",
]

[tool.uv]
dev-dependencies = [
    "pytest==7.2.0",
    "pytest-django==4.5.2",
    "ipdb~=0.13.9",
    "django-types~=0.19.1",
    "types-pyyaml~=6.0.0",
    "types-requests~=2.25.11",
    "syrupy~=3.0.5",
    "types-urllib3~=1.26.23",
    "types-dj-database-url~=1.0.0",
    "mypy~=1.7.0",
    "bpython~=0.24",
    "ruff~=0.3.5",
    "pytest-xdist~=3.5.0",
    "boto3-stubs[s3]~=1.24.44",
]

[tool.ruff]
src = ["recipeyak"]
target-version = "py311"

[tool.ruff.lint]
select = [
    "E",
    "F",
    "TID252",
    "I001",
    "T20",
    "C4",
    "UP",
    "N",
    "BLE",
    "B",
    "RET",
    "SIM",
    "ARG",
    "DTZ",
    "ERA",
    "PTH",
    "TCH",
    "PYI",
    "PT",
    "INP001",
    "T100",
    "PGH003",
    "RUF",
]
ignore = [
    "E501", # line length is handled by black
    "ARG001", # pytest fixtures mess with this
    "ARG002", # sometimes parent classes require params
    "N806", # django migrations violate this a lot
    "B008", # type.Argument violates this
    "N815", # we mix and match casing in serializers
    "ARG005", # monkey patching false positive with *args, and **kwargs
    "N805", # false positive with pydantic
    "N802", # DRF serializers mess with this
    "RET505", # if, elif, else are fine with returns
    "RET507", # if, elif, else with continue is also fine
    "RET508", # if, elif, else with break is also fine
    "TCH003", # not until autofixable
    "TCH002", # not until autofixable
    "TCH001", # not until autofixable
    "PT004", # makes the function appear unused to pyright
]
unfixable = ["ERA001"] # we want to check ourselves before we delete commented out code. Also this doesn't cleanup all of it.

[tool.ruff.lint.per-file-ignores]
"recipeyak/migrations/*" = [
    # it's very common to use class vars in Django migrations.
    "RUF012",
]

[tool.ruff.lint.flake8-pytest-style]
fixture-parentheses = false

[tool.ruff.lint.isort]
known-third-party = ["django"]
known-first-party = ["recipeyak"]

[tool.ruff.lint.flake8-tidy-imports]
# Disallow all relative imports.
ban-relative-imports = "all"

[tool.pytest.ini_options]
DJANGO_SETTINGS_MODULE = "recipeyak.django.settings"
python_files = "*_test.py *_tests.py"
addopts = "-s --pdbcls IPython.terminal.debugger:TerminalPdb --reuse-db -p no:warnings -p no:pastebin -p no:nose -p no:doctest -p no:freeze_support -p no:stepwise -p no:python_path -p no:setuponly -p no:setupplan -p no:legacypath-tmpdir -p no:unittest"
testpaths = "recipeyak"

[tool.mypy]
mypy_path = "./typings"
files = ["**/*.py"]

show_column_numbers = true
show_error_codes = true

disallow_any_unimported=false
disallow_any_expr=false
disallow_any_decorated=false
disallow_any_explicit=false
disallow_any_generics=true
disallow_subclassing_any=false

disallow_untyped_calls=false
disallow_untyped_defs=true
disallow_incomplete_defs=true
check_untyped_defs=true
disallow_untyped_decorators=true

no_implicit_optional=true
strict_optional=true

warn_redundant_casts=true
warn_unused_ignores=true
warn_no_return=true
warn_return_any=true
# doesn't consider how methods can change the value of properties
warn_unreachable=false

strict_equality=true

ignore_missing_imports=false

plugins = [
  "pydantic.mypy"
]

[[tool.mypy.overrides]]
module = [
    'icalendar.*',
    'advocate.*',
    'user_sessions.*',
    'ably.*',
    'ruamel.*'
]
ignore_missing_imports = true

[tool.pydantic-mypy]
init_forbid_extra = true
init_typed = true
warn_required_dynamic_aliases = true
warn_untyped_fields = true

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

It looks like this comes from Hatchling. I think it's correct per the spec?

ah I thought it was related to upgrading from 0.3.3 but checked it out on that version and it's broken there too, oops!

Turns out poetry and pypa/hatchling have different structures for authors
https://github.com/pypa/packaging.python.org/issues/1134

authors: charliermarsh sbdchd


text:
Opt-into / opt-out of automatic re-sync with uv run?

uv 0.4.5.
Hi, thanks for uv, it's hot! :volcano:
I recently started using the higher-level commands of uv, like uv sync instead of uv pip .... Working great :rocket: uv sync makes things much, much faster within my workflow :smile:
I also started using uv run. And there's something about it that I both love and dislike: the fact that it automatically re-syncs the env each time I use it.

I love it because it means I can clone my repo, enter it, and immediately run my format task (which uses Ruff :yum:) to format the code, and uv will automatically create the venv, lock and install the dependencies, and run the specified command. That is awesome.
I dislike it because I often tinker with my venvs, installing different versions of dependencies to try things out. But now each time I use uv run, it resets these dependencies to the versions saved in the lock file.

I am aware of the --with option (which is awesome too!), but I would really prefer "persisting" my changes in the venv, so that I don't have to use --with x==y in each subsequent commands. So, ideally I would like to have a way to opt-out of this automatic re-sync, which would result in the following behavior:

if there's no venv, create one, lock, install deps
if there's a venv, don't touch it

(venv path is determined with UV_PROJECT_ENVIRONMENT and usual fallback(s))
Do you think you can consider such a thing :thinking:?
Happy to elaborate on my use-case, as maybe there's a different/better workflow that uv suggests.

Ooooh it seems --no-project is maybe doing what I want :thinking:

I think it's gonna be hard for us to achieve both (1) and (2). We're trying to avoid reading state from disk like that. We could, it's just more of a departure from how things work today. I think --no-project will work if you've already activated the environment... Otherwise, I think you want something like uv run --no-sync (which doesn't exist IIRC).

\cc @zanieb who may have opinions on point (1).

I think we're getting consistent feedback that uv run --no-sync should exist.
But... I don't think an operating mode that touches the virtual environment if it doesn't exist but not otherwise makes a ton of sense for general use — it seems hard to teach. I guess this would be a variant like uv run --only-initial-sync(?).

I would really prefer "persisting" my changes in the venv, so that I don't have to use --with x==y in each subsequent commands.

I think that we can do better here. We don't want you to have to persist the changes to your environment nor should you have to specify --with on every invocation. The options are probably

Use --with-requirements and write them to a file
Add support for running commands with extra dependencies in #5903

Would (2) address your use case?

@zanieb -- Does --no-sync also not lock? (Should that just be the --frozen behavior perhaps?)

I would be surprised if it locked. I was also surprised --frozen syncs —  but it makes sense that we allow for syncing without updating the lock.
Looking for consistency with other things... the uv add documention says:

The lockfile and project environment will be updated to reflect the added dependencies. To skip updating the lockfile, use --frozen. To skip updating the environment, use --no-sync.

Which seems reasonable. For uv run though I feel like --no-sync could imply --frozen since the intent of the command is not to modify the project's dependencies as opposed to, e.g., uv add.

authors: charliermarsh pawamoy zanieb


text:
uv pip install - Azure packages from upstreamSources are never found

Hi,
I don't think I can reproduce the error here, but here's the issue:
We have many azure artifacts feeds on my company. Some feeds are linked to others through Upstream Sources, which means that for instance, if feed ProjectB is an upstream source on ProjectA, I should be able to get packages from ProjectB using the index-url of ProjectA only.
In the example below, I try to install a 'test_package' using the index-url (extra-index-url also fails) of the feed 'Feed1', in which this package doesn't exist. Feed1 however, has as Upstream Source another feed in which test_package exists.
When using pip install, I can find and install test_package and any other packages on my Feed1.
With uv pip install, I can only find package that exist on Feed1, any other package that is coming from another feed (through Upstream Sources) can't be found.
The Azure REST API (Get Feeds) returns a feed object with attribute upstreamSources. Those upstream sources should also be searched when installing a package (I believe that is what is missing).
Here's what I tried:
uv pip install test_package --index-url="https://PAT@pkgs.dev.azure.com/<Organization>/<project>/_packaging/Feed1/pypi/simple/" --verbose
DEBUG uv 0.4.16
DEBUG Searching for default Python interpreter in system path or `py` launcher
DEBUG Found `cpython-3.11.6-windows-x86_64-none` at `C:\Users\<user>\testt\venv\Scripts\python.exe` (active virtual environment)
DEBUG Using Python 3.11.6 environment at venv\Scripts\python.exe
DEBUG Acquired lock for `venv`
DEBUG At least one requirement is not satisfied: test_package
DEBUG Using request timeout of 30s
DEBUG Solving with installed Python version: 3.11.6
DEBUG Solving with target Python version: >=3.11.6
DEBUG Adding direct dependency: test_package*
DEBUG No cache entry for: https://pkgs.dev.azure.com/<Organization>/<project>/_packaging/Feed1/pypi/simple/test_package/
DEBUG No cache entry for: https://pkgs.dev.azure.com/<Organization>/<project>/_packaging/Feed1/pypi/simple/test_package/
DEBUG Searching for a compatible version of test_package(*)
DEBUG No compatible version found for: test_package
  × No solution found when resolving dependencies:
  ╰─▶ Because test_package was not found in the package registry and you require test_package, we can conclude that your requirements are unsatisfiable.
DEBUG Released lock at `C:\Users\<user>\testt\venv\.lock`

I'd love to help but I think we really need a reproduction that we can test here since it likely depends on details on how the Upstream Sources work, and how pip treats the redirect.

Thank you for following up!

authors: ErichMarx charliermarsh


text:
Update of all dependencies of package  with -U may lead to not working environment (numba and numpy problem)

When updated, a package using uv pip install -U the uv updates its dependencies (which is nice), but it ignores upper constraints in dependencies of all installed packages.
In contradiction, the pip update only these dependencies that are enforced by minimum required version of dependency.
In my case, it creates a problem with any package that has numpy in dependencies as numba project do not support the latest numpy version.
Here MRE (in real scenario I was switching the zarr version).
$ uv pip install numba
Using Python 3.11.10 environment at venv
Resolved 3 packages in 108ms
Prepared 2 packages in 1.53s
Installed 3 packages in 48ms
 + llvmlite==0.43.0
 + numba==0.60.0
 + numpy==2.0.2

$ uv pip install zarr
Using Python 3.11.10 environment at venv
Resolved 5 packages in 5ms
Installed 4 packages in 1ms
 + asciitree==0.3.3
 + fasteners==0.19
 + numcodecs==0.13.1
 + zarr==2.18.3

$ uv pip install -U zarr
Using Python 3.11.10 environment at venv
Resolved 5 packages in 124ms
Prepared 1 package in 0.58ms
Uninstalled 1 package in 14ms
Installed 1 package in 16ms
 - numpy==2.0.2
 + numpy==2.1.2

$ python
Python 3.11.10 (main, Oct  2 2024, 16:32:22) [Clang 18.1.8 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numba
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/czaki/venv/lib/python3.11/site-packages/numba/__init__.py", line 59, in <module>
    _ensure_critical_deps()
  File "/home/czaki/venv/lib/python3.11/site-packages/numba/__init__.py", line 45, in _ensure_critical_deps
    raise ImportError(msg)
ImportError: Numba needs NumPy 2.0 or less. Got NumPy 2.1.

When call update of both numba and zarr it selects the correct NumPy version
$ uv pip install -U zarr numba
Using Python 3.11.10 environment at venv
Resolved 7 packages in 156ms
Prepared 1 package in 0.64ms
Uninstalled 1 package in 18ms
Installed 1 package in 13ms
 - numpy==2.1.2
 + numpy==2.0.2

Platform: Ubuntu 24.04
uv version: 0.4.22
It will be nice if uv could take a care of upper constraints of already installed package and require --override flag to ignore them.

Just to clarify what's going on here, I don't think pip is taking Numba into account at all. Rather, I think pip treats pip install -U zarr as "upgrade zarr", whereas we treat pip install -U zarr as "upgrade any dependencies you encounter when resolving zarr".

pip will also let you break the environment trivially (pip install numpy==2.1.2 would have the same problem).

Yes. I agree. There is difference, I try to point it in description.
But with pip I end with working environment, and with uv, the environment is broken.
I also expect that uv pip install numpy==2.1.2 will break the environment. I even expect that uv pip install -U numpy will do this.
But now, I do not know how to update a single package in a way that does not break the environment, without going on PyPI and manual typing version in terminal.

If you only want to upgrade zarr, you can do uv pip install --upgrade-package zarr zarr

I think there's some overlap with: https://github.com/astral-sh/uv/issues/4779

Oh, and also: https://github.com/astral-sh/uv/issues/6100

I'm going to merge into https://github.com/astral-sh/uv/issues/4779 so we have a single issue for this.

authors: Czaki charliermarsh


text:
uv python find --system chooses Homebrew Python instead of system one

Here is the Fedora 41 setup.
$ which uv
/home/linuxbrew/.linuxbrew/bin/uv
$ uv --version
uv 0.5.7 (Homebrew 2024-12-06)

$ which python
/usr/bin/python
$ which python3
/home/linuxbrew/.linuxbrew/bin/python3

Here are Python interpreters that uv sees.
$ uv python list
cpython-3.13.1+freethreaded-linux-x86_64-gnu    <download available>
cpython-3.13.1-linux-x86_64-gnu                 <download available>
cpython-3.13.0-linux-x86_64-gnu                 /usr/bin/python3.13
cpython-3.13.0-linux-x86_64-gnu                 /usr/bin/python3 -> python3.13
cpython-3.13.0-linux-x86_64-gnu                 /usr/bin/python -> ./python3
cpython-3.13.0-linux-x86_64-gnu                 /home/linuxbrew/.linuxbrew/opt/python@3.13/bin/python3.13
cpython-3.12.8-linux-x86_64-gnu                 <download available>
cpython-3.12.7-linux-x86_64-gnu                 /home/linuxbrew/.linuxbrew/opt/python@3.12/bin/python3.12
cpython-3.11.11-linux-x86_64-gnu                <download available>
cpython-3.10.16-linux-x86_64-gnu                <download available>
cpython-3.9.21-linux-x86_64-gnu                 <download available>
cpython-3.8.20-linux-x86_64-gnu                 <download available>
cpython-3.7.9-linux-x86_64-gnu                  <download available>
pypy-3.10.14-linux-x86_64-gnu                   <download available>
pypy-3.9.19-linux-x86_64-gnu                    <download available>
pypy-3.8.16-linux-x86_64-gnu                    <download available>
pypy-3.7.13-linux-x86_64-gnu                    <download available>

I expect ux python find --system to get /usr/bin/python first (which points to /usr/bin/python3.13, but instead it chooses Homebrew one.
$ uv python find --system -vvv
    0.000121s DEBUG uv uv 0.5.7 (Homebrew 2024-12-06)
    0.002906s DEBUG uv_python::discovery Searching for default Python interpreter in managed installations or search path
    0.002969s DEBUG uv_python::discovery Searching for managed installations at `/home/anatoli/.local/share/uv/python`
    0.008152s DEBUG uv_python::discovery Found `cpython-3.13.0-linux-x86_64-gnu` at `/home/linuxbrew/.linuxbrew/bin/python3` (search path)
/home/linuxbrew/.linuxbrew/opt/python@3.13/bin/python3.13

EDIT: This is important, because virtual environment with /usr/bin/python doesn't have problem with tkinter (https://github.com/astral-sh/uv/issues/7036) and Homebrew one needs extra steps.

https://docs.astral.sh/uv/concepts/python-versions/#discovery-of-python-versions

A Python interpreter on the PATH as python, python3, or python3.x on macOS and Linux, or python.exe on Windows.

Adjusting the order in PATH might help your desired Python version be found first.
While it's not the ideal solution, it should be able to fix your problem temporarily.

Please see https://docs.astral.sh/uv/concepts/python-versions/#managed-and-system-python-installations

uv does not distinguish between Python versions installed by the operating system vs those installed and managed by other tools. For example, if a Python installation is managed with pyenv, it would still be considered a system Python version in uv.

We have some sort of unfortunate naming here that we inherited from pip install --system. I have some plans to re-frame the option, but uv does not have the capability to distinguish between a Python installation native to your system and one that you installed separately (at this time).

I'd recommend being explicit about the interpreter you need in this case, e.g.,  --python /usr/bin/python3 python --version Python 3.9.6.

uv does not have the capability to distinguish between a Python installation native to your system and one that you installed separately (at this time)

On Linux system it is just a matter of sorting, putting /bin/env and /usr/bin/env first. In this particular case it help if lookup for python was made first, and if it is not found, then a search for python3 would be done.
Even uv python list is right, so selecting first available from it would do the trick. I tried to see if I can patch https://github.com/astral-sh/uv/blob/main/crates/uv-python/src/discovery.rs but nope, Rust is not my language.

On Linux system it is just a matter of sorting, putting /bin and /usr/bin first.

We respect the order in PATH — which I believe is correct.

In this particular case it helps if lookup for python was made first, and if it is not found, then a search for python3 would be done.

Perhaps, but I think that would also be surprising? Some discussion on this in https://github.com/astral-sh/uv/issues/6444

Even now the uv python list order is right, so selecting first available from it would do the trick.

The uv python list order isn't sorted by discovery order, it's sorted by implementation, version, then platform ~alphabetically.

We have some sort of unfortunate naming here that we inherited from pip install --system.

Wait, that's not true. This is a uv-specific option:
❯ pip install --help | grep -- "--system" || echo "Nothing to see here."
Nothing to see here.
❯ uv pip install --help | grep -- "--system" || echo "Nothing to see here."
      --system                               Install packages into the system Python environment [env: UV_SYSTEM_PYTHON=]

(I think we came up with --system on our own.)

Oh, sorry — misremembered there. Thanks for the correction @pradyunsg.
The unfortunate naming is my mistake, I guess :)

I think it might be mine :)

It makes sense until you pick at the definition of a system interpreter.
Anyway.. this behavior is intentional. We should track better naming for the options elsewhere, but --system is here to stay for compatibility purposes.

I suspect the name "system" was inspired by the actual pip flag "--break-system-packages".

This root cause of this issue is actually a duplicate of https://github.com/astral-sh/uv/issues/6444

authors: FishAlchemist abitrolly charliermarsh notatallshaw pradyunsg zanieb


text:
Update Rooster config to bump minor on breaking label

Following https://github.com/astral-sh/uv/pull/3151

Sorry I remembered this later but subsequently forgot to change it.

Thank you!

source: gharchive/pull-request

authors: charliermarsh zanieb


text:
fix typo in readme introduced in  #3162

Summary
When creating #3162 I used a single quote ' instead of grave accent `

Thanks!

authors: AlexWaygood Czaki


text:
Enable LTO optimizations in release builds to reduce binary size

Summary
In the same spirit as #5745, release builds could be a bit slightly more size efficient by enabling LTO, which removes dead code (either in uv through fully inlined functions or the libraries it depends on). Also has the side-effect (more what LTO was created for) of slighly speeding up uv.
In this case, I have measured a 5MB size decrease!.
Unfortunately, this change also comes with the disadvantage of more than doubling the build time of a clean build on my machine (see "Test Plan"). I have opened this pull request to show my findings and suggest this as an option.
I have also started looking into what effects optimizing for size rather than speed could have, but that calls for another pr
Test Plan
Comparing the binary size before and after (starting off in just a simple clone of the repository)
System info:
CPU: AMD Ryzen 7 3700X (16) @ 3.600GHz
Memory: 32GB @ 3200 MT/s
Uname: Linux galaxy 6.6.44-1-MANJARO #1 SMP PREEMPT_DYNAMIC Sat Aug  3 10:09:33 UTC 2024 x86_64 GNU/Linux

Before:
$ cargo build --release
<snip>
Finished `release` profile [optimized] target(s) in 1m 29s

$ du target/release/uv -h
30M	target/release/uv

After:
$ cargo build --release
<snip>
Finished `release` profile [optimized] target(s) in 3m 43s

$ du target/release/uv -h
25M	target/release/uv

I'm seeing a small speedup, too:
hyperfine --prepare "rm -f uv.lock" --warmup 3 --runs 30 "~/projects/uv-main/uv-main lock" "~/projects/uv-main/uv-lto lock"
Benchmark 1: ~/projects/uv-main/uv-main lock
  Time (mean ± σ):     218.1 ms ±   3.6 ms    [User: 217.5 ms, System: 129.5 ms]
  Range (min … max):   212.5 ms … 227.1 ms    30 runs

Benchmark 2: ~/projects/uv-main/uv-lto lock
  Time (mean ± σ):     208.5 ms ±   4.3 ms    [User: 204.8 ms, System: 128.0 ms]
  Range (min … max):   201.7 ms … 222.1 ms    30 runs

related discussion: https://github.com/astral-sh/ruff/issues/9224

Comparing the binary size before and after (starting off in just a simple clone of the repository)

Can you also share final released wheels size (compressed)?

You can use maturin build --release (or even uvx maturin build --release)

I'm supportive of this. Saving on binary size is a win for the registry, CDN, and users. We can always revisit in the future.

I would say I'm somewhat mildly negative on this change, largely for the same reasons I discussed here for ruff: https://github.com/astral-sh/ruff/pull/9031
Building uv already takes a very long time, and doubling its build time for small improvements to binary size and runtime speed doesn't seem like the best trade off to me. Although the improvement to binary size does look pretty good here. Compounded over lots of downloads, that could really add up.
With that said, I'm already using --profile profiling locally when building uv for benchmarking, which is different from the release configuration (but only insomuch as debug symbols aren't stripped). With this change, the configurations differ even more now, with optimizations potentially being different between the builds. This means that when we're doing benchmarking locally, we'll be measuring the thing we aren't actually shipping. It is very difficult for me to estimate just how big of a deal that is. It's probably not a huge deal in the vast majority of circumstances. But it's a concern I have.
I'm not strongly opposed to this change though. So I fine with keeping it for now and evaluating just how much the longer build times annoy us.

The profiling profile inherits from the release one, so I believe it should have lto enabled too (not a cargo expert).

Oof. Right. That needs to be undone. It is not tenable to wait minutes between benchmarking runs IMO. (The compile times are already too long.)

I don't think we need to revert the PR. I think we just need to make the profiling profile not inherit from release.

This change was not tested for all of our release builds unfortunately, it's failing in #5984 — considering reverting to unblock the release and revisiting.

authors: BurntSushi T-256 charliermarsh davfsa konstin zanieb


text:
Negative Wind Gust

The problem
On some of the weatherstations there is a negative value of wind gust (-0.4 m/s). The wind speed an wind direction i ok.
Version of Weatherlink integration having the issue?
2024.4.0b0
Version of Home Assistant Core having the issue?
2024.9.3
Anything in the logs that might be useful for us?
I have 36 stations. 10 of them show -0.4 m/s. 9 of them is 6555 WLIP, 1 is 06558. But I have other 6555 WL IP working.

Diagnostic data file
No response
Additional information
No response

Please get a diagnostic download from the device page when gust is displaying -0.4

/Lennart
Från: Åke Strandberg @.>
Skickat: den 27 september 2024 20:37
Till: astrandb/weatherlink @.>
Kopia: ELJI Elektronik (Lennart Jansson) @.>; Author @.>
Ämne: Re: [astrandb/weatherlink] Negative Wind Gust (Issue #190)
Please get a diagnostic download from the device page when gust is displaying -0.4
—
Reply to this email directly, view it on GitHubhttps://github.com/astrandb/weatherlink/issues/190#issuecomment-2379850631, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AGDTDELZ6OLCMQU5ZDE76ZLZYWQVHAVCNFSM6AAAAABO7FZTS6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNZZHA2TANRTGE.
You are receiving this because you authored the thread.Message ID: @.@.>>

Nothing was attached??

config_entry-weatherlink-5e1848a90fba5e7dd7c3239e5247e36d.json

I sorry not closed

Weatherlink API reports:
"wind_gust_10_min": -1

The value is in mph and is displayed as -0.4 m/s
-1 is obviously an invalid value and should be reported to Davis/Weatherlink. I cannot say if the equipment is sending erroneous data or if the error occurs in the cloud servers.

But the wind gust value is ok in the website weatherlink.com
28 sep. 2024 kl. 10:44 skrev Åke Strandberg @.***>:

Weatherlink API reports:
"wind_gust_10_min": -1
The value is in mph and is displayed as -0.4 m/s
-1 is obviously an invalid value and should be reported to Davis/Weatherlink. I cannot say if the equipment is sending erroneous data or if the error occurs in the cloud servers.
—
Reply to this email directly, view it on GitHubhttps://github.com/astrandb/weatherlink/issues/190#issuecomment-2380569843, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AGDTDEO4D2M6UYQ3OJQBSMTZYZT7XAVCNFSM6AAAAABO7FZTS6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOBQGU3DSOBUGM.
You are receiving this because you modified the open/close state.Message ID: @.***>

Is this behaviour new or has it always been like this?
I can ask developers support how the -1 should be interpreted.

I have submitted the question. They usually answer same day or upcoming business day.

What type of equipment is uploading the  negative gust values?

All of them is Weatherlink IP (6555). But many WLIP is working.
Från: Åke Strandberg @.>
Skickat: den 3 oktober 2024 21:40
Till: astrandb/weatherlink @.>
Kopia: ELJI Elektronik (Lennart Jansson) @.>; State change @.>
Ämne: Re: [astrandb/weatherlink] Negative Wind Gust (Issue #190)
What type of equipment is uploading the negative gust values?
—
Reply to this email directly, view it on GitHubhttps://github.com/astrandb/weatherlink/issues/190#issuecomment-2392190537, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AGDTDEKO4XXCEWZYQ5BCPHLZZWMQFAVCNFSM6AAAAABO7FZTS6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJSGE4TANJTG4.
You are receiving this because you modified the open/close state.Message ID: @.@.>>

My contact at developer support asks for a couple of station-id for stations that show negative values and a couble of correct stations. He got an id from the diagnostic file you posted but it was apparently not conclusive.

Ver 1.1.5 not working
001D0A00A062
001D0A00665B
001D0A001FA7
001D0A0067A1
001D0A001EA0
001D0A006705
001D0A0064BB
001D0A006668
001D0A00ED87
Ver 6.0.0 not working
001D0AE03F72
Ver 1.1.5 working
001D0A002D5B
001D0AE0C462
001D0AF18BFF
001D0AF11151
001D0A001ED6
001D0A001EBA
001D0AE0C461
001D0A001EF1
001D0A00669E
001D0A002D8C
Från: Åke Strandberg @.>
Skickat: den 4 oktober 2024 10:50
Till: astrandb/weatherlink @.>
Kopia: ELJI Elektronik (Lennart Jansson) @.>; State change @.>
Ämne: Re: [astrandb/weatherlink] Negative Wind Gust (Issue #190)
My contact at developer support asks for a couple of station-id for stations that show negative values and a couble of correct stations. He got an id from the diagnostic file you posted but it was apparently not conclusive.
—
Reply to this email directly, view it on GitHubhttps://github.com/astrandb/weatherlink/issues/190#issuecomment-2393177315, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AGDTDEJINRFNGVZKMDPG3DTZZZJB3AVCNFSM6AAAAABO7FZTS6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJTGE3TOMZRGU.
You are receiving this because you modified the open/close state.Message ID: @.@.>>

Got a reply from Davis. It is an inconsistency in the uploading devices. -1 represents no value available and should really be null instead.
I don’t think Davis will fix this bug. These negative values must therefore be handled in the integration.
Which is best? Zero or ”unavailable”? I vote for zero.

Zero
9 okt. 2024 kl. 22:00 skrev Åke Strandberg @.***>:

Got a reply from Davis. It is an inconsistency in the uploading devices. -1 represents no value available and should really be null instead.
I don’t think Davis will fix this bug. These negative values must therefore be handled in the integration.
Which is best? Zero or ”unavailable”? I vote for zero.
—
Reply to this email directly, view it on GitHubhttps://github.com/astrandb/weatherlink/issues/190#issuecomment-2403325219, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AGDTDEPNRCXIKN6U4ZIDNNTZ2WDNLAVCNFSM6AAAAABO7FZTS6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMBTGMZDKMRRHE.
You are receiving this because you modified the open/close state.Message ID: @.***>

@elji-lennart A new beta version is released as v2024.10.0b0 . Can you please verify that the negative gust values are gone and that there are no obvious side-effects.

I have installed and check.
10 okt. 2024 kl. 12:23 skrev Åke Strandberg @.***>:

@elji-lennarthttps://github.com/elji-lennart A new beta version is released as v2024.10.0b0 . Can you please verify that the negative gust values are gone and that there are no obvious side-effects.
—
Reply to this email directly, view it on GitHubhttps://github.com/astrandb/weatherlink/issues/190#issuecomment-2404697255, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AGDTDEIABXYLSE3XTG4ANLLZ2ZIQFAVCNFSM6AAAAABO7FZTS6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMBUGY4TOMRVGU.
You are receiving this because you were mentioned.Message ID: @.***>

I have tested and it seems fine. Unfortunately, it is probably not so good with 0.0 if the highest wind speed is missing. It can be a real value with 0.0 m/s and then it is not possible to distinguish whether it is a real 0 value or whether it is an error. A result "-" or "not avaliable" would probably have been better, but now I have solved it in my application (swedweather.com).
Från: Åke Strandberg @.>
Skickat: den 10 oktober 2024 12:23
Till: astrandb/weatherlink @.>
Kopia: ELJI Elektronik (Lennart Jansson) @.>; Mention @.>
Ämne: Re: [astrandb/weatherlink] Negative Wind Gust (Issue #190)
@elji-lennarthttps://github.com/elji-lennart A new beta version is released as v2024.10.0b0 . Can you please verify that the negative gust values are gone and that there are no obvious side-effects.
—
Reply to this email directly, view it on GitHubhttps://github.com/astrandb/weatherlink/issues/190#issuecomment-2404697255, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AGDTDEIABXYLSE3XTG4ANLLZ2ZIQFAVCNFSM6AAAAABO7FZTS6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMBUGY4TOMRVGU.
You are receiving this because you were mentioned.Message ID: @.@.>>

After considering your thoughts and the answer from Davis I think it better to translate the negative value to None internally. It will then be displayed as "Unknown". Same as for all other observations where the API reports "null" or "None". I will prepare a new beta.

authors: astrandb elji-lennart

repo: astrandb/weatherlink

license: MIT


text:
Startup condition

Fixed the switch to set FUNCTIONAL if the class is a SAM.
Fixed the race condition by converting getFunctional to static.
Preemptively sets the functional_interface_parameter_count in the TypeManage.
Tests now pass

Apparently GitHub doesn't consider it merged when cherry-picked. Either way this seems to have fixed it. Thank you!

No problem.  Just request a review when the PR is ready for inclusion.

authors: Thrameos astrelsky

repo: astrelsky/jpype


text:
Utilize the CheckTxKind to avoid needless execution of immutable steps of check_tx in sequencer

When handling a CheckTx request, we currently ignore the CheckTxKind.  Instead we should ensure that we don't repeat steps unnecessarily if the request indicates it is a recheck rather than a new check.
We can also avoid calling mempool::remove on a tx which fails any of the immutable steps (i.e. tx size check, parsing tx, stateless check, chain ID check), since it cannot exist in the app mempool if it fails these.

No longer an issue in light of recent mempool improvements.

repo: astriaorg/astria


text:
Support sending parameterized SQL queries to Databricks Jobs

Problem statement
Currently the DatabricksWorkflowTaskGroup only supports creating notebook tasks using the DatabricksNotebookOperator. While this feature unlocks all databricks python-based development (and to some extent SQL through spark.sql commands), it does not allow users to take advantage of the Databricks SQL, which would limit the flows that users can create.
To solve this, we should offer support for adding support for sql_task tasks.
sql_task tasks allow databricks to refer to query objects that have been created in the databricks SQL editor. These queries can be parameterized by the user at runtime.

Solving this issue would involve two steps:
The first step is to create a DatabricksSqlQueryOperator that expects a query ID instead of a SQL query.  If run outside of a DatabricksWorkflowTaskgroup, this operator would be able to launch and monitor a SQL task on its own. The second step would be to create a convert_to_databricks_workflow_task to convert the SQL operator task into a workflow task.
For this task to be completed, a SQL query should be added to the example DAG and should run through CI/CD.

Moved to the Databricks repo: https://github.com/astronomer/astro-provider-databricks/issues/26

authors: dimberman jlaneve

repo: astronomer/astronomer-cosmos


text:
Build ExternalDeploymentTaskSensor

Relevant link : https://astronomer.slack.com/archives/C0387PMM2E7/p1659556447204159

Based on the slack conversation, @pohek321 tried using the HttpSensorAsync and pass the response_check lambda function to check for the state he expected to behave as async task, In HttpSensorAsync if we pass response_check, it behaves as sync version of HTTP sensor.
So this ExternalDeploymentTaskSensor task is to check for the upstream deployment task is in completed state, waits until the task is "running" and mark the task as failed if the task is not in "success" state.

Completed Dev code part, writing test case

repo: astronomer/astronomer-providers


text:
Slack and Teams on_x_callbacks

Is your feature request related to a problem? Please describe.
Airflow users often want to either alert for DAG or Task success or failure. Examples for this are plentiful but still require a lot of "roll it yourself"
Describe the solution you'd like
I would like to advise something like
import providers.alerts.slack_notification

with DAG(
  on_failure_callback=slack_notification(channel="xyz", conn_id="abc")
):

or
BashOperator(
  ...,
  on_failure_callback=slack_notification(channel="xyz", conn_id="abc")
)

with sensible defaults and simple (enough) setup.
Being able to pass in a message is a bonus.
Having a default message that gives links to the task, maybe lineage, and failure task logs would be best.

on_failure_callback expect python callable (i.e python function) what about directly calling using the slack operator in the on_failure_callback callable function?
def slack_notification(...)
    SlackWebhookOperator(...).execute(context=None)

with DAG(
  on_failure_callback=slack_notification
):

or expectation is to have some function wrapper over these notification operators?

@pankajastro - I imagine the function signature would be slack_notification(channel: str, conn_id: str) -> Callable[Context] - so takes some configuration and returns the callable

@fritz-astronomer Since Airflow has a notifier feature does it still relevant?
https://airflow.apache.org/docs/apache-airflow/2.6.0/howto/notifications.html#using-a-notifier
https://github.com/apache/airflow/tree/main/airflow/providers/slack/notifications

No :/ not really. Airflow does need a teams notifier though :)

We introduced apprise notifier  https://github.com/apache/airflow/pull/31533 that should handle ms team.

closing this in favour of the Airflow notifier feature.

authors: fritz-astronomer pankajastro


text:
Support reading a file to pyarrow table in catalog import

Change Description
This is related to issue #351, but does not close it.
Allows the InputReader read method to return a pyarrow Table, instead of a Pandas dataframe. Pandas dataframes are converted to pyarrow tables, and all manipulation after that point is based on pyarrow operations.
This means that tables generated will NOT have the _hipscat_index field set as the pandas index. This PR should not be merged until LSDB can support these tables, via fixing https://github.com/astronomy-commons/lsdb/issues/67

Being replaced by https://github.com/astronomy-commons/hats-import/pull/415

repo: astronomy-commons/hats-import


text:
screenshot() on ArchLinux in Python 3.6 not overwriting existing file

If I enter a filename, it takes a screenshot just fine. But if I take another screenshot with the same filename, it doesn't overwrite the existing one, instead it creates a new one with a filename like "Blabla_000.png".
I've read that it uses Scrot on Linux, and that Scrot has "overwrite" disabled as default.
But I've run "Scrot -o" in terminal, which according to its description, would turn "overwriting" on, but it's still not doing so for me.

The code you're interested in is in https://github.com/asweigart/pyscreeze, there is a function _screenshot_linux and it doesn't pass -o flag.

The code you're interested in is in https://github.com/asweigart/pyscreeze, there is a function _screenshot_linux and it doesn't pass -o flag.

Thanks a lot, it works now as intended! My mistake was that I was only looking into files from PyAutoGui, which obviously isn't the source to the function in question.

authors: EgZvor MasterChenSensei

repo: asweigart/pyautogui

license_source: bigquery


text:
"presses" arg of press function in keyboard.rst

Mention the possibility of use presses argument instead of array with repeated same word in keyboard.rst file.

Thanks!

authors: asweigart hugoesb