From b5fa826d71d852774e5f702eefc33e2808723743 Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Wed, 8 Oct 2025 10:24:08 -0600 Subject: [PATCH 01/10] Change reviewers field to be optional --- src/pyosmeta/models/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyosmeta/models/base.py b/src/pyosmeta/models/base.py index 374b0e6..64356a4 100644 --- a/src/pyosmeta/models/base.py +++ b/src/pyosmeta/models/base.py @@ -256,7 +256,7 @@ class ReviewModel(BaseModel): categories: Optional[list[str]] = None editor: ReviewUser | list[ReviewUser] | None = None eic: ReviewUser | list[ReviewUser] | None = None - reviewers: list[ReviewUser] = Field(default_factory=list) + reviewers: list[ReviewUser] | None = None archive: str | None = None version_accepted: str | None = None date_accepted: str | None = Field( From f73cf0c095811f2fd4b372fd71c04e7f3700cc2a Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:06:41 -0600 Subject: [PATCH 02/10] Modify get_contributor_data return type to include None Update get_contributor_data method to return None when no models are found. --- src/pyosmeta/parse_issues.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pyosmeta/parse_issues.py b/src/pyosmeta/parse_issues.py index 77f4a9b..9458f70 100644 --- a/src/pyosmeta/parse_issues.py +++ b/src/pyosmeta/parse_issues.py @@ -340,7 +340,7 @@ def parse_issues( def get_contributor_data( self, line: str - ) -> Union[ReviewUser, List[ReviewUser]]: + ) -> Union[ReviewUser, List[ReviewUser], None]: """Parse names for various review roles from issue metadata. Parameters @@ -360,6 +360,8 @@ def get_contributor_data( models = [model for model in models if model is not None] if len(models) == 1: models = models[0] + if len(models) == 0: + return None return models # TODO: This now returns a dict of owner:repo_name to support graphql From 2972e450f886768dd421cbd5aed067200c01dcaa Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:10:54 -0600 Subject: [PATCH 03/10] Add check for empty GitHub username and name return None instead of trying to instantiate a ReviewUser --- src/pyosmeta/utils_parse.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pyosmeta/utils_parse.py b/src/pyosmeta/utils_parse.py index b3b0eb5..43d8ee5 100644 --- a/src/pyosmeta/utils_parse.py +++ b/src/pyosmeta/utils_parse.py @@ -45,5 +45,6 @@ def parse_user_names(username: str) -> ReviewUser | None: "github_username": clean_name(names[0]), "name": "", } - + if (parsed["github_username"] == "") and (parsed["name"] == ""): + return None return ReviewUser(**parsed) From d12f6c50540d3392292350e080f4fca79e5ab076 Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Wed, 8 Oct 2025 18:07:34 -0600 Subject: [PATCH 04/10] fix models checking logic --- src/pyosmeta/parse_issues.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pyosmeta/parse_issues.py b/src/pyosmeta/parse_issues.py index 9458f70..b0464b1 100644 --- a/src/pyosmeta/parse_issues.py +++ b/src/pyosmeta/parse_issues.py @@ -358,10 +358,10 @@ def get_contributor_data( users = line.split(",") models = [parse_user_names(username=user) for user in users] models = [model for model in models if model is not None] - if len(models) == 1: - models = models[0] if len(models) == 0: return None + if len(models) == 1: + models = models[0] return models # TODO: This now returns a dict of owner:repo_name to support graphql From 04237a6da24435a39f2585f0948c642e0e86bfdc Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Wed, 8 Oct 2025 18:11:45 -0600 Subject: [PATCH 05/10] debug: hatch run --- src/pyosmeta/parse_issues.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pyosmeta/parse_issues.py b/src/pyosmeta/parse_issues.py index b0464b1..14cbf2a 100644 --- a/src/pyosmeta/parse_issues.py +++ b/src/pyosmeta/parse_issues.py @@ -358,10 +358,10 @@ def get_contributor_data( users = line.split(",") models = [parse_user_names(username=user) for user in users] models = [model for model in models if model is not None] - if len(models) == 0: - return None if len(models) == 1: models = models[0] + if isinstance(models, list) and len(models) == 0: + return None return models # TODO: This now returns a dict of owner:repo_name to support graphql From 6a7b4d5713a345990f258f7d0d953bc0b87ee1a5 Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Thu, 9 Oct 2025 11:46:39 -0600 Subject: [PATCH 06/10] go back to simpler handling of empty models Refactor user model parsing to handle empty lists. --- src/pyosmeta/parse_issues.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pyosmeta/parse_issues.py b/src/pyosmeta/parse_issues.py index 14cbf2a..b0464b1 100644 --- a/src/pyosmeta/parse_issues.py +++ b/src/pyosmeta/parse_issues.py @@ -358,10 +358,10 @@ def get_contributor_data( users = line.split(",") models = [parse_user_names(username=user) for user in users] models = [model for model in models if model is not None] + if len(models) == 0: + return None if len(models) == 1: models = models[0] - if isinstance(models, list) and len(models) == 0: - return None return models # TODO: This now returns a dict of owner:repo_name to support graphql From 61c41c18f53ca8be76aabc55b05ca5134aa89d79 Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Thu, 9 Oct 2025 12:05:53 -0600 Subject: [PATCH 07/10] Fix error handling for new contributors in update_review_teams early return when we're missing a ReviewUser / fail to validate the PersonModel (skip behavior to align with the existing log statement) --- src/pyosmeta/cli/update_review_teams.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pyosmeta/cli/update_review_teams.py b/src/pyosmeta/cli/update_review_teams.py index ac65fe4..dac28e7 100644 --- a/src/pyosmeta/cli/update_review_teams.py +++ b/src/pyosmeta/cli/update_review_teams.py @@ -119,6 +119,7 @@ def process_user( f"Error processing new contributor {gh_user}. Skipping this user.", exc_info=True, ) + return user, contribs # Update user the list of contribution types if there are new types to add # for instance a new reviewer would have a "Reviewer" contributor type From 6e98d53ffbb8fb269794f2d991b5e4f6bc1e22e7 Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Thu, 9 Oct 2025 13:42:53 -0600 Subject: [PATCH 08/10] Add '*' to unwanted characters in clean_name function there's a contributor that's being processed with * in their name. stripping this character should allow them to be processed as a PersonModel (in theory) --- src/pyosmeta/utils_clean.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyosmeta/utils_clean.py b/src/pyosmeta/utils_clean.py index 2d99769..45b7a19 100644 --- a/src/pyosmeta/utils_clean.py +++ b/src/pyosmeta/utils_clean.py @@ -74,7 +74,7 @@ def clean_date(source_date: str | None) -> datetime | str: def clean_name(source_name: str) -> str: """Remove unwanted characters from a name.""" - unwanted = ["(", ")", "@"] + unwanted = ["(", ")", "@", "*"] for char in unwanted: source_name = source_name.replace(char, "") From e4c678e27817304126b689b87a2f61e30ce23ef8 Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:23:19 -0600 Subject: [PATCH 09/10] Remove markdown formatting from issue value Strip markdown formatting from returned value. --- src/pyosmeta/parse_issues.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyosmeta/parse_issues.py b/src/pyosmeta/parse_issues.py index b0464b1..5695afd 100644 --- a/src/pyosmeta/parse_issues.py +++ b/src/pyosmeta/parse_issues.py @@ -250,7 +250,7 @@ def _parse_field(self, key: str, val: str) -> Any: # add other conditions here for special processing of fields.. # pass else: - return val + return val.strip("*").strip("__") # remove markdown formatting def parse_issue(self, issue: Issue | str) -> ReviewModel: """ From 313f844acfe7492017d3bc6317d6310a2c05ca4c Mon Sep 17 00:00:00 2001 From: "Michael Pilosov, PhD" <40366263+mathematicalmichael@users.noreply.github.com> Date: Thu, 9 Oct 2025 20:42:34 -0600 Subject: [PATCH 10/10] Update CHANGELOG for version 1.7.6 Added details for version 1.7.6 including bug fix and feature. --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1147122..82e43fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ See [GitHub releases](https://github.com/pyOpenSci/pyosMeta/releases) page for a ## [Unreleased] +## [v1.7.6] - 2025-10-10 +* Bug fix: handle markdown styling in issue template for package submission +* Feature: allow empty reviewers for in issue template for package submission + ## [v1.7.5] - 2025-09-10 * Bug fix: remove an extra newline character that prevents Jekyll from building pages from RSS feed stubs (@banesullivan, #306)