Identifiers: the format error reads 'a ORCID identifier', and its code exists twice #645

Closed
opened 2026-10-01 10:48:37 +00:00 by tiagoagueda · 0 comments
Owner

Found on 2026-09-29 in a read-only review of postulo at 95348908d, running clean with a malformed value for every shipped scheme and comparing the two identifier modules.

Checked again on 2026-10-01 against main at 0a5cad587: still present. accounts/identifiers.py and jobs/identifiers.py are unchanged; core/identifiers.py gained the rows' one-of-each-kind rule (#307) and still holds none of the four functions.

The message for a malformed identifier puts the scheme's label after a fixed article and before the word "identifier". Several shipped labels do not fit that sentence. The sentence, and the four functions around it, exist in two modules that are the same code with PERSON swapped for COMPANY, although both module docstrings say the second copy of the machinery is gone.

  • Where: accounts/identifiers.py:81 and jobs/identifiers.py:82 (the message); accounts/identifiers.py:63-100 and jobs/identifiers.py:65-101 (normalise, validate, clean, url_for); the docstrings at accounts/identifiers.py:12-16 and jobs/identifiers.py:8-12.

  • What happens: run against the snapshot, a value of the wrong shape gives:

    • "That does not look like a ORCID identifier (for example 0000-0002-1825-0097)."
    • "That does not look like a ISNI identifier (for example 0000 0001 2281 955X)."
    • "That does not look like a OpenCorporates identifier (for example gb/01234567)."
    • "That does not look like a Legal Entity Identifier (LEI) identifier (for example HWUPKR0MPOU8FGXBT394)."
    • "That does not look like a Company register number identifier (for example PT 501234567, FR 552081317, DE HRB 12345)."
    • "That does not look like a Other identifier (for example a staff number, a national registration)." This one needs a value a text box cannot hold (a line break inside it), so it is met through the API or an import, not by typing.

    A person meets the first five by mistyping an ORCID on Your details or an LEI on a company's form. Every catalogue translates the same frame, so a translator can move the label but cannot make it agree with an article or a case.

    The four functions in the two modules compare equal once the subject constant is replaced (checked by comparing their syntax trees). A change to the message or to the order of the checks has to be made twice, and nothing fails when it is made once.

  • Why it matters: the sentence a person reads when they mistype their ORCID is ungrammatical, and the duplication is the kind the registry of #109 was written to remove. #311 lets an administrator define schemes with labels of their own, which will go through the same frame.

  • Fix: word the message so the label needs neither an article nor a trailing noun, for example _("%(scheme)s: that is not the usual form (for example %(example)s)."), or give Scheme a format_message beside its checksum_message. Move normalise, validate, clean and url_for into core/identifiers.py with a subject argument, and leave the two modules as the views they describe: each passes PERSON or COMPANY. tests/test_identifiers.py:261 asserts the words "does not look like a" and changes with the message. The reworded string changes one entry in every catalogue.

Done when

  • tests/test_identifier_registry.py checks, for every scheme in the registry and both subjects, that the format error contains neither "a " followed by the label nor the label followed by " identifier", and that it names the scheme and its example.
  • accounts/identifiers.py and jobs/identifiers.py hold no ValidationError of their own; a test in tests/test_identifier_registry.py asserts that both modules' validate raise the same message for the same malformed ISNI.
Found on 2026-09-29 in a read-only review of postulo at 95348908d, running `clean` with a malformed value for every shipped scheme and comparing the two identifier modules. Checked again on 2026-10-01 against `main` at `0a5cad587`: still present. `accounts/identifiers.py` and `jobs/identifiers.py` are unchanged; `core/identifiers.py` gained the rows' one-of-each-kind rule (#307) and still holds none of the four functions. The message for a malformed identifier puts the scheme's label after a fixed article and before the word "identifier". Several shipped labels do not fit that sentence. The sentence, and the four functions around it, exist in two modules that are the same code with `PERSON` swapped for `COMPANY`, although both module docstrings say the second copy of the machinery is gone. - **Where:** `accounts/identifiers.py:81` and `jobs/identifiers.py:82` (the message); `accounts/identifiers.py:63-100` and `jobs/identifiers.py:65-101` (`normalise`, `validate`, `clean`, `url_for`); the docstrings at `accounts/identifiers.py:12-16` and `jobs/identifiers.py:8-12`. - **What happens:** run against the snapshot, a value of the wrong shape gives: - "That does not look like a ORCID identifier (for example 0000-0002-1825-0097)." - "That does not look like a ISNI identifier (for example 0000 0001 2281 955X)." - "That does not look like a OpenCorporates identifier (for example gb/01234567)." - "That does not look like a Legal Entity Identifier (LEI) identifier (for example HWUPKR0MPOU8FGXBT394)." - "That does not look like a Company register number identifier (for example PT 501234567, FR 552081317, DE HRB 12345)." - "That does not look like a Other identifier (for example a staff number, a national registration)." This one needs a value a text box cannot hold (a line break inside it), so it is met through the API or an import, not by typing. A person meets the first five by mistyping an ORCID on *Your details* or an LEI on a company's form. Every catalogue translates the same frame, so a translator can move the label but cannot make it agree with an article or a case. The four functions in the two modules compare equal once the subject constant is replaced (checked by comparing their syntax trees). A change to the message or to the order of the checks has to be made twice, and nothing fails when it is made once. - **Why it matters:** the sentence a person reads when they mistype their ORCID is ungrammatical, and the duplication is the kind the registry of #109 was written to remove. #311 lets an administrator define schemes with labels of their own, which will go through the same frame. - **Fix:** word the message so the label needs neither an article nor a trailing noun, for example `_("%(scheme)s: that is not the usual form (for example %(example)s).")`, or give `Scheme` a `format_message` beside its `checksum_message`. Move `normalise`, `validate`, `clean` and `url_for` into `core/identifiers.py` with a `subject` argument, and leave the two modules as the views they describe: each passes `PERSON` or `COMPANY`. `tests/test_identifiers.py:261` asserts the words "does not look like a" and changes with the message. The reworded string changes one entry in every catalogue. ## Done when - `tests/test_identifier_registry.py` checks, for every scheme in the registry and both subjects, that the format error contains neither "a " followed by the label nor the label followed by " identifier", and that it names the scheme and its example. - `accounts/identifiers.py` and `jobs/identifiers.py` hold no `ValidationError` of their own; a test in `tests/test_identifier_registry.py` asserts that both modules' `validate` raise the same message for the same malformed ISNI.
tiagoagueda added this to the 0.6.0 milestone 2026-10-01 10:48:37 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#645
No description provided.