Repository navigation
Conversation
b0f3e13 to
8eddc7e
Compare
8eddc7e to
9daa784
Compare
9daa784 to
a844295
Compare
A UID is 32 hex characters, and the code declared that in two incompatible ways. UIDReferenceField used ASCIILine, which under Python 2 means a native string, while the datagrid rows of AnalysisProfile, SampleTemplate and WorksheetTemplate used TextLine, which means unicode. The same value was therefore right in one place and wrong in the next, and which of the two arrived depended on nothing but the route: a JSON body carries unicode, code running in the process carries what the catalog holds. One field type now, UIDField, used for the value type of UIDReferenceField and for the uid of each of those rows. It takes both, because both are already stored and because refusing one would turn how a value arrived into a WrongContainedType on a field the caller never mentioned. What is stored is the native string. That is what plone.uuid makes, it is what the object keeps under _plone.uuid, it is what UID() hands out and what the uid catalog is indexed with, so a reference stored as text would differ in type from the thing it points at. Nothing has to be converted: the two compare and hash alike under Python 2, and an object written again is written in the one shape. Both fields normalize where they store, not where they are called from. zope.schema never asks a subfield to store anything, so the rows of a datagrid go in as they came; the three fields holding them are DataGridField now, which has somewhere to put that. The field also refuses a value that is not a UID, which is what UIDReferenceField has always done for the UIDs it holds itself. A UID inside a datagrid row had nothing checking it: a record with a made-up uid passed the setter's type check and was stored, and the API answered that the object had been created. It is refused now.
a844295 to
a99dbf9
Compare
|
Force-pushed a correction.
That broke the edit form of every Dexterity type holding a
|
|
Cross-reference: #3049 touches the same two files and is independent of this one, in either merge order. This pull request changes the field types of a sample template's service record; #3049 changes what the setters write into it. Between them a record has two sub-fields in the wrong type, and they fix one each: The |
A UID is 32 hex characters, and the code declares that in two incompatible ways. The same value is therefore right in one place and wrong in the next, and the complaint arrives as a
WrongContainedTypeon the whole object, far from the value that caused it.Description of the issue/feature this PR addresses
Two declarations for one thing:
SampleTemplateandWorksheetTemplatedeclare their rows likeAnalysisProfile.Which spelling arrives depends on nothing but the route. A JSON body carries unicode; code running in the process carries what the catalog holds, which is a native string. Both directions have been hit: a spec composed in process stored native strings into the profile rows and the object stopped validating, and a UID that came in over the JSON API as unicode did the same to an analysis category.
And nothing checked that a UID in a datagrid row is a UID at all.
Current behavior before PR
A row with a made-up UID passes the setter's type check and is stored, and the API reports success:
Desired behavior after PR is merged
One field type,
UIDField, exported fromsenaite.core.schemalike its neighbours and used for the value type ofUIDReferenceFieldand for theuidof each of those rows. It takes both spellings, because both are already stored, and refuses a value that is not a UID:What is stored is the native string, and the writers normalize to it:
The same request as above is now refused with
{"services": "WrongContainedType"}.Migration
None, and deliberately so.
The field only widens what it accepts, so everything that validated before still validates and no stored value becomes invalid. The two spellings compare and hash alike under Python 2, and the uid catalog finds an object under either, which was checked rather than assumed:
An object written again is written in the one shape, so the mixture clears itself as sites are used. There is nothing for an upgrade step to convert and the profile version is untouched.
Verification
bin/test-senaite -s senaite.core: 229 tests, 0 failures, 0 errors.bin/test-senaite -s senaite.jsonapi: 41 tests, 0 failures, 0 errors.uidreferencefield.txtgained a section covering both spellings for the reference field and for a datagrid row, the native string that comes back out, the portal's own0, a value that is not a UID, and one that is not ASCII at all.I confirm I have tested the PR thoroughly and coded it according to PEP8 standards.