drop environment abstraction layer over Python interpreter (#5)

This commit is contained in:
Josh Thomas 2024-12-06 09:45:36 -06:00 committed by GitHub
parent 39523d1f89
commit b7a1de98dd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 17 additions and 66 deletions

View file

@ -1,53 +0,0 @@
use crate::python::{Interpreter, PythonError};
use std::fmt;
use std::path::PathBuf;
use which::which;
#[derive(Debug)]
pub struct PythonEnvironment {
root: PathBuf,
py: Interpreter,
}
impl PythonEnvironment {
fn new(root: PathBuf, py: Interpreter) -> Self {
Self { root, py }
}
pub fn initialize() -> Result<Self, EnvironmentError> {
let executable = which("python")?;
let py = Interpreter::from_sys_executable(&executable)?;
let root = py.sys_prefix().clone();
Ok(Self::new(root, py))
}
pub fn root(&self) -> &PathBuf {
&self.root
}
pub fn py(&self) -> &Interpreter {
&self.py
}
}
impl fmt::Display for PythonEnvironment {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "Python Environment")?;
writeln!(f, "Root: {}", self.root.display())?;
writeln!(f)?;
writeln!(f, "Interpreter")?;
writeln!(f, "{}", self.py)
}
}
#[derive(Debug, thiserror::Error)]
pub enum EnvironmentError {
#[error("Failed to locate Python executable: {0}")]
PythonNotFound(#[from] which::Error),
#[error("Runtime error: {0}")]
Runtime(#[from] PythonError),
#[error("Environment initialization failed: {0}")]
Init(String),
}

View file

@ -1,5 +1,4 @@
mod environment;
mod packaging;
mod python;
pub use environment::PythonEnvironment;
pub use python::Python;

View file

@ -3,6 +3,7 @@ use serde::Deserialize;
use std::fmt;
use std::path::PathBuf;
use std::process::Command;
use which::which;
#[derive(Clone, Debug, Deserialize)]
pub struct VersionInfo {
@ -101,7 +102,7 @@ impl fmt::Display for SysconfigPaths {
}
#[derive(Clone, Debug)]
pub struct Interpreter {
pub struct Python {
version_info: VersionInfo,
sysconfig_paths: SysconfigPaths,
sys_prefix: PathBuf,
@ -111,7 +112,7 @@ pub struct Interpreter {
packages: Packages,
}
impl Interpreter {
impl Python {
fn new(
version_info: VersionInfo,
sysconfig_paths: SysconfigPaths,
@ -132,8 +133,9 @@ impl Interpreter {
}
}
pub fn from_sys_executable(executable: &PathBuf) -> Result<Self, PythonError> {
let output = Command::new(executable)
pub fn initialize() -> Result<Self, PythonError> {
let executable = which("python")?;
let output = Command::new(&executable)
.args([
"-c",
r#"
@ -152,8 +154,8 @@ print(json.dumps({
let sys_info: serde_json::Value = serde_json::from_str(&output_str)?;
Ok(Self::new(
VersionInfo::from_executable(executable)?,
SysconfigPaths::from_executable(executable)?,
VersionInfo::from_executable(&executable)?,
SysconfigPaths::from_executable(&executable)?,
PathBuf::from(sys_info["prefix"].as_str().unwrap()),
PathBuf::from(sys_info["base_prefix"].as_str().unwrap()),
PathBuf::from(sys_info["executable"].as_str().unwrap()),
@ -163,7 +165,7 @@ print(json.dumps({
.iter()
.map(|p| PathBuf::from(p.as_str().unwrap()))
.collect(),
Packages::from_executable(executable)?,
Packages::from_executable(&executable)?,
))
}
@ -230,7 +232,7 @@ print(json.dumps({
}
}
impl fmt::Display for Interpreter {
impl fmt::Display for Python {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "Version: {}", self.version_info)?;
writeln!(f, "Executable: {}", self.sys_executable.display())?;
@ -249,6 +251,9 @@ impl fmt::Display for Interpreter {
#[derive(Debug, thiserror::Error)]
pub enum PythonError {
#[error("Failed to locate Python executable: {0}")]
PythonNotFound(#[from] which::Error),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),

View file

@ -3,12 +3,12 @@ use tower_lsp::jsonrpc::Result as LspResult;
use tower_lsp::lsp_types::*;
use tower_lsp::{Client, LanguageServer, LspService, Server};
use djls_python::PythonEnvironment;
use djls_python::Python;
#[derive(Debug)]
struct Backend {
client: Client,
python: PythonEnvironment,
python: Python,
}
#[tower_lsp::async_trait]
@ -46,7 +46,7 @@ impl LanguageServer for Backend {
#[tokio::main]
async fn main() -> Result<()> {
let python = PythonEnvironment::initialize()?;
let python = Python::initialize()?;
let stdin = tokio::io::stdin();
let stdout = tokio::io::stdout();