Europass import: an untitled entry keeps 80 characters of its text, and skills past forty are dropped, without a note #640

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

Found on 2026-09-29 in a read-only review of postulo at 95348908d, reading the three Europass readers and running each on a file with an untitled entry and 55 skills under one heading.

The reader's stated rule is that a file "imports the half that is right and says what it skipped" (plugins/europass/reader.py:50-52), and the wiki's Your career record says the review page lists what could not be read "so nothing goes missing quietly". Three places cut content and say nothing, so the person confirms an import believing it is complete.

Checked again on 2026-10-01 against main at 0a5cad587: still present. _project_from is now at plugins/europass/common.py:113-116, and the cuts in reader.py at :468 and :738.

1. An entry with a description and no title loses everything after 80 characters

  • Where: plugins/europass/reader.py:222-225 (_project_from): return {"name": title or description[:80], "summary": description if title else ""}. Called for the old formats' achievements (:601, :870) and for the Candidate format's projects and custom sections (plugins/europass/candidate.py:606, :614).
  • What happens: an achievement, project or custom-section entry with a paragraph and no title becomes a project whose name is the first 80 characters, cut mid-word, with an empty summary. A 145-character description came back as {'name': 'Wrote the migration plan for the billing platform and led the cut-over across th', 'summary': ''} from all three readers, with record.skipped empty. Project.name holds 200 characters and Project.summary has no limit.
  • Fix: with no title, keep the whole description as the summary and take the name from its first line, shortened at a word boundary.

2. A heading's skills past the fortieth are dropped

  • Where: plugins/europass/reader.py:592 and :862, plugins/europass/candidate.py:574, :585 and :599: lines[:40] / skills[:40].
  • What happens: 55 lines under Computer in the old formats, or 55 DigitalSkill elements in the Candidate format, give 40 skills and an empty record.skipped. The review page shows the count that was kept, which the person has no reason to doubt.
  • Fix: where a list is cut, append a sentence to record.skipped that names the heading and says how many were left out. Or drop the cap: the upload is already limited to MAX_IMPORT_BYTES.

3. In the JSON reader a Skills block of the wrong shape is ignored without the note the other sections get

  • Where: plugins/europass/reader.py:834-862 (_read_json_skills). WorkExperience, Education and Achievement go through _readable (:741-752), which adds "… was in the file but could not be read."; Skills and its headings do not.
  • What happens: "Skills": "a string", "Computer": "Python; Django" or "Computer": ["Python"] reads as no skills at all, with nothing in record.skipped.
  • Fix: run Skills, Linguistic and each heading under them through _readable.

Why it matters: the import only ever adds, so the person's file is the only place the missing text still exists, and nothing tells them to look there. The same quiet cut happens once more downstream, where resume/importing.py:247 stores name[:100] for a skill; a note in Report.skipped would cover it.

Done when

  • A test in tests/test_europass.py reads an old-format file whose achievement has a 145-character description and no title, and finds the whole description in the project's summary. A test in tests/test_europass_candidate.py does the same for an Other entry. Both fail today.
  • A test in each of those files reads 55 skills under one heading and finds either 55 skills or a sentence in record.skipped that says 15 were left out.
  • A test in tests/test_europass.py reads a JSON file whose Skills is a string and finds a "could not be read" sentence in record.skipped.
Found on 2026-09-29 in a read-only review of postulo at 95348908d, reading the three Europass readers and running each on a file with an untitled entry and 55 skills under one heading. The reader's stated rule is that a file "imports the half that is right and says what it skipped" (`plugins/europass/reader.py:50-52`), and the wiki's *Your career record* says the review page lists what could not be read "so nothing goes missing quietly". Three places cut content and say nothing, so the person confirms an import believing it is complete. Checked again on 2026-10-01 against `main` at `0a5cad587`: still present. `_project_from` is now at `plugins/europass/common.py:113-116`, and the cuts in `reader.py` at `:468` and `:738`. ## 1. An entry with a description and no title loses everything after 80 characters - **Where:** `plugins/europass/reader.py:222-225` (`_project_from`): `return {"name": title or description[:80], "summary": description if title else ""}`. Called for the old formats' achievements (`:601`, `:870`) and for the Candidate format's projects and custom sections (`plugins/europass/candidate.py:606`, `:614`). - **What happens:** an achievement, project or custom-section entry with a paragraph and no title becomes a project whose name is the first 80 characters, cut mid-word, with an empty summary. A 145-character description came back as `{'name': 'Wrote the migration plan for the billing platform and led the cut-over across th', 'summary': ''}` from all three readers, with `record.skipped` empty. `Project.name` holds 200 characters and `Project.summary` has no limit. - **Fix:** with no title, keep the whole description as the summary and take the name from its first line, shortened at a word boundary. ## 2. A heading's skills past the fortieth are dropped - **Where:** `plugins/europass/reader.py:592` and `:862`, `plugins/europass/candidate.py:574`, `:585` and `:599`: `lines[:40]` / `skills[:40]`. - **What happens:** 55 lines under *Computer* in the old formats, or 55 `DigitalSkill` elements in the Candidate format, give 40 skills and an empty `record.skipped`. The review page shows the count that was kept, which the person has no reason to doubt. - **Fix:** where a list is cut, append a sentence to `record.skipped` that names the heading and says how many were left out. Or drop the cap: the upload is already limited to `MAX_IMPORT_BYTES`. ## 3. In the JSON reader a `Skills` block of the wrong shape is ignored without the note the other sections get - **Where:** `plugins/europass/reader.py:834-862` (`_read_json_skills`). `WorkExperience`, `Education` and `Achievement` go through `_readable` (`:741-752`), which adds "… was in the file but could not be read."; `Skills` and its headings do not. - **What happens:** `"Skills": "a string"`, `"Computer": "Python; Django"` or `"Computer": ["Python"]` reads as no skills at all, with nothing in `record.skipped`. - **Fix:** run `Skills`, `Linguistic` and each heading under them through `_readable`. **Why it matters:** the import only ever adds, so the person's file is the only place the missing text still exists, and nothing tells them to look there. The same quiet cut happens once more downstream, where `resume/importing.py:247` stores `name[:100]` for a skill; a note in `Report.skipped` would cover it. ## Done when - A test in `tests/test_europass.py` reads an old-format file whose achievement has a 145-character description and no title, and finds the whole description in the project's `summary`. A test in `tests/test_europass_candidate.py` does the same for an `Other` entry. Both fail today. - A test in each of those files reads 55 skills under one heading and finds either 55 skills or a sentence in `record.skipped` that says 15 were left out. - A test in `tests/test_europass.py` reads a JSON file whose `Skills` is a string and finds a "could not be read" sentence in `record.skipped`.
tiagoagueda added this to the 0.6.0 milestone 2026-10-01 10:48:35 +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#640
No description provided.