An exact decimal is a decimal.Decimal - #42
Merged
Merged
Conversation
The engine grew a decimal at ABI 0.15: an i128 of unscaled units and a
scale, reachable today through CAST('1.20' AS DECIMAL(5, 2)). Python
already has the type for it, so this hands one over as a
decimal.Decimal and takes one back as a parameter.
Not a float, which is the whole reason the engine has the type. A tenth
is not a binary fraction, and a price read into a float is not the
price. Built from the engine's own spelling rather than from the digits
and the scale, because Decimal("1.20") is the one constructor exact for
both, and read back through format(d, "f") rather than str(d), because
Python prints some decimals with an exponent and Decimal("1E+2") is a
hundred at no places rather than a one at two of them.
A parameter that is not an exact number is refused at the call and says
which: a NaN or an infinity is not a number the engine holds, thirty
eight digits is the widest DECIMAL(p, s) takes, and a scale past that
is a point further right than a column could declare. Failing there is
the point, since a decimal that quietly became a float would be a query
comparing a price against something that is not it.
The type check runs before the integer and the float arms, since a
Decimal is neither and would otherwise go through extract::<f64>, which
is the loss the caller picked the type to avoid.
NUMBER in the DB-API module now covers it, because PEP 249 puts every
numeric column under NUMBER and a decimal is one. The conformance
runner learned to print and compare decimals with the scale as well as
the number, since two decimals of one number at two scales are equal to
Python and print differently. DECIMAL stays a reserved name a case may
not write, matching the reference runner.
Three git dependencies point at the engine and the lock records the revision each of them resolved to, so a pin that moves without it is a build that fetches one commit and records another.
pyo3 0.29 renamed the downcast family to cast, which is what the rest of this crate already calls. The decimal type object was the one place still spelling it the old way, and it did not compile.
The api gate compares the public surface against main and lets a change through once the version has moved, which is the same rule the engine gets from cargo semver-checks and the TypeScript client gets from its committed report. Two names moved here: Value now admits a decimal.Decimal and NUMBER now counts one as a number. Both are additions rather than removals, and both are still the surface changing, so the version moves with them. The wheel test that wanted two versions out of one build now wants 0.0.2 and 0.0.3, since 0.0.2 is no longer a version this project is not.
A Windows runner came in at 20.3 ms against a ceiling of 20, and the module that put it there is decimal, which costs about four milliseconds and is now imported at package scope because Value names decimal.Decimal. The alternative was to import it only for a type checker and leave the union as a string, which is cheaper and worse: Value stops being a real object, and every annotation that mentions it stops resolving under get_type_hints. The engine grew an exact decimal, so the package grew a module, and the ceiling says so.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The engine grew a decimal at ABI 0.15: an i128 of unscaled units and a scale, reachable today through
CAST('1.20' AS DECIMAL(5, 2)). Python already has the type for it, so this hands one over as adecimal.Decimaland takes one back as a parameter.Not a
float, which is the whole reason the engine has the type. A tenth is not a binary fraction, and a price read into afloatis not the price.Built from the engine's own spelling rather than from the digits and the scale, because
Decimal("1.20")is the one constructor that is exact for both. Read back throughformat(d, "f")rather thanstr(d), because Python prints some decimals with an exponent andDecimal("1E+2")is a hundred at no places rather than a one at two of them.A parameter that is not an exact number is refused at the call and says which: a NaN or an infinity is not a number the engine holds, thirty eight digits is the widest
DECIMAL(p, s)takes, and a scale past that is a point further right than a column could declare. Failing there is the point, since a decimal that quietly became a float would be a query comparing a price against something that is not it.The type check runs before the integer and the float arms, since a
Decimalis neither and would otherwise go throughextract::<f64>, which is the loss the caller picked the type to avoid.NUMBERin the DB-API module now covers it, because PEP 249 puts every numeric column under NUMBER and a decimal is one. The conformance runner learned to print and compare decimals with the scale as well as the number, since two decimals of one number at two scales are equal to Python and print differently. DECIMAL stays a reserved name a case may not write, matching the reference runner.The engine pin moves to
cfdc70f291719309b96a8300dc8425154d0fd5d5.