Move implementations next to definitions (#10131)

This commit is contained in:
Charlie Marsh 2024-12-23 19:16:48 -05:00 committed by GitHub
parent b24fb774b1
commit 6ed7302432
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 169 additions and 169 deletions

View File

@ -448,175 +448,6 @@ pub(crate) enum ProjectInterpreter {
Environment(PythonEnvironment),
}
#[derive(Debug, Clone)]
pub(crate) enum PythonRequestSource {
/// The request was provided by the user.
UserRequest,
/// The request was inferred from a `.python-version` or `.python-versions` file.
DotPythonVersion(PythonVersionFile),
/// The request was inferred from a `pyproject.toml` file.
RequiresPython,
}
impl std::fmt::Display for PythonRequestSource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PythonRequestSource::UserRequest => write!(f, "explicit request"),
PythonRequestSource::DotPythonVersion(file) => {
write!(f, "version file at `{}`", file.path().user_display())
}
PythonRequestSource::RequiresPython => write!(f, "`requires-python` metadata"),
}
}
}
/// The resolved Python request and requirement for a [`Workspace`].
#[derive(Debug, Clone)]
pub(crate) struct WorkspacePython {
/// The source of the Python request.
pub(crate) source: PythonRequestSource,
/// The resolved Python request, computed by considering (1) any explicit request from the user
/// via `--python`, (2) any implicit request from the user via `.python-version`, and (3) any
/// `Requires-Python` specifier in the `pyproject.toml`.
pub(crate) python_request: Option<PythonRequest>,
/// The resolved Python requirement for the project, computed by taking the intersection of all
/// `Requires-Python` specifiers in the workspace.
pub(crate) requires_python: Option<RequiresPython>,
}
impl WorkspacePython {
/// Determine the [`WorkspacePython`] for the current [`Workspace`].
pub(crate) async fn from_request(
python_request: Option<PythonRequest>,
workspace: Option<&Workspace>,
project_dir: &Path,
no_config: bool,
) -> Result<Self, ProjectError> {
let requires_python = workspace.and_then(find_requires_python);
let workspace_root = workspace.map(Workspace::install_path);
let (source, python_request) = if let Some(request) = python_request {
// (1) Explicit request from user
let source = PythonRequestSource::UserRequest;
let request = Some(request);
(source, request)
} else if let Some(file) = PythonVersionFile::discover(
project_dir,
&VersionFileDiscoveryOptions::default()
.with_stop_discovery_at(workspace_root.map(PathBuf::as_ref))
.with_no_config(no_config),
)
.await?
{
// (2) Request from `.python-version`
let source = PythonRequestSource::DotPythonVersion(file.clone());
let request = file.into_version();
(source, request)
} else {
// (3) `requires-python` in `pyproject.toml`
let request = requires_python
.as_ref()
.map(RequiresPython::specifiers)
.map(|specifiers| {
PythonRequest::Version(VersionRequest::Range(
specifiers.clone(),
PythonVariant::Default,
))
});
let source = PythonRequestSource::RequiresPython;
(source, request)
};
if let Some(python_request) = python_request.as_ref() {
debug!(
"Using Python request `{}` from {source}",
python_request.to_canonical_string()
);
};
Ok(Self {
source,
python_request,
requires_python,
})
}
}
/// The source of a `Requires-Python` specifier.
#[derive(Debug, Clone)]
pub(crate) enum RequiresPythonSource {
/// From the PEP 723 inline script metadata.
Script,
/// From a `pyproject.toml` in a workspace.
Project,
}
/// The resolved Python request and requirement for a [`Pep723Script`]
#[derive(Debug, Clone)]
pub(crate) struct ScriptPython {
/// The source of the Python request.
pub(crate) source: PythonRequestSource,
/// The resolved Python request, computed by considering (1) any explicit request from the user
/// via `--python`, (2) any implicit request from the user via `.python-version`, (3) any
/// `Requires-Python` specifier in the script metadata, and (4) any `Requires-Python` specifier
/// in the `pyproject.toml`.
pub(crate) python_request: Option<PythonRequest>,
/// The resolved Python requirement for the script and its source.
pub(crate) requires_python: Option<(RequiresPython, RequiresPythonSource)>,
}
impl ScriptPython {
/// Determine the [`ScriptPython`] for the current [`Workspace`].
pub(crate) async fn from_request(
python_request: Option<PythonRequest>,
workspace: Option<&Workspace>,
script: &Pep723Item,
no_config: bool,
) -> Result<Self, ProjectError> {
// First, discover a requirement from the workspace
let WorkspacePython {
mut source,
mut python_request,
requires_python,
} = WorkspacePython::from_request(
python_request,
workspace,
script.path().and_then(Path::parent).unwrap_or(&**CWD),
no_config,
)
.await?;
// If the script has a `requires-python` specifier, prefer that over one from the workspace.
let requires_python =
if let Some(requires_python_specifiers) = script.metadata().requires_python.as_ref() {
if python_request.is_none() {
python_request = Some(PythonRequest::Version(VersionRequest::Range(
requires_python_specifiers.clone(),
PythonVariant::Default,
)));
source = PythonRequestSource::RequiresPython;
}
Some((
RequiresPython::from_specifiers(requires_python_specifiers),
RequiresPythonSource::Script,
))
} else {
requires_python.map(|requirement| (requirement, RequiresPythonSource::Project))
};
if let Some(python_request) = python_request.as_ref() {
debug!("Using Python request {python_request} from {source}");
};
Ok(Self {
source,
python_request,
requires_python,
})
}
}
impl ProjectInterpreter {
/// Discover the interpreter to use in the current [`Workspace`].
pub(crate) async fn discover(
@ -767,6 +598,175 @@ impl ProjectInterpreter {
}
}
/// The source of a `Requires-Python` specifier.
#[derive(Debug, Clone)]
pub(crate) enum RequiresPythonSource {
/// From the PEP 723 inline script metadata.
Script,
/// From a `pyproject.toml` in a workspace.
Project,
}
#[derive(Debug, Clone)]
pub(crate) enum PythonRequestSource {
/// The request was provided by the user.
UserRequest,
/// The request was inferred from a `.python-version` or `.python-versions` file.
DotPythonVersion(PythonVersionFile),
/// The request was inferred from a `pyproject.toml` file.
RequiresPython,
}
impl std::fmt::Display for PythonRequestSource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PythonRequestSource::UserRequest => write!(f, "explicit request"),
PythonRequestSource::DotPythonVersion(file) => {
write!(f, "version file at `{}`", file.path().user_display())
}
PythonRequestSource::RequiresPython => write!(f, "`requires-python` metadata"),
}
}
}
/// The resolved Python request and requirement for a [`Workspace`].
#[derive(Debug, Clone)]
pub(crate) struct WorkspacePython {
/// The source of the Python request.
pub(crate) source: PythonRequestSource,
/// The resolved Python request, computed by considering (1) any explicit request from the user
/// via `--python`, (2) any implicit request from the user via `.python-version`, and (3) any
/// `Requires-Python` specifier in the `pyproject.toml`.
pub(crate) python_request: Option<PythonRequest>,
/// The resolved Python requirement for the project, computed by taking the intersection of all
/// `Requires-Python` specifiers in the workspace.
pub(crate) requires_python: Option<RequiresPython>,
}
impl WorkspacePython {
/// Determine the [`WorkspacePython`] for the current [`Workspace`].
pub(crate) async fn from_request(
python_request: Option<PythonRequest>,
workspace: Option<&Workspace>,
project_dir: &Path,
no_config: bool,
) -> Result<Self, ProjectError> {
let requires_python = workspace.and_then(find_requires_python);
let workspace_root = workspace.map(Workspace::install_path);
let (source, python_request) = if let Some(request) = python_request {
// (1) Explicit request from user
let source = PythonRequestSource::UserRequest;
let request = Some(request);
(source, request)
} else if let Some(file) = PythonVersionFile::discover(
project_dir,
&VersionFileDiscoveryOptions::default()
.with_stop_discovery_at(workspace_root.map(PathBuf::as_ref))
.with_no_config(no_config),
)
.await?
{
// (2) Request from `.python-version`
let source = PythonRequestSource::DotPythonVersion(file.clone());
let request = file.into_version();
(source, request)
} else {
// (3) `requires-python` in `pyproject.toml`
let request = requires_python
.as_ref()
.map(RequiresPython::specifiers)
.map(|specifiers| {
PythonRequest::Version(VersionRequest::Range(
specifiers.clone(),
PythonVariant::Default,
))
});
let source = PythonRequestSource::RequiresPython;
(source, request)
};
if let Some(python_request) = python_request.as_ref() {
debug!(
"Using Python request `{}` from {source}",
python_request.to_canonical_string()
);
};
Ok(Self {
source,
python_request,
requires_python,
})
}
}
/// The resolved Python request and requirement for a [`Pep723Script`]
#[derive(Debug, Clone)]
pub(crate) struct ScriptPython {
/// The source of the Python request.
pub(crate) source: PythonRequestSource,
/// The resolved Python request, computed by considering (1) any explicit request from the user
/// via `--python`, (2) any implicit request from the user via `.python-version`, (3) any
/// `Requires-Python` specifier in the script metadata, and (4) any `Requires-Python` specifier
/// in the `pyproject.toml`.
pub(crate) python_request: Option<PythonRequest>,
/// The resolved Python requirement for the script and its source.
pub(crate) requires_python: Option<(RequiresPython, RequiresPythonSource)>,
}
impl ScriptPython {
/// Determine the [`ScriptPython`] for the current [`Workspace`].
pub(crate) async fn from_request(
python_request: Option<PythonRequest>,
workspace: Option<&Workspace>,
script: &Pep723Item,
no_config: bool,
) -> Result<Self, ProjectError> {
// First, discover a requirement from the workspace
let WorkspacePython {
mut source,
mut python_request,
requires_python,
} = WorkspacePython::from_request(
python_request,
workspace,
script.path().and_then(Path::parent).unwrap_or(&**CWD),
no_config,
)
.await?;
// If the script has a `requires-python` specifier, prefer that over one from the workspace.
let requires_python =
if let Some(requires_python_specifiers) = script.metadata().requires_python.as_ref() {
if python_request.is_none() {
python_request = Some(PythonRequest::Version(VersionRequest::Range(
requires_python_specifiers.clone(),
PythonVariant::Default,
)));
source = PythonRequestSource::RequiresPython;
}
Some((
RequiresPython::from_specifiers(requires_python_specifiers),
RequiresPythonSource::Script,
))
} else {
requires_python.map(|requirement| (requirement, RequiresPythonSource::Project))
};
if let Some(python_request) = python_request.as_ref() {
debug!("Using Python request {python_request} from {source}");
};
Ok(Self {
source,
python_request,
requires_python,
})
}
}
/// Initialize a virtual environment for the current project.
pub(crate) async fn get_or_init_environment(
workspace: &Workspace,