Skip to content

Conversation

@btangmu
Copy link
Member

@btangmu btangmu commented Nov 25, 2025

-Revise ldml.dtd to allow numberSystem attribute for currency element

-Delete the (disabled) check for numberSystem in CheckNumbers.java

-Update attributeOrderGrandfathered, for currency, allow numberSystem after references

CLDR-18963

  • This PR completes the ticket.

ALLOW_MANY_COMMITS=true

-Revise ldml.dtd to allow numberSystem attribute for currency element

-Delete the (disabled) check for numberSystem in CheckNumbers.java
@btangmu btangmu self-assigned this Nov 25, 2025
-Move numberSystem after references and validSubLocales
@btangmu
Copy link
Member Author

btangmu commented Nov 25, 2025

I think this PR is between essentially the same rock and hard place as the previous PR (#5149). Here we're adding numberSystem for currency not for pattern, but otherwise it's the same problem.

Per testAttributeOrder status (distinguished before value before metadata), we need numberSystem (distinguished) before draft (metadata). See:

public enum AttributeStatus {
    distinguished("§d"),
    value("§v"),
    metadata("§m︎");

But, per MergeLists, we need draft before numberSystem for consistency with, e.g.,

<!ELEMENT decimal ( #PCDATA ) >
<!ATTLIST decimal alt NMTOKENS #IMPLIED >
    <!--@MATCH:literal/variant, us, official-->
<!ATTLIST decimal draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
    <!--@METADATA-->
    <!--@DEPRECATED:true, false-->
<!ATTLIST decimal references CDATA #IMPLIED >
    <!--@METADATA-->
<!ATTLIST decimal numberSystem CDATA #IMPLIED >
    <!--@MATCH:bcp47/nu-->

A most ingenious paradox.

@btangmu btangmu marked this pull request as ready for review November 25, 2025 20:20
@btangmu btangmu requested a review from macchiati November 25, 2025 20:20
@macchiati
Copy link
Member

A refinement of my previous advice.

The order is vital among distinguishing attributes (no @metadata and no @value) and @value attributes, but not with @metadata attributes. So you can move the @metadata items (keeping their same relative order) to the end of the items.

@macchiati
Copy link
Member

It is still good that we tripped across this in the first PR, because having (optional) numberSystem attributes for currency elements is the better structure.

@btangmu
Copy link
Member Author

btangmu commented Nov 26, 2025

move the @metadata items (keeping their same relative order) to the end of the items

I've just tried that locally. Starting with

<!ATTLIST currency type NMTOKEN "standard" >
    <!--@MATCH:validity/currency-->
<!ATTLIST currency alt NMTOKENS #IMPLIED >
    <!--@MATCH:literal/variant-->
<!ATTLIST currency draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
    <!--@METADATA-->
    <!--@DEPRECATED-->
<!ATTLIST currency references CDATA #IMPLIED >
    <!--@METADATA-->
<!ATTLIST currency validSubLocales CDATA #IMPLIED >
    <!--@VALUE-->
    <!--@DEPRECATED-->

The item to be added is

<!ATTLIST currency numberSystem CDATA #IMPLIED >
    <!--@MATCH:bcp47/nu-->

The two metadata items to be moved are draft and references. So I have tried this:

<!ATTLIST currency type NMTOKEN "standard" >
    <!--@MATCH:validity/currency-->
<!ATTLIST currency alt NMTOKENS #IMPLIED >
    <!--@MATCH:literal/variant-->
<!ATTLIST currency validSubLocales CDATA #IMPLIED >
    <!--@VALUE-->
    <!--@DEPRECATED-->
<!ATTLIST currency numberSystem CDATA #IMPLIED >
    <!--@MATCH:bcp47/nu-->
<!ATTLIST currency draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
    <!--@METADATA-->
    <!--@DEPRECATED-->
<!ATTLIST currency references CDATA #IMPLIED >
    <!--@METADATA-->

The test result is:

java.lang.IllegalArgumentException: Inconsistent requested ordering: cannot merge if we have [...A...B...] and [...B...A...]: {references=[draft, references], standard=[draft, standard, references, validSubLocales], validSubLocales=[draft, standard, references, validSubLocales], numberSystem=[draft, validSubLocales, numberSystem], draft=[validSubLocales, numberSystem, draft, references]}
	at org.unicode.cldr.util.MergeLists.merge(MergeLists.java:68)

That is:

references     =[draft, references]
standard       =[draft, standard, references, validSubLocales]
validSubLocales=[draft, standard, references, validSubLocales]
numberSystem   =[draft, validSubLocales, numberSystem]
draft          =[validSubLocales, numberSystem, draft, references]

Meaning, I think, that MergeLists won't accept validSubLocales before draft since elsewhere there is validSubLocales after draft. Am I understanding your instructions and the result correctly?

It would help if the algorithm and error reporting of MergeLists were less mysterious. Would it be worthwhile to add some comments and debugging output to make it unambiguous what A and B are in "cannot merge if we have [...A...B...] and [...B...A...]"? Here it seems A and B could be validSubLocales and draft, or draft and numberSystem, or references and validSubLocales...

@macchiati
Copy link
Member

macchiati commented Nov 27, 2025 via email

@btangmu
Copy link
Member Author

btangmu commented Nov 28, 2025

leave validSubLocales where it was

Then I still get:

Caused by: java.lang.IllegalArgumentException: Inconsistent requested ordering: cannot merge if we have [...A...B...] and [...B...A...]: {references=[draft, references], standard=[draft, standard, references, validSubLocales], validSubLocales=[draft, standard, references, validSubLocales], numberSystem=[draft, validSubLocales, numberSystem], draft=[numberSystem, draft, references, validSubLocales]}
	at org.unicode.cldr.util.MergeLists.merge(MergeLists.java:68)

That is,

references     =[draft, references]
standard       =[draft, standard, references, validSubLocales]
validSubLocales=[draft, standard, references, validSubLocales]
numberSystem   =[draft, validSubLocales, numberSystem]
draft          =[numberSystem, draft, references, validSubLocales]

The position of validSubLocales is different in the last part of the error message but the essential problem remains for other A, B versus B, A.

srl295
srl295 previously approved these changes Nov 29, 2025
@macchiati
Copy link
Member

The ordering of attributes within elements is controlled by a global MapComparator across all elements with a given DTD, to save having to have individual attribute comparators for each element. That MapComparator created using MergeLists, which merges the attributes based on their ordering in the DTD file. MergeLists also enforces that there are no cycles among elements; for example, you can’t have:

element1: attributeA < attributeB
element2: attributeB < attributeC
element3: attributeC < attributeA

The order of attributes should always be

  1. Distinguishing
  2. Value
  3. Metadata

There is a test for that, but for backwards compatibility there is an exception list. So we retain the ‘bad’ order if we have to (by updating the exception list)

I took a look, and numberSystem is almost always after draft and references. So for currency let's move it before validSubLocales, and adjust the exception list in the failing test.

@btangmu
Copy link
Member Author

btangmu commented Dec 2, 2025

numberSystem is almost always after draft and references. So for currency let's move it before validSubLocales, and adjust the exception list in the failing test.

By "exception list" I think you mean attributeOrderGrandfathered. I'll try that. Note that the earlier PR used attributeOrderGrandfathered (#5149).

-For currency, allow numberSystem after references
@btangmu
Copy link
Member Author

btangmu commented Dec 2, 2025

I think you mean attributeOrderGrandfathered

That works. The tests are now passing.

Note that currency needs to be after validSubLocales to satisfy MergeLists ("cannot merge if we have [...A...B...] and [...B...A...]"), which has no exception list.

Copy link
Member

@macchiati macchiati left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one remaining issue

}
}

// Check that symbols are for an explicit number system;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this being dropped? We still want to ensure that .../symbols has a numberSystem.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake! I confused this section with the one below that's deleted. I'll fix that now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by the 5th commit.

@macchiati
Copy link
Member

Also, we will need documentation in the spec (doesn't have to be this PR, but the ticket can't be closed until that is done).

@btangmu btangmu requested a review from macchiati December 3, 2025 16:18
}
XPathParts parts = XPathParts.getFrozenInstance(path);

// TODO: re-enable this commented-out check
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm. Rather than disable the following for all cases in order for currency to have it be optional, we probably want to just disable it for currency. Sorry, should have caught this earlier.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just disable it for currency

Done in the 6th commit

-Restore the long-ago disabled check but skip for NumericType.CURRENCY
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants