Skip to content

introduce a builder for InterpreterConfig#6034

Merged
davidhewitt merged 7 commits into
PyO3:mainfrom
davidhewitt:interpreter-builder
May 13, 2026
Merged

introduce a builder for InterpreterConfig#6034
davidhewitt merged 7 commits into
PyO3:mainfrom
davidhewitt:interpreter-builder

Conversation

@davidhewitt
Copy link
Copy Markdown
Member

Cherry picked from #5807

This changes InterpreterConfig construction to be done through an InterpreterConfigBuilder type.

Additionally, all fields on InterpreterConfig are marked deprecated and have getters to retrieve the value instead.

This should give us flexibility to make changes to the internals of this structure in the future without it being breaking for users.

Co-authored-by: David Hewitt <mail@davidhewitt.dev>
@davidhewitt davidhewitt requested a review from ngoldbaum May 12, 2026 07:33
@davidhewitt davidhewitt force-pushed the interpreter-builder branch from 0418741 to f091c9a Compare May 12, 2026 07:55
Copy link
Copy Markdown
Contributor

@ngoldbaum ngoldbaum left a comment

Choose a reason for hiding this comment

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

Thanks! This looks great and will cut down the diff in #5807 substantially. Just one comment inline about whether or not to deprecate the PY3XX constants.

#[deprecated(
since = "0.29.0",
note = "please construct `PythonVersion` directly rather than use these constants"
)]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I personally prefer using these constants and wouldn't deprecate them. That said, happy to defer to your preferences. Should they all be deprecated?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't have a super strong opinion, can revert if desired.

I think we were pretty bad at keeping the set of these constants complete, and I don't really want to have to go through deprecation cycles for old versions when we remove them, so my inclination was to stop exporting them and leave them for users to define where they need?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Works for me, let's make them only defined for tests unless we already exported them. No need to add new deprecations that need to be accounted for in tests.

@davidhewitt
Copy link
Copy Markdown
Member Author

@Icxolu mind taking a look here please, since you were also involved in review on #5924?

@davidhewitt davidhewitt requested a review from Icxolu May 12, 2026 14:33
@davidhewitt davidhewitt mentioned this pull request May 12, 2026
Comment thread pyo3-build-config/src/impl_.rs Outdated
Comment thread pyo3-build-config/src/impl_.rs Outdated
InterpreterConfig {
implementation: self.implementation,
version: self.version,
shared: self.shared.unwrap_or(true),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code might be very slightly simpler by making the field type be just bool and initialize it to true in the builder new method (same for the other non optional field)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Agreed, if there is a sensible default it can go directly into the builder, no need for Option wrapping. (Like is done for extra_build_script_lines)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Will clean up 👍

Comment thread pyo3-build-config/src/impl_.rs Outdated
Comment thread pyo3-build-config/src/impl_.rs Outdated
Copy link
Copy Markdown
Member

@Icxolu Icxolu left a comment

Choose a reason for hiding this comment

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

LGTM. Some small remarks, but nothing major.

if let Some(path) = find_sysconfigdata(cross_compile_config)? {
let data = parse_sysconfigdata(path)?;
let mut config = InterpreterConfig::from_sysconfigdata(&data)?;
#[expect(deprecated, reason = "modifying config inline")]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does this indicate that we should have a InterpreterConfigBuilder::from_sysconfigdata?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think possibly, however we will remove the direct access deprecation again in ~2 versions when we make the fields private and we'll be able to drop the expect then, so I'm not too bothered. Could be a follow up, perhaps.

Comment thread pyo3-build-config/src/impl_.rs Outdated
}

// private variants of some methods where it's convenient to potentially pass None
fn pointer_width_opt(mut self, pointer_width: Option<u32>) -> InterpreterConfigBuilder {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If we wanted, we could combine these with the normal ones above by taking impl Into<Option<T>> as the argument, allowing all of T, Some(T) and None.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done 👍

Comment thread pyo3-build-config/src/impl_.rs Outdated
InterpreterConfig {
implementation: self.implementation,
version: self.version,
shared: self.shared.unwrap_or(true),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Agreed, if there is a sensible default it can go directly into the builder, no need for Option wrapping. (Like is done for extra_build_script_lines)

Comment thread pyo3-build-config/src/impl_.rs Outdated
}
}

pub fn finalize(self) -> InterpreterConfig {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can this return a Result? You don't have any error cases now, but I'd like to add some to centralize all ABI version checking logic here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done.

davidhewitt and others added 2 commits May 12, 2026 21:43
Co-authored-by: Thomas Tanon <thomas@pellissier-tanon.fr>
@davidhewitt
Copy link
Copy Markdown
Member Author

Thanks all!

@davidhewitt davidhewitt enabled auto-merge May 12, 2026 20:53
@davidhewitt davidhewitt added this pull request to the merge queue May 12, 2026
Merged via the queue into PyO3:main with commit c92117c May 13, 2026
90 checks passed
@davidhewitt davidhewitt deleted the interpreter-builder branch May 13, 2026 00:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants