Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(RUF012) Fixed mutable class Defaults- Task 2 #10286

Merged
merged 42 commits into from
Feb 5, 2025

Conversation

ananyakaligal
Copy link
Contributor

@ananyakaligal ananyakaligal commented Jan 6, 2025

Part of #10196
NOTE: These are NOT automated changes, they are done by hand
This pull request addresses Part of RUF012 Rule - Task 2, with a focus on enhancing code quality and resolving linting issues related to mutable class attributes.

Technical Details:

  • Updated Files: The ClassVar annotations were added to mutable class attributes in two files, ensuring they are treated as class-level attributes. This change resolves the RUF012 linting issues.
  • Remaining File: The update could not be applied to plugins/worksearch/schemes/editions.py due to a shared base class with the files mentioned in Task 1, which would introduce an overriding issue. Therefore, the change was not feasible for this file.
  • Type Safety: Added proper type hints for better clarity and type safety throughout the affected files.

Testing:
Ran ruff check --select RUF012 to confirm that no further warnings related to mutable class attributes remain.

Screenshot:
N/A
Stakeholders:
@RayBB

@ananyakaligal ananyakaligal changed the title Task 2 (RUF012) Fixed mutable class Defaults- Task 2 Jan 6, 2025
@RayBB RayBB added Affects: Developers Needs: Staff / Internal Reviewed a PR but don't have merge powers? Use this. labels Jan 7, 2025
Copy link
Collaborator

@RayBB RayBB left a comment

Choose a reason for hiding this comment

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

As far as I'm concerned this looks good.
However, I'm going to need to get a second opinion from staff

@RayBB RayBB added Needs: Submitter Input Waiting on input from the creator of the issue/pr [managed] and removed Needs: Staff / Internal Reviewed a PR but don't have merge powers? Use this. labels Jan 15, 2025
@RayBB
Copy link
Collaborator

RayBB commented Jan 16, 2025

@ananyakaligal I looked at this with Drini and we realized we probably don't want all these values to be mutable.
Can you review and add non-mutable options to this (unless it needs to be mutable).

See https://docs.astral.sh/ruff/rules/mutable-class-default/

@ananyakaligal
Copy link
Contributor Author

@RayBB sure, I will work on this.

@RayBB
Copy link
Collaborator

RayBB commented Jan 21, 2025

@ananyakaligal any update on this?

@ananyakaligal
Copy link
Contributor Author

Hey @RayBB, My schedule has been pretty packed, and I'm working on the preview button right now. The CSS part of that is a bit much and very specific, so it's taking some time. I'll definitely work on this by the end of this week. My apologies!

@RayBB RayBB marked this pull request as draft January 21, 2025 17:42
@RayBB
Copy link
Collaborator

RayBB commented Jan 21, 2025

No problem. Marking as draft until it's ready 👍

@github-actions github-actions bot removed the Needs: Submitter Input Waiting on input from the creator of the issue/pr [managed] label Jan 23, 2025
@ananyakaligal ananyakaligal marked this pull request as ready for review January 23, 2025 22:00
@ananyakaligal
Copy link
Contributor Author

ananyakaligal commented Jan 23, 2025

@RayBB I used MappingProxyType to ensure immutability, as I encountered dictionaries throughout and wanted to maintain consistency. Now, I will investigate the files where the class variable overriding issue popped up.

@ananyakaligal
Copy link
Contributor Author

@RayBB
I’ve analyzed the behavior of several variables in the SearchScheme parent class (e.g., facet_fields, field_name_map, etc.), which are currently treated as instance variables. This design makes it challenging to override or modify these variables in the EditionSearchScheme child class without encountering errors like "cannot override instance variable with class variable."

Proposed Solutions:

1.Use Instance Variables
Define all variables (e.g., facet_fields, field_name_map, etc.) as instance variables explicitly in both parent and child classes via init.
Pros: Isolated per instance.
Cons: Requires explicit initialization for every instance.

class SearchScheme:
    def __init__(self):
        self.facet_fields: set[str] = set()
        self.field_name_map: dict[str, str] = {}

class EditionSearchScheme(SearchScheme):
    def __init__(self):
        super().__init__()
        self.facet_fields = {"field1", "field2"}
        self.field_name_map = {"title": "new_title"}

2.Use Immutable Types
Convert all variables into immutable, class-level attributes (e.g., frozenset, tuple) if they should remain constant across instances.
Pros: Shared and unmodifiable.
Cons: Limited flexibility if dynamic updates are needed.

class SearchScheme:
    facet_fields = frozenset()
    field_name_map = {}

class EditionSearchScheme(SearchScheme):
    facet_fields = frozenset({"field1", "field2"})
    field_name_map = {"title": "new_title"}

3.Rename in Child Class
Introduce new variable names in the child class to avoid overriding conflicts.
Pros: Avoids conflicts entirely.
Cons: May lead to inconsistencies in the codebase.

class SearchScheme:
    facet_fields = set()
    field_name_map = {}

class EditionSearchScheme(SearchScheme):
    edition_facet_fields = {"field1", "field2"}
    edition_field_name_map = {"title": "new_title"}

Considering these solutions, which approach do you recommend for managing multiple variables like facet_fields and field_name_map? Should we refactor the parent class to enforce a consistent approach across its attributes?

@ananyakaligal
Copy link
Contributor Author

@RayBB Could you please provide your feedback on the solutions I proposed earlier?

@RayBB
Copy link
Collaborator

RayBB commented Jan 29, 2025

I see how messy this one is really great work diving in on it. Lets move openlibrary/plugins/worksearch/schemes/editions.py to be part of #10283
In general the approach we'll want (when moving to the other PR) is:

  • By default, assume it should be moved to an immutable type.
  • Check if there is anywhere that is is being changed
  • If it is being changed somewhere we'll need to discuss but it should then probably become and instance variable.

@RayBB
Copy link
Collaborator

RayBB commented Jan 29, 2025

PS: I went ahead and removed the editions.py changes so Drini and I can review this one tomorrow. Hopefully merge it!

@RayBB RayBB added the Needs: Staff / Internal Reviewed a PR but don't have merge powers? Use this. label Jan 29, 2025
Copy link
Collaborator

@cdrini cdrini left a comment

Choose a reason for hiding this comment

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

Awesome thank you @ananyakaligal ! One change request for you in the testing file ; the schema file looks good.

openlibrary/tests/core/test_db.py Outdated Show resolved Hide resolved
@ananyakaligal
Copy link
Contributor Author

ananyakaligal commented Jan 30, 2025

@cdrini I hope I have made all the changes as requested.

@cdrini cdrini self-assigned this Feb 3, 2025
Copy link
Collaborator

@cdrini cdrini left a comment

Choose a reason for hiding this comment

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

Lgtm, nice work @ananyakaligal !

@cdrini cdrini merged commit 8b54d97 into internetarchive:master Feb 5, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Affects: Developers Needs: Staff / Internal Reviewed a PR but don't have merge powers? Use this.
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants