Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Remove pint dependency from Datasette 1.0 #2400

Closed
simonw opened this issue Aug 21, 2024 · 3 comments
Closed

Remove pint dependency from Datasette 1.0 #2400

simonw opened this issue Aug 21, 2024 · 3 comments

Comments

@simonw
Copy link
Owner

simonw commented Aug 21, 2024

Pint still hasn't made itself compatible with Python 3.13. More importantly, the functionality that it supports in Datasette (unit conversions) is not at all widely used, and adds up to some gnarly complexity in the codebase.

I've decided to remove unit functionality and Pint prior to Datasette 1.0

If there's demand for that functionality to come back I'd like to do that as a plugin, adding extra plugin hooks if needed to support it. Those hooks could be added in a post 1.0 version without breaking backwards compatibility, so I don't think we need to solve those prior to the 1.0 release.

@simonw
Copy link
Owner Author

simonw commented Aug 21, 2024

Some relevant parts of the code and docs:

datasette/docs/metadata.rst

Lines 267 to 277 in d444b6a

Units are interpreted using Pint_, and you can see the full list of available units in
Pint's `unit registry`_. You can also add `custom units`_ to the metadata, which will be
registered with Pint:
.. [[[cog
metadata_example(cog, {
"custom_units": [
"decibel = [] = dB"
]
})
.. ]]]

elif column in table_config.get("units", {}) and value != "":
# Interpret units using pint
value = value * ureg(table_config["units"][column])
# Pint uses floating point which sometimes introduces errors in the compact
# representation, which we have to round off to avoid ugliness. In the vast
# majority of cases this rounding will be inconsequential. I hope.
value = round(value.to_compact(), 6)
display_value = markupsafe.Markup(f"{value:~P}".replace(" ", " "))

filters = Filters(sorted(filter_args), units, ureg)

def convert_unit(self, column, value):
"""If the user has provided a unit in the query, convert it into the column unit, if present."""
if column not in self.units:
return value
# Try to interpret the value as a unit
value = self.ureg(value)
if isinstance(value, numbers.Number):
# It's just a bare number, assume it's the column unit
return value
column_unit = self.ureg(self.units[column])
return value.to(column_unit).magnitude

@simonw
Copy link
Owner Author

simonw commented Aug 21, 2024

Look for ureg and units.

@simonw
Copy link
Owner Author

simonw commented Aug 21, 2024

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

No branches or pull requests

1 participant