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

Stop abusing Blueprints._prepConstruction or make it public #1862

Open
drewj-tp opened this issue Sep 10, 2024 · 4 comments
Open

Stop abusing Blueprints._prepConstruction or make it public #1862

drewj-tp opened this issue Sep 10, 2024 · 4 comments
Labels
cleanup Code/comment cleanup: Low Priority

Comments

@drewj-tp
Copy link
Contributor

drewj-tp commented Sep 10, 2024

Blueprints._prepConstruction does a lot. Its docstring even says as much

def _prepConstruction(self, cs):
"""
This method initializes a bunch of information within a Blueprints object such

Not only does it construct the design of each individual assembly type, it

  1. Does processing on nuclides found in the blueprints.
  2. Checks the area of assemblies.
  3. Conditionally configures the axial snap mesh.
  4. Conditionally performs initial thermal axial expansion on assemblies.
  5. Calls the afterConstructionOfAssemblies plugin hook.

That's a lot! The value there is clear, as all those things must be done in order to make sure the assembly designs are ready to be used.

While I was working on the axial expansion work (#1843), I noticed that this private method is used directly. Which raises some hairs on the back of my neck because, 1) it points out this contradiction in its own docstring

This method should not be called directly, but it is used in testing.

and 2) I am of the belief that non-public methods (single or double leading underscore) should not be called by anything that is not the owning class. Yes, everything in Python is public, somethings just harder to access. But this public/protected/private distinction also allows developers some wiggle room.

If a method or attribute was truly protected, I have more freedom to refactor and break it up or think around that method. Maybe the four things it does don't all need to happen at once can be moved around. But if it's functionally public, it's a heavier lift.

Resolution

I propose that we rethink Blueprints._prepConstruction and determine how to either

  1. stop misusing (in my opinion) a protected method, or
  2. what functionality callers are expecting and make that public.

I've collected the cases where we use this method. Thankfully the majority of them are in testing. I presume that most are needed because we want to build assemblies without spinning up entire reactors from blueprints, but the blueprints class requires the assembly to be processed in _prepConstruction.

Non-test modules

case.bp._prepConstruction(case.cs)

self.parent.blueprints._prepConstruction(cs)

Test modules

bps._prepConstruction(cs)

self.r.blueprints._prepConstruction(self.cs)

self.blueprints._prepConstruction(self.cs)

cls.blueprints._prepConstruction(cls.cs)

design._prepConstruction(cs)

design._prepConstruction(settings.Settings())

self.bp._prepConstruction(settings.Settings())

design._prepConstruction(settings.Settings())

design._prepConstruction(settings.Settings())

self.blueprints._prepConstruction(self.cs)

@drewj-tp drewj-tp added the architecture Issues related to big picture system architecture label Sep 10, 2024
@john-science
Copy link
Member

john-science commented Sep 10, 2024

I'm not worried about the times when this pops up in testing.

Unit tests should be able to test private methods. Just because logic is internal to a class doesn't mean it's not complicated enough, or important enough, to warrant testing.

So, from my perspective, this only pops up once in a non-test environment. Still, that IS interesting.

@drewj-tp
Copy link
Contributor Author

Unit tests should be able to test private methods

Agree to a point. A unit test on the Blueprints object using and testing protected methods on that object> I can get behind that.

But at test for a materials object needing a private method from `Blueprints?

def loadAssembly(self, materialModifications):
yamlString = self.baseInput + "\n" + materialModifications
design = blueprints.Blueprints.load(yamlString)
design._prepConstruction(settings.Settings())
return design.assemblies["fuel a"]

I think that's stretching the domain of applicability.

I think nearly all of these could be mitigated if we have a Blueprints.buildAssembly method because that's what the majority of these tests need. After some brief skimming at least.

this only pops up once in a non-test environment

Twice

case.bp._prepConstruction(case.cs)

and

self.parent.blueprints._prepConstruction(cs)

@john-science john-science added cleanup Code/comment cleanup: Low Priority and removed architecture Issues related to big picture system architecture labels Sep 17, 2024
@john-science
Copy link
Member

I agree, if this is needed to be public in a non-test setting, we should probably make it public. Sure.

@drewj-tp
Copy link
Contributor Author

FWIW I have been able to have identical success replacing patterns of

bp._prepConstruction(cs)
assem = bp.assemblies[assem_name]

with

assem = bp.constructAssembly(cs, name=assem_name)

The tradeoff is bp.constructAssembly does a deepcopy of an assembly and calls Assembly.makeUnique prior to returning the new assembly. Those may or may not be important for testing but are certainly important for production analysis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cleanup Code/comment cleanup: Low Priority
Projects
None yet
Development

No branches or pull requests

2 participants