feat(context): expose a _phase context variable (fix #1883)#1948
feat(context): expose a _phase context variable (fix #1883)#1948sisp merged 1 commit intocopier-org:masterfrom
_phase context variable (fix #1883)#1948Conversation
8173a15 to
166fc44
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #1948 +/- ##
==========================================
- Coverage 98.06% 97.93% -0.13%
==========================================
Files 53 53
Lines 5580 5677 +97
==========================================
+ Hits 5472 5560 +88
- Misses 108 117 +9
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Looking super good to me 😄 Thank you for the awesome PRs @noirbizarre! |
3d6dbd8 to
dc3071d
Compare
|
PR updated with the typo fixes. You're welcome 🙏🏼 It benefits everybody 👌🏼 |
sisp
left a comment
There was a problem hiding this comment.
Fantastic work again, @noirbizarre! 🙏
Just a minor stylistic request: It seems Python enums should be upper-case12. I suggest following this guideline.
Footnotes
317a8ed to
41bef6c
Compare
|
Updated to upper case 👍🏼 I, personally, tend to do the opposite with |
sisp
left a comment
There was a problem hiding this comment.
It seems you're right, there isn't a definitive style rule about enums. 🫣 Thanks for elaborating on this topic (especially the detailed message before you edited it 😉)! Well, now it's upper-case. Shall we leave it like this?
Just a final thought: Shall we expose the phase via the _phase variable (as it is now) or would it be better to rename/move it? E.g.:
_copier_phase– only_folder_name,now, andmake_secretseems to not have the_copierprefix wherenowandmake_secretare both deprecated._copier_conf.phase– or should we only have static values under_copier_conf?
@noirbizarre @copier-org/maintainers Any opinions?
|
I tend to use lowercase too, except when the enum contains names that are reserved keywords like I'm accessing the phase with |
|
@pawamoy So, would you tend to be in favor of |
This comment was marked as outdated.
This comment was marked as outdated.
|
Yes, |
|
Here's my final comprehension of the issue (which may be worth adding as documentation or code comments at least).
|
41bef6c to
badf574
Compare
|
Oh, I didn't though about all that 😅 Note that I actually use context extensions during prompt on my projects, and actually this PR can maybe help to have a more general approach on this and assume that extensions can run at any phase. (This might later lead to having copier-template-extensions Anyway, PR update with |
sisp
left a comment
There was a problem hiding this comment.
I've thought about this PR some more and also about – what @pawamoy noticed – the phase value being automatically exposed as _copier_conf.phase because most Worker dataclass attributes are automatically included in _copier_conf. As
I would go for a root
_copier_phaseas it is not a configuration, just a runtime state.
makes sense to me, I think the phase value should not be accessible under _copier_conf though. This PR also reminds me of a similar situation we've had in #1733 where initially a dataclass attribute was used as well and I suggested to use a context variable instead. Now, it feels odd to me to use a dataclass attribute here to manage the phase value because it has no meaning while not rendering, prompting or executing tasks/migrations. How about applying an approach similar to #1733 (review) in this PR as well?
Slightly off-topic: I just realized that #1733 exposes a top-level _operation Jinja variable; we might want to rename it to _copier_operation there for consistency.
|
@pawamoy This comment pre-dates my involvement with Copier, but I don't think the (raw) |
|
Fine by me. I'd suggest making sure |
badf574 to
a8c7d53
Compare
|
PR updated with I saw the deprecation noticed, but it is used by all rendering except those for the prompts.
Agreed, but I would go even further (not in this PR to keep it scoped), I would isolate rendering in a single class/module/function/whatever, so future modification of this kind occurs in a single place. It would be easier to maintain and evolve, and easier to test. |
a8c7d53 to
17efb40
Compare
bedd1ff to
fab4cca
Compare
|
Updated: rebased, solved conflicts and adapted to the latest changes.
As a consequence, the values used to generate I found a fix for this PR and added a comment to keep track of it. |
|
There are some merge conflicts because of #1993 now, which mostly reverted the system render context change because of #1977 that also affected this PR.
I still think that the |
fab4cca to
07b9fbb
Compare
|
Updated:
|
There was a problem hiding this comment.
Thanks, @noirbizarre!
Sorry for being a little pedantic about the context variable approach. 🫣 But could you remove the default phase value and use a context manager to manage the phase value, such that a particular phase value is only set within an explicitly created context? This way, we reduce the risk of forgetting to set a new phase value and accidentally exposing a previously set one, as ContextVar.get() raises a LookupError when neither a value is set nor a default value is provided.
E.g.:
with use_phase(phase.TASK):
self._execute_task(self.template.tasks)(I'm open to better context manager names than use_phase by the way. 😄)
07b9fbb to
ca9986d
Compare
|
Updated with a context manager.
Not having a default value would mean:
That would mean having most of the codebase modified just to add a variable, and potential conflict with any pending PR, or any PR merged before this one. So instead, I added a WDYT ? |
sisp
left a comment
There was a problem hiding this comment.
Thanks for explaining why no default value for the context variable won't work. You're right, and I think introducing "undefined" and using it as a default value is a good idea. I also like the implementation of the context manager as a class method of Phase. 👍 Well done! 👏
IIUC, the phase value when rendering the answers file path of external data depends on the phase in which that particular external data is first accessed due to lazy access. Would it be better to override the phase value with "undefined" instead? The meaning of the phase doesn't seem well defined in this case. WDYT?
cad3446 to
46312c6
Compare
|
Very nice, thanks!
WDYT about this? |
46312c6 to
781e9e7
Compare
|
Make sense 👍🏼 |
781e9e7 to
b2eb03a
Compare
c2ff1bd to
ceb8039
Compare
ceb8039 to
4cba543
Compare
There was a problem hiding this comment.
Awesome! 🤩 Huge thanks for adding this feature and being incredibly patient with my pedantic review feedback and the many iterations involving code updates and discussions! 🙇 Fantastic work, @noirbizarre! 🏆
Close #1883.
This PR exposes a
_phasevariable which can be one ofprompt,tasks,mmigrateandrender.The known phases are grouped into the
copier.types.Phaseenum.This implements #1883 and allows fixing copier-org/copier-template-extensions#7