From d4d92255e6b4c927ee1d2d78074df6c36f978d0f Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 24 Jun 2023 16:57:05 -0500 Subject: [PATCH 01/51] Begin invocation debug/test work. Add infrastructure and some tests for app, workspace, and user-global invocations. --- .github/workflows/regression_test.yml | 21 + .gitignore | 7 +- python/origen/origen/__init__.py | 23 +- python/origen/origen/helpers/env.py | 11 +- python/origen/pyproject.toml | 2 +- rust/origen/cli/src/python.rs | 184 +- rust/origen/src/core/config.rs | 10 +- rust/origen/src/core/status.rs | 62 + rust/origen_metal/src/utils/command.rs | 28 +- rust/origen_metal/src/utils/file.rs | 18 + rust/pyapi/src/infrastructure/mod.rs | 10 + rust/pyapi/src/infrastructure/pyproject.rs | 53 + rust/pyapi/src/lib.rs | 20 + test_apps/no_workspace/__init__.py | 0 test_apps/no_workspace/t_invocation_env.py | 130 ++ .../no_workspace/templates/pyproject.toml | 24 + test_apps/no_workspace/test_user_install.py | 60 + .../no_workspace/user_install/inner/.keep | 0 .../no_workspace/user_install/poetry.lock | 1976 +++++++++++++++++ .../no_workspace/user_install/pyproject.toml | 13 + test_apps/python_app/tests/cli_test.py | 12 +- test_apps/python_no_app/tests/shared.py | 5 + test_apps/python_no_app/tests/test_configs.py | 7 +- .../tests/test_global_invocation.py | 13 +- .../pyproject.toml | 1 + 25 files changed, 2649 insertions(+), 41 deletions(-) create mode 100644 rust/pyapi/src/infrastructure/mod.rs create mode 100644 rust/pyapi/src/infrastructure/pyproject.rs create mode 100644 test_apps/no_workspace/__init__.py create mode 100644 test_apps/no_workspace/t_invocation_env.py create mode 100644 test_apps/no_workspace/templates/pyproject.toml create mode 100644 test_apps/no_workspace/test_user_install.py create mode 100644 test_apps/no_workspace/user_install/inner/.keep create mode 100644 test_apps/no_workspace/user_install/poetry.lock create mode 100644 test_apps/no_workspace/user_install/pyproject.toml create mode 100644 test_apps/python_no_app/tests/shared.py diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 2b174595..01f9824f 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -139,3 +139,24 @@ jobs: working-directory: rust/origen_metal run: cargo test + # Use a global pytest install for invocation tests + - name: Install Pytest + run: pip install pytest==7.2.1 + + - name: Get Pytest Version (Check Install) + run: pytest --version + + - name: Run User-Global Invocation Tests + working-directory: test_apps/no_workspace + run: pytest test_user_install.py -vv + + # TODO eventually want to move this into a poetry build step + # For now, manually move the binary. Also keeps us from having to mess with the path across OSs + # 'mv' command should be be fine for both linux & powershell + # - name: Move Origen executable (Linux) + # if: matrix.os == 'ubuntu-latest' + # run: mv rust/origen/target/debug/origen python/origen/origen/__bin__/bin + + # - name: Move Origen executable (Windows) + # if: matrix.os == 'windows-latest' + # run: mv rust/origen/target/debug/origen.exe python/origen/origen/__bin__/bin diff --git a/.gitignore b/.gitignore index f078ed88..deb10ffb 100755 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,9 @@ log/ /test_apps/**/.session /python/origen/dist /python/origen_metal/dist +/python/origen_metal/build rls/ +.pytest_cache # pyenv .python-version @@ -35,9 +37,10 @@ rls/ # Output files from regressions python/origen/templates/dut_info.txt +test_apps/no_workspace/templates/output/ # Bin directory for packaging -python/origen/__bin__/bin/* -!python/origen/__bin__/bin/.keep +python/origen/origen/__bin__/bin/* +!python/origen/origen/__bin__/bin/.keep python/origen_metal/__bin__/bin/* !python/origen_metal/__bin__/bin/.keep diff --git a/python/origen/origen/__init__.py b/python/origen/origen/__init__.py index fd614e08..c5de3c1d 100644 --- a/python/origen/origen/__init__.py +++ b/python/origen/origen/__init__.py @@ -5,11 +5,15 @@ cli_path = None cli_ver = None vks = [] +pyproject_src = None +invoc = None regexp = re.compile(r'verbosity=(\d+)') cli_re = re.compile(r'origen_cli=(.+)') cli_ver_re = re.compile(r'origen_cli_version=(.+)') vk_re = re.compile(r'verbosity_keywords=(.+)') +pyproj_src_re = re.compile(r'pyproject_src=(.+)') +invoc_re = re.compile(r'invocation=(.+)') for arg in sys.argv: matches = regexp.search(arg) if matches: @@ -27,6 +31,14 @@ if matches: cli_ver = matches.group(1) next + matches = pyproj_src_re.search(arg) + if matches: + pyproject_src = matches.group(1) + next + matches = invoc_re.search(arg) + if matches: + invoc = matches.group(1) + next import _origen from _origen import _origen_metal @@ -64,7 +76,16 @@ def __getattr__(name: str): om = origen_metal origen_metal.frontend.initialize() -_origen.initialize(init_verbosity, vks, cli_path, cli_ver, pathlib.Path(__file__).parent, sys.executable) +_origen.initialize( + init_verbosity, + vks, + cli_path, + cli_ver, + pathlib.Path(__file__).parent, + sys.executable, + ((invoc, pyproject_src) if invoc else None) +) +del init_verbosity, vks, cli_path, cli_ver, invoc, pyproject_src from pathlib import Path import importlib diff --git a/python/origen/origen/helpers/env.py b/python/origen/origen/helpers/env.py index 01b82ff0..f554900b 100644 --- a/python/origen/origen/helpers/env.py +++ b/python/origen/origen/helpers/env.py @@ -21,11 +21,16 @@ def run_cli_cmd(cmd, *, shell=None, targets=None, check=True, + poetry_run=False, + origen_exe=None ): if isinstance(cmd, str): - cmd = ["origen", cmd] - else: - cmd = ["origen", *cmd] + cmd = [cmd] + if (origen_exe is None) or isinstance(origen_exe, str): + origen_exe = [origen_exe or 'origen'] + if poetry_run: + origen_exe = ["poetry", "run", *origen_exe] + cmd = [*origen_exe, *cmd] subp_env = os.environ.copy() if isinstance(with_configs, str) or isinstance(with_configs, pathlib.Path): diff --git a/python/origen/pyproject.toml b/python/origen/pyproject.toml index a1465970..40e392b0 100644 --- a/python/origen/pyproject.toml +++ b/python/origen/pyproject.toml @@ -18,7 +18,7 @@ script = "poetry_build.py" generate-setup-file = false [tool.poetry.scripts] -o2 = 'origen.__bin__:run_origen' +origen = 'origen.__bin__:run_origen' [tool.poetry.dependencies] python = ">=3.7,<3.11" diff --git a/rust/origen/cli/src/python.rs b/rust/origen/cli/src/python.rs index d1471e9b..1491ae3f 100644 --- a/rust/origen/cli/src/python.rs +++ b/rust/origen/cli/src/python.rs @@ -1,8 +1,10 @@ // Responsible for managing Python execution - use crate::built_info; -use origen::Result; +use origen::{Result, STATUS}; +use origen::core::status::DependencySrc; +use origen_metal::utils::file::search_backwards_for_first; use semver::Version; +use std::env; use std::path::PathBuf; use std::process::{Command, ExitStatus, Stdio}; @@ -31,6 +33,16 @@ lazy_static! { pub static ref PYTHON_CONFIG: Config = Config::default(); } +macro_rules! pyproject_str { + () => { "pyproject.toml" } +} +macro_rules! user_env_str { + () => { "ORIGEN_PYPROJECT" } +} + +const PYPROJECT: &'static str = pyproject_str!(); +const USER_ENV: &'static str = user_env_str!(); + pub struct Config { pub available: bool, pub command: String, @@ -38,18 +50,170 @@ pub struct Config { pub error: String, } +pub fn resolve_pyproject() -> Result { + // TODO allow a .origen offset when looking for pyprojects? + // let offset = ".origen"; + if let Some(app) = STATUS.app.as_ref() { + let path = app.root.join(PYPROJECT); + log_trace!("Found app pyproject: {}", path.display()); + return Ok(DependencySrc::App(path)); + } + + if let Some(p) = search_backwards_for_first(env::current_dir()?, |p| { + let f = p.join(PYPROJECT); + log_trace!("Searching for workspace project from {}", p.display()); + if f.exists() { + log_trace!("Found workspace pyproject: {}", f.display()); + Ok(Some(f)) + } else { + Ok(None) + } + })? { + return Ok(DependencySrc::Workspace(p.to_path_buf())) + } + + if let Some(p) = env::var_os(USER_ENV) { + log_trace!("Attempting to find user-given pyproject: {}", p.to_string_lossy()); + let mut f = PathBuf::from(p); + if f.exists() { + f = f.join(PYPROJECT); + if f.exists() { + log_trace!("Found user-given pyproject: {}", f.display()); + return Ok(DependencySrc::UserGlobal(f)); + } else { + bail!(concat!("Could not locate ", pyproject_str!(), " from ", user_env_str!(), " {}"), f.display()); + } + } else { + bail!(concat!(user_env_str!(), " '{}' does not exists!"), f.display()); + } + } + + // Try the python package installation directory + let path = std::env::current_exe()?; + log_trace!("Searching CLI installation directories for pyproject: {}", path.display()); + if let Some(p) = search_backwards_for_first(path, |p| { + let f = p.join(PYPROJECT); + log_trace!("Searching for workspace project from {}", p.display()); + if f.exists() { + log_trace!("Found workspace pyproject: {}", f.display()); + Ok(Some(f)) + } else { + Ok(None) + } + })? { + return Ok(DependencySrc::Global(p.to_path_buf())) + } + + log_trace!("No pyproject found. Skipping Poetry invocations..."); + Ok(DependencySrc::None) +} + impl Config { + pub fn base_cmd(&self) -> Command { + let dep_src = STATUS.dependency_src(); + let mut c = Command::new(&self.command); + + if let Some(dep_src) = dep_src.as_ref() { + match dep_src { + DependencySrc::App(_path) | DependencySrc::Workspace(_path) => { + c.arg("-m"); + c.arg("poetry"); + }, + DependencySrc::UserGlobal(path) | DependencySrc::Global(path) => { + c.arg("-m"); + c.arg("poetry"); + c.arg("-C"); + c.arg(path); + } + DependencySrc::None => {} + } + } else { + log_error!("Dependency source has not been set - defaulting to global Python installation"); + } + c + } + + pub fn run_cmd(&self, code: &str) -> Command { + let mut c = self.base_cmd(); + if let Some(d) = STATUS.dependency_src().as_ref() { + if d.src_available() { + c.arg("run"); + c.arg(&self.command); + } + } + c.arg("-c"); + c.arg(code); + if let Some(d) = STATUS.dependency_src().as_ref() { + c.arg(format!("invocation={}", d)); + if let Some(path) = d.src_file() { + c.arg(format!("pyproject_src={}", path.display())); + } + } + c + } + pub fn poetry_command(&self) -> Command { let mut c = Command::new(&self.command); c.arg("-m"); c.arg("poetry"); + if let Some(d) = STATUS.dependency_src().as_ref() { + if let Some(path) = d.src_file() { + c.arg("-C"); + c.arg(path); + } + } c } + + // TODO Invocation see if these are needed or can be cleaned up + // fn get_origen_pkg_path(&self) -> Result { + // let mut c = Command::new("pip"); + // c.arg("show"); + // c.arg("origen"); + // let output = exec_and_capture_cmd(c)?; + // if let Some(loc) = output.1.iter().find_map( |line| line.strip_prefix("Location: ")) { + // Ok(PathBuf::from(loc)) + // } else { + // bail!( + // "Error locating origen package information from pip.\nReceived stdout:\n{}\nReceived stderr:\n{}", + // output.1.join("\n"), + // output.2.join("\n") + // ); + // } + // } + + // fn in_workspace(&self) -> Result { + // let mut c = Command::new(&self.command); + // c.arg("-m"); + // c.arg("poetry"); + // c.arg("env"); + // c.arg("info"); + // let output = exec_and_capture_cmd(c)?; + // if !output.0.success() { + // if let Some(l) = output.2.last() { + // if l.starts_with("Poetry could not find a pyproject.toml file in ") { + // return Ok(false); + // } + // } + // bail!( + // "Unexpected response when querying poetry environment:\nReceived stdout:\n{}Received stderr:\n{}", + // output.1.join("\n"), + // output.2.join("\n") + // ); + // } + // Ok(true) + // } } impl Default for Config { fn default() -> Config { let mut available = false; + match resolve_pyproject() { + Ok(deps) => { + STATUS.set_dependency_src(Some(deps)) + }, + Err(e) => log_error!("Errors encountered resolving pyproject: {}", e) + } for cmd in PYTHONS.iter() { match get_version(cmd) { Some(version) => { @@ -163,11 +327,7 @@ fn extract_version(text: &str) -> Option { /// Execute the given Python code pub fn run(code: &str) -> Result { - let mut cmd = PYTHON_CONFIG.poetry_command(); - cmd.arg("run"); - cmd.arg(&PYTHON_CONFIG.command); - cmd.arg("-c"); - cmd.arg(&code); + let mut cmd = PYTHON_CONFIG.run_cmd(code); // current_exe returns the Python process once it gets underway, so pass in the CLI // location for Origen to use (used to resolve Origen config files) if let Ok(p) = std::env::current_exe() { @@ -190,15 +350,7 @@ pub fn run_with_callbacks( ) -> Result<()> { use origen::utility::command_helpers::log_stdout_and_stderr; - let mut cmd = PYTHON_CONFIG.poetry_command(); - cmd.arg("run"); - cmd.arg(&PYTHON_CONFIG.command); - cmd.arg("-c"); - cmd.arg(&code); - cmd.arg("-"); - // Force logger to be silent, use case for this is parsing output data so keep - // noise to a minimum - cmd.arg("verbosity=0"); + let mut cmd = PYTHON_CONFIG.run_cmd(code); // current_exe returns the Python process once it gets underway, so pass in the CLI // location for Origen to use (used to resolve Origen config files) if let Ok(p) = std::env::current_exe() { diff --git a/rust/origen/src/core/config.rs b/rust/origen/src/core/config.rs index 7039268b..42e28b24 100644 --- a/rust/origen/src/core/config.rs +++ b/rust/origen/src/core/config.rs @@ -404,12 +404,20 @@ impl Default for Config { } } else { match std::env::current_dir() { - Ok(path) => { + Ok(mut path) => { let f = path.join("origen.toml"); log_trace!("Looking for Origen config file in current working directory at '{}'", f.display()); if f.exists() { files.push(f); } + + while path.pop() { + let f = path.join("origen.toml"); + log_trace!("Looking for Origen config file at '{}'", f.display()); + if f.exists() { + files.push(f); + } + } } Err(e) => { log_error!("Failed to lookup current working directory: {}", e.to_string()) diff --git a/rust/origen/src/core/status.rs b/rust/origen/src/core/status.rs index d9be1b88..01d66434 100644 --- a/rust/origen/src/core/status.rs +++ b/rust/origen/src/core/status.rs @@ -54,6 +54,57 @@ impl FromStr for Operation { } } +#[derive(Debug, Display)] +pub enum DependencySrc { + // Dependencies resolve from... + App(PathBuf), // the application + Workspace(PathBuf), // current directory tree (in workspace) + UserGlobal(PathBuf), // explicitly given by user, no workspace + Global(PathBuf), // the origen CLI installation directory, no workspace + None, // None available. Use whatever is available in the same install environment as Origen itself +} + +impl DependencySrc { + pub fn src_available(&self) -> bool { + match self { + Self::None => false, + _ => true, + } + } + + pub fn src_file(&self) -> Option<&PathBuf> { + match self { + Self::App(path) | Self::Workspace(path) | Self::UserGlobal(path) | Self::Global(path) => Some(path), + Self::None => None, + } + } +} + +impl TryFrom<(S, Option)> for DependencySrc +where S: AsRef { + type Error = crate::Error; + + fn try_from(value: (S, Option)) -> Result { + macro_rules! gen_case { + ($t: ident) => { + if let Some(path) = value.1 { + Self::$t(path) + } else { + bail!(concat!("A path is required with dependency src type '", stringify!($t), "'")); + } + } + } + Ok(match value.0.as_ref() { + "App" => gen_case!(App), + "Workspace" => gen_case!(Workspace), + "UserGlobal" => gen_case!(UserGlobal), + "Global" => gen_case!(Global), + "None" => Self::None, + _ => bail!("Cannot convert value '{}' to dependency src type", value.0.as_ref()) + }) + } +} + // FEATURE Backend Current Command. Either store some basics here, or use a frontend wrapper // use crate::TypedValueMap; // #[derive(Debug)] @@ -114,6 +165,7 @@ pub struct Status { unique_id: RwLock, debug_enabled: RwLock, _operation: RwLock, + dependency_src: RwLock>, // command: RwLock>, // FEATURE Backend Current Command } @@ -207,6 +259,7 @@ impl Default for Status { unique_id: RwLock::new(0), debug_enabled: RwLock::new(false), _operation: RwLock::new(Operation::None), + dependency_src: RwLock::new(None), // command: RwLock::new(None), // FEATURE Backend Current Command }; log_trace!("Status built successfully"); @@ -444,6 +497,15 @@ impl Status { *s = stat; } + pub fn set_dependency_src(&self, src: Option) { + let mut dependency_src = self.dependency_src.write().unwrap(); + *dependency_src = src; + } + + pub fn dependency_src(&self) -> RwLockReadGuard> { + self.dependency_src.read().unwrap() + } + /// This is the main method to get the current output directory, accounting for all /// possible ways to set it, from current command, the app, default, etc. /// If nothing has been set (only possible when running globally), then it will default diff --git a/rust/origen_metal/src/utils/command.rs b/rust/origen_metal/src/utils/command.rs index 2560bdaf..a2b70af3 100644 --- a/rust/origen_metal/src/utils/command.rs +++ b/rust/origen_metal/src/utils/command.rs @@ -6,18 +6,7 @@ use std::process::{Command, Stdio}; use std::time::Duration; use wait_timeout::ChildExt; -/// Executes the given command/args, returning all captured stdout and stderr lines and -/// the exit code of the process. -pub fn exec_and_capture( - cmd: &str, - args: Option>, -) -> Result<(std::process::ExitStatus, Vec, Vec)> { - let mut command = Command::new(cmd); - if let Some(args) = args { - for arg in args { - command.arg(arg); - } - } +pub fn exec_and_capture_cmd(mut command: Command) -> Result<(std::process::ExitStatus, Vec, Vec)> { let mut process = command .stdout(Stdio::piped()) .stderr(Stdio::piped()) @@ -39,6 +28,21 @@ pub fn exec_and_capture( Ok((exit_code, stdout_lines, stderr_lines)) } +/// Executes the given command/args, returning all captured stdout and stderr lines and +/// the exit code of the process. +pub fn exec_and_capture( + cmd: &str, + args: Option>, +) -> Result<(std::process::ExitStatus, Vec, Vec)> { + let mut command = Command::new(cmd); + if let Some(args) = args { + for arg in args { + command.arg(arg); + } + } + exec_and_capture_cmd(command) +} + /// Log both stdout and stderr to the debug and error logs respectively, optionally /// calling a callback function for each line captured. /// If no callbacks are given then any captures lines will be sent to the debug and diff --git a/rust/origen_metal/src/utils/file.rs b/rust/origen_metal/src/utils/file.rs index 1bb1c729..17a70fb3 100644 --- a/rust/origen_metal/src/utils/file.rs +++ b/rust/origen_metal/src/utils/file.rs @@ -60,6 +60,24 @@ pub fn search_backwards_for(files: Vec<&str>, base: &Path) -> (bool, PathBuf) { } } +/// Similar to search_backwards_for but takes a func returning Result> if found, None otherwise. +/// Returns Ok(Some) for the first result and ceases running. If no results are found, returns Ok(None) +pub fn search_backwards_for_first(mut start_path: PathBuf, mut func: F) -> Result> +where + F: FnMut(&Path) -> Result> +{ + if let Some(res) = func(&start_path)? { + return Ok(Some(res)); + } + + while start_path.pop() { + if let Some(res) = func(&start_path)? { + return Ok(Some(res)); + } + } + Ok(None) +} + /// Change the current directory to the given one pub fn cd(dir: &Path) -> Result<()> { env::set_current_dir(&dir).context(&format!("When cd'ing to '{}'", dir.display()))?; diff --git a/rust/pyapi/src/infrastructure/mod.rs b/rust/pyapi/src/infrastructure/mod.rs new file mode 100644 index 00000000..5ca25963 --- /dev/null +++ b/rust/pyapi/src/infrastructure/mod.rs @@ -0,0 +1,10 @@ +pub mod pyproject; + +use pyo3::prelude::*; + +pub fn define(py: Python, m: &PyModule) -> PyResult<()> { + let subm = PyModule::new(py, "infrastructure")?; + pyproject::define(py, subm)?; + m.add_submodule(subm)?; + Ok(()) +} diff --git a/rust/pyapi/src/infrastructure/pyproject.rs b/rust/pyapi/src/infrastructure/pyproject.rs new file mode 100644 index 00000000..319e1f19 --- /dev/null +++ b/rust/pyapi/src/infrastructure/pyproject.rs @@ -0,0 +1,53 @@ +use origen::STATUS; +use pyo3::prelude::*; +use pyo3::types::PyDict; +use origen::core::status::DependencySrc; + +pub fn populate_status(py: Python, status: &PyDict) -> PyResult<()> { + if let Some(d) = STATUS.dependency_src().as_ref() { + if let Some(pyproject) = d.src_file() { + status.set_item("pyproject", pyapi_metal::pypath!(py, pyproject.display()))?; + } else { + status.set_item("pyproject", py.None())?; + } + status.set_item("invocation", PyProjectSrc::from(d).to_py(py)?)?; + } else { + status.set_item("pyproject", py.None())?; + status.set_item("invocation", py.None())?; + } + Ok(()) +} + +pub fn define(py: Python, m: &PyModule) -> PyResult<()> { + let subm = PyModule::new(py, "pyproject")?; + subm.add_class::()?; + m.add_submodule(subm)?; + Ok(()) +} + +#[pyclass] +pub enum PyProjectSrc { + App, + Workspace, + UserGlobal, + Global, + None, +} + +impl PyProjectSrc { + pub fn to_py(self, py: Python) -> PyResult> { + Py::new(py, self) + } +} + +impl From<&DependencySrc> for PyProjectSrc { + fn from(src: &DependencySrc) -> Self { + match src { + DependencySrc::App(_) => Self::App, + DependencySrc::Workspace(_) => Self::Workspace, + DependencySrc::UserGlobal(_) => Self::UserGlobal, + DependencySrc::Global(_) => Self::Global, + DependencySrc::None => Self::None, + } + } +} \ No newline at end of file diff --git a/rust/pyapi/src/lib.rs b/rust/pyapi/src/lib.rs index f78560b5..fccc92f3 100644 --- a/rust/pyapi/src/lib.rs +++ b/rust/pyapi/src/lib.rs @@ -13,6 +13,7 @@ mod current_command; mod dut; mod extensions; mod file_handler; +mod infrastructure; mod meta; mod model; #[macro_use] @@ -48,6 +49,7 @@ use std::str::FromStr; use std::sync::MutexGuard; use utility::location::Location; use paste::paste; +use origen::core::status::DependencySrc; use crate::dut::__PYO3_PYMODULE_DEF_DUT; use crate::tester::__PYO3_PYMODULE_DEF_TESTER; @@ -112,6 +114,7 @@ fn _origen(py: Python, m: &PyModule) -> PyResult<()> { plugins::define(py, m)?; extensions::define(py, m)?; current_command::define(py, m)?; + infrastructure::define(py, m)?; // Compile the _origen_metal library along with this one // to allow re-use from that library @@ -379,9 +382,16 @@ fn initialize( cli_version: Option, fe_pkg_loc: Option, fe_exe_loc: Option, + invocation: Option<(String, Option)>, ) -> PyResult<()> { origen::initialize(log_verbosity, verbosity_keywords, cli_location, cli_version, fe_pkg_loc, fe_exe_loc); origen::STATUS.update_other_build_info("pyapi_version", built_info::PKG_VERSION)?; + if let Some(invoc) = invocation { + match DependencySrc::try_from(invoc) { + Ok(d) => origen::STATUS.set_dependency_src(Some(d)), + Err(e) => log_error!("{}", e.to_string()) + } + } origen::FRONTEND .write() .unwrap() @@ -516,11 +526,21 @@ fn status(py: Python) -> PyResult { None => py.None(), }, )?; + ret.set_item( + "cli_location", + match STATUS.cli_location() { + Some(path) => pypath!(py, path.display()), + None => py.None(), + }, + )?; ret.set_item( "is_app_in_origen_dev_mode", STATUS.is_app_in_origen_dev_mode, )?; ret.set_item("in_origen_core_app", STATUS.in_origen_core_app())?; + + // Invocation details + infrastructure::pyproject::populate_status(py, ret)?; Ok(ret.into()) } diff --git a/test_apps/no_workspace/__init__.py b/test_apps/no_workspace/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test_apps/no_workspace/t_invocation_env.py b/test_apps/no_workspace/t_invocation_env.py new file mode 100644 index 00000000..9185b399 --- /dev/null +++ b/test_apps/no_workspace/t_invocation_env.py @@ -0,0 +1,130 @@ +# Use the dev version but actual tests should be done through 'eval'. +import sys, pathlib +p = pathlib.Path(__file__).parent.parent.parent.joinpath("python/origen") +sys.path.append(str(p)) +sys.path.append(str(p.parent.joinpath("origen_metal"))) + +import origen, _origen, origen_metal + +import pytest, pip, jinja2, shutil, subprocess +from origen.helpers.regressions.cli import CLI +from types import ModuleType +from pathlib import Path, PosixPath, WindowsPath + +PyProjectSrc = _origen.infrastructure.pyproject.PyProjectSrc +toml = "pyproject.toml" +lockfile = "poetry.lock" +no_workspace_test_dir = pathlib.Path(__file__).parent +o2_root = no_workspace_test_dir.parent.parent +debug_cli_loc = o2_root.joinpath(f"rust/origen/target/debug/origen{'.exe' if origen.running_on_windows else ''}") + +# Assume pip is installed in 'site-packages' +site_packages_dir = pathlib.Path(pip.__file__).parent.parent + +class T_InvocationBaseTests(CLI): + templates_dir = no_workspace_test_dir.joinpath("templates") + templates_out_dir = templates_dir.joinpath("output") + debug_cli_loc = debug_cli_loc + PyProjectSrc = PyProjectSrc + + @classmethod + def setup(cls): + cls.set_params() + cls.target_pyproj_toml = cls.target_pyproj_dir.joinpath(toml) + cls.target_poetry_lock = cls.target_pyproj_dir.joinpath(lockfile) + + @property + def header(self): + return "--Origen Eval--" + + def test_invocation_from_pytest(self): + assert origen.status["pyproject"] is None + assert origen.status["invocation"] is None + + def eval_and_parse(self, code): + # out = CLI.global_cmds.eval.run(code, "-vv", run_opts={"return_details": True}) + out = CLI.global_cmds.eval.run(code) + out = out.split("\n") + idx = out.index(self.header) + return eval(out[idx+1]) + + def test_pyproject_and_invocation_set(self): + code = f"print('{self.header}'); print(origen.status)" + # code = r"print\(\\\"Origen\ Status:\\\"\) print\(origen.status\)" + status = self.eval_and_parse(code) + print(status) + assert status["pyproject"] == self.target_pyproj_toml + assert status["invocation"] == self.invocation + + def test_cli_location(self): + code = f"print('{self.header}'); print(origen.status)" + status = self.eval_and_parse(code) + assert status['cli_location'] == self.cli_location + +class T_InvocationEnv(T_InvocationBaseTests): + @classmethod + def setup(cls): + super().setup() + # cls.set_params() + cls._pyproj_src_file = cls.gen_pyproj() + if not hasattr(cls, "move_pyproject"): + cls.move_pyproject = True + # TODO clear any existing pyproject/poetry.locks ? + # cls._pyproj_lock = cls._pyproj_file.parent.joinpath("poetry.lock") + # for d in origen_exe_loc.parents: + # f = d.joinpath(toml) + # if f.exists(): + # target = f.parent.joinpath(f"{toml}.origen.regressions") + # print(f"Temporarily moving pyproject {f} to {target}") + # f.rename(target) + if cls.move_pyproject: + target = cls.target_pyproj_dir.joinpath(toml) + print(f"Moving pyproject {cls._pyproj_src_file} to {target}") + shutil.copy(cls._pyproj_src_file, target) + subprocess.run(["poetry", "install"], check=True, cwd=cls.target_pyproj_dir) + + @classmethod + def teardown(cls): + if cls.move_pyproject: + print(f"Cleaning pyproject and lockfile {cls.target_pyproj_toml}, {cls.target_poetry_lock}") + cls.target_pyproj_toml.unlink() + cls.target_poetry_lock.unlink() + + @classmethod + def gen_pyproj(cls): + env = jinja2.Environment( + loader=jinja2.FileSystemLoader(searchpath="./templates") + ) + t = env.get_template("pyproject.toml") + cls.templates_out_dir.mkdir(exist_ok=True) + pyproj = cls.templates_out_dir.joinpath(f"{cls.__name__}.{toml}") + with open(pyproj, "w") as f: + f.write(t.render(local_origen=cls.local_origen, name=cls.__name__, o2_root=o2_root)) + return pyproj + + # TEST_NEEDED invocation origen/metal package locations + # class TestBareEnv(CLI): + # @pytest.mark.parameterize( + # [origen, origen._origen, origen_metal, origen._origen_metal], + # ids=["origen", "_origen", "origen_metal", "_origen_metal"] + # ) + # def test_origen_pkgs(self, mod, ext, ): + # # assert origen.__file__ == ? + # # assert origen._origen.__file__ == + # # assert origen_metal.__file__ == ? + # # TEST_NEEDED CLI not sure why origen_metal._origen_metal has no filename + # # Just assert its a module fo now. + # # if id == "_origen_metal": + # assert isinstance(origen_metal._origen_metal, ModuleType) + + @pytest.mark.skip + def test_origen_h(self): + fail + + def test_plugins(self): + code = f"print('{self.header}'); print(list(origen.plugins.keys()))" + pls = self.eval_and_parse(code) + if self.has_pls: + assert pls == ['python_plugin_the_second', 'pl_ext_cmds', 'test_apps_shared_test_helpers', 'python_plugin'] + else: + assert pls == [] diff --git a/test_apps/no_workspace/templates/pyproject.toml b/test_apps/no_workspace/templates/pyproject.toml new file mode 100644 index 00000000..7be3df09 --- /dev/null +++ b/test_apps/no_workspace/templates/pyproject.toml @@ -0,0 +1,24 @@ +[tool.poetry] +name = "{{ name }}" +version = "0.1.0" +description = "Origen Installation Test" +authors = ["Origen-SDK"] + +[tool.poetry.dependencies] +python = ">=3.7,<3.11" +{% if local_origen %} +origen = { path = "{{ o2_root }}/python/origen", develop = true } +origen_metal = { path = "{{ o2_root }}/python/origen_metal", develop = true } +{% else %} +origen = ">= 0.0.0" +origen_metal = ">= 0.0.0" +{% endif %} +{% if include_plugins %} + {% if local_origen %} +pl_ext_cmds = { path = "{{ o2_root }}/test_apps/pl_ext_cmds", develop = true } +test_apps_shared_test_helpers = { path = "{{ o2_root }}/test_apps/test_apps_shared_test_helpers", develop = true } + {% else %} +pl_ext_cmds = ">= 0.0.0" +test_apps_shared_test_helpers = ">= 0.0.0" + {% endif %} +{% endif %} \ No newline at end of file diff --git a/test_apps/no_workspace/test_user_install.py b/test_apps/no_workspace/test_user_install.py new file mode 100644 index 00000000..01dd7e25 --- /dev/null +++ b/test_apps/no_workspace/test_user_install.py @@ -0,0 +1,60 @@ +import os +from .t_invocation_env import T_InvocationEnv, no_workspace_test_dir, PyProjectSrc + +# class TestGlobalNoPlugins(T_InvocationEnv): +# @classmethod +# def set_params(cls): +# cls.local_origen = True +# cls.has_pls = False +# cls.target_pyproj_dir = cls.site_packages_dir +# cls.invocation = PyProjectSrc.Global + +# class TestGlobalWithPluginsHigherLevel(T_InvocationEnv): +# @classmethod +# def set_params(cls): +# cls.local_origen = True +# cls.has_pls = False +# cls.target_pyproj_dir = cls.site_packages_dir.parent + +# class TestGlobalWithPlugins(T_InvocationEnv): +# ... + +class TestUserInstall(T_InvocationEnv): + user_install_dir = no_workspace_test_dir.joinpath("user_install") + + @classmethod + def set_params(cls): + cls.local_origen = True + cls.has_pls = True + cls.target_pyproj_dir = cls.user_install_dir + cls.move_pyproject = False + cls.invocation = PyProjectSrc.UserGlobal + cls.cli_location = cls.debug_cli_loc + + @classmethod + def setup_method(cls): + super().setup() + os.environ["ORIGEN_PYPROJECT"] = str(cls.user_install_dir) + + @classmethod + def teardown_method(cls): + del os.environ["ORIGEN_PYPROJECT"] + + def test_exts_in_user_global_context(self): + out = self.global_cmds.eval.run("print('hi with exts')", "-b", "-a") + assert "Hi from python-plugin during 'eval'!" in out + assert "Hi again from python-plugin during 'eval'!" in out + +# class TestGlobalInstall(T_InvocationEnv): +# ... + +# class TestGlobalInstallWithPlugins(T_InvocationEnv): +# ... + +# @pytest.mark.skip +# class TestErrorCases(T_InvocationEnv): +# def test_origen_pkg_not_installed(self): +# fail + +# def test_missing_pyproject(self): +# fail diff --git a/test_apps/no_workspace/user_install/inner/.keep b/test_apps/no_workspace/user_install/inner/.keep new file mode 100644 index 00000000..e69de29b diff --git a/test_apps/no_workspace/user_install/poetry.lock b/test_apps/no_workspace/user_install/poetry.lock new file mode 100644 index 00000000..dfd75ab2 --- /dev/null +++ b/test_apps/no_workspace/user_install/poetry.lock @@ -0,0 +1,1976 @@ +# This file is automatically @generated by Poetry and should not be changed by hand. + +[[package]] +name = "alabaster" +version = "0.7.13" +description = "A configurable sidebar-enabled Sphinx theme" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, + {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, +] + +[[package]] +name = "attrs" +version = "23.1.0" +description = "Classes Without Boilerplate" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, +] + +[package.dependencies] +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] + +[[package]] +name = "babel" +version = "2.12.1" +description = "Internationalization utilities" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"}, + {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"}, +] + +[package.dependencies] +pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} + +[[package]] +name = "backports-cached-property" +version = "1.0.2" +description = "cached_property() - computed once per instance, cached as attribute" +category = "main" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "backports.cached-property-1.0.2.tar.gz", hash = "sha256:9306f9eed6ec55fd156ace6bc1094e2c86fae5fb2bf07b6a9c00745c656e75dd"}, + {file = "backports.cached_property-1.0.2-py3-none-any.whl", hash = "sha256:baeb28e1cd619a3c9ab8941431fe34e8490861fb998c6c4590693d50171db0cc"}, +] + +[[package]] +name = "beautifulsoup4" +version = "4.8.2" +description = "Screen-scraping library" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "beautifulsoup4-4.8.2-py2-none-any.whl", hash = "sha256:e1505eeed31b0f4ce2dbb3bc8eb256c04cc2b3b72af7d551a4ab6efd5cbe5dae"}, + {file = "beautifulsoup4-4.8.2-py3-none-any.whl", hash = "sha256:9fbb4d6e48ecd30bcacc5b63b94088192dcda178513b2ae3c394229f8911b887"}, + {file = "beautifulsoup4-4.8.2.tar.gz", hash = "sha256:05fd825eb01c290877657a56df4c6e4c311b3965bda790c613a3d6fb01a5462a"}, +] + +[package.dependencies] +soupsieve = ">=1.2" + +[package.extras] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[[package]] +name = "bs4" +version = "0.0.1" +description = "Dummy package for Beautiful Soup" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "bs4-0.0.1.tar.gz", hash = "sha256:36ecea1fd7cc5c0c6e4a1ff075df26d50da647b75376626cc186e2212886dd3a"}, +] + +[package.dependencies] +beautifulsoup4 = "*" + +[[package]] +name = "build" +version = "0.10.0" +description = "A simple, correct Python build frontend" +category = "main" +optional = false +python-versions = ">= 3.7" +files = [ + {file = "build-0.10.0-py3-none-any.whl", hash = "sha256:af266720050a66c893a6096a2f410989eeac74ff9a68ba194b3f6473e8e26171"}, + {file = "build-0.10.0.tar.gz", hash = "sha256:d5b71264afdb5951d6704482aac78de887c80691c52b88a9ad195983ca2c9269"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "os_name == \"nt\""} +importlib-metadata = {version = ">=0.22", markers = "python_version < \"3.8\""} +packaging = ">=19.0" +pyproject_hooks = "*" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} + +[package.extras] +docs = ["furo (>=2021.08.31)", "sphinx (>=4.0,<5.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)"] +test = ["filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "toml (>=0.10.0)", "wheel (>=0.36.0)"] +typing = ["importlib-metadata (>=5.1)", "mypy (==0.991)", "tomli", "typing-extensions (>=3.7.4.3)"] +virtualenv = ["virtualenv (>=20.0.35)"] + +[[package]] +name = "cachecontrol" +version = "0.12.14" +description = "httplib2 caching for requests" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "CacheControl-0.12.14-py2.py3-none-any.whl", hash = "sha256:1c2939be362a70c4e5f02c6249462b3b7a24441e4f1ced5e9ef028172edf356a"}, + {file = "CacheControl-0.12.14.tar.gz", hash = "sha256:d1087f45781c0e00616479bfd282c78504371ca71da017b49df9f5365a95feba"}, +] + +[package.dependencies] +lockfile = {version = ">=0.9", optional = true, markers = "extra == \"filecache\""} +msgpack = ">=0.5.2" +requests = "*" + +[package.extras] +filecache = ["lockfile (>=0.9)"] +redis = ["redis (>=2.10.5)"] + +[[package]] +name = "certifi" +version = "2023.5.7" +description = "Python package for providing Mozilla's CA Bundle." +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, + {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, +] + +[[package]] +name = "cffi" +version = "1.15.1" +description = "Foreign Function Interface for Python calling C code." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "charset-normalizer" +version = "3.1.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, + {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, +] + +[[package]] +name = "cleo" +version = "2.0.1" +description = "Cleo allows you to create beautiful and testable command-line interfaces." +category = "main" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "cleo-2.0.1-py3-none-any.whl", hash = "sha256:6eb133670a3ed1f3b052d53789017b6e50fca66d1287e6e6696285f4cb8ea448"}, + {file = "cleo-2.0.1.tar.gz", hash = "sha256:eb4b2e1f3063c11085cebe489a6e9124163c226575a3c3be69b2e51af4a15ec5"}, +] + +[package.dependencies] +crashtest = ">=0.4.1,<0.5.0" +rapidfuzz = ">=2.2.0,<3.0.0" + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "commonmark" +version = "0.9.1" +description = "Python parser for the CommonMark Markdown spec" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, + {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, +] + +[package.extras] +test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] + +[[package]] +name = "crashtest" +version = "0.4.1" +description = "Manage Python errors with ease" +category = "main" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "crashtest-0.4.1-py3-none-any.whl", hash = "sha256:8d23eac5fa660409f57472e3851dab7ac18aba459a8d19cbbba86d3d5aecd2a5"}, + {file = "crashtest-0.4.1.tar.gz", hash = "sha256:80d7b1f316ebfbd429f648076d6275c877ba30ba48979de4191714a75266f0ce"}, +] + +[[package]] +name = "cryptography" +version = "41.0.1" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-41.0.1-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:f73bff05db2a3e5974a6fd248af2566134d8981fd7ab012e5dd4ddb1d9a70699"}, + {file = "cryptography-41.0.1-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:1a5472d40c8f8e91ff7a3d8ac6dfa363d8e3138b961529c996f3e2df0c7a411a"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fa01527046ca5facdf973eef2535a27fec4cb651e4daec4d043ef63f6ecd4ca"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b46e37db3cc267b4dea1f56da7346c9727e1209aa98487179ee8ebed09d21e43"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d198820aba55660b4d74f7b5fd1f17db3aa5eb3e6893b0a41b75e84e4f9e0e4b"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:948224d76c4b6457349d47c0c98657557f429b4e93057cf5a2f71d603e2fc3a3"}, + {file = "cryptography-41.0.1-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:059e348f9a3c1950937e1b5d7ba1f8e968508ab181e75fc32b879452f08356db"}, + {file = "cryptography-41.0.1-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:b4ceb5324b998ce2003bc17d519080b4ec8d5b7b70794cbd2836101406a9be31"}, + {file = "cryptography-41.0.1-cp37-abi3-win32.whl", hash = "sha256:8f4ab7021127a9b4323537300a2acfb450124b2def3756f64dc3a3d2160ee4b5"}, + {file = "cryptography-41.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:1fee5aacc7367487b4e22484d3c7e547992ed726d14864ee33c0176ae43b0d7c"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9a6c7a3c87d595608a39980ebaa04d5a37f94024c9f24eb7d10262b92f739ddb"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5d092fdfedaec4cbbffbf98cddc915ba145313a6fdaab83c6e67f4e6c218e6f3"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a8e6c2de6fbbcc5e14fd27fb24414507cb3333198ea9ab1258d916f00bc3039"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb33ccf15e89f7ed89b235cff9d49e2e62c6c981a6061c9c8bb47ed7951190bc"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5f0ff6e18d13a3de56f609dd1fd11470918f770c6bd5d00d632076c727d35485"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7bfc55a5eae8b86a287747053140ba221afc65eb06207bedf6e019b8934b477c"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:eb8163f5e549a22888c18b0d53d6bb62a20510060a22fd5a995ec8a05268df8a"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8dde71c4169ec5ccc1087bb7521d54251c016f126f922ab2dfe6649170a3b8c5"}, + {file = "cryptography-41.0.1.tar.gz", hash = "sha256:d34579085401d3f49762d2f7d6634d6b6c2ae1242202e860f4d26b046e3a1006"}, +] + +[package.dependencies] +cffi = ">=1.12" + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] +nox = ["nox"] +pep8test = ["black", "check-sdist", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "distlib" +version = "0.3.6" +description = "Distribution utilities" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, + {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, +] + +[[package]] +name = "docutils" +version = "0.20.1" +description = "Docutils -- Python Documentation Utilities" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, + {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, +] + +[[package]] +name = "dulwich" +version = "0.21.5" +description = "Python Git Library" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "dulwich-0.21.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8864719bc176cdd27847332a2059127e2f7bab7db2ff99a999873cb7fff54116"}, + {file = "dulwich-0.21.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3800cdc17d144c1f7e114972293bd6c46688f5bcc2c9228ed0537ded72394082"}, + {file = "dulwich-0.21.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e2f676bfed8146966fe934ee734969d7d81548fbd250a8308582973670a9dab1"}, + {file = "dulwich-0.21.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4db330fb59fe3b9d253bdf0e49a521739db83689520c4921ab1c5242aaf77b82"}, + {file = "dulwich-0.21.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e8f6d4f4f4d01dd1d3c968e486d4cd77f96f772da7265941bc506de0944ddb9"}, + {file = "dulwich-0.21.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1cc0c9ba19ac1b2372598802bc9201a9c45e5d6f1f7a80ec40deeb10acc4e9ae"}, + {file = "dulwich-0.21.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:61e10242b5a7a82faa8996b2c76239cfb633620b02cdd2946e8af6e7eb31d651"}, + {file = "dulwich-0.21.5-cp310-cp310-win32.whl", hash = "sha256:7f357639b56146a396f48e5e0bc9bbaca3d6d51c8340bd825299272b588fff5f"}, + {file = "dulwich-0.21.5-cp310-cp310-win_amd64.whl", hash = "sha256:891d5c73e2b66d05dbb502e44f027dc0dbbd8f6198bc90dae348152e69d0befc"}, + {file = "dulwich-0.21.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:45d6198e804b539708b73a003419e48fb42ff2c3c6dd93f63f3b134dff6dd259"}, + {file = "dulwich-0.21.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c2a565d4e704d7f784cdf9637097141f6d47129c8fffc2fac699d57cb075a169"}, + {file = "dulwich-0.21.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:823091d6b6a1ea07dc4839c9752198fb39193213d103ac189c7669736be2eaff"}, + {file = "dulwich-0.21.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2c9931b657f2206abec0964ec2355ee2c1e04d05f8864e823ffa23c548c4548"}, + {file = "dulwich-0.21.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7dc358c2ee727322a09b7c6da43d47a1026049dbd3ad8d612eddca1f9074b298"}, + {file = "dulwich-0.21.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6155ab7388ee01c670f7c5d8003d4e133eebebc7085a856c007989f0ba921b36"}, + {file = "dulwich-0.21.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a605e10d72f90a39ea2e634fbfd80f866fc4df29a02ea6db52ae92e5fd4a2003"}, + {file = "dulwich-0.21.5-cp311-cp311-win32.whl", hash = "sha256:daa607370722c3dce99a0022397c141caefb5ed32032a4f72506f4817ea6405b"}, + {file = "dulwich-0.21.5-cp311-cp311-win_amd64.whl", hash = "sha256:5e56b2c1911c344527edb2bf1a4356e2fb7e086b1ba309666e1e5c2224cdca8a"}, + {file = "dulwich-0.21.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:85d3401d08b1ec78c7d58ae987c4bb7b768a438f3daa74aeb8372bebc7fb16fa"}, + {file = "dulwich-0.21.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90479608e49db93d8c9e4323bc0ec5496678b535446e29d8fd67dc5bbb5d51bf"}, + {file = "dulwich-0.21.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9a6bf99f57bcac4c77fc60a58f1b322c91cc4d8c65dc341f76bf402622f89cb"}, + {file = "dulwich-0.21.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3e68b162af2aae995355e7920f89d50d72b53d56021e5ac0a546d493b17cbf7e"}, + {file = "dulwich-0.21.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0ab86d6d42e385bf3438e70f3c9b16de68018bd88929379e3484c0ef7990bd3c"}, + {file = "dulwich-0.21.5-cp37-cp37m-win32.whl", hash = "sha256:f2eeca6d61366cf5ee8aef45bed4245a67d4c0f0d731dc2383eabb80fa695683"}, + {file = "dulwich-0.21.5-cp37-cp37m-win_amd64.whl", hash = "sha256:1b20a3656b48c941d49c536824e1e5278a695560e8de1a83b53a630143c4552e"}, + {file = "dulwich-0.21.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3932b5e17503b265a85f1eda77ede647681c3bab53bc9572955b6b282abd26ea"}, + {file = "dulwich-0.21.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6616132d219234580de88ceb85dd51480dc43b1bdc05887214b8dd9cfd4a9d40"}, + {file = "dulwich-0.21.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:eaf6c7fb6b13495c19c9aace88821c2ade3c8c55b4e216cd7cc55d3e3807d7fa"}, + {file = "dulwich-0.21.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be12a46f73023970125808a4a78f610c055373096c1ecea3280edee41613eba8"}, + {file = "dulwich-0.21.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baecef0d8b9199822c7912876a03a1af17833f6c0d461efb62decebd45897e49"}, + {file = "dulwich-0.21.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:82f632afb9c7c341a875d46aaa3e6c5e586c7a64ce36c9544fa400f7e4f29754"}, + {file = "dulwich-0.21.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82cdf482f8f51fcc965ffad66180b54a9abaea9b1e985a32e1acbfedf6e0e363"}, + {file = "dulwich-0.21.5-cp38-cp38-win32.whl", hash = "sha256:c8ded43dc0bd2e65420eb01e778034be5ca7f72e397a839167eda7dcb87c4248"}, + {file = "dulwich-0.21.5-cp38-cp38-win_amd64.whl", hash = "sha256:2aba0fdad2a19bd5bb3aad6882580cb33359c67b48412ccd4cfccd932012b35e"}, + {file = "dulwich-0.21.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fd4ad079758514375f11469e081723ba8831ce4eaa1a64b41f06a3a866d5ac34"}, + {file = "dulwich-0.21.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fe62685bf356bfb4d0738f84a3fcf0d1fc9e11fee152e488a20b8c66a52429e"}, + {file = "dulwich-0.21.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aae448da7d80306dda4fc46292fed7efaa466294571ab3448be16714305076f1"}, + {file = "dulwich-0.21.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b24cb1fad0525dba4872e9381bc576ea2a6dcdf06b0ed98f8e953e3b1d719b89"}, + {file = "dulwich-0.21.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e39b7c2c9bda6acae83b25054650a8bb7e373e886e2334721d384e1479bf04b"}, + {file = "dulwich-0.21.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26456dba39d1209fca17187db06967130e27eeecad2b3c2bbbe63467b0bf09d6"}, + {file = "dulwich-0.21.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:281310644e02e3aa6d76bcaffe2063b9031213c4916b5f1a6e68c25bdecfaba4"}, + {file = "dulwich-0.21.5-cp39-cp39-win32.whl", hash = "sha256:4814ca3209dabe0fe7719e9545fbdad7f8bb250c5a225964fe2a31069940c4cf"}, + {file = "dulwich-0.21.5-cp39-cp39-win_amd64.whl", hash = "sha256:c922a4573267486be0ef85216f2da103fb38075b8465dc0e90457843884e4860"}, + {file = "dulwich-0.21.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e52b20c4368171b7d32bd3ab0f1d2402e76ad4f2ea915ff9aa73bc9fa2b54d6d"}, + {file = "dulwich-0.21.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeb736d777ee21f2117a90fc453ee181aa7eedb9e255b5ef07c51733f3fe5cb6"}, + {file = "dulwich-0.21.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e8a79c1ed7166f32ad21974fa98d11bf6fd74e94a47e754c777c320e01257c6"}, + {file = "dulwich-0.21.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:b943517e30bd651fbc275a892bb96774f3893d95fe5a4dedd84496a98eaaa8ab"}, + {file = "dulwich-0.21.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:32493a456358a3a6c15bbda07106fc3d4cc50834ee18bc7717968d18be59b223"}, + {file = "dulwich-0.21.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0aa44b812d978fc22a04531f5090c3c369d5facd03fa6e0501d460a661800c7f"}, + {file = "dulwich-0.21.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f46bcb6777e5f9f4af24a2bd029e88b77316269d24ce66be590e546a0d8f7b7"}, + {file = "dulwich-0.21.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a917fd3b4493db3716da2260f16f6b18f68d46fbe491d851d154fc0c2d984ae4"}, + {file = "dulwich-0.21.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:684c52cff867d10c75a7238151ca307582b3d251bbcd6db9e9cffbc998ef804e"}, + {file = "dulwich-0.21.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9019189d7a8f7394df6a22cd5b484238c5776e42282ad5d6d6c626b4c5f43597"}, + {file = "dulwich-0.21.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:494024f74c2eef9988adb4352b3651ac1b6c0466176ec62b69d3d3672167ba68"}, + {file = "dulwich-0.21.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f9b6ac1b1c67fc6083c42b7b6cd3b211292c8a6517216c733caf23e8b103ab6d"}, + {file = "dulwich-0.21.5.tar.gz", hash = "sha256:70955e4e249ddda6e34a4636b90f74e931e558f993b17c52570fa6144b993103"}, +] + +[package.dependencies] +typing-extensions = {version = "*", markers = "python_version <= \"3.7\""} +urllib3 = ">=1.25" + +[package.extras] +fastimport = ["fastimport"] +https = ["urllib3 (>=1.24.1)"] +paramiko = ["paramiko"] +pgp = ["gpg"] + +[[package]] +name = "exceptiongroup" +version = "1.1.1" +description = "Backport of PEP 654 (exception groups)" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"}, + {file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "filelock" +version = "3.12.2" +description = "A platform independent file lock." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, + {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, +] + +[package.extras] +docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] + +[[package]] +name = "html5lib" +version = "1.1" +description = "HTML parser based on the WHATWG HTML specification" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"}, + {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"}, +] + +[package.dependencies] +six = ">=1.9" +webencodings = "*" + +[package.extras] +all = ["chardet (>=2.2)", "genshi", "lxml"] +chardet = ["chardet (>=2.2)"] +genshi = ["genshi"] +lxml = ["lxml"] + +[[package]] +name = "idna" +version = "3.4" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] + +[[package]] +name = "imagesize" +version = "1.4.1" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, +] + +[[package]] +name = "importlib-metadata" +version = "6.7.0" +description = "Read metadata from Python packages" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5"}, + {file = "importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4"}, +] + +[package.dependencies] +typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] + +[[package]] +name = "importlib-resources" +version = "5.12.0" +description = "Read resources from Python packages" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, + {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"}, +] + +[package.dependencies] +zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "installer" +version = "0.7.0" +description = "A library for installing Python wheels." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "installer-0.7.0-py3-none-any.whl", hash = "sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53"}, + {file = "installer-0.7.0.tar.gz", hash = "sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631"}, +] + +[[package]] +name = "jaraco-classes" +version = "3.2.3" +description = "Utility functions for Python class constructs" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jaraco.classes-3.2.3-py3-none-any.whl", hash = "sha256:2353de3288bc6b82120752201c6b1c1a14b058267fa424ed5ce5984e3b922158"}, + {file = "jaraco.classes-3.2.3.tar.gz", hash = "sha256:89559fa5c1d3c34eff6f631ad80bb21f378dbcbb35dd161fd2c6b93f5be2f98a"}, +] + +[package.dependencies] +more-itertools = "*" + +[package.extras] +docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + +[[package]] +name = "jeepney" +version = "0.8.0" +description = "Low-level, pure Python DBus protocol wrapper." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"}, + {file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"}, +] + +[package.extras] +test = ["async-timeout", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] +trio = ["async_generator", "trio"] + +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "jsonschema" +version = "4.17.3" +description = "An implementation of JSON Schema validation for Python" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, +] + +[package.dependencies] +attrs = ">=17.4.0" +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" +typing-extensions = {version = "*", markers = "python_version < \"3.8\""} + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "keyring" +version = "23.13.1" +description = "Store and access your passwords safely." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "keyring-23.13.1-py3-none-any.whl", hash = "sha256:771ed2a91909389ed6148631de678f82ddc73737d85a927f382a8a1b157898cd"}, + {file = "keyring-23.13.1.tar.gz", hash = "sha256:ba2e15a9b35e21908d0aaf4e0a47acc52d6ae33444df0da2b49d41a46ef6d678"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.11.4", markers = "python_version < \"3.12\""} +importlib-resources = {version = "*", markers = "python_version < \"3.9\""} +"jaraco.classes" = "*" +jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} +pywin32-ctypes = {version = ">=0.2.0", markers = "sys_platform == \"win32\""} +SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} + +[package.extras] +completion = ["shtab"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + +[[package]] +name = "lockfile" +version = "0.12.2" +description = "Platform-independent file locking module" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "lockfile-0.12.2-py2.py3-none-any.whl", hash = "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa"}, + {file = "lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799"}, +] + +[[package]] +name = "mako" +version = "1.1.0" +description = "A super-fast templating language that borrows the best ideas from the existing templating languages." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "Mako-1.1.0.tar.gz", hash = "sha256:a36919599a9b7dc5d86a7a8988f23a9a3a3d083070023bab23d64f7f1d1e0a4b"}, +] + +[package.dependencies] +MarkupSafe = ">=0.9.2" + +[[package]] +name = "markupsafe" +version = "2.1.3" +description = "Safely add untrusted strings to HTML/XML markup." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, +] + +[[package]] +name = "more-itertools" +version = "9.1.0" +description = "More routines for operating on iterables, beyond itertools" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "more-itertools-9.1.0.tar.gz", hash = "sha256:cabaa341ad0389ea83c17a94566a53ae4c9d07349861ecb14dc6d0345cf9ac5d"}, + {file = "more_itertools-9.1.0-py3-none-any.whl", hash = "sha256:d2bc7f02446e86a68911e58ded76d6561eea00cddfb2a91e7019bbb586c799f3"}, +] + +[[package]] +name = "msgpack" +version = "1.0.5" +description = "MessagePack serializer" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:525228efd79bb831cf6830a732e2e80bc1b05436b086d4264814b4b2955b2fa9"}, + {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f8d8b3bf1ff2672567d6b5c725a1b347fe838b912772aa8ae2bf70338d5a198"}, + {file = "msgpack-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdc793c50be3f01106245a61b739328f7dccc2c648b501e237f0699fe1395b81"}, + {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cb47c21a8a65b165ce29f2bec852790cbc04936f502966768e4aae9fa763cb7"}, + {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e42b9594cc3bf4d838d67d6ed62b9e59e201862a25e9a157019e171fbe672dd3"}, + {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:55b56a24893105dc52c1253649b60f475f36b3aa0fc66115bffafb624d7cb30b"}, + {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1967f6129fc50a43bfe0951c35acbb729be89a55d849fab7686004da85103f1c"}, + {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20a97bf595a232c3ee6d57ddaadd5453d174a52594bf9c21d10407e2a2d9b3bd"}, + {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d25dd59bbbbb996eacf7be6b4ad082ed7eacc4e8f3d2df1ba43822da9bfa122a"}, + {file = "msgpack-1.0.5-cp310-cp310-win32.whl", hash = "sha256:382b2c77589331f2cb80b67cc058c00f225e19827dbc818d700f61513ab47bea"}, + {file = "msgpack-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:4867aa2df9e2a5fa5f76d7d5565d25ec76e84c106b55509e78c1ede0f152659a"}, + {file = "msgpack-1.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9f5ae84c5c8a857ec44dc180a8b0cc08238e021f57abdf51a8182e915e6299f0"}, + {file = "msgpack-1.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e6ca5d5699bcd89ae605c150aee83b5321f2115695e741b99618f4856c50898"}, + {file = "msgpack-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5494ea30d517a3576749cad32fa27f7585c65f5f38309c88c6d137877fa28a5a"}, + {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ab2f3331cb1b54165976a9d976cb251a83183631c88076613c6c780f0d6e45a"}, + {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28592e20bbb1620848256ebc105fc420436af59515793ed27d5c77a217477705"}, + {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe5c63197c55bce6385d9aee16c4d0641684628f63ace85f73571e65ad1c1e8d"}, + {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed40e926fa2f297e8a653c954b732f125ef97bdd4c889f243182299de27e2aa9"}, + {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b2de4c1c0538dcb7010902a2b97f4e00fc4ddf2c8cda9749af0e594d3b7fa3d7"}, + {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bf22a83f973b50f9d38e55c6aade04c41ddda19b00c4ebc558930d78eecc64ed"}, + {file = "msgpack-1.0.5-cp311-cp311-win32.whl", hash = "sha256:c396e2cc213d12ce017b686e0f53497f94f8ba2b24799c25d913d46c08ec422c"}, + {file = "msgpack-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c4c68d87497f66f96d50142a2b73b97972130d93677ce930718f68828b382e2"}, + {file = "msgpack-1.0.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a2b031c2e9b9af485d5e3c4520f4220d74f4d222a5b8dc8c1a3ab9448ca79c57"}, + {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f837b93669ce4336e24d08286c38761132bc7ab29782727f8557e1eb21b2080"}, + {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1d46dfe3832660f53b13b925d4e0fa1432b00f5f7210eb3ad3bb9a13c6204a6"}, + {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:366c9a7b9057e1547f4ad51d8facad8b406bab69c7d72c0eb6f529cf76d4b85f"}, + {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4c075728a1095efd0634a7dccb06204919a2f67d1893b6aa8e00497258bf926c"}, + {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:f933bbda5a3ee63b8834179096923b094b76f0c7a73c1cfe8f07ad608c58844b"}, + {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:36961b0568c36027c76e2ae3ca1132e35123dcec0706c4b7992683cc26c1320c"}, + {file = "msgpack-1.0.5-cp36-cp36m-win32.whl", hash = "sha256:b5ef2f015b95f912c2fcab19c36814963b5463f1fb9049846994b007962743e9"}, + {file = "msgpack-1.0.5-cp36-cp36m-win_amd64.whl", hash = "sha256:288e32b47e67f7b171f86b030e527e302c91bd3f40fd9033483f2cacc37f327a"}, + {file = "msgpack-1.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:137850656634abddfb88236008339fdaba3178f4751b28f270d2ebe77a563b6c"}, + {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c05a4a96585525916b109bb85f8cb6511db1c6f5b9d9cbcbc940dc6b4be944b"}, + {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56a62ec00b636583e5cb6ad313bbed36bb7ead5fa3a3e38938503142c72cba4f"}, + {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef8108f8dedf204bb7b42994abf93882da1159728a2d4c5e82012edd92c9da9f"}, + {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1835c84d65f46900920b3708f5ba829fb19b1096c1800ad60bae8418652a951d"}, + {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e57916ef1bd0fee4f21c4600e9d1da352d8816b52a599c46460e93a6e9f17086"}, + {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:17358523b85973e5f242ad74aa4712b7ee560715562554aa2134d96e7aa4cbbf"}, + {file = "msgpack-1.0.5-cp37-cp37m-win32.whl", hash = "sha256:cb5aaa8c17760909ec6cb15e744c3ebc2ca8918e727216e79607b7bbce9c8f77"}, + {file = "msgpack-1.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:ab31e908d8424d55601ad7075e471b7d0140d4d3dd3272daf39c5c19d936bd82"}, + {file = "msgpack-1.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b72d0698f86e8d9ddf9442bdedec15b71df3598199ba33322d9711a19f08145c"}, + {file = "msgpack-1.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:379026812e49258016dd84ad79ac8446922234d498058ae1d415f04b522d5b2d"}, + {file = "msgpack-1.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:332360ff25469c346a1c5e47cbe2a725517919892eda5cfaffe6046656f0b7bb"}, + {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:476a8fe8fae289fdf273d6d2a6cb6e35b5a58541693e8f9f019bfe990a51e4ba"}, + {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9985b214f33311df47e274eb788a5893a761d025e2b92c723ba4c63936b69b1"}, + {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48296af57cdb1d885843afd73c4656be5c76c0c6328db3440c9601a98f303d87"}, + {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:addab7e2e1fcc04bd08e4eb631c2a90960c340e40dfc4a5e24d2ff0d5a3b3edb"}, + {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:916723458c25dfb77ff07f4c66aed34e47503b2eb3188b3adbec8d8aa6e00f48"}, + {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:821c7e677cc6acf0fd3f7ac664c98803827ae6de594a9f99563e48c5a2f27eb0"}, + {file = "msgpack-1.0.5-cp38-cp38-win32.whl", hash = "sha256:1c0f7c47f0087ffda62961d425e4407961a7ffd2aa004c81b9c07d9269512f6e"}, + {file = "msgpack-1.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:bae7de2026cbfe3782c8b78b0db9cbfc5455e079f1937cb0ab8d133496ac55e1"}, + {file = "msgpack-1.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:20c784e66b613c7f16f632e7b5e8a1651aa5702463d61394671ba07b2fc9e025"}, + {file = "msgpack-1.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:266fa4202c0eb94d26822d9bfd7af25d1e2c088927fe8de9033d929dd5ba24c5"}, + {file = "msgpack-1.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18334484eafc2b1aa47a6d42427da7fa8f2ab3d60b674120bce7a895a0a85bdd"}, + {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57e1f3528bd95cc44684beda696f74d3aaa8a5e58c816214b9046512240ef437"}, + {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586d0d636f9a628ddc6a17bfd45aa5b5efaf1606d2b60fa5d87b8986326e933f"}, + {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a740fa0e4087a734455f0fc3abf5e746004c9da72fbd541e9b113013c8dc3282"}, + {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3055b0455e45810820db1f29d900bf39466df96ddca11dfa6d074fa47054376d"}, + {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a61215eac016f391129a013c9e46f3ab308db5f5ec9f25811e811f96962599a8"}, + {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:362d9655cd369b08fda06b6657a303eb7172d5279997abe094512e919cf74b11"}, + {file = "msgpack-1.0.5-cp39-cp39-win32.whl", hash = "sha256:ac9dd47af78cae935901a9a500104e2dea2e253207c924cc95de149606dc43cc"}, + {file = "msgpack-1.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:06f5174b5f8ed0ed919da0e62cbd4ffde676a374aba4020034da05fab67b9164"}, + {file = "msgpack-1.0.5.tar.gz", hash = "sha256:c075544284eadc5cddc70f4757331d99dcbc16b2bbd4849d15f8aae4cf36d31c"}, +] + +[[package]] +name = "origen" +version = "2.0.0.dev5" +description = "Semiconductor Developer's Kit" +category = "main" +optional = false +python-versions = ">=3.7,<3.11" +files = [] +develop = true + +[package.dependencies] +beautifulsoup4 = "4.8.2" +bs4 = "0.0.1" +colorama = "^0.4" +importlib-metadata = ">= 1.7.0" +Jinja2 = "^3" +mako = "1.1.0" +origen_autoapi = "2.0.1" +origen_metal = "= 0.4.0" +poetry = "^1.1.14" +recommonmark = ">= 0" +sphinx = "3.0.2" +sphinxbootstrap4theme = ">= 0" +termcolor = ">= 1.1.0" +yapf = "0.30" + +[package.source] +type = "directory" +url = "../../../python/origen" + +[[package]] +name = "origen-autoapi" +version = "2.0.1" +description = "Automatic API reference documentation generation for Sphinx inspired by Doxygen, with changes for the Origen project." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "origen_autoapi-2.0.1-py3-none-any.whl", hash = "sha256:2807aaa7c861e54679a572bdf36d5c77ea4f26f61464b5dba293f44dd4db8dca"}, + {file = "origen_autoapi-2.0.1.tar.gz", hash = "sha256:df282703e9a430a4242299684d69d0631ea8c6e323c920e57580dc04d78c0c3d"}, +] + +[package.dependencies] +sphinx = "*" + +[[package]] +name = "origen-metal" +version = "0.4.0" +description = "Bare metal APIs for the Origen SDK" +category = "main" +optional = false +python-versions = ">=3.7,<3.11" +files = [] +develop = true + +[package.dependencies] +colorama = ">= 0.4.4" +pyreadline3 = {version = "^3.3", markers = "sys_platform == \"win32\""} +termcolor = ">= 1.1.0" + +[package.source] +type = "directory" +url = "../../../python/origen_metal" + +[[package]] +name = "packaging" +version = "23.1" +description = "Core utilities for Python packages" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, + {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, +] + +[[package]] +name = "pexpect" +version = "4.8.0" +description = "Pexpect allows easy control of interactive console applications." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, + {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pkginfo" +version = "1.9.6" +description = "Query metadata from sdists / bdists / installed packages." +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pkginfo-1.9.6-py3-none-any.whl", hash = "sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546"}, + {file = "pkginfo-1.9.6.tar.gz", hash = "sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046"}, +] + +[package.extras] +testing = ["pytest", "pytest-cov"] + +[[package]] +name = "pkgutil-resolve-name" +version = "1.3.10" +description = "Resolve a name to an object." +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, + {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, +] + +[[package]] +name = "pl-ext-cmds" +version = "0.1.0" +description = "Plugin Extending Cmds" +category = "main" +optional = false +python-versions = ">=3.7,<3.11" +files = [] +develop = true + +[package.dependencies] +origen = {path = "../../python/origen", develop = true} +origen_metal = {path = "../../python/origen_metal", develop = true} + +[package.source] +type = "directory" +url = "../../pl_ext_cmds" + +[[package]] +name = "platformdirs" +version = "3.6.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "platformdirs-3.6.0-py3-none-any.whl", hash = "sha256:ffa199e3fbab8365778c4a10e1fbf1b9cd50707de826eb304b50e57ec0cc8d38"}, + {file = "platformdirs-3.6.0.tar.gz", hash = "sha256:57e28820ca8094678b807ff529196506d7a21e17156cb1cddb3e74cebce54640"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.6.3", markers = "python_version < \"3.8\""} + +[package.extras] +docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"] + +[[package]] +name = "pluggy" +version = "1.0.0" +description = "plugin and hook calling mechanisms for python" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "poetry" +version = "1.5.1" +description = "Python dependency management and packaging made easy." +category = "main" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "poetry-1.5.1-py3-none-any.whl", hash = "sha256:dfc7ce3a38ae216c0465694e2e674bef6eb1a2ba81aa47a26f9dc03362fe2f5f"}, + {file = "poetry-1.5.1.tar.gz", hash = "sha256:cc7ea4524d1a11558006224bfe8ba8ed071417d4eb5ef6c89decc6a37d437eeb"}, +] + +[package.dependencies] +"backports.cached-property" = {version = ">=1.0.2,<2.0.0", markers = "python_version < \"3.8\""} +build = ">=0.10.0,<0.11.0" +cachecontrol = {version = ">=0.12.9,<0.13.0", extras = ["filecache"]} +cleo = ">=2.0.0,<3.0.0" +crashtest = ">=0.4.1,<0.5.0" +dulwich = ">=0.21.2,<0.22.0" +filelock = ">=3.8.0,<4.0.0" +html5lib = ">=1.0,<2.0" +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} +installer = ">=0.7.0,<0.8.0" +jsonschema = ">=4.10.0,<5.0.0" +keyring = ">=23.9.0,<24.0.0" +lockfile = ">=0.12.2,<0.13.0" +packaging = ">=20.4" +pexpect = ">=4.7.0,<5.0.0" +pkginfo = ">=1.9.4,<2.0.0" +platformdirs = ">=3.0.0,<4.0.0" +poetry-core = "1.6.1" +poetry-plugin-export = ">=1.4.0,<2.0.0" +pyproject-hooks = ">=1.0.0,<2.0.0" +requests = ">=2.18,<3.0" +requests-toolbelt = ">=0.9.1,<2" +shellingham = ">=1.5,<2.0" +tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""} +tomlkit = ">=0.11.4,<1.0.0" +trove-classifiers = ">=2022.5.19" +urllib3 = ">=1.26.0,<2.0.0" +virtualenv = ">=20.22.0,<21.0.0" +xattr = {version = ">=0.10.0,<0.11.0", markers = "sys_platform == \"darwin\""} + +[[package]] +name = "poetry-core" +version = "1.6.1" +description = "Poetry PEP 517 Build Backend" +category = "main" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "poetry_core-1.6.1-py3-none-any.whl", hash = "sha256:70707340447dee0e7f334f9495ae652481c67b32d8d218f296a376ac2ed73573"}, + {file = "poetry_core-1.6.1.tar.gz", hash = "sha256:0f9b0de39665f36d6594657e7d57b6f463cc10f30c28e6d1c3b9ff54c26c9ac3"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=1.7.0", markers = "python_version < \"3.8\""} + +[[package]] +name = "poetry-plugin-export" +version = "1.4.0" +description = "Poetry plugin to export the dependencies to various formats" +category = "main" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "poetry_plugin_export-1.4.0-py3-none-any.whl", hash = "sha256:5d9186d6f77cf2bf35fc96bd11fe650cc7656e515b17d99cb65018d50ba22589"}, + {file = "poetry_plugin_export-1.4.0.tar.gz", hash = "sha256:f16974cd9f222d4ef640fa97a8d661b04d4fb339e51da93973f1bc9d578e183f"}, +] + +[package.dependencies] +poetry = ">=1.5.0,<2.0.0" +poetry-core = ">=1.6.0,<2.0.0" + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] + +[[package]] +name = "pygments" +version = "2.15.1" +description = "Pygments is a syntax highlighting package written in Python." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, + {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, +] + +[package.extras] +plugins = ["importlib-metadata"] + +[[package]] +name = "pyproject-hooks" +version = "1.0.0" +description = "Wrappers to call pyproject.toml-based build backend hooks." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"}, + {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"}, +] + +[package.dependencies] +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} + +[[package]] +name = "pyreadline3" +version = "3.4.1" +description = "A python implementation of GNU readline." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "pyreadline3-3.4.1-py3-none-any.whl", hash = "sha256:b0efb6516fd4fb07b45949053826a62fa4cb353db5be2bbb4a7aa1fdd1e345fb"}, + {file = "pyreadline3-3.4.1.tar.gz", hash = "sha256:6f3d1f7b8a31ba32b73917cefc1f28cc660562f39aea8646d30bd6eff21f7bae"}, +] + +[[package]] +name = "pyrsistent" +version = "0.19.3" +description = "Persistent/Functional/Immutable data structures" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, + {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, + {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, + {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"}, + {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"}, + {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"}, + {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"}, + {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"}, + {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"}, + {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"}, + {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"}, + {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"}, + {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"}, + {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"}, + {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"}, + {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"}, + {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"}, + {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"}, + {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"}, + {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"}, + {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, + {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, +] + +[[package]] +name = "pytest" +version = "7.3.2" +description = "pytest: simple powerful testing with Python" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-7.3.2-py3-none-any.whl", hash = "sha256:cdcbd012c9312258922f8cd3f1b62a6580fdced17db6014896053d47cddf9295"}, + {file = "pytest-7.3.2.tar.gz", hash = "sha256:ee990a3cc55ba808b80795a79944756f315c67c12b56abd3ac993a7b8c17030b"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} + +[package.extras] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "python-plugin" +version = "0.1.0" +description = "Example Origen Plugin" +category = "main" +optional = false +python-versions = ">=3.7,<3.11" +files = [] +develop = true + +[package.dependencies] +origen = {path = "../../python/origen", develop = true} + +[package.source] +type = "directory" +url = "../../python_plugin" + +[[package]] +name = "pytz" +version = "2023.3" +description = "World timezone definitions, modern and historical" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, + {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, +] + +[[package]] +name = "pywin32-ctypes" +version = "0.2.1" +description = "A (partial) reimplementation of pywin32 using ctypes/cffi" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pywin32-ctypes-0.2.1.tar.gz", hash = "sha256:934a2def1e5cbc472b2b6bf80680c0f03cd87df65dfd58bfd1846969de095b03"}, + {file = "pywin32_ctypes-0.2.1-py3-none-any.whl", hash = "sha256:b9a53ef754c894a525469933ab2a447c74ec1ea6b9d2ef446f40ec50d3dcec9f"}, +] + +[[package]] +name = "rapidfuzz" +version = "2.15.1" +description = "rapid fuzzy string matching" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "rapidfuzz-2.15.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fc0bc259ebe3b93e7ce9df50b3d00e7345335d35acbd735163b7c4b1957074d3"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d59fb3a410d253f50099d7063855c2b95df1ef20ad93ea3a6b84115590899f25"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c525a3da17b6d79d61613096c8683da86e3573e807dfaecf422eea09e82b5ba6"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4deae6a918ecc260d0c4612257be8ba321d8e913ccb43155403842758c46fbe"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2577463d10811386e704a3ab58b903eb4e2a31b24dfd9886d789b0084d614b01"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f67d5f56aa48c0da9de4ab81bffb310683cf7815f05ea38e5aa64f3ba4368339"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7927722ff43690e52b3145b5bd3089151d841d350c6f8378c3cfac91f67573a"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6534afc787e32c4104f65cdeb55f6abe4d803a2d0553221d00ef9ce12788dcde"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d0ae6ec79a1931929bb9dd57bc173eb5ba4c7197461bf69e3a34b6dd314feed2"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:be7ccc45c4d1a7dfb595f260e8022a90c6cb380c2a346ee5aae93f85c96d362b"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:8ba013500a2b68c64b2aecc5fb56a2dad6c2872cf545a0308fd044827b6e5f6a"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4d9f7d10065f657f960b48699e7dddfce14ab91af4bab37a215f0722daf0d716"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7e24a1b802cea04160b3fccd75d2d0905065783ebc9de157d83c14fb9e1c6ce2"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-win32.whl", hash = "sha256:dffdf03499e0a5b3442951bb82b556333b069e0661e80568752786c79c5b32de"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d150d90a7c6caae7962f29f857a4e61d42038cfd82c9df38508daf30c648ae7"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-win_arm64.whl", hash = "sha256:87c30e9184998ff6eb0fa9221f94282ce7c908fd0da96a1ef66ecadfaaa4cdb7"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6986413cb37035eb796e32f049cbc8c13d8630a4ac1e0484e3e268bb3662bd1b"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a72f26e010d4774b676f36e43c0fc8a2c26659efef4b3be3fd7714d3491e9957"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b5cd54c98a387cca111b3b784fc97a4f141244bbc28a92d4bde53f164464112e"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da7fac7c3da39f93e6b2ebe386ed0ffe1cefec91509b91857f6e1204509e931f"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f976e76ac72f650790b3a5402431612175b2ac0363179446285cb3c901136ca9"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:abde47e1595902a490ed14d4338d21c3509156abb2042a99e6da51f928e0c117"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca8f1747007a3ce919739a60fa95c5325f7667cccf6f1c1ef18ae799af119f5e"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c35da09ab9797b020d0d4f07a66871dfc70ea6566363811090353ea971748b5a"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a3a769ca7580686a66046b77df33851b3c2d796dc1eb60c269b68f690f3e1b65"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d50622efefdb03a640a51a6123748cd151d305c1f0431af762e833d6ffef71f0"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b7461b0a7651d68bc23f0896bffceea40f62887e5ab8397bf7caa883592ef5cb"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:074ee9e17912e025c72a5780ee4c7c413ea35cd26449719cc399b852d4e42533"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7025fb105a11f503943f17718cdb8241ea3bb4d812c710c609e69bead40e2ff0"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-win32.whl", hash = "sha256:2084d36b95139413cef25e9487257a1cc892b93bd1481acd2a9656f7a1d9930c"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:5a738fcd24e34bce4b19126b92fdae15482d6d3a90bd687fd3d24ce9d28ce82d"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-win_arm64.whl", hash = "sha256:dc3cafa68cfa54638632bdcadf9aab89a3d182b4a3f04d2cad7585ed58ea8731"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3c53d57ba7a88f7bf304d4ea5a14a0ca112db0e0178fff745d9005acf2879f7d"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6ee758eec4cf2215dc8d8eafafcea0d1f48ad4b0135767db1b0f7c5c40a17dd"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d93ba3ae59275e7a3a116dac4ffdb05e9598bf3ee0861fecc5b60fb042d539e"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7c3ff75e647908ddbe9aa917fbe39a112d5631171f3fcea5809e2363e525a59d"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d89c421702474c6361245b6b199e6e9783febacdbfb6b002669e6cb3ef17a09"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f69e6199fec0f58f9a89afbbaea78d637c7ce77f656a03a1d6ea6abdc1d44f8"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:41dfea282844d0628279b4db2929da0dacb8ac317ddc5dcccc30093cf16357c1"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2dd03477feefeccda07b7659dd614f6738cfc4f9b6779dd61b262a73b0a9a178"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:5efe035aa76ff37d1b5fa661de3c4b4944de9ff227a6c0b2e390a95c101814c0"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:ed2cf7c69102c7a0a06926d747ed855bc836f52e8d59a5d1e3adfd980d1bd165"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a0e441d4c2025110ec3eba5d54f11f78183269a10152b3a757a739ffd1bb12bf"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-win32.whl", hash = "sha256:a4a54efe17cc9f53589c748b53f28776dfdfb9bc83619685740cb7c37985ac2f"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:bb8318116ecac4dfb84841d8b9b461f9bb0c3be5b616418387d104f72d2a16d1"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e9296c530e544f68858c3416ad1d982a1854f71e9d2d3dcedb5b216e6d54f067"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:49c4bcdb9238f11f8c4eba1b898937f09b92280d6f900023a8216008f299b41a"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb40a279e134bb3fef099a8b58ed5beefb201033d29bdac005bddcdb004ef71"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7381c11cb590bbd4e6f2d8779a0b34fdd2234dfa13d0211f6aee8ca166d9d05"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfdcdedfd12a0077193f2cf3626ff6722c5a184adf0d2d51f1ec984bf21c23c3"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f85bece1ec59bda8b982bd719507d468d4df746dfb1988df11d916b5e9fe19e8"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1b393f4a1eaa6867ffac6aef58cfb04bab2b3d7d8e40b9fe2cf40dd1d384601"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53de456ef020a77bf9d7c6c54860a48e2e902584d55d3001766140ac45c54bc7"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2492330bc38b76ed967eab7bdaea63a89b6ceb254489e2c65c3824efcbf72993"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:099e4c6befaa8957a816bdb67ce664871f10aaec9bebf2f61368cf7e0869a7a1"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:46599b2ad4045dd3f794a24a6db1e753d23304699d4984462cf1ead02a51ddf3"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:591f19d16758a3c55c9d7a0b786b40d95599a5b244d6eaef79c7a74fcf5104d8"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ed17359061840eb249f8d833cb213942e8299ffc4f67251a6ed61833a9f2ea20"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-win32.whl", hash = "sha256:aa1e5aad325168e29bf8e17006479b97024aa9d2fdbe12062bd2f8f09080acf8"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:c2bb68832b140c551dbed691290bef4ee6719d4e8ce1b7226a3736f61a9d1a83"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3fac40972cf7b6c14dded88ae2331eb50dfbc278aa9195473ef6fc6bfe49f686"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0e456cbdc0abf39352800309dab82fd3251179fa0ff6573fa117f51f4e84be8"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:22b9d22022b9d09fd4ece15102270ab9b6a5cfea8b6f6d1965c1df7e3783f5ff"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46754fe404a9a6f5cbf7abe02d74af390038d94c9b8c923b3f362467606bfa28"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91abb8bf7610efe326394adc1d45e1baca8f360e74187f3fa0ef3df80cdd3ba6"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e40a2f60024f9d3c15401e668f732800114a023f3f8d8c40f1521a62081ff054"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a48ee83916401ac73938526d7bd804e01d2a8fe61809df7f1577b0b3b31049a3"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c71580052f9dbac443c02f60484e5a2e5f72ad4351b84b2009fbe345b1f38422"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:82b86d5b8c1b9bcbc65236d75f81023c78d06a721c3e0229889ff4ed5c858169"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fc4528b7736e5c30bc954022c2cf410889abc19504a023abadbc59cdf9f37cae"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e1e0e569108a5760d8f01d0f2148dd08cc9a39ead79fbefefca9e7c7723c7e88"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:94e1c97f0ad45b05003806f8a13efc1fc78983e52fa2ddb00629003acf4676ef"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47e81767a962e41477a85ad7ac937e34d19a7d2a80be65614f008a5ead671c56"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-win32.whl", hash = "sha256:79fc574aaf2d7c27ec1022e29c9c18f83cdaf790c71c05779528901e0caad89b"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:f3dd4bcef2d600e0aa121e19e6e62f6f06f22a89f82ef62755e205ce14727874"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-win_arm64.whl", hash = "sha256:cac095cbdf44bc286339a77214bbca6d4d228c9ebae3da5ff6a80aaeb7c35634"}, + {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b89d1126be65c85763d56e3b47d75f1a9b7c5529857b4d572079b9a636eaa8a7"}, + {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19b7460e91168229768be882ea365ba0ac7da43e57f9416e2cfadc396a7df3c2"}, + {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c33c03e7092642c38f8a15ca2d8fc38da366f2526ec3b46adf19d5c7aa48ba"}, + {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040faca2e26d9dab5541b45ce72b3f6c0e36786234703fc2ac8c6f53bb576743"}, + {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:6e2a3b23e1e9aa13474b3c710bba770d0dcc34d517d3dd6f97435a32873e3f28"}, + {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2e597b9dfd6dd180982684840975c458c50d447e46928efe3e0120e4ec6f6686"}, + {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d14752c9dd2036c5f36ebe8db5f027275fa7d6b3ec6484158f83efb674bab84e"}, + {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:558224b6fc6124d13fa32d57876f626a7d6188ba2a97cbaea33a6ee38a867e31"}, + {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c89cfa88dc16fd8c9bcc0c7f0b0073f7ef1e27cceb246c9f5a3f7004fa97c4d"}, + {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:509c5b631cd64df69f0f011893983eb15b8be087a55bad72f3d616b6ae6a0f96"}, + {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0f73a04135a03a6e40393ecd5d46a7a1049d353fc5c24b82849830d09817991f"}, + {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c99d53138a2dfe8ada67cb2855719f934af2733d726fbf73247844ce4dd6dd5"}, + {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f01fa757f0fb332a1f045168d29b0d005de6c39ee5ce5d6c51f2563bb53c601b"}, + {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60368e1add6e550faae65614844c43f8a96e37bf99404643b648bf2dba92c0fb"}, + {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:785744f1270828cc632c5a3660409dee9bcaac6931a081bae57542c93e4d46c4"}, + {file = "rapidfuzz-2.15.1.tar.gz", hash = "sha256:d62137c2ca37aea90a11003ad7dc109c8f1739bfbe5a9a217f3cdb07d7ac00f6"}, +] + +[package.extras] +full = ["numpy"] + +[[package]] +name = "recommonmark" +version = "0.7.1" +description = "A docutils-compatibility bridge to CommonMark, enabling you to write CommonMark inside of Docutils & Sphinx projects." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "recommonmark-0.7.1-py2.py3-none-any.whl", hash = "sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f"}, + {file = "recommonmark-0.7.1.tar.gz", hash = "sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67"}, +] + +[package.dependencies] +commonmark = ">=0.8.1" +docutils = ">=0.11" +sphinx = ">=1.3.1" + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +name = "secretstorage" +version = "3.3.3" +description = "Python bindings to FreeDesktop.org Secret Service API" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"}, + {file = "SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77"}, +] + +[package.dependencies] +cryptography = ">=2.0" +jeepney = ">=0.6" + +[[package]] +name = "setuptools" +version = "68.0.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, + {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "shellingham" +version = "1.5.0.post1" +description = "Tool to Detect Surrounding Shell" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "shellingham-1.5.0.post1-py2.py3-none-any.whl", hash = "sha256:368bf8c00754fd4f55afb7bbb86e272df77e4dc76ac29dbcbb81a59e9fc15744"}, + {file = "shellingham-1.5.0.post1.tar.gz", hash = "sha256:823bc5fb5c34d60f285b624e7264f4dda254bc803a3774a147bf99c0e3004a28"}, +] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] + +[[package]] +name = "soupsieve" +version = "2.4.1" +description = "A modern CSS selector implementation for Beautiful Soup." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"}, + {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, +] + +[[package]] +name = "sphinx" +version = "3.0.2" +description = "Python documentation generator" +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "Sphinx-3.0.2-py3-none-any.whl", hash = "sha256:3145d87d0962366d4c5264c39094eae3f5788d01d4b1a12294051bfe4271d91b"}, + {file = "Sphinx-3.0.2.tar.gz", hash = "sha256:d7c6e72c6aa229caf96af82f60a0d286a1521d42496c226fe37f5a75dcfe2941"}, +] + +[package.dependencies] +alabaster = ">=0.7,<0.8" +babel = ">=1.3" +colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.12" +imagesize = "*" +Jinja2 = ">=2.3" +packaging = "*" +Pygments = ">=2.0" +requests = ">=2.5.0" +setuptools = "*" +snowballstemmer = ">=1.1" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = "*" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = "*" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-import-order", "mypy (>=0.770)"] +test = ["cython", "html5lib", "pytest", "pytest-cov", "typed-ast"] + +[[package]] +name = "sphinxbootstrap4theme" +version = "0.6.0" +description = "Sphinx Bootstrap4 Theme" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "sphinxbootstrap4theme-0.6.0.tar.gz", hash = "sha256:d3b2e413785afc74aa178872aa553d7b4156206037fdb39b7ff1490c7926d138"}, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "1.0.2" +description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, + {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "1.0.2" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.0.0" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"}, + {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["html5lib", "pytest"] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] + +[package.extras] +test = ["flake8", "mypy", "pytest"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "1.0.3" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "1.1.5" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, + {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "termcolor" +version = "2.3.0" +description = "ANSI color formatting for output in terminal" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "termcolor-2.3.0-py3-none-any.whl", hash = "sha256:3afb05607b89aed0ffe25202399ee0867ad4d3cb4180d98aaf8eefa6a5f7d475"}, + {file = "termcolor-2.3.0.tar.gz", hash = "sha256:b5b08f68937f138fe92f6c089b99f1e2da0ae56c52b78bf7075fd95420fd9a5a"}, +] + +[package.extras] +tests = ["pytest", "pytest-cov"] + +[[package]] +name = "test-apps-shared-test-helpers" +version = "0.1.0" +description = "Shared Regression Test Helpers for Test Apps" +category = "main" +optional = false +python-versions = ">=3.7,<3.11" +files = [] +develop = true + +[package.dependencies] +origen = {path = "../../python/origen", develop = true} +pl_ext_cmds = {path = "../pl_ext_cmds", develop = true} +pytest = ">=7.2.1" + +[package.source] +type = "directory" +url = "../../test_apps_shared_test_helpers" + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "tomlkit" +version = "0.11.8" +description = "Style preserving TOML library" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomlkit-0.11.8-py3-none-any.whl", hash = "sha256:8c726c4c202bdb148667835f68d68780b9a003a9ec34167b6c673b38eff2a171"}, + {file = "tomlkit-0.11.8.tar.gz", hash = "sha256:9330fc7faa1db67b541b28e62018c17d20be733177d290a13b24c62d1614e0c3"}, +] + +[[package]] +name = "trove-classifiers" +version = "2023.5.24" +description = "Canonical source for classifiers on PyPI (pypi.org)." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "trove-classifiers-2023.5.24.tar.gz", hash = "sha256:fd5a1546283be941f47540a135bdeae8fb261380a6a204d9c18012f2a1b0ceae"}, + {file = "trove_classifiers-2023.5.24-py3-none-any.whl", hash = "sha256:d9d7ae14fb90bf3d50bef99c3941b176b5326509e6e9037e622562d6352629d0"}, +] + +[[package]] +name = "typing-extensions" +version = "4.6.3" +description = "Backported and Experimental Type Hints for Python 3.7+" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "typing_extensions-4.6.3-py3-none-any.whl", hash = "sha256:88a4153d8505aabbb4e13aacb7c486c2b4a33ca3b3f807914a9b4c844c471c26"}, + {file = "typing_extensions-4.6.3.tar.gz", hash = "sha256:d91d5919357fe7f681a9f2b5b4cb2a5f1ef0a1e9f59c4d8ff0d3491e05c0ffd5"}, +] + +[[package]] +name = "urllib3" +version = "1.26.16" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "urllib3-1.26.16-py2.py3-none-any.whl", hash = "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f"}, + {file = "urllib3-1.26.16.tar.gz", hash = "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[[package]] +name = "virtualenv" +version = "20.23.1" +description = "Virtual Python Environment builder" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "virtualenv-20.23.1-py3-none-any.whl", hash = "sha256:34da10f14fea9be20e0fd7f04aba9732f84e593dac291b757ce42e3368a39419"}, + {file = "virtualenv-20.23.1.tar.gz", hash = "sha256:8ff19a38c1021c742148edc4f81cb43d7f8c6816d2ede2ab72af5b84c749ade1"}, +] + +[package.dependencies] +distlib = ">=0.3.6,<1" +filelock = ">=3.12,<4" +importlib-metadata = {version = ">=6.6", markers = "python_version < \"3.8\""} +platformdirs = ">=3.5.1,<4" + +[package.extras] +docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezer (>=0.4.6)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.8)", "time-machine (>=2.9)"] + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] + +[[package]] +name = "xattr" +version = "0.10.1" +description = "Python wrapper for extended filesystem attributes" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "xattr-0.10.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:16a660a883e703b311d1bbbcafc74fa877585ec081cd96e8dd9302c028408ab1"}, + {file = "xattr-0.10.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1e2973e72faa87ca29d61c23b58c3c89fe102d1b68e091848b0e21a104123503"}, + {file = "xattr-0.10.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:13279fe8f7982e3cdb0e088d5cb340ce9cbe5ef92504b1fd80a0d3591d662f68"}, + {file = "xattr-0.10.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1dc9b9f580ef4b8ac5e2c04c16b4d5086a611889ac14ecb2e7e87170623a0b75"}, + {file = "xattr-0.10.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:485539262c2b1f5acd6b6ea56e0da2bc281a51f74335c351ea609c23d82c9a79"}, + {file = "xattr-0.10.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:295b3ab335fcd06ca0a9114439b34120968732e3f5e9d16f456d5ec4fa47a0a2"}, + {file = "xattr-0.10.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:a126eb38e14a2f273d584a692fe36cff760395bf7fc061ef059224efdb4eb62c"}, + {file = "xattr-0.10.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:b0e919c24f5b74428afa91507b15e7d2ef63aba98e704ad13d33bed1288dca81"}, + {file = "xattr-0.10.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:e31d062cfe1aaeab6ba3db6bd255f012d105271018e647645941d6609376af18"}, + {file = "xattr-0.10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:209fb84c09b41c2e4cf16dd2f481bb4a6e2e81f659a47a60091b9bcb2e388840"}, + {file = "xattr-0.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c4120090dac33eddffc27e487f9c8f16b29ff3f3f8bcb2251b2c6c3f974ca1e1"}, + {file = "xattr-0.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3e739d624491267ec5bb740f4eada93491de429d38d2fcdfb97b25efe1288eca"}, + {file = "xattr-0.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2677d40b95636f3482bdaf64ed9138fb4d8376fb7933f434614744780e46e42d"}, + {file = "xattr-0.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40039f1532c4456fd0f4c54e9d4e01eb8201248c321c6c6856262d87e9a99593"}, + {file = "xattr-0.10.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:148466e5bb168aba98f80850cf976e931469a3c6eb11e9880d9f6f8b1e66bd06"}, + {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0aedf55b116beb6427e6f7958ccd80a8cbc80e82f87a4cd975ccb61a8d27b2ee"}, + {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c3024a9ff157247c8190dd0eb54db4a64277f21361b2f756319d9d3cf20e475f"}, + {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f1be6e733e9698f645dbb98565bb8df9b75e80e15a21eb52787d7d96800e823b"}, + {file = "xattr-0.10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7880c8a54c18bc091a4ce0adc5c6d81da1c748aec2fe7ac586d204d6ec7eca5b"}, + {file = "xattr-0.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:89c93b42c3ba8aedbc29da759f152731196c2492a2154371c0aae3ef8ba8301b"}, + {file = "xattr-0.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6b905e808df61b677eb972f915f8a751960284358b520d0601c8cbc476ba2df6"}, + {file = "xattr-0.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1ef954d0655f93a34d07d0cc7e02765ec779ff0b59dc898ee08c6326ad614d5"}, + {file = "xattr-0.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:199b20301b6acc9022661412346714ce764d322068ef387c4de38062474db76c"}, + {file = "xattr-0.10.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec0956a8ab0f0d3f9011ba480f1e1271b703d11542375ef73eb8695a6bd4b78b"}, + {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffcb57ca1be338d69edad93cf59aac7c6bb4dbb92fd7bf8d456c69ea42f7e6d2"}, + {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f0563196ee54756fe2047627d316977dc77d11acd7a07970336e1a711e934db"}, + {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc354f086f926a1c7f04886f97880fed1a26d20e3bc338d0d965fd161dbdb8ab"}, + {file = "xattr-0.10.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c0cd2d02ef2fb45ecf2b0da066a58472d54682c6d4f0452dfe7ae2f3a76a42ea"}, + {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49626096ddd72dcc1654aadd84b103577d8424f26524a48d199847b5d55612d0"}, + {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ceaa26bef8fcb17eb59d92a7481c2d15d20211e217772fb43c08c859b01afc6a"}, + {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8c014c371391f28f8cd27d73ea59f42b30772cd640b5a2538ad4f440fd9190b"}, + {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:46c32cd605673606b9388a313b0050ee7877a0640d7561eea243ace4fa2cc5a6"}, + {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:772b22c4ff791fe5816a7c2a1c9fcba83f9ab9bea138eb44d4d70f34676232b4"}, + {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:183ad611a2d70b5a3f5f7aadef0fcef604ea33dcf508228765fd4ddac2c7321d"}, + {file = "xattr-0.10.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8068df3ebdfa9411e58d5ae4a05d807ec5994645bb01af66ec9f6da718b65c5b"}, + {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bc40570155beb85e963ae45300a530223d9822edfdf09991b880e69625ba38a"}, + {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:436e1aaf23c07e15bed63115f1712d2097e207214fc6bcde147c1efede37e2c5"}, + {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7298455ccf3a922d403339781b10299b858bb5ec76435445f2da46fb768e31a5"}, + {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:986c2305c6c1a08f78611eb38ef9f1f47682774ce954efb5a4f3715e8da00d5f"}, + {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5dc6099e76e33fa3082a905fe59df766b196534c705cf7a2e3ad9bed2b8a180e"}, + {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:042ad818cda6013162c0bfd3816f6b74b7700e73c908cde6768da824686885f8"}, + {file = "xattr-0.10.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9d4c306828a45b41b76ca17adc26ac3dc00a80e01a5ba85d71df2a3e948828f2"}, + {file = "xattr-0.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a606280b0c9071ef52572434ecd3648407b20df3d27af02c6592e84486b05894"}, + {file = "xattr-0.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5b49d591cf34cda2079fd7a5cb2a7a1519f54dc2e62abe3e0720036f6ed41a85"}, + {file = "xattr-0.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b8705ac6791426559c1a5c2b88bb2f0e83dc5616a09b4500899bfff6a929302"}, + {file = "xattr-0.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5ea974930e876bc5c146f54ac0f85bb39b7b5de2b6fc63f90364712ae368ebe"}, + {file = "xattr-0.10.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f55a2dd73a12a1ae5113c5d9cd4b4ab6bf7950f4d76d0a1a0c0c4264d50da61d"}, + {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:475c38da0d3614cc5564467c4efece1e38bd0705a4dbecf8deeb0564a86fb010"}, + {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:925284a4a28e369459b2b7481ea22840eed3e0573a4a4c06b6b0614ecd27d0a7"}, + {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa32f1b45fed9122bed911de0fcc654da349e1f04fa4a9c8ef9b53e1cc98b91e"}, + {file = "xattr-0.10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c5d3d0e728bace64b74c475eb4da6148cd172b2d23021a1dcd055d92f17619ac"}, + {file = "xattr-0.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8faaacf311e2b5cc67c030c999167a78a9906073e6abf08eaa8cf05b0416515c"}, + {file = "xattr-0.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cc6b8d5ca452674e1a96e246a3d2db5f477aecbc7c945c73f890f56323e75203"}, + {file = "xattr-0.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3725746a6502f40f72ef27e0c7bfc31052a239503ff3eefa807d6b02a249be22"}, + {file = "xattr-0.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:789bd406d1aad6735e97b20c6d6a1701e1c0661136be9be862e6a04564da771f"}, + {file = "xattr-0.10.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9a7a807ab538210ff8532220d8fc5e2d51c212681f63dbd4e7ede32543b070f"}, + {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3e5825b5fc99ecdd493b0cc09ec35391e7a451394fdf623a88b24726011c950d"}, + {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:80638d1ce7189dc52f26c234cee3522f060fadab6a8bc3562fe0ddcbe11ba5a4"}, + {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3ff0dbe4a6ce2ce065c6de08f415bcb270ecfd7bf1655a633ddeac695ce8b250"}, + {file = "xattr-0.10.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5267e5f9435c840d2674194150b511bef929fa7d3bc942a4a75b9eddef18d8d8"}, + {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b27dfc13b193cb290d5d9e62f806bb9a99b00cd73bb6370d556116ad7bb5dc12"}, + {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:636ebdde0277bce4d12d2ef2550885804834418fee0eb456b69be928e604ecc4"}, + {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d60c27922ec80310b45574351f71e0dd3a139c5295e8f8b19d19c0010196544f"}, + {file = "xattr-0.10.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b34df5aad035d0343bd740a95ca30db99b776e2630dca9cc1ba8e682c9cc25ea"}, + {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f24a7c04ff666d0fe905dfee0a84bc899d624aeb6dccd1ea86b5c347f15c20c1"}, + {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3878e1aff8eca64badad8f6d896cb98c52984b1e9cd9668a3ab70294d1ef92d"}, + {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4abef557028c551d59cf2fb3bf63f2a0c89f00d77e54c1c15282ecdd56943496"}, + {file = "xattr-0.10.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0e14bd5965d3db173d6983abdc1241c22219385c22df8b0eb8f1846c15ce1fee"}, + {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f9be588a4b6043b03777d50654c6079af3da60cc37527dbb80d36ec98842b1e"}, + {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bc4ae264aa679aacf964abf3ea88e147eb4a22aea6af8c6d03ebdebd64cfd6"}, + {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:827b5a97673b9997067fde383a7f7dc67342403093b94ea3c24ae0f4f1fec649"}, + {file = "xattr-0.10.1.tar.gz", hash = "sha256:c12e7d81ffaa0605b3ac8c22c2994a8e18a9cf1c59287a1b7722a2289c952ec5"}, +] + +[package.dependencies] +cffi = ">=1.0" + +[[package]] +name = "yapf" +version = "0.30.0" +description = "A formatter for Python code." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "yapf-0.30.0-py2.py3-none-any.whl", hash = "sha256:3abf61ba67cf603069710d30acbc88cfe565d907e16ad81429ae90ce9651e0c9"}, + {file = "yapf-0.30.0.tar.gz", hash = "sha256:3000abee4c28daebad55da6c85f3cd07b8062ce48e2e9943c8da1b9667d48427"}, +] + +[[package]] +name = "zipp" +version = "3.15.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, + {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + +[metadata] +lock-version = "2.0" +python-versions = ">=3.7,<3.11" +content-hash = "152a296654d05ccfbaadc5b03711b43e486f70748ba5433d0e8197128cfb5df6" diff --git a/test_apps/no_workspace/user_install/pyproject.toml b/test_apps/no_workspace/user_install/pyproject.toml new file mode 100644 index 00000000..5eb8004b --- /dev/null +++ b/test_apps/no_workspace/user_install/pyproject.toml @@ -0,0 +1,13 @@ +[tool.poetry] +name = "TestUserInstall" +version = "0.1.0" +description = "Origen Installation Test" +authors = ["Origen-SDK"] + +[tool.poetry.dependencies] +python = ">=3.7,<3.11" + +origen = { path = "../../../python/origen", develop = true } +origen_metal = { path = "../../../python/origen_metal", develop = true } +python_plugin = { path = "../../python_plugin", develop = true } +test_apps_shared_test_helpers = { path = "../../test_apps_shared_test_helpers", develop = true } diff --git a/test_apps/python_app/tests/cli_test.py b/test_apps/python_app/tests/cli_test.py index 598c74e8..7f83ba8e 100644 --- a/test_apps/python_app/tests/cli_test.py +++ b/test_apps/python_app/tests/cli_test.py @@ -1,8 +1,11 @@ -import pytest, pathlib +import pytest, pathlib, sys import subprocess import os import origen +sys.path.insert(-1, str(pathlib.Path(__file__).parent.parent.parent.joinpath("no_workspace"))) +from t_invocation_env import T_InvocationBaseTests + from cli.tests__app_cmd_building import T_AppCmdBuilding from cli.tests__core_cmds import T_AppWorkspaceCoreCommands from cli.tests__cmd_exts_from_app import T_ExtendingFromAppCmds @@ -67,3 +70,10 @@ class TestAuxCommandsAreAdded: class TestModeOpts(): def test_(): fail + +class TestAppInvocation(T_InvocationBaseTests): + @classmethod + def set_params(cls): + cls.invocation = cls.PyProjectSrc.App + cls.cli_location = cls.debug_cli_loc + cls.target_pyproj_dir = pathlib.Path(__file__).parent.parent diff --git a/test_apps/python_no_app/tests/shared.py b/test_apps/python_no_app/tests/shared.py new file mode 100644 index 00000000..79c7e788 --- /dev/null +++ b/test_apps/python_no_app/tests/shared.py @@ -0,0 +1,5 @@ +from pathlib import Path + +tests_root = Path(__file__).parent +working_dir = Path(__file__).parent.parent +working_dir_config = working_dir.joinpath("origen.toml") diff --git a/test_apps/python_no_app/tests/test_configs.py b/test_apps/python_no_app/tests/test_configs.py index b2557d47..fab05146 100644 --- a/test_apps/python_no_app/tests/test_configs.py +++ b/test_apps/python_no_app/tests/test_configs.py @@ -1,4 +1,5 @@ import pytest, origen, shutil, os +from .shared import tests_root, working_dir, working_dir_config from pathlib import Path from origen.helpers.env import in_new_origen_proc, run_cli_cmd from tests import configs as config_funcs @@ -6,9 +7,9 @@ from test_apps_shared_test_helpers.cli import CLIShared class Common(CLIShared): - tests_root = Path(__file__).parent - working_dir = Path(__file__).parent.parent - working_dir_config = working_dir.joinpath("origen.toml") + tests_root = tests_root + working_dir = working_dir + working_dir_config = working_dir_config cli_config = CLIShared.cli_dir.joinpath("origen.toml") configs_dir = Path(__file__).parent.joinpath("configs") diff --git a/test_apps/python_no_app/tests/test_global_invocation.py b/test_apps/python_no_app/tests/test_global_invocation.py index 7e57fa72..30201aa7 100644 --- a/test_apps/python_no_app/tests/test_global_invocation.py +++ b/test_apps/python_no_app/tests/test_global_invocation.py @@ -1,4 +1,8 @@ -import origen, origen_metal, _origen, getpass, pytest +import origen, origen_metal, _origen, getpass, pytest, pathlib, sys +from .shared import working_dir + +sys.path.insert(-1, str(pathlib.Path(__file__).parent.parent.parent.joinpath("no_workspace"))) +from t_invocation_env import T_InvocationBaseTests def test_import(): assert "2." in origen.version @@ -11,6 +15,13 @@ def test_is_app_present(): assert _origen.is_app_present() is False assert origen.status["is_app_present"] is False +class TestWorkspaceInvocation(T_InvocationBaseTests): + @classmethod + def set_params(cls): + cls.invocation = cls.PyProjectSrc.Workspace + cls.cli_location = cls.debug_cli_loc + cls.target_pyproj_dir = working_dir + class TestGlobalFEIntegration: def test_frontend_is_accessible(self): assert (origen_metal.frontend.frontend() is not None) diff --git a/test_apps/test_apps_shared_test_helpers/pyproject.toml b/test_apps/test_apps_shared_test_helpers/pyproject.toml index 22f42005..8b7a9a00 100644 --- a/test_apps/test_apps_shared_test_helpers/pyproject.toml +++ b/test_apps/test_apps_shared_test_helpers/pyproject.toml @@ -6,6 +6,7 @@ authors = ["Origen-SDK"] [tool.poetry.dependencies] python = ">=3.7,<3.11" +pytest = ">=7.2.1" origen = { path = "../../python/origen", develop = true } pl_ext_cmds = { path = "../pl_ext_cmds", develop = true } From 1dcce4c1e6b0ae1b5efe3ce3e6d6345cbfdcc33d Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 24 Jun 2023 18:20:20 -0500 Subject: [PATCH 02/51] Add missing checkin --- .../python_plugin/commands/extensions/core.eval.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test_apps/python_plugin/python_plugin/commands/extensions/core.eval.py b/test_apps/python_plugin/python_plugin/commands/extensions/core.eval.py index a77b60f5..9f477db0 100644 --- a/test_apps/python_plugin/python_plugin/commands/extensions/core.eval.py +++ b/test_apps/python_plugin/python_plugin/commands/extensions/core.eval.py @@ -1,10 +1,12 @@ import origen +from origen.boot import before_cmd, after_cmd -def before_cmd(): - print(origen.current_command.args) - if "say_hi_before_eval" in origen.current_command.args: +@before_cmd +def before_cmd(**ext_kwargs): + if "say_hi_before_eval" in ext_kwargs: print("Hi from python-plugin during 'eval'!") -def after_cmd(): - if "say_hi_before_eval" in origen.current_command.args: +@after_cmd +def after_cmd(**ext_kwargs): + if "say_hi_after_eval" in ext_kwargs: print("Hi again from python-plugin during 'eval'!") From ae15f17c24eb0c401fe3f9c9d84f505b0905b7cf Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 24 Jun 2023 19:11:33 -0500 Subject: [PATCH 03/51] Debugging regressions --- python/origen/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/origen/pyproject.toml b/python/origen/pyproject.toml index 40e392b0..a1465970 100644 --- a/python/origen/pyproject.toml +++ b/python/origen/pyproject.toml @@ -18,7 +18,7 @@ script = "poetry_build.py" generate-setup-file = false [tool.poetry.scripts] -origen = 'origen.__bin__:run_origen' +o2 = 'origen.__bin__:run_origen' [tool.poetry.dependencies] python = ">=3.7,<3.11" From 03f2d3531e64e05ac05a9e1f58b7cc5c822ca01a Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 24 Jun 2023 19:55:15 -0500 Subject: [PATCH 04/51] Add jinja2 install --- .github/workflows/regression_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 01f9824f..350dc1b2 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -141,7 +141,7 @@ jobs: # Use a global pytest install for invocation tests - name: Install Pytest - run: pip install pytest==7.2.1 + run: pip install pytest==7.2.1 jinja2=3.1.2 - name: Get Pytest Version (Check Install) run: pytest --version From 17e26e6f1d56e7fdf64fce82b5d7e62b6e2d60ba Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 24 Jun 2023 20:51:07 -0500 Subject: [PATCH 05/51] Fix pip install in actions yml --- .github/workflows/regression_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 350dc1b2..99e7c7a6 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -141,7 +141,7 @@ jobs: # Use a global pytest install for invocation tests - name: Install Pytest - run: pip install pytest==7.2.1 jinja2=3.1.2 + run: pip install pytest==7.2.1 jinja2==3.1.2 - name: Get Pytest Version (Check Install) run: pytest --version From 8700aebce8f9ce68b913ae0e6a4ba1f0dece5960 Mon Sep 17 00:00:00 2001 From: Corey Date: Sun, 25 Jun 2023 08:23:16 -0500 Subject: [PATCH 06/51] Try re-lock of user install invocation. --- .../no_workspace/user_install/poetry.lock | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test_apps/no_workspace/user_install/poetry.lock b/test_apps/no_workspace/user_install/poetry.lock index dfd75ab2..a448e9c4 100644 --- a/test_apps/no_workspace/user_install/poetry.lock +++ b/test_apps/no_workspace/user_install/poetry.lock @@ -1064,14 +1064,14 @@ url = "../../pl_ext_cmds" [[package]] name = "platformdirs" -version = "3.6.0" +version = "3.8.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.6.0-py3-none-any.whl", hash = "sha256:ffa199e3fbab8365778c4a10e1fbf1b9cd50707de826eb304b50e57ec0cc8d38"}, - {file = "platformdirs-3.6.0.tar.gz", hash = "sha256:57e28820ca8094678b807ff529196506d7a21e17156cb1cddb3e74cebce54640"}, + {file = "platformdirs-3.8.0-py3-none-any.whl", hash = "sha256:ca9ed98ce73076ba72e092b23d3c93ea6c4e186b3f1c3dad6edd98ff6ffcca2e"}, + {file = "platformdirs-3.8.0.tar.gz", hash = "sha256:b0cabcb11063d21a0b261d557acb0a9d2126350e63b70cdf7db6347baea456dc"}, ] [package.dependencies] @@ -1083,14 +1083,14 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest- [[package]] name = "pluggy" -version = "1.0.0" +version = "1.2.0" description = "plugin and hook calling mechanisms for python" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, + {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, + {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, ] [package.dependencies] @@ -1279,14 +1279,14 @@ files = [ [[package]] name = "pytest" -version = "7.3.2" +version = "7.4.0" description = "pytest: simple powerful testing with Python" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.3.2-py3-none-any.whl", hash = "sha256:cdcbd012c9312258922f8cd3f1b62a6580fdced17db6014896053d47cddf9295"}, - {file = "pytest-7.3.2.tar.gz", hash = "sha256:ee990a3cc55ba808b80795a79944756f315c67c12b56abd3ac993a7b8c17030b"}, + {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"}, + {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"}, ] [package.dependencies] From 2794bd2b2403145d881d72d6d90d5b12a0c690f4 Mon Sep 17 00:00:00 2001 From: Corey Date: Sun, 25 Jun 2023 12:59:09 -0500 Subject: [PATCH 07/51] Debug tests on GA --- test_apps/no_workspace/t_invocation_env.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test_apps/no_workspace/t_invocation_env.py b/test_apps/no_workspace/t_invocation_env.py index 9185b399..8686e8dc 100644 --- a/test_apps/no_workspace/t_invocation_env.py +++ b/test_apps/no_workspace/t_invocation_env.py @@ -81,6 +81,7 @@ def setup(cls): target = cls.target_pyproj_dir.joinpath(toml) print(f"Moving pyproject {cls._pyproj_src_file} to {target}") shutil.copy(cls._pyproj_src_file, target) + subprocess.run(["poetry", "--version"], check=True, cwd=cls.target_pyproj_dir) subprocess.run(["poetry", "install"], check=True, cwd=cls.target_pyproj_dir) @classmethod From 2e0bbc1fec139236b6fd064db2e6fb81d5f02b1f Mon Sep 17 00:00:00 2001 From: Corey Date: Sun, 25 Jun 2023 16:41:55 -0500 Subject: [PATCH 08/51] (GA) Remove poetry update before OM tests --- .github/workflows/regression_test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 99e7c7a6..f8559e42 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -121,10 +121,10 @@ jobs: - name: Build PyAPI - Metal run: origen origen build --metal - - name: Install Poetry - uses: abatilo/actions-poetry@v2.0.0 - with: - poetry-version: 1.1.14 + # - name: Install Poetry + # uses: abatilo/actions-poetry@v2.0.0 + # with: + # poetry-version: 1.3.2 - name: Setup Python Env - Metal working-directory: python/origen_metal From cffef7cee1fd299374b61dd7930241bc43ab282b Mon Sep 17 00:00:00 2001 From: Corey Date: Sun, 25 Jun 2023 19:50:39 -0500 Subject: [PATCH 09/51] GA debug - unordered PL compare --- test_apps/no_workspace/t_invocation_env.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test_apps/no_workspace/t_invocation_env.py b/test_apps/no_workspace/t_invocation_env.py index 8686e8dc..5c272c84 100644 --- a/test_apps/no_workspace/t_invocation_env.py +++ b/test_apps/no_workspace/t_invocation_env.py @@ -126,6 +126,7 @@ def test_plugins(self): code = f"print('{self.header}'); print(list(origen.plugins.keys()))" pls = self.eval_and_parse(code) if self.has_pls: - assert pls == ['python_plugin_the_second', 'pl_ext_cmds', 'test_apps_shared_test_helpers', 'python_plugin'] + # TODO consistent plugin loading + assert set(pls) == {'python_plugin_the_second', 'pl_ext_cmds', 'test_apps_shared_test_helpers', 'python_plugin'} else: assert pls == [] From 6f0b72aa57e0b7478167e5184ee1c69dc78a6071 Mon Sep 17 00:00:00 2001 From: Corey Date: Sun, 25 Jun 2023 21:08:20 -0500 Subject: [PATCH 10/51] Add pytest rewrite for t_invocation_env in no_workspace --- test_apps/no_workspace/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test_apps/no_workspace/__init__.py b/test_apps/no_workspace/__init__.py index e69de29b..9f5919ba 100644 --- a/test_apps/no_workspace/__init__.py +++ b/test_apps/no_workspace/__init__.py @@ -0,0 +1,2 @@ +import pytest +pytest.register_assert_rewrite("no_workspace.t_invocation_env") From 6e6f8b60481c735943947a9469923dd44e44d6a6 Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 26 Jun 2023 07:47:41 -0500 Subject: [PATCH 11/51] (GA Debug) Local env. was stale. --- test_apps/no_workspace/t_invocation_env.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_apps/no_workspace/t_invocation_env.py b/test_apps/no_workspace/t_invocation_env.py index 5c272c84..fcd4c36d 100644 --- a/test_apps/no_workspace/t_invocation_env.py +++ b/test_apps/no_workspace/t_invocation_env.py @@ -127,6 +127,6 @@ def test_plugins(self): pls = self.eval_and_parse(code) if self.has_pls: # TODO consistent plugin loading - assert set(pls) == {'python_plugin_the_second', 'pl_ext_cmds', 'test_apps_shared_test_helpers', 'python_plugin'} + assert set(pls) == {'pl_ext_cmds', 'test_apps_shared_test_helpers', 'python_plugin'} else: assert pls == [] From 5213de78fa5d3f2853cf1ba1702d8ff004941bd4 Mon Sep 17 00:00:00 2001 From: Corey Date: Fri, 30 Jun 2023 22:16:47 -0500 Subject: [PATCH 12/51] Have eval cmd support running from script files. --- python/origen/origen/boot.py | 8 +-- .../origen/origen/core/commands/__init__.py | 3 + python/origen/origen/core/commands/eval.py | 63 ++++++++++++++++++ .../origen/helpers/regressions/cli/origen.py | 16 ++++- rust/origen/cli/src/commands/eval.rs | 15 ++++- rust/origen/cli/src/commands/mod.rs | 30 ++++++++- rust/pyapi/src/current_command.rs | 20 +++++- rust/pyapi/src/extensions.rs | 16 ++++- .../tests/cli/tests__cmd_exts_from_app.py | 5 +- .../python_app/tests/cli/tests__core_cmds.py | 4 +- .../tests/cli/tests__reserved_opts.py | 4 +- .../tests/cli/tests__cmd__eval.py | 64 +++++++++++++++++-- .../cli/tests__cmd__eval__scripts/err.py | 2 + .../tests/cli/tests__cmd__eval__scripts/hi.py | 5 ++ .../override_preface.py | 1 + .../tests/cmd_exts/tests__ext_conflicts.py | 1 + .../tests/cmd_exts/tests__extending_cmds.py | 1 + test_apps/python_no_app/tests/shared.py | 8 +++ .../tests/test_plugin_loading.py | 2 + 19 files changed, 248 insertions(+), 20 deletions(-) create mode 100644 python/origen/origen/core/commands/eval.py create mode 100644 test_apps/python_no_app/tests/cli/tests__cmd__eval__scripts/err.py create mode 100644 test_apps/python_no_app/tests/cli/tests__cmd__eval__scripts/hi.py create mode 100644 test_apps/python_no_app/tests/cli/tests__cmd__eval__scripts/override_preface.py diff --git a/python/origen/origen/boot.py b/python/origen/origen/boot.py index 41abd8c0..a94956a2 100644 --- a/python/origen/origen/boot.py +++ b/python/origen/origen/boot.py @@ -15,7 +15,9 @@ def run_cmd(command, mode=None, debug=False, args=None, + arg_indices=None, ext_args=None, + ext_arg_indices=None, extensions=None, dispatch_root=None, dispatch_src=None, @@ -202,7 +204,7 @@ def run(func): if "on_load" in ext: getattr((ext["mod"]), ext["on_load"])(ext["mod"]) current_ext = None - _origen.current_command.set_command(command, subcmds, args, ext_args, extensions) + _origen.current_command.set_command(command, subcmds, args, ext_args, arg_indices, ext_arg_indices, extensions) def run_ext(phase, continue_on_fail=False): for ext in extensions: @@ -251,10 +253,6 @@ def run_ext(phase, continue_on_fail=False): interactive.interact(banner=f"Origen {origen.version}", context=origen.__interactive_context__()) - elif command == "eval": - for c in args['code']: - exec(c) - elif command == "web:build": _origen.set_operation("web") from origen.web import run_cmd diff --git a/python/origen/origen/core/commands/__init__.py b/python/origen/origen/core/commands/__init__.py index ec3377c5..6adf3d28 100644 --- a/python/origen/origen/core/commands/__init__.py +++ b/python/origen/origen/core/commands/__init__.py @@ -1,6 +1,7 @@ import importlib, origen creds = "credentials" +eval = "eval" _subcmds = None _base_cmd = None @@ -24,6 +25,8 @@ def run_core_cmd(base_cmd, sub_cmds, args): try: if base_cmd == creds: import_cmd(creds).run(args) + elif base_cmd == eval: + import_cmd(eval).run(args) else: return False return True diff --git a/python/origen/origen/core/commands/eval.py b/python/origen/origen/core/commands/eval.py new file mode 100644 index 00000000..500fd066 --- /dev/null +++ b/python/origen/origen/core/commands/eval.py @@ -0,0 +1,63 @@ +import origen, pathlib + +def run(args): + code = list(args.get('code', [])) + files = list(args.get('scripts', [])) + code_indices = list(origen.current_command.arg_indices.get('code', [])) + file_indices = list(origen.current_command.arg_indices.get('scripts', [])) + if len(code_indices) > 0: + code_idx = code_indices.pop() + else: + code_idx = None + if len(file_indices) > 0: + files_idx = file_indices.pop() + else: + files_idx = None + + # Build the run order based on where the given code or script file appear in the command line + to_run = [] + while (code_idx is not None) or (files_idx is not None): + if (code_idx or -1) > (files_idx or -1): + to_run.append(code.pop()) + if len(code_indices) > 0: + code_idx = code_indices.pop() + else: + code_idx = None + else: + p = pathlib.Path(files.pop()) + if not p.exists(): + msg = f"Could not find script file '{p}'" + origen.logger.error(msg) + exit(1) + to_run.append(p) + if len(file_indices) > 0: + files_idx = file_indices.pop() + else: + files_idx = None + + # Decouple run environment from boot environment, but assume origen is already imported + eval_locals = {"origen": origen} + eval_globals = {} + + # Above is actually built with highest index first, so iterate through in reverse + for code in reversed(to_run): + if isinstance(code, pathlib.Path): + c = open(code).read() + else: + c = code + + try: + exec(c, eval_globals, eval_locals) + except Exception as e: + # Doctor the traceback to remove the references to boot.py + # Cleans up the traceback to just what the user should care about + import traceback, sys + tb = e.__traceback__ + exc = traceback.format_exception(None, e, tb) + exc = [exc[0]] + exc[2:-1] + [exc[-1].strip()] + if isinstance(code, pathlib.Path): + origen.logger.error(f"Exception occurred evaluating from script '{code}'") + else: + origen.logger.error(f"Exception occurred evaluating code:\n{c}") + print(''.join(exc), file=sys.stderr) + exit(1) diff --git a/python/origen/origen/helpers/regressions/cli/origen.py b/python/origen/origen/helpers/regressions/cli/origen.py index b0a14d2d..07de3869 100644 --- a/python/origen/origen/helpers/regressions/cli/origen.py +++ b/python/origen/origen/helpers/regressions/cli/origen.py @@ -30,7 +30,21 @@ def eval_cmd(cls, add_opts=None): args=[ CmdArg("code", "Statements to evaluate", multi=True, required=True) ], - opts=add_opts, + opts=(add_opts or []) + [ + CmdOpt( + "scripts", + help="Evaluate from script files", + ln="scripts", + sn="s", + ln_aliases=["files"], + sn_aliases=["f"], + multi=True, + required=False, + ) + ], + h_opt_idx=0, + v_opt_idx=2, + vk_opt_idx=3, demos=[ CmdDemo( "minimal", diff --git a/rust/origen/cli/src/commands/eval.rs b/rust/origen/cli/src/commands/eval.rs index 2704e011..7f3a2339 100644 --- a/rust/origen/cli/src/commands/eval.rs +++ b/rust/origen/cli/src/commands/eval.rs @@ -13,7 +13,20 @@ gen_core_cmd_funcs!( .action(AppendArgs) .value_name("CODE") .multiple(true) - .required(true) + .required_unless_present("scripts") + ) + .arg( + Arg::new("scripts") + .help("Evaluate from script files") + .long("scripts") + .short('s') + .visible_alias("files") + .visible_short_alias('f') + .action(AppendArgs) + .value_name("SCRIPTS") + .multiple(true) + .use_value_delimiter(true) + .require_value_delimiter(true) ) }} ); diff --git a/rust/origen/cli/src/commands/mod.rs b/rust/origen/cli/src/commands/mod.rs index a8a05784..5685a8a4 100644 --- a/rust/origen/cli/src/commands/mod.rs +++ b/rust/origen/cli/src/commands/mod.rs @@ -111,9 +111,11 @@ pub fn launch(base_cmd: Option<&str>, subcmds: Option<&Vec>, invocation: } let mut args: Vec = vec!(); + let mut arg_indices: Vec = vec!(); let mut opt_names = HashMap::new(); - let mut ext_args = HashMap::new(); + let mut ext_args: HashMap<&ExtensionSource, Vec> = HashMap::new(); + let mut ext_arg_indices: HashMap<&ExtensionSource, Vec> = HashMap::new(); if let Some(exts) = cmd_exts { for ext in exts { if let Some(opts) = ext.opts.as_ref() { @@ -121,6 +123,7 @@ pub fn launch(base_cmd: Option<&str>, subcmds: Option<&Vec>, invocation: opt_names.insert(opt.full_name.as_ref().unwrap().as_str(), &ext.source); if !ext_args.contains_key(&ext.source) { ext_args.insert(&ext.source, vec!()); + ext_arg_indices.insert(&ext.source, vec!()); } } } @@ -182,10 +185,17 @@ pub fn launch(base_cmd: Option<&str>, subcmds: Option<&Vec>, invocation: } } } + let indices_str = format!( + "r'{}': [{}]", + as_name!(arg_n), + invocation.indices_of(arg_n).unwrap().map(|i| i.to_string()).collect::>().join(", ") + ); if let Some(ext_src) = opt_names.get(arg_n) { ext_args.get_mut(ext_src).unwrap().push(arg_str); + ext_arg_indices.get_mut(ext_src).unwrap().push(indices_str); } else { args.push(arg_str); + arg_indices.push(indices_str); } } } @@ -194,37 +204,51 @@ pub fn launch(base_cmd: Option<&str>, subcmds: Option<&Vec>, invocation: if let Some(subs) = subcmds.as_ref() { cmd += &format!(", subcmds=[{}]", subs.iter().map( |s| format!("r'{}'", s) ).collect::>().join(", ")); } - cmd += &format!(", args={{{}}}", args.join(", ")); + cmd += &format!(", args={{{}}}, arg_indices={{{}}}", args.join(", "), arg_indices.join(", ")); let mut app_ext_str = "".to_string(); let mut pl_ext_str = "".to_string(); let mut aux_ext_str = "".to_string(); + let mut app_ext_indices_str = "".to_string(); + let mut pl_ext_indices_str = "".to_string(); + let mut aux_ext_indices_str = "".to_string(); if !ext_args.is_empty() { for ext in ext_args { match ext.0 { ExtensionSource::App => { app_ext_str = ext.1.join(", "); + app_ext_indices_str = ext_arg_indices[ext.0].join(", "); }, ExtensionSource::Plugin(ref pl_name) => { pl_ext_str += &format!(", '{}': {{{}}}", pl_name, ext.1.join(", ")); + pl_ext_indices_str += &format!(", '{}': {{{}}}", pl_name, ext_arg_indices[ext.0].join(", ")); }, ExtensionSource::Aux(ref ns, _) => { aux_ext_str += &format!(", '{}': {{{}}}", ns, ext.1.join(", ")); + aux_ext_indices_str += &format!(", '{}': {{{}}}", ns, ext_arg_indices[ext.0].join(", ")); }, } } if !pl_ext_str.is_empty() { pl_ext_str = pl_ext_str[2..].to_string(); + pl_ext_indices_str = pl_ext_indices_str[2..].to_string(); } if !aux_ext_str.is_empty() { aux_ext_str = aux_ext_str[2..].to_string(); + aux_ext_indices_str = aux_ext_indices_str[2..].to_string(); } } cmd += &format!( - ", ext_args={{'app': {{{}}}, 'plugin': {{{}}}, 'aux': {{{}}}}}", + concat!( + ", ext_args={{'app': {{{}}}, 'plugin': {{{}}}, 'aux': {{{}}}}}", + ", ext_arg_indices={{'app': {{{}}}, 'plugin': {{{}}}, 'aux': {{{}}}}}" + ), app_ext_str, pl_ext_str, aux_ext_str, + app_ext_indices_str, + pl_ext_indices_str, + aux_ext_indices_str, ); if let Some(exts) = cmd_exts { diff --git a/rust/pyapi/src/current_command.rs b/rust/pyapi/src/current_command.rs index 407ecec0..4636ce3f 100644 --- a/rust/pyapi/src/current_command.rs +++ b/rust/pyapi/src/current_command.rs @@ -20,12 +20,22 @@ pub fn get_command(py: Python) -> PyResult> { } #[pyfunction] -fn set_command(py: Python, base_cmd: String, subcmds: Vec, args: Py, ext_args: Py, exts: &PyList) -> PyResult<()> { +fn set_command( + py: Python, + base_cmd: String, + subcmds: Vec, + args: Py, + ext_args: Py, + arg_indices: Py, + ext_arg_indices: Py, + exts: &PyList +) -> PyResult<()> { let cmd = CurrentCommand { base: base_cmd, subcmds: subcmds, args: args, - exts: Py::new(py, Extensions::new(py, exts, ext_args)?)?, + arg_indices: arg_indices, + exts: Py::new(py, Extensions::new(py, exts, ext_args, ext_arg_indices)?)?, }; _origen!(py).setattr(ATTR_NAME, Py::new(py, cmd)?) } @@ -41,6 +51,7 @@ pub struct CurrentCommand { base: String, subcmds: Vec, args: Py, + arg_indices: Py, exts: Py, } @@ -74,4 +85,9 @@ impl CurrentCommand { pub fn args<'py>(&'py self, py: Python<'py>) -> PyResult<&'py PyDict> { Ok(self.args.as_ref(py)) } + + #[getter] + pub fn arg_indices<'py>(&'py self, py: Python<'py>) -> PyResult<&'py PyDict> { + Ok(self.arg_indices.as_ref(py)) + } } \ No newline at end of file diff --git a/rust/pyapi/src/extensions.rs b/rust/pyapi/src/extensions.rs index 41bcfb7a..fa18ff75 100644 --- a/rust/pyapi/src/extensions.rs +++ b/rust/pyapi/src/extensions.rs @@ -15,6 +15,7 @@ pub fn define(py: Python, m: &PyModule) -> PyResult<()> { pub struct Extension { name: String, args: Py, + arg_indices: Py, source: String, ext_mod: Option>, } @@ -31,6 +32,11 @@ impl Extension { Ok(self.args.as_ref(py)) } + #[getter] + pub fn arg_indices<'py>(&'py self, py: Python<'py>) -> PyResult<&'py PyDict> { + Ok(self.arg_indices.as_ref(py)) + } + #[getter] pub fn source(&self, py: Python) -> PyResult { Ok(pyapi_metal::pypath!(py, &self.source)) @@ -128,7 +134,7 @@ impl ExtensionsIter { } impl Extensions { - pub fn new<'py>(py: Python<'py>, exts: &PyList, ext_args: Py) -> PyResult { + pub fn new<'py>(py: Python<'py>, exts: &PyList, ext_args: Py, ext_arg_indices: Py) -> PyResult { let mut slf = Self { exts: IndexMap::new(), }; @@ -146,6 +152,7 @@ impl Extensions { ext_path = format!("{}.{}", source, ext_name); } let src_ext_args = PyAny::get_item(ext_args.as_ref(py), &source)?.extract::<&PyDict>()?; + let src_ext_args_indices = PyAny::get_item(ext_arg_indices.as_ref(py), &source)?.extract::<&PyDict>()?; let py_ext = Extension { args: { @@ -155,6 +162,13 @@ impl Extensions { PyAny::get_item(src_ext_args, &ext_name)?.extract::>()? } }, + arg_indices: { + if source == "app" { + src_ext_args_indices.into() + } else { + PyAny::get_item(src_ext_args_indices, &ext_name)?.extract::>()? + } + }, name: ext_name, source: ext_path.clone(), ext_mod: { diff --git a/test_apps/python_app/tests/cli/tests__cmd_exts_from_app.py b/test_apps/python_app/tests/cli/tests__cmd_exts_from_app.py index bf924968..3b4809e8 100644 --- a/test_apps/python_app/tests/cli/tests__cmd_exts_from_app.py +++ b/test_apps/python_app/tests/cli/tests__cmd_exts_from_app.py @@ -83,10 +83,12 @@ def test_extending_global_cmds(self): cmd = self.core_cmd help = cmd.get_help_msg() help.assert_args(cmd.code) + opts = list(self.in_app_cmds.standard_opts()) + opts.insert(3, cmd.scripts) help.assert_opts( cmd.generic_app_ext_action, cmd.generic_app_ext_flag, - *self.in_app_cmds.standard_opts() + *opts ) assert help.aux_exts == None @@ -113,6 +115,7 @@ def test_stacking_pl_aux_and_app_ext(self): cmd.generic_app_ext_flag, "help", "mode", "no_targets", cmd.pl_ext_cmds_generic_ext, + cmd.scripts, "targets", "v", 'vk' ) assert help.aux_exts == ['core_cmd_exts'] diff --git a/test_apps/python_app/tests/cli/tests__core_cmds.py b/test_apps/python_app/tests/cli/tests__core_cmds.py index 4e8b79f9..cfda3c16 100644 --- a/test_apps/python_app/tests/cli/tests__core_cmds.py +++ b/test_apps/python_app/tests/cli/tests__core_cmds.py @@ -43,7 +43,9 @@ def test_help_msg(self, cmd, no_config_run_opts): help = cmd.get_help_msg(run_opts=no_config_run_opts) help.assert_summary(cmd.help) help.assert_args(cmd.code) - help.assert_bare_app_opts() + opts = list(self.in_app_cmds.standard_opts()) + opts.insert(3, cmd.scripts) + help.assert_opts(*opts) def test_basic_eval(self, cmd, no_config_run_opts): d = cmd.demos["multi_statement_single_arg"] diff --git a/test_apps/python_app/tests/cli/tests__reserved_opts.py b/test_apps/python_app/tests/cli/tests__reserved_opts.py index 73f7edbd..33ac9f69 100644 --- a/test_apps/python_app/tests/cli/tests__reserved_opts.py +++ b/test_apps/python_app/tests/cli/tests__reserved_opts.py @@ -261,7 +261,9 @@ def test_ext_opts_are_added_with_respect_to_errors(self): "m", cmd.conflicting_mode, cmd.conflicting_no_target, - "nt", "t", "v", "vk" + "nt", + cmd.scripts, + "t", "v", "vk" ) help.assert_subcmds(None) diff --git a/test_apps/python_no_app/tests/cli/tests__cmd__eval.py b/test_apps/python_no_app/tests/cli/tests__cmd__eval.py index 105a3d20..bf1823cb 100644 --- a/test_apps/python_no_app/tests/cli/tests__cmd__eval.py +++ b/test_apps/python_no_app/tests/cli/tests__cmd__eval.py @@ -1,4 +1,4 @@ -import origen, pytest +import origen, pytest, pathlib from .shared import CLICommon class T_Eval(CLICommon): @@ -7,6 +7,10 @@ class T_Eval(CLICommon): "with_configs": CLICommon.configs.suppress_plugin_collecting_config, "bypass_config_lookup": True } + script_dir = pathlib.Path(__file__).parent.joinpath("tests__cmd__eval__scripts") + + def eval_script(self, name): + return self.script_dir.joinpath(f"{name}.py") @pytest.fixture def no_config_run_opts(self): @@ -14,9 +18,7 @@ def no_config_run_opts(self): def test_help_msg(self, cmd, no_config_run_opts): help = cmd.get_help_msg(run_opts=no_config_run_opts) - help.assert_summary(cmd.help) - help.assert_args(cmd.code) - help.assert_bare_opts() + help.assert_cmd(cmd) def test_with_single_statement(self, cmd, no_config_run_opts): d = cmd.demos["multi_statement_single_arg"] @@ -41,3 +43,57 @@ def test_clean_eval(self): eval_prefix = "Origen Version From Eval: " out = self.eval("print (f'" + eval_prefix + "{origen.version}' )") assert out == f"{eval_prefix}{origen.version}\n" + + def test_eval_with_script(self, cmd): + out = cmd.run(cmd.scripts.ln_to_cli(), self.eval_script("hi")) + assert out == "eval_script__say_hi: hi!\n" + + out = cmd.run( + cmd.scripts.ln_to_cli(), self.eval_script("override_preface"), + cmd.scripts.ln_to_cli(), self.eval_script("hi") + ) + assert out == "eval_script_override: hi!\n" + + def test_eval_context_persists_over_scripts(self, cmd): + out = cmd.run( + "preface='preface_override'", + cmd.scripts.ln_to_cli(), self.eval_script("hi"), + "print(hi)" + ) + assert out == "preface_override: hi!\nhi!\n" + + def test_error_in_script(self, cmd): + err = self.eval_script("err") + out = cmd.gen_error( + "print('test_error_in_script')", + cmd.scripts.ln_to_cli(), err, + return_full=True + ) + + stdout = out["stdout"] + errs = self.extract_logged_errors(stdout) + assert errs[0] == f"Exception occurred evaluating from script '{err}'" + assert len(errs) == 1 + + stdout = stdout.split("\n") + assert "test_error_in_script" in stdout[1] + assert stdout[2] == "tests__cmd__eval__scripts: gen error" + assert stdout[3] == '' + assert len(stdout) == 4 + + stderr = out["stderr"].split("\n") + assert "Traceback" in stderr[0] + assert "line 2" in stderr[1] + assert stderr[2] == "NameError: name 'hello' is not defined" + assert stdout[3] == '' + assert len(stderr) == 4 + + def test_eval_with_invalid_script(self, cmd): + invalid = self.eval_script("invalid") + out = cmd.gen_error( + "print('hi')", + cmd.scripts.ln_to_cli(), invalid, + return_full=True + ) + assert out["stderr"] == '' + assert f"Could not find script file '{invalid}'" in out['stdout'] diff --git a/test_apps/python_no_app/tests/cli/tests__cmd__eval__scripts/err.py b/test_apps/python_no_app/tests/cli/tests__cmd__eval__scripts/err.py new file mode 100644 index 00000000..0def8f75 --- /dev/null +++ b/test_apps/python_no_app/tests/cli/tests__cmd__eval__scripts/err.py @@ -0,0 +1,2 @@ +print('tests__cmd__eval__scripts: gen error') +print(hello) diff --git a/test_apps/python_no_app/tests/cli/tests__cmd__eval__scripts/hi.py b/test_apps/python_no_app/tests/cli/tests__cmd__eval__scripts/hi.py new file mode 100644 index 00000000..ecbee244 --- /dev/null +++ b/test_apps/python_no_app/tests/cli/tests__cmd__eval__scripts/hi.py @@ -0,0 +1,5 @@ +preface = locals().get("preface", None) +hi = "hi!" +if not preface: + preface = "eval_script__say_hi" +print(f"{preface}: {hi}") diff --git a/test_apps/python_no_app/tests/cli/tests__cmd__eval__scripts/override_preface.py b/test_apps/python_no_app/tests/cli/tests__cmd__eval__scripts/override_preface.py new file mode 100644 index 00000000..c3eb5426 --- /dev/null +++ b/test_apps/python_no_app/tests/cli/tests__cmd__eval__scripts/override_preface.py @@ -0,0 +1 @@ +preface = "eval_script_override" \ No newline at end of file diff --git a/test_apps/python_no_app/tests/cmd_exts/tests__ext_conflicts.py b/test_apps/python_no_app/tests/cmd_exts/tests__ext_conflicts.py index 4c36ed7e..0fa15dc2 100644 --- a/test_apps/python_no_app/tests/cmd_exts/tests__ext_conflicts.py +++ b/test_apps/python_no_app/tests/cmd_exts/tests__ext_conflicts.py @@ -279,6 +279,7 @@ def test_ext_arg_conflicts_with_core_cmd_help_msg(self): pl_code_opt, aux_code_opt, "help", + cmd.scripts, cmd.say_hi_during_cleanup, "v", "vk", diff --git a/test_apps/python_no_app/tests/cmd_exts/tests__extending_cmds.py b/test_apps/python_no_app/tests/cmd_exts/tests__extending_cmds.py index a7f0c929..45e1e94e 100644 --- a/test_apps/python_no_app/tests/cmd_exts/tests__extending_cmds.py +++ b/test_apps/python_no_app/tests/cmd_exts/tests__extending_cmds.py @@ -554,6 +554,7 @@ def test_extending_origen_cmd_from_plugin(self): cmd.core_cmd_exts_generic_core_ext, "help", cmd.pl_ext_cmds_generic_ext, + cmd.scripts, "v", "vk", ) diff --git a/test_apps/python_no_app/tests/shared.py b/test_apps/python_no_app/tests/shared.py index 79c7e788..e8ae7ba2 100644 --- a/test_apps/python_no_app/tests/shared.py +++ b/test_apps/python_no_app/tests/shared.py @@ -3,3 +3,11 @@ tests_root = Path(__file__).parent working_dir = Path(__file__).parent.parent working_dir_config = working_dir.joinpath("origen.toml") + +def tmp_dir(offset=None): + t = Path(__file__).parent.parent.parent.joinpath('tmp/pytest') + if offset: + t = t.joinpath(offset) + if not t.exists(): + t.mkdir(parents=True, exist_ok=True) + return t diff --git a/test_apps/python_no_app/tests/test_plugin_loading.py b/test_apps/python_no_app/tests/test_plugin_loading.py index 781964c5..445306f7 100644 --- a/test_apps/python_no_app/tests/test_plugin_loading.py +++ b/test_apps/python_no_app/tests/test_plugin_loading.py @@ -25,11 +25,13 @@ def get_configs_and_plugins_from_cli(cls, configs=None, bypass_config_lookup=Fal def test_plugins_are_collected_by_default(self): retn = in_new_origen_proc(mod=config_funcs) assert retn['configs'] == [] + # TODO consistent plugin loading assert set(retn['plugins']) == set(self.plugins.python_no_app_collected_pl_names) # Test from CLI retn = self.get_configs_and_plugins_from_cli(bypass_config_lookup=True) assert retn['configs'] == [] + # TODO consistent plugin loading assert set(retn['plugins']) == set(self.plugins.python_no_app_collected_pl_names) def test_plugins_are_accessible(self): From 678494073b7a5428587802b7f75de5d858edcbf6 Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 1 Jul 2023 21:13:45 -0500 Subject: [PATCH 13/51] Set indices to empty-dict if not given. Add test for arg indices. Fix typo in assertions filename. --- python/origen/origen/boot.py | 4 ++ .../tests/cmd_exts/tests__extending_cmds.py | 11 ------ .../tests/test_current_command.py | 38 +++++++++++++++++++ .../cli/__init__.py | 6 ++- .../cli/{asertions.py => assertions.py} | 0 .../cli/ext_helpers.py | 17 ++++++++- 6 files changed, 63 insertions(+), 13 deletions(-) rename test_apps/test_apps_shared_test_helpers/test_apps_shared_test_helpers/cli/{asertions.py => assertions.py} (100%) diff --git a/python/origen/origen/boot.py b/python/origen/origen/boot.py index a94956a2..a5630c6f 100644 --- a/python/origen/origen/boot.py +++ b/python/origen/origen/boot.py @@ -43,6 +43,8 @@ def run_cmd(command, if args is None: args = {} + if arg_indices is None: + arg_indices = {} if command == dispatch_plugin_cmd: cmd_src = "plugin" @@ -144,6 +146,8 @@ def call_user_cmd(cmd_type): subcmds = [] if ext_args is None: ext_args = {} + if ext_arg_indices is None: + ext_arg_indices = {} if extensions is None: extensions = [] current_ext = None diff --git a/test_apps/python_no_app/tests/cmd_exts/tests__extending_cmds.py b/test_apps/python_no_app/tests/cmd_exts/tests__extending_cmds.py index 45e1e94e..46bffb17 100644 --- a/test_apps/python_no_app/tests/cmd_exts/tests__extending_cmds.py +++ b/test_apps/python_no_app/tests/cmd_exts/tests__extending_cmds.py @@ -35,17 +35,6 @@ class TestExtensionOpts(Common): ext_mvd = ["mvd0", "mvd1"] ext_rv = ["no_action"] - def get_action_results(self, output, actions): - retn = {} - for action in actions: - a = {} - r = output.split(f"Start Action Before CMD: {action}")[1].strip() - a["Before"], r = r.split(f"End Action Before CMD: {action}") - r = output.split(f"Start Action After CMD: {action}")[1].strip() - a["After"], r = r.split(f"End Action After CMD: {action}") - retn[action] = a - return retn - def test_help_msg(self): help = self.cmd.get_help_msg() help.assert_args(self.sa, self.ma) diff --git a/test_apps/python_no_app/tests/test_current_command.py b/test_apps/python_no_app/tests/test_current_command.py index aaea3d1a..196d8063 100644 --- a/test_apps/python_no_app/tests/test_current_command.py +++ b/test_apps/python_no_app/tests/test_current_command.py @@ -41,6 +41,44 @@ def test_current_command_from_pl_cmd(self): {} ) + def test_arg_indices(self): + cmd = CLIShared.python_plugin.plugin_test_args.extend( + CLIShared.exts.exts["plugin.python_plugin.plugin_test_args"]["exts"], + from_configs=CLIShared.exts.exts_workout_cfg + ) + + ext_flag = cmd.flag_extension + ext_ha = cmd.hidden_opt + ext_action = cmd.exts_workout_action + + args = "show_arg_indices" + exts = "show_ext_arg_indices" + # Index 0 is the command name + # NOTE: per the clap API, when flags (options not accepting values) are used, only the last index is given + out = cmd.run( + "sv", "m0", "m1", "m2", # indices 1, 2-4 + ext_flag.ln_to_cli(), # 5 + cmd.opt_taking_value.ln_to_cli(), "opt_val", # 6 (opt name), 7 (value) + ext_flag.sn_to_cli(), # 8 + ext_ha.ln_to_cli(), # 9 + ext_action.ln_to_cli(), args, exts, # 10 (opt name), 11, 12 (values) + cmd.multi_val_delim_opt.ln_to_cli(), "d0,d1,d2" + ) + parsed = self.get_action_results(out, [args, exts]) + assert eval(parsed[args]["Before"]) == { + cmd.single_arg.name: [1], + cmd.multi_arg.name: [2, 3, 4], + cmd.opt_taking_value.name: [7] + } + assert eval(parsed[exts]["Before"]) == { + "aux.exts_workout": { + ext_flag.name: [8], + ext_ha.name: [9], + ext_action.name: [11, 12], + cmd.multi_val_delim_opt.name: [14, 15, 16], + } + } + @pytest.mark.skip def test_current_command_from_aux_cmd(self): # TEST_NEEDED Current Command core case diff --git a/test_apps/test_apps_shared_test_helpers/test_apps_shared_test_helpers/cli/__init__.py b/test_apps/test_apps_shared_test_helpers/test_apps_shared_test_helpers/cli/__init__.py index 9425d29d..25b2649f 100644 --- a/test_apps/test_apps_shared_test_helpers/test_apps_shared_test_helpers/cli/__init__.py +++ b/test_apps/test_apps_shared_test_helpers/test_apps_shared_test_helpers/cli/__init__.py @@ -9,7 +9,7 @@ from .cmd_models.plugins import Plugins from .error_cases import ErrorCases -from .asertions import AssertionHelpers +from .assertions import AssertionHelpers develop_origen = "develop_origen" def develop_origen_cmd(): @@ -103,6 +103,10 @@ class CLIShared(cli.CLI, AssertionHelpers): error_messages = ErrorCases() na = "no_action" + def get_action_results(self, *args): + from .ext_helpers import get_action_results as get_action_results_wrap + return get_action_results_wrap(*args) + @pytest.fixture def cmd(self): return self._cmd diff --git a/test_apps/test_apps_shared_test_helpers/test_apps_shared_test_helpers/cli/asertions.py b/test_apps/test_apps_shared_test_helpers/test_apps_shared_test_helpers/cli/assertions.py similarity index 100% rename from test_apps/test_apps_shared_test_helpers/test_apps_shared_test_helpers/cli/asertions.py rename to test_apps/test_apps_shared_test_helpers/test_apps_shared_test_helpers/cli/assertions.py diff --git a/test_apps/test_apps_shared_test_helpers/test_apps_shared_test_helpers/cli/ext_helpers.py b/test_apps/test_apps_shared_test_helpers/test_apps_shared_test_helpers/cli/ext_helpers.py index 17761bb1..70e0b547 100644 --- a/test_apps/test_apps_shared_test_helpers/test_apps_shared_test_helpers/cli/ext_helpers.py +++ b/test_apps/test_apps_shared_test_helpers/test_apps_shared_test_helpers/cli/ext_helpers.py @@ -86,8 +86,23 @@ def do_action(actions, phase): # TEST_NEEDED CLI check for extension mods for n, e in origen.current_command.exts.items(): print(f"{n}: {e.mod}") + elif action == "show_arg_indices": + print(origen.current_command.arg_indices) + elif action == "show_ext_arg_indices": + print({ n: v.arg_indices for n, v in origen.current_command.exts.items() }) elif action == "no_action": pass else: raise RuntimeError(f"No action '{action}' is known!") - print(f"End Action {p_out} CMD: {action}") \ No newline at end of file + print(f"End Action {p_out} CMD: {action}") + +def get_action_results(output, actions): + retn = {} + for action in actions: + a = {} + r = output.split(f"Start Action Before CMD: {action}")[1].strip() + a["Before"], r = r.split(f"End Action Before CMD: {action}") + r = output.split(f"Start Action After CMD: {action}")[1].strip() + a["After"], r = r.split(f"End Action After CMD: {action}") + retn[action] = a + return retn From c4d62873a5e1631321bbb9f4cecd8c983163e075 Mon Sep 17 00:00:00 2001 From: Corey Date: Sun, 2 Jul 2023 08:20:50 -0500 Subject: [PATCH 14/51] Support auto-interpreting some args as strs in run_cli_cmd --- python/origen/origen/helpers/env.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/origen/origen/helpers/env.py b/python/origen/origen/helpers/env.py index f554900b..279ee339 100644 --- a/python/origen/origen/helpers/env.py +++ b/python/origen/origen/helpers/env.py @@ -26,6 +26,14 @@ def run_cli_cmd(cmd, *, ): if isinstance(cmd, str): cmd = [cmd] + else: + def to_cmd(c): + if isinstance(c, pathlib.Path): + return str(c) + else: + return c + cmd = list(map(to_cmd, cmd)) + if (origen_exe is None) or isinstance(origen_exe, str): origen_exe = [origen_exe or 'origen'] if poetry_run: From 69242fa5662cd54e876bad295eb7ea14e0b8e0d8 Mon Sep 17 00:00:00 2001 From: coreyeng Date: Sun, 2 Jul 2023 20:50:52 -0500 Subject: [PATCH 15/51] Fix for windows path conversion with given as arg to run_cli_cmd --- python/origen/origen/helpers/env.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/python/origen/origen/helpers/env.py b/python/origen/origen/helpers/env.py index 279ee339..23e1439d 100644 --- a/python/origen/origen/helpers/env.py +++ b/python/origen/origen/helpers/env.py @@ -29,7 +29,7 @@ def run_cli_cmd(cmd, *, else: def to_cmd(c): if isinstance(c, pathlib.Path): - return str(c) + return c.as_posix() else: return c cmd = list(map(to_cmd, cmd)) @@ -68,7 +68,9 @@ def to_cmd(c): cmd = ' '.join(cmd) raise RuntimeError(f"Expected cmd '{cmd}' to fail but received return code 0") else: - result = subprocess.run(cmd, shell=shell, check=check, capture_output=True, text=True, input=input, env=subp_env) + result = subprocess.run(cmd, shell=shell, check=False, capture_output=True, text=True, input=input, env=subp_env) + print(result.stderr) + print(result.stdout) if return_details: return { "stderr": result.stderr, From a9200fb770a70a502798d9ba3438da1d0ea60313 Mon Sep 17 00:00:00 2001 From: coreyeng Date: Sun, 2 Jul 2023 20:59:36 -0500 Subject: [PATCH 16/51] Accidentally left in some debug stuff --- python/origen/origen/helpers/env.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/python/origen/origen/helpers/env.py b/python/origen/origen/helpers/env.py index 23e1439d..716dd67e 100644 --- a/python/origen/origen/helpers/env.py +++ b/python/origen/origen/helpers/env.py @@ -68,9 +68,7 @@ def to_cmd(c): cmd = ' '.join(cmd) raise RuntimeError(f"Expected cmd '{cmd}' to fail but received return code 0") else: - result = subprocess.run(cmd, shell=shell, check=False, capture_output=True, text=True, input=input, env=subp_env) - print(result.stderr) - print(result.stdout) + result = subprocess.run(cmd, shell=shell, check=check, capture_output=True, text=True, input=input, env=subp_env) if return_details: return { "stderr": result.stderr, From 62cabad2c4fb57f1f5626abfda22c29dd65dee45 Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 3 Jul 2023 21:02:39 -0500 Subject: [PATCH 17/51] Add no-workspace with/without plugins tests --- .github/workflows/regression_test.yml | 38 ++++++++-- python/origen/pyproject.toml | 2 +- rust/origen/cli/src/python.rs | 4 +- rust/origen/src/core/status.rs | 8 +- rust/pyapi/src/infrastructure/pyproject.rs | 4 +- .../eval_scripts/print_pl_names.py | 4 + .../no_workspace/eval_scripts/print_status.py | 4 + test_apps/no_workspace/t_invocation_env.py | 74 ++++++++++++++----- test_apps/no_workspace/test_no_workspace.py | 27 +++++++ test_apps/pl_ext_cmds/pyproject.toml | 2 +- 10 files changed, 131 insertions(+), 36 deletions(-) create mode 100644 test_apps/no_workspace/eval_scripts/print_pl_names.py create mode 100644 test_apps/no_workspace/eval_scripts/print_status.py create mode 100644 test_apps/no_workspace/test_no_workspace.py diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index f8559e42..41184b48 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -124,7 +124,7 @@ jobs: # - name: Install Poetry # uses: abatilo/actions-poetry@v2.0.0 # with: - # poetry-version: 1.3.2 + # poetry-version: 1.1.14 - name: Setup Python Env - Metal working-directory: python/origen_metal @@ -153,10 +153,34 @@ jobs: # TODO eventually want to move this into a poetry build step # For now, manually move the binary. Also keeps us from having to mess with the path across OSs # 'mv' command should be be fine for both linux & powershell - # - name: Move Origen executable (Linux) - # if: matrix.os == 'ubuntu-latest' - # run: mv rust/origen/target/debug/origen python/origen/origen/__bin__/bin + - name: Move Origen executable (Linux) + if: matrix.os == 'ubuntu-latest' + run: mv rust/origen/target/debug/origen python/origen/origen/__bin__/bin + - name: Move Origen executable (Windows) + if: matrix.os == 'windows-latest' + run: mv rust/origen/target/debug/origen.exe python/origen/origen/__bin__/bin + + - name: Install Origen Packages + run: + pip install python/origen + pip install python/origen_metal + + - name: Show Origen Binary Location (Linux) + run: which origen + - name: Show Origen Binary Location (Windows) + run: where.exe origen - # - name: Move Origen executable (Windows) - # if: matrix.os == 'windows-latest' - # run: mv rust/origen/target/debug/origen.exe python/origen/origen/__bin__/bin + # Should be no pyprojects in the root so far. Start with no-workspace tests + - name: Run No-Workspace-No-Plugins Tests + working-directory: test_apps/no_workspace + run: pytest test_no_workspace.py::TestNoWorkspaceNoPlugins -vv + + - name: Install Plugins + run: + pip install test_apps/test_apps_shared_test_helpers + pip install test_apps/python_plugin + pip install python/origen_metal + + - name: Run No-Workspace-With-Plugins Tests + working-directory: test_apps/no_workspace + run: pytest test_no_workspace.py::TestNoWorkspaceWithPlugins -vv diff --git a/python/origen/pyproject.toml b/python/origen/pyproject.toml index a1465970..40e392b0 100644 --- a/python/origen/pyproject.toml +++ b/python/origen/pyproject.toml @@ -18,7 +18,7 @@ script = "poetry_build.py" generate-setup-file = false [tool.poetry.scripts] -o2 = 'origen.__bin__:run_origen' +origen = 'origen.__bin__:run_origen' [tool.poetry.dependencies] python = ">=3.7,<3.11" diff --git a/rust/origen/cli/src/python.rs b/rust/origen/cli/src/python.rs index 1491ae3f..880c312d 100644 --- a/rust/origen/cli/src/python.rs +++ b/rust/origen/cli/src/python.rs @@ -105,7 +105,7 @@ pub fn resolve_pyproject() -> Result { } log_trace!("No pyproject found. Skipping Poetry invocations..."); - Ok(DependencySrc::None) + Ok(DependencySrc::NoneFound) } impl Config { @@ -125,7 +125,7 @@ impl Config { c.arg("-C"); c.arg(path); } - DependencySrc::None => {} + DependencySrc::NoneFound => {} } } else { log_error!("Dependency source has not been set - defaulting to global Python installation"); diff --git a/rust/origen/src/core/status.rs b/rust/origen/src/core/status.rs index 01d66434..d6beceb4 100644 --- a/rust/origen/src/core/status.rs +++ b/rust/origen/src/core/status.rs @@ -61,13 +61,13 @@ pub enum DependencySrc { Workspace(PathBuf), // current directory tree (in workspace) UserGlobal(PathBuf), // explicitly given by user, no workspace Global(PathBuf), // the origen CLI installation directory, no workspace - None, // None available. Use whatever is available in the same install environment as Origen itself + NoneFound, // None available. Use whatever is available in the same install environment as Origen itself } impl DependencySrc { pub fn src_available(&self) -> bool { match self { - Self::None => false, + Self::NoneFound => false, _ => true, } } @@ -75,7 +75,7 @@ impl DependencySrc { pub fn src_file(&self) -> Option<&PathBuf> { match self { Self::App(path) | Self::Workspace(path) | Self::UserGlobal(path) | Self::Global(path) => Some(path), - Self::None => None, + Self::NoneFound => None, } } } @@ -99,7 +99,7 @@ where S: AsRef { "Workspace" => gen_case!(Workspace), "UserGlobal" => gen_case!(UserGlobal), "Global" => gen_case!(Global), - "None" => Self::None, + "None" => Self::NoneFound, _ => bail!("Cannot convert value '{}' to dependency src type", value.0.as_ref()) }) } diff --git a/rust/pyapi/src/infrastructure/pyproject.rs b/rust/pyapi/src/infrastructure/pyproject.rs index 319e1f19..876bdd34 100644 --- a/rust/pyapi/src/infrastructure/pyproject.rs +++ b/rust/pyapi/src/infrastructure/pyproject.rs @@ -31,7 +31,7 @@ pub enum PyProjectSrc { Workspace, UserGlobal, Global, - None, + NoneFound, } impl PyProjectSrc { @@ -47,7 +47,7 @@ impl From<&DependencySrc> for PyProjectSrc { DependencySrc::Workspace(_) => Self::Workspace, DependencySrc::UserGlobal(_) => Self::UserGlobal, DependencySrc::Global(_) => Self::Global, - DependencySrc::None => Self::None, + DependencySrc::NoneFound => Self::NoneFound, } } } \ No newline at end of file diff --git a/test_apps/no_workspace/eval_scripts/print_pl_names.py b/test_apps/no_workspace/eval_scripts/print_pl_names.py new file mode 100644 index 00000000..4cb9d252 --- /dev/null +++ b/test_apps/no_workspace/eval_scripts/print_pl_names.py @@ -0,0 +1,4 @@ +import origen +header = "--Origen Eval--" +print(header) +print(list(origen.plugins.keys())) diff --git a/test_apps/no_workspace/eval_scripts/print_status.py b/test_apps/no_workspace/eval_scripts/print_status.py new file mode 100644 index 00000000..dd9606d5 --- /dev/null +++ b/test_apps/no_workspace/eval_scripts/print_status.py @@ -0,0 +1,4 @@ +import origen +header = "--Origen Eval--" +print(header) +print(origen.status) diff --git a/test_apps/no_workspace/t_invocation_env.py b/test_apps/no_workspace/t_invocation_env.py index fcd4c36d..d0d57b81 100644 --- a/test_apps/no_workspace/t_invocation_env.py +++ b/test_apps/no_workspace/t_invocation_env.py @@ -1,3 +1,4 @@ +# FOR_PR clean up # Use the dev version but actual tests should be done through 'eval'. import sys, pathlib p = pathlib.Path(__file__).parent.parent.parent.joinpath("python/origen") @@ -17,6 +18,9 @@ no_workspace_test_dir = pathlib.Path(__file__).parent o2_root = no_workspace_test_dir.parent.parent debug_cli_loc = o2_root.joinpath(f"rust/origen/target/debug/origen{'.exe' if origen.running_on_windows else ''}") +eval_scripts_dir = no_workspace_test_dir.joinpath("eval_scripts") +status_eval_script = eval_scripts_dir.joinpath("print_status.py") +pl_names_eval_script = eval_scripts_dir.joinpath("print_pl_names.py") # Assume pip is installed in 'site-packages' site_packages_dir = pathlib.Path(pip.__file__).parent.parent @@ -30,45 +34,69 @@ class T_InvocationBaseTests(CLI): @classmethod def setup(cls): cls.set_params() - cls.target_pyproj_toml = cls.target_pyproj_dir.joinpath(toml) - cls.target_poetry_lock = cls.target_pyproj_dir.joinpath(lockfile) + if cls.target_pyproj_dir: + cls.target_pyproj_toml = cls.target_pyproj_dir.joinpath(toml) + cls.target_poetry_lock = cls.target_pyproj_dir.joinpath(lockfile) + else: + cls.target_pyproj_toml = None + cls.target_poetry_lock = None + + if not hasattr(cls, "file_based_evals"): + cls.file_based_evals = False + cls.cli_location = cls.cli_dir.joinpath(f"origen{'.exe' if origen.running_on_windows else ''}") @property def header(self): return "--Origen Eval--" - def test_invocation_from_pytest(self): - assert origen.status["pyproject"] is None - assert origen.status["invocation"] is None - def eval_and_parse(self, code): # out = CLI.global_cmds.eval.run(code, "-vv", run_opts={"return_details": True}) - out = CLI.global_cmds.eval.run(code) + if isinstance(code, str): + code = [code] + print(code) + # out = CLI.global_cmds.eval.run(*code, run_opts={"return_details": True, "check": False}) + out = CLI.global_cmds.eval.run(*code) + print(out) out = out.split("\n") idx = out.index(self.header) return eval(out[idx+1]) + def get_status(self): + if self.file_based_evals: + return self.eval_and_parse(["-f", status_eval_script]) + else: + return self.eval_and_parse(f"print('{self.header}'); print(origen.status)") + + def test_invocation_from_pytest(self): + assert origen.status["pyproject"] is None + assert origen.status["invocation"] is None + def test_pyproject_and_invocation_set(self): - code = f"print('{self.header}'); print(origen.status)" + # code = f"print('{self.header}'); print(origen.status)" # code = r"print\(\\\"Origen\ Status:\\\"\) print\(origen.status\)" - status = self.eval_and_parse(code) + status = self.get_status() print(status) assert status["pyproject"] == self.target_pyproj_toml assert status["invocation"] == self.invocation def test_cli_location(self): - code = f"print('{self.header}'); print(origen.status)" - status = self.eval_and_parse(code) + # code = f"print('{self.header}'); print(origen.status)" + # status = self.eval_and_parse(code) + status = self.get_status() assert status['cli_location'] == self.cli_location class T_InvocationEnv(T_InvocationBaseTests): @classmethod - def setup(cls): + def setup_method(cls): super().setup() # cls.set_params() - cls._pyproj_src_file = cls.gen_pyproj() + if cls.target_pyproj_dir: + cls._pyproj_src_file = cls.gen_pyproj() if not hasattr(cls, "move_pyproject"): - cls.move_pyproject = True + if cls.target_pyproj_dir: + cls.move_pyproject = True + else: + cls.move_pyproject = False # TODO clear any existing pyproject/poetry.locks ? # cls._pyproj_lock = cls._pyproj_file.parent.joinpath("poetry.lock") # for d in origen_exe_loc.parents: @@ -81,11 +109,12 @@ def setup(cls): target = cls.target_pyproj_dir.joinpath(toml) print(f"Moving pyproject {cls._pyproj_src_file} to {target}") shutil.copy(cls._pyproj_src_file, target) - subprocess.run(["poetry", "--version"], check=True, cwd=cls.target_pyproj_dir) - subprocess.run(["poetry", "install"], check=True, cwd=cls.target_pyproj_dir) + if cls.target_pyproj_dir: + subprocess.run(["poetry", "--version"], check=True, cwd=cls.target_pyproj_dir) + subprocess.run(["poetry", "install"], check=True, cwd=cls.target_pyproj_dir) @classmethod - def teardown(cls): + def teardown_method(cls): if cls.move_pyproject: print(f"Cleaning pyproject and lockfile {cls.target_pyproj_toml}, {cls.target_poetry_lock}") cls.target_pyproj_toml.unlink() @@ -118,13 +147,20 @@ def gen_pyproj(cls): # # if id == "_origen_metal": # assert isinstance(origen_metal._origen_metal, ModuleType) + def get_plugin_names(self): + if self.file_based_evals: + return self.eval_and_parse(["-f", pl_names_eval_script]) + else: + return self.eval_and_parse(f"print('{self.header}'); print(list(origen.plugins.keys()))") + @pytest.mark.skip def test_origen_h(self): fail def test_plugins(self): - code = f"print('{self.header}'); print(list(origen.plugins.keys()))" - pls = self.eval_and_parse(code) + # code = f"print('{self.header}'); print(list(origen.plugins.keys()))" + pls = self.get_plugin_names() + # pls = self.eval_and_parse(code) if self.has_pls: # TODO consistent plugin loading assert set(pls) == {'pl_ext_cmds', 'test_apps_shared_test_helpers', 'python_plugin'} diff --git a/test_apps/no_workspace/test_no_workspace.py b/test_apps/no_workspace/test_no_workspace.py new file mode 100644 index 00000000..1d571779 --- /dev/null +++ b/test_apps/no_workspace/test_no_workspace.py @@ -0,0 +1,27 @@ +from .t_invocation_env import T_InvocationEnv, no_workspace_test_dir, PyProjectSrc, site_packages_dir + +class TestNoWorkspaceNoPlugins(T_InvocationEnv): + user_install_dir = no_workspace_test_dir.joinpath("user_install") + + @classmethod + def set_params(cls): + cls.target_pyproj_dir = None + cls.invocation = PyProjectSrc.NoneFound + cls.cli_dir = site_packages_dir.joinpath("origen/__bin__/bin") + cls.has_pls = False + + @classmethod + def setup_method(cls): + cls.file_based_evals = True + super().setup_method() + +class TestNoWorkspaceWithPlugins(TestNoWorkspaceNoPlugins): + @classmethod + def set_params(cls): + super().set_params() + cls.has_pls = True + + def test_exts_in_user_global_context(self): + out = self.global_cmds.eval.run("1==1", "-b", "-a") + assert "Hi from python-plugin during 'eval'!" in out + assert "Hi again from python-plugin during 'eval'!" in out diff --git a/test_apps/pl_ext_cmds/pyproject.toml b/test_apps/pl_ext_cmds/pyproject.toml index 9fc1d4dd..889ce813 100644 --- a/test_apps/pl_ext_cmds/pyproject.toml +++ b/test_apps/pl_ext_cmds/pyproject.toml @@ -7,7 +7,7 @@ authors = ["Origen-SDK"] [tool.poetry.dependencies] python = ">=3.7,<3.11" origen = { path = "../../python/origen", develop = true } -origen_metal = { path = "../../python/origen_metal", develop = true } +origen_metal = ">=0.0.0" [tool.poetry.dev-dependencies] pytest = "^3" From 8889c54a9c41b65a21fc989f96e85e1da11ea9c7 Mon Sep 17 00:00:00 2001 From: Corey Date: Tue, 4 Jul 2023 07:22:09 -0500 Subject: [PATCH 18/51] Debug regression tests --- .github/workflows/regression_test.yml | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 41184b48..89f9768f 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -45,12 +45,21 @@ jobs: - name: Add Origen to PATH (Linux) if: matrix.os == 'ubuntu-latest' - run: echo "${{ github.workspace }}/rust/origen/target/debug" >> $GITHUB_PATH + run: + echo "${{ github.workspace }}/rust/origen/target/debug" >> $GITHUB_PATH + echo "${{ github.workspace }}/rust/origen/target/debug" >> $PATH - name: Add Origen to PATH (Windows) if: matrix.os == 'windows-latest' - run: echo "${{ github.workspace }}/rust/origen/target/debug" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - + run: + echo "${{ github.workspace }}/rust/origen/target/debug" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + echo "${{ github.workspace }}/rust/origen/target/debug" | Out-File -FilePath $env:PATH -Encoding utf8 -Append + + - name: Show Origen Binary Location (Linux) + run: which origen + - name: Show Origen Binary Location (Windows) + run: where.exe origen + - name: Display Python Version run: python -c "import sys; print(sys.version)" @@ -67,7 +76,12 @@ jobs: - name: Display Origen App Version working-directory: test_apps/python_app run: origen -v - + + - name: Show Origen Binary Location (Linux) + run: which origen + - name: Show Origen Binary Location (Windows) + run: where.exe origen + - name: Display Poetry Version working-directory: test_apps/python_app run: poetry --version From 55c8b2706a1b77e046c3eb15de5dbc338ceee06e Mon Sep 17 00:00:00 2001 From: Corey Date: Tue, 4 Jul 2023 07:44:37 -0500 Subject: [PATCH 19/51] GA: fix multiple run steps --- .github/workflows/regression_test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 89f9768f..d2d7a0c3 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -45,13 +45,13 @@ jobs: - name: Add Origen to PATH (Linux) if: matrix.os == 'ubuntu-latest' - run: + run: | echo "${{ github.workspace }}/rust/origen/target/debug" >> $GITHUB_PATH echo "${{ github.workspace }}/rust/origen/target/debug" >> $PATH - name: Add Origen to PATH (Windows) if: matrix.os == 'windows-latest' - run: + run: | echo "${{ github.workspace }}/rust/origen/target/debug" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append echo "${{ github.workspace }}/rust/origen/target/debug" | Out-File -FilePath $env:PATH -Encoding utf8 -Append @@ -175,7 +175,7 @@ jobs: run: mv rust/origen/target/debug/origen.exe python/origen/origen/__bin__/bin - name: Install Origen Packages - run: + run: | pip install python/origen pip install python/origen_metal @@ -190,7 +190,7 @@ jobs: run: pytest test_no_workspace.py::TestNoWorkspaceNoPlugins -vv - name: Install Plugins - run: + run: | pip install test_apps/test_apps_shared_test_helpers pip install test_apps/python_plugin pip install python/origen_metal From 2dcfcdb461b9f796bcf1fef29c178342af2f1990 Mon Sep 17 00:00:00 2001 From: Corey Date: Tue, 4 Jul 2023 08:10:10 -0500 Subject: [PATCH 20/51] GA: More debug --- .github/workflows/regression_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index d2d7a0c3..25328e4d 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -47,13 +47,13 @@ jobs: if: matrix.os == 'ubuntu-latest' run: | echo "${{ github.workspace }}/rust/origen/target/debug" >> $GITHUB_PATH - echo "${{ github.workspace }}/rust/origen/target/debug" >> $PATH + export PATH="${{ github.workspace }}/rust/origen/target/debug:$PATH" - name: Add Origen to PATH (Windows) if: matrix.os == 'windows-latest' run: | echo "${{ github.workspace }}/rust/origen/target/debug" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - echo "${{ github.workspace }}/rust/origen/target/debug" | Out-File -FilePath $env:PATH -Encoding utf8 -Append + $env:Path = "${{ github.workspace }}/rust/origen/target/debug;$env:Path" - name: Show Origen Binary Location (Linux) run: which origen From 8c472547aa8d97afd46defd0f3f56eaee5a738c2 Mon Sep 17 00:00:00 2001 From: Corey Date: Tue, 4 Jul 2023 08:21:45 -0500 Subject: [PATCH 21/51] GA: More debug --- .github/workflows/regression_test.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 25328e4d..50e14394 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -56,8 +56,10 @@ jobs: $env:Path = "${{ github.workspace }}/rust/origen/target/debug;$env:Path" - name: Show Origen Binary Location (Linux) + if: matrix.os == 'ubuntu-latest' run: which origen - name: Show Origen Binary Location (Windows) + if: matrix.os == 'windows-latest' run: where.exe origen - name: Display Python Version @@ -78,8 +80,10 @@ jobs: run: origen -v - name: Show Origen Binary Location (Linux) + if: matrix.os == 'ubuntu-latest' run: which origen - name: Show Origen Binary Location (Windows) + if: matrix.os == 'windows-latest' run: where.exe origen - name: Display Poetry Version @@ -180,8 +184,10 @@ jobs: pip install python/origen_metal - name: Show Origen Binary Location (Linux) + if: matrix.os == 'ubuntu-latest' run: which origen - name: Show Origen Binary Location (Windows) + if: matrix.os == 'windows-latest' run: where.exe origen # Should be no pyprojects in the root so far. Start with no-workspace tests From 013db4fa7faf6c4e4f63623d167379ac7bb648ba Mon Sep 17 00:00:00 2001 From: Corey Date: Tue, 4 Jul 2023 16:57:53 -0500 Subject: [PATCH 22/51] GA: More debug --- .github/workflows/regression_test.yml | 45 ++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 50e14394..5028609b 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -55,13 +55,6 @@ jobs: echo "${{ github.workspace }}/rust/origen/target/debug" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append $env:Path = "${{ github.workspace }}/rust/origen/target/debug;$env:Path" - - name: Show Origen Binary Location (Linux) - if: matrix.os == 'ubuntu-latest' - run: which origen - - name: Show Origen Binary Location (Windows) - if: matrix.os == 'windows-latest' - run: where.exe origen - - name: Display Python Version run: python -c "import sys; print(sys.version)" @@ -89,7 +82,43 @@ jobs: - name: Display Poetry Version working-directory: test_apps/python_app run: poetry --version - + + - name: Show Origen Binary Location (Linux) + if: matrix.os == 'ubuntu-latest' + working-directory: test_apps/python_app + run: | + which origen + poetry run which origen + - name: Show Origen Binary Location (Windows) + if: matrix.os == 'windows-latest' + working-directory: test_apps/python_app + run: | + where.exe origen + poetry run where.exe origen + + # TODO need to see why this is the case and come up with a better solution + - name: Remove Poetry's Origen Wrapper (Linux) + if: matrix.os == 'ubuntu-latest' + working-directory: test_apps/python_app + run: poetry run which origen | rm -f + - name: Remove Poetry's Origen Wrapper (Windows) + if: matrix.os == 'windows-latest' + working-directory: test_apps/python_app + run: poetry run where.exe origen | rm -f + + - name: Show Origen Binary Location (Linux) + if: matrix.os == 'ubuntu-latest' + working-directory: test_apps/python_app + run: | + which origen + poetry run which origen + - name: Show Origen Binary Location (Windows) + if: matrix.os == 'windows-latest' + working-directory: test_apps/python_app + run: | + where.exe origen + poetry run where.exe origen + - name: Run Python-App Unit Tests working-directory: test_apps/python_app run: origen exec pytest -vv From 0f16b7f88d1371fb4a5d624db2aa04d2e767d4d9 Mon Sep 17 00:00:00 2001 From: Corey Date: Tue, 4 Jul 2023 20:00:05 -0500 Subject: [PATCH 23/51] GA: Continued Debug --- .github/workflows/regression_test.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 5028609b..a56e79d7 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -94,17 +94,18 @@ jobs: working-directory: test_apps/python_app run: | where.exe origen + echo "" poetry run where.exe origen # TODO need to see why this is the case and come up with a better solution - name: Remove Poetry's Origen Wrapper (Linux) if: matrix.os == 'ubuntu-latest' working-directory: test_apps/python_app - run: poetry run which origen | rm -f + run: poetry run which origen | xargs rm - name: Remove Poetry's Origen Wrapper (Windows) if: matrix.os == 'windows-latest' working-directory: test_apps/python_app - run: poetry run where.exe origen | rm -f + run: poetry run where.exe origen | select -first 1 | rm - name: Show Origen Binary Location (Linux) if: matrix.os == 'ubuntu-latest' @@ -117,6 +118,7 @@ jobs: working-directory: test_apps/python_app run: | where.exe origen + echo "" poetry run where.exe origen - name: Run Python-App Unit Tests From 22c7f7c69d653d2d4668fe4e0b92dad64c904130 Mon Sep 17 00:00:00 2001 From: Corey Date: Tue, 4 Jul 2023 21:04:42 -0500 Subject: [PATCH 24/51] Update from cli-loc to cli-dir in invocation tests --- test_apps/no_workspace/t_invocation_env.py | 4 ++-- test_apps/no_workspace/test_user_install.py | 2 +- test_apps/python_app/tests/cli_test.py | 2 +- test_apps/python_no_app/tests/test_global_invocation.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test_apps/no_workspace/t_invocation_env.py b/test_apps/no_workspace/t_invocation_env.py index d0d57b81..aea3d7ae 100644 --- a/test_apps/no_workspace/t_invocation_env.py +++ b/test_apps/no_workspace/t_invocation_env.py @@ -17,7 +17,7 @@ lockfile = "poetry.lock" no_workspace_test_dir = pathlib.Path(__file__).parent o2_root = no_workspace_test_dir.parent.parent -debug_cli_loc = o2_root.joinpath(f"rust/origen/target/debug/origen{'.exe' if origen.running_on_windows else ''}") +debug_cli_dir = o2_root.joinpath(f"rust/origen/target/debug") eval_scripts_dir = no_workspace_test_dir.joinpath("eval_scripts") status_eval_script = eval_scripts_dir.joinpath("print_status.py") pl_names_eval_script = eval_scripts_dir.joinpath("print_pl_names.py") @@ -28,7 +28,7 @@ class T_InvocationBaseTests(CLI): templates_dir = no_workspace_test_dir.joinpath("templates") templates_out_dir = templates_dir.joinpath("output") - debug_cli_loc = debug_cli_loc + debug_cli_dir = debug_cli_dir PyProjectSrc = PyProjectSrc @classmethod diff --git a/test_apps/no_workspace/test_user_install.py b/test_apps/no_workspace/test_user_install.py index 01dd7e25..b3f42a31 100644 --- a/test_apps/no_workspace/test_user_install.py +++ b/test_apps/no_workspace/test_user_install.py @@ -29,7 +29,7 @@ def set_params(cls): cls.target_pyproj_dir = cls.user_install_dir cls.move_pyproject = False cls.invocation = PyProjectSrc.UserGlobal - cls.cli_location = cls.debug_cli_loc + cls.cli_dir = cls.debug_cli_dir @classmethod def setup_method(cls): diff --git a/test_apps/python_app/tests/cli_test.py b/test_apps/python_app/tests/cli_test.py index 7f83ba8e..04ea18cc 100644 --- a/test_apps/python_app/tests/cli_test.py +++ b/test_apps/python_app/tests/cli_test.py @@ -75,5 +75,5 @@ class TestAppInvocation(T_InvocationBaseTests): @classmethod def set_params(cls): cls.invocation = cls.PyProjectSrc.App - cls.cli_location = cls.debug_cli_loc + cls.cli_dir = cls.debug_cli_dir cls.target_pyproj_dir = pathlib.Path(__file__).parent.parent diff --git a/test_apps/python_no_app/tests/test_global_invocation.py b/test_apps/python_no_app/tests/test_global_invocation.py index 30201aa7..ec8778d4 100644 --- a/test_apps/python_no_app/tests/test_global_invocation.py +++ b/test_apps/python_no_app/tests/test_global_invocation.py @@ -19,7 +19,7 @@ class TestWorkspaceInvocation(T_InvocationBaseTests): @classmethod def set_params(cls): cls.invocation = cls.PyProjectSrc.Workspace - cls.cli_location = cls.debug_cli_loc + cls.cli_dir = cls.debug_cli_dir cls.target_pyproj_dir = working_dir class TestGlobalFEIntegration: From ba984750693846e45c61e237f799d9f66bd32864 Mon Sep 17 00:00:00 2001 From: Corey Date: Wed, 5 Jul 2023 07:01:32 -0500 Subject: [PATCH 25/51] GA: Continued Debug --- .github/workflows/regression_test.yml | 38 +++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index a56e79d7..b5b3a5e2 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -158,6 +158,44 @@ jobs: working-directory: test_apps/python_no_app run: poetry run origen -vvv + - name: Show Origen Binary Location (Linux) + if: matrix.os == 'ubuntu-latest' + working-directory: test_apps/python_no_app + run: | + which origen + poetry run which origen + - name: Show Origen Binary Location (Windows) + if: matrix.os == 'windows-latest' + working-directory: test_apps/python_no_app + run: | + where.exe origen + echo "" + poetry run where.exe origen + + # TODO need to see why this is the case and come up with a better solution + - name: Remove Poetry's Origen Wrapper (Linux) + if: matrix.os == 'ubuntu-latest' + working-directory: test_apps/python_no_app + run: poetry run which origen | xargs rm + - name: Remove Poetry's Origen Wrapper (Windows) + if: matrix.os == 'windows-latest' + working-directory: test_apps/python_no_app + run: poetry run where.exe origen | select -first 1 | rm + + - name: Show Origen Binary Location (Linux) + if: matrix.os == 'ubuntu-latest' + working-directory: test_apps/python_no_app + run: | + which origen + poetry run which origen + - name: Show Origen Binary Location (Windows) + if: matrix.os == 'windows-latest' + working-directory: test_apps/python_no_app + run: | + where.exe origen + echo "" + poetry run where.exe origen + - name: Run Python-No-App Unit Tests working-directory: test_apps/python_no_app run: poetry run pytest -vv From 2a1f0e100678242e24cb64644d1f42e579e201f4 Mon Sep 17 00:00:00 2001 From: Corey Date: Wed, 5 Jul 2023 10:26:10 -0500 Subject: [PATCH 26/51] GA: Continued Debug --- test_apps/no_workspace/test_user_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_apps/no_workspace/test_user_install.py b/test_apps/no_workspace/test_user_install.py index b3f42a31..0bf33202 100644 --- a/test_apps/no_workspace/test_user_install.py +++ b/test_apps/no_workspace/test_user_install.py @@ -33,7 +33,7 @@ def set_params(cls): @classmethod def setup_method(cls): - super().setup() + super().setup_method() os.environ["ORIGEN_PYPROJECT"] = str(cls.user_install_dir) @classmethod From 10268409a3c4e9cfefd7e43526e767a812fe8089 Mon Sep 17 00:00:00 2001 From: Corey Date: Wed, 5 Jul 2023 13:42:54 -0500 Subject: [PATCH 27/51] GA: Continued Debug --- .github/workflows/regression_test.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index b5b3a5e2..d5b0375b 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -247,6 +247,11 @@ jobs: if: matrix.os == 'windows-latest' run: mv rust/origen/target/debug/origen.exe python/origen/origen/__bin__/bin + # TODO not sure why, but the tmp directory in origen_metal causes some issues + # For now, just removing it. + - name: Remove origen_metal tmp Directory + run: rm python/origen_metal/tmp -r + - name: Install Origen Packages run: | pip install python/origen From be436202402ee6b43cb59958ed30ca736907a3e3 Mon Sep 17 00:00:00 2001 From: Corey Date: Wed, 5 Jul 2023 14:31:48 -0500 Subject: [PATCH 28/51] GA: Continued Debug --- rust/origen/src/core/status.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/origen/src/core/status.rs b/rust/origen/src/core/status.rs index d6beceb4..a821268b 100644 --- a/rust/origen/src/core/status.rs +++ b/rust/origen/src/core/status.rs @@ -99,7 +99,7 @@ where S: AsRef { "Workspace" => gen_case!(Workspace), "UserGlobal" => gen_case!(UserGlobal), "Global" => gen_case!(Global), - "None" => Self::NoneFound, + "NoneFound" => Self::NoneFound, _ => bail!("Cannot convert value '{}' to dependency src type", value.0.as_ref()) }) } From 9c572965065863b0cec92a790894ef2a5804ae81 Mon Sep 17 00:00:00 2001 From: Corey Date: Wed, 5 Jul 2023 16:59:06 -0500 Subject: [PATCH 29/51] GA: Continued Debug --- .github/workflows/regression_test.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index d5b0375b..90fd7282 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -97,7 +97,7 @@ jobs: echo "" poetry run where.exe origen - # TODO need to see why this is the case and come up with a better solution + # TODO GA: Regressions: need to see why this is the case and come up with a better solution - name: Remove Poetry's Origen Wrapper (Linux) if: matrix.os == 'ubuntu-latest' working-directory: test_apps/python_app @@ -172,7 +172,7 @@ jobs: echo "" poetry run where.exe origen - # TODO need to see why this is the case and come up with a better solution + # TODO GA: Regressions: need to see why this is the case and come up with a better solution - name: Remove Poetry's Origen Wrapper (Linux) if: matrix.os == 'ubuntu-latest' working-directory: test_apps/python_no_app @@ -237,7 +237,7 @@ jobs: working-directory: test_apps/no_workspace run: pytest test_user_install.py -vv - # TODO eventually want to move this into a poetry build step + # TODO GA: Regressions: eventually want to move this into a poetry build step # For now, manually move the binary. Also keeps us from having to mess with the path across OSs # 'mv' command should be be fine for both linux & powershell - name: Move Origen executable (Linux) @@ -247,11 +247,18 @@ jobs: if: matrix.os == 'windows-latest' run: mv rust/origen/target/debug/origen.exe python/origen/origen/__bin__/bin - # TODO not sure why, but the tmp directory in origen_metal causes some issues + # TODO GA: Regressions: not sure why, but the tmp directory in origen_metal causes some issues # For now, just removing it. - name: Remove origen_metal tmp Directory run: rm python/origen_metal/tmp -r + # TODO GA: Regressions: Need to better handle this + # Issue being that working on a newer Python version than what's released will not resolve + # Workaround by removing origen_metal package from origen dependencies and installing separately + - name: Hack origen pyproject + working-directory: python/origen + run: poetry remove origen_metal + - name: Install Origen Packages run: | pip install python/origen From d5dcdb3360772fec9248054356362be910d8ed38 Mon Sep 17 00:00:00 2001 From: Corey Date: Thu, 6 Jul 2023 13:17:24 -0500 Subject: [PATCH 30/51] Add global workspace tests --- .github/workflows/regression_test.yml | 13 ++++++++ test_apps/no_workspace/t_invocation_env.py | 10 +++++- .../no_workspace/templates/pyproject.toml | 6 ++-- test_apps/no_workspace/test_global_install.py | 33 +++++++++++++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 test_apps/no_workspace/test_global_install.py diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 90fd7282..b16854e6 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -285,3 +285,16 @@ jobs: - name: Run No-Workspace-With-Plugins Tests working-directory: test_apps/no_workspace run: pytest test_no_workspace.py::TestNoWorkspaceWithPlugins -vv + + # Leave the no-workspace setup. The global setup should override + - name: Run Global No-Plugins One Above Site-Packages Dir + working-directory: test_apps/no_workspace + run: pytest test_global_install.py::TestGlobalInstallNoPlugins -vv + + - name: Run Global With Plugins At Site-Packages Dir + working-directory: test_apps/no_workspace + run: pytest test_global_install.py::TestGlobalInstallWithPlugins -vv + + - name: Run Global No-Plugins At CLI Dir + working-directory: test_apps/no_workspace + run: pytest test_global_install.py::TestGlobalInstallAtCliDir -vv diff --git a/test_apps/no_workspace/t_invocation_env.py b/test_apps/no_workspace/t_invocation_env.py index aea3d7ae..d7c43914 100644 --- a/test_apps/no_workspace/t_invocation_env.py +++ b/test_apps/no_workspace/t_invocation_env.py @@ -24,8 +24,11 @@ # Assume pip is installed in 'site-packages' site_packages_dir = pathlib.Path(pip.__file__).parent.parent +site_cli_dir = site_packages_dir.joinpath("origen/__bin__/bin") class T_InvocationBaseTests(CLI): + site_packages_dir = site_packages_dir + site_cli_dir = site_cli_dir templates_dir = no_workspace_test_dir.joinpath("templates") templates_out_dir = templates_dir.joinpath("output") debug_cli_dir = debug_cli_dir @@ -129,7 +132,12 @@ def gen_pyproj(cls): cls.templates_out_dir.mkdir(exist_ok=True) pyproj = cls.templates_out_dir.joinpath(f"{cls.__name__}.{toml}") with open(pyproj, "w") as f: - f.write(t.render(local_origen=cls.local_origen, name=cls.__name__, o2_root=o2_root)) + f.write(t.render( + local_origen=cls.local_origen, + name=cls.__name__, + o2_root=o2_root, + has_pls=cls.has_pls, + )) return pyproj # TEST_NEEDED invocation origen/metal package locations diff --git a/test_apps/no_workspace/templates/pyproject.toml b/test_apps/no_workspace/templates/pyproject.toml index 7be3df09..d05e79ab 100644 --- a/test_apps/no_workspace/templates/pyproject.toml +++ b/test_apps/no_workspace/templates/pyproject.toml @@ -13,12 +13,12 @@ origen_metal = { path = "{{ o2_root }}/python/origen_metal", develop = true } origen = ">= 0.0.0" origen_metal = ">= 0.0.0" {% endif %} -{% if include_plugins %} +{% if has_pls %} {% if local_origen %} -pl_ext_cmds = { path = "{{ o2_root }}/test_apps/pl_ext_cmds", develop = true } +python_plugin = { path = "{{ o2_root }}/test_apps/python_plugin", develop = true } test_apps_shared_test_helpers = { path = "{{ o2_root }}/test_apps/test_apps_shared_test_helpers", develop = true } {% else %} -pl_ext_cmds = ">= 0.0.0" +python_plugin = ">= 0.0.0" test_apps_shared_test_helpers = ">= 0.0.0" {% endif %} {% endif %} \ No newline at end of file diff --git a/test_apps/no_workspace/test_global_install.py b/test_apps/no_workspace/test_global_install.py new file mode 100644 index 00000000..64a61523 --- /dev/null +++ b/test_apps/no_workspace/test_global_install.py @@ -0,0 +1,33 @@ +from .t_invocation_env import T_InvocationEnv, PyProjectSrc + +class GlobalInstalBase(T_InvocationEnv): + @classmethod + def set_params(cls): + cls.local_origen = True + cls.invocation = PyProjectSrc.Global + cls.cli_dir = cls.site_cli_dir + cls.file_based_evals = True + +# Pyproject closer to root - no plugins +class TestGlobalInstallNoPlugins(GlobalInstalBase): + @classmethod + def set_params(cls): + super().set_params() + cls.target_pyproj_dir = cls.site_packages_dir.parent + cls.has_pls = False + +# Pyproject at site-packages dir - with plugins +class TestGlobalInstallWithPlugins(GlobalInstalBase): + @classmethod + def set_params(cls): + super().set_params() + cls.target_pyproj_dir = cls.site_packages_dir + cls.has_pls = True + +# Pyproject at binary location - no plugins +class TestGlobalInstallAtCliDir(GlobalInstalBase): + @classmethod + def set_params(cls): + super().set_params() + cls.target_pyproj_dir = cls.site_cli_dir + cls.has_pls = False From 716ce8c7e19b5a5a3f8346d1ebe4161249ebd73e Mon Sep 17 00:00:00 2001 From: Corey Date: Thu, 6 Jul 2023 16:42:24 -0500 Subject: [PATCH 31/51] GA: Continued Debug --- test_apps/no_workspace/templates/pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test_apps/no_workspace/templates/pyproject.toml b/test_apps/no_workspace/templates/pyproject.toml index d05e79ab..e36101b3 100644 --- a/test_apps/no_workspace/templates/pyproject.toml +++ b/test_apps/no_workspace/templates/pyproject.toml @@ -7,16 +7,16 @@ authors = ["Origen-SDK"] [tool.poetry.dependencies] python = ">=3.7,<3.11" {% if local_origen %} -origen = { path = "{{ o2_root }}/python/origen", develop = true } -origen_metal = { path = "{{ o2_root }}/python/origen_metal", develop = true } +origen = { path = "{{ o2_root.joinpath("python/origen").as_posix() }}", develop = true } +origen_metal = { path = "{{ o2_root.joinpath("python/origen_metal").as_posix() }}", develop = true } {% else %} origen = ">= 0.0.0" origen_metal = ">= 0.0.0" {% endif %} {% if has_pls %} {% if local_origen %} -python_plugin = { path = "{{ o2_root }}/test_apps/python_plugin", develop = true } -test_apps_shared_test_helpers = { path = "{{ o2_root }}/test_apps/test_apps_shared_test_helpers", develop = true } +python_plugin = { path = "{{ o2_root.joinpath("test_apps/python_plugin").as_posix() }}", develop = true } +test_apps_shared_test_helpers = { path = "{{ o2_root.joinpath("test_apps/test_apps_shared_test_helpers").as_posix() }}", develop = true } {% else %} python_plugin = ">= 0.0.0" test_apps_shared_test_helpers = ">= 0.0.0" From 62b82b7c3f9dd626b224a5d1946b873f1661b8b9 Mon Sep 17 00:00:00 2001 From: Corey Date: Thu, 6 Jul 2023 20:06:08 -0500 Subject: [PATCH 32/51] GA: Continued Debug --- .github/workflows/regression_test.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index b16854e6..128762c1 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -24,7 +24,13 @@ jobs: toolchain: "nightly-2022-05-17" override: true #components: rustfmt, clippy - + + - name: Pre-Python Install Setup (Windows-Only) + if: matrix.os == 'windows-latest' + run: | + $env:RUNNER_TOOL_CACHE = ${{ github.workspace }} | Split-Path | Join-Path -ChildPath o2_GA_tools + mkdir $env:RUNNER_TOOL_CACHE + - name: Setup Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: From 34051fec94fc9339acf45249976cea4fa5194ddd Mon Sep 17 00:00:00 2001 From: Corey Date: Thu, 6 Jul 2023 20:25:50 -0500 Subject: [PATCH 33/51] GA: Continued Debug --- .github/workflows/regression_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 128762c1..4da2136d 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -28,7 +28,7 @@ jobs: - name: Pre-Python Install Setup (Windows-Only) if: matrix.os == 'windows-latest' run: | - $env:RUNNER_TOOL_CACHE = ${{ github.workspace }} | Split-Path | Join-Path -ChildPath o2_GA_tools + $env:RUNNER_TOOL_CACHE = '${{ github.workspace }}' | Split-Path | Join-Path -ChildPath o2_GA_tools mkdir $env:RUNNER_TOOL_CACHE - name: Setup Python ${{ matrix.python-version }} From a4a95a5c4567da9c47ce7616bde5113b405d2318 Mon Sep 17 00:00:00 2001 From: Corey Date: Thu, 6 Jul 2023 21:29:50 -0500 Subject: [PATCH 34/51] GA: Continued Debug --- .github/workflows/regression_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 4da2136d..2bfda709 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -29,6 +29,7 @@ jobs: if: matrix.os == 'windows-latest' run: | $env:RUNNER_TOOL_CACHE = '${{ github.workspace }}' | Split-Path | Join-Path -ChildPath o2_GA_tools + $env:AGENT_TOOLSDIRECTORY = $env:RUNNER_TOOL_CACHE mkdir $env:RUNNER_TOOL_CACHE - name: Setup Python ${{ matrix.python-version }} From 2509ae47d02e8a561a3bfb40d6ccdbcef159b501 Mon Sep 17 00:00:00 2001 From: Corey Date: Fri, 7 Jul 2023 08:22:53 -0500 Subject: [PATCH 35/51] GA: Continued Debug --- .github/workflows/regression_test.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 2bfda709..e7719ac5 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -33,10 +33,18 @@ jobs: mkdir $env:RUNNER_TOOL_CACHE - name: Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + - name: Check Python Install + run: | + echo $AGENT_TOOLSDIRECTORY + echo $RUNNER_TOOL_CACHE + ls $AGENT_TOOLSDIRECTORY + python -c "import os; [print(f'{v}: {k}') for v,k in os.environ.items()];" + python -c "import os, sys; print(os.path.dirname(sys.executable))" + # Needed to compile keyring library # Install taken from keyring library: # https://github.com/hwchen/keyring-rs/blob/v0.10.1/.github/workflows/ci.yaml#L80-L84 From 2685b45cfe4159f6298eee70219a9e4bf3ca71f4 Mon Sep 17 00:00:00 2001 From: Corey Date: Fri, 7 Jul 2023 14:33:12 -0500 Subject: [PATCH 36/51] GA: Continued Debug --- .github/workflows/regression_test.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index e7719ac5..269f74f9 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -31,17 +31,23 @@ jobs: $env:RUNNER_TOOL_CACHE = '${{ github.workspace }}' | Split-Path | Join-Path -ChildPath o2_GA_tools $env:AGENT_TOOLSDIRECTORY = $env:RUNNER_TOOL_CACHE mkdir $env:RUNNER_TOOL_CACHE + echo $env:AGENT_TOOLSDIRECTORY + echo $env:RUNNER_TOOL_CACHE + ls $env:AGENT_TOOLSDIRECTORY + echo "RUNNER_TOOL_CACHE=$env:RUNNER_TOOL_CACHE" >> $GITHUB_ENV + echo "AGENT_TOOLSDIRECTORY=$env:AGENT_TOOLSDIRECTORY" >> $GITHUB_ENV - name: Setup Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - name: Check Python Install + - name: Check Python Install (Windows-Only) + if: matrix.os == 'windows-latest' run: | - echo $AGENT_TOOLSDIRECTORY - echo $RUNNER_TOOL_CACHE - ls $AGENT_TOOLSDIRECTORY + echo $env:AGENT_TOOLSDIRECTORY + echo $env:RUNNER_TOOL_CACHE + ls $env:AGENT_TOOLSDIRECTORY python -c "import os; [print(f'{v}: {k}') for v,k in os.environ.items()];" python -c "import os, sys; print(os.path.dirname(sys.executable))" From 3c6e3855392525de4f7db7dced7e53773529ec65 Mon Sep 17 00:00:00 2001 From: Corey Date: Fri, 7 Jul 2023 17:06:22 -0500 Subject: [PATCH 37/51] GA: Continued Debug --- .github/workflows/regression_test.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 269f74f9..c7d29604 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -34,11 +34,23 @@ jobs: echo $env:AGENT_TOOLSDIRECTORY echo $env:RUNNER_TOOL_CACHE ls $env:AGENT_TOOLSDIRECTORY + echo "RUNNER_TOOL_CACHE=$env:RUNNER_TOOL_CACHE" + echo "AGENT_TOOLSDIRECTORY=$env:AGENT_TOOLSDIRECTORY" echo "RUNNER_TOOL_CACHE=$env:RUNNER_TOOL_CACHE" >> $GITHUB_ENV echo "AGENT_TOOLSDIRECTORY=$env:AGENT_TOOLSDIRECTORY" >> $GITHUB_ENV + - name: Check ENV Variables (Windows-Only) + if: matrix.os == 'windows-latest' + run: | + echo $env:AGENT_TOOLSDIRECTORY + echo $env:RUNNER_TOOL_CACHE + + - name: Setup Python ${{ matrix.python-version }} uses: actions/setup-python@v4 + env: + RUNNER_TOOL_CACHE: D:\a\o2\o2_GA_tools + AGENT_TOOLSDIRECTORY: D:\a\o2\o2_GA_tools with: python-version: ${{ matrix.python-version }} From dd92cf865010a1f809e12ed6044e1760cb34c175 Mon Sep 17 00:00:00 2001 From: Corey Date: Fri, 7 Jul 2023 22:17:00 -0500 Subject: [PATCH 38/51] Continued GA Debug --- .github/workflows/regression_test.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index c7d29604..2237f47e 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -44,19 +44,29 @@ jobs: run: | echo $env:AGENT_TOOLSDIRECTORY echo $env:RUNNER_TOOL_CACHE - + echo ${{ env.RUNNER_TOOL_CACHE }} + echo ${{ env.AGENT_TOOLSDIRECTORY }} - name: Setup Python ${{ matrix.python-version }} + if: matrix.os != 'windows-latest' + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Setup Python ${{ matrix.python-version }} + if: matrix.os == 'windows-latest' uses: actions/setup-python@v4 env: - RUNNER_TOOL_CACHE: D:\a\o2\o2_GA_tools - AGENT_TOOLSDIRECTORY: D:\a\o2\o2_GA_tools + RUNNER_TOOL_CACHE: ${{ env.RUNNER_TOOL_CACHE }} + AGENT_TOOLSDIRECTORY: ${{ env.AGENT_TOOLSDIRECTORY }} with: python-version: ${{ matrix.python-version }} - name: Check Python Install (Windows-Only) if: matrix.os == 'windows-latest' run: | + echo ${{ env.RUNNER_TOOL_CACHE }} + echo ${{ env.AGENT_TOOLSDIRECTORY }} echo $env:AGENT_TOOLSDIRECTORY echo $env:RUNNER_TOOL_CACHE ls $env:AGENT_TOOLSDIRECTORY From 8d885d36f8337f0895c837478354a721fe46ea22 Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 8 Jul 2023 07:40:16 -0500 Subject: [PATCH 39/51] GA: Continued Debug --- .github/workflows/regression_test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 2237f47e..81e239cb 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -44,8 +44,8 @@ jobs: run: | echo $env:AGENT_TOOLSDIRECTORY echo $env:RUNNER_TOOL_CACHE - echo ${{ env.RUNNER_TOOL_CACHE }} - echo ${{ env.AGENT_TOOLSDIRECTORY }} + echo $RUNNER_TOOL_CACHE + echo $AGENT_TOOLSDIRECTORY - name: Setup Python ${{ matrix.python-version }} if: matrix.os != 'windows-latest' @@ -65,8 +65,8 @@ jobs: - name: Check Python Install (Windows-Only) if: matrix.os == 'windows-latest' run: | - echo ${{ env.RUNNER_TOOL_CACHE }} - echo ${{ env.AGENT_TOOLSDIRECTORY }} + echo $RUNNER_TOOL_CACHE + echo $AGENT_TOOLSDIRECTORY echo $env:AGENT_TOOLSDIRECTORY echo $env:RUNNER_TOOL_CACHE ls $env:AGENT_TOOLSDIRECTORY From d1c471d4a016989d19572eeef24729e84f80f143 Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 8 Jul 2023 07:59:01 -0500 Subject: [PATCH 40/51] GA: Continued Debug --- .github/workflows/regression_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 81e239cb..fd61960d 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -57,8 +57,8 @@ jobs: if: matrix.os == 'windows-latest' uses: actions/setup-python@v4 env: - RUNNER_TOOL_CACHE: ${{ env.RUNNER_TOOL_CACHE }} - AGENT_TOOLSDIRECTORY: ${{ env.AGENT_TOOLSDIRECTORY }} + RUNNER_TOOL_CACHE: D:\a\o2\o2_GA_tools + AGENT_TOOLSDIRECTORY: D:\a\o2\o2_GA_tools with: python-version: ${{ matrix.python-version }} From d54344ee4140e00b77ef2a03f22dbb0e8c7f8c94 Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 8 Jul 2023 17:03:23 -0500 Subject: [PATCH 41/51] Some cleanup and add some context for Windows issue in GA --- .github/workflows/regression_test.yml | 5 +++++ test_apps/no_workspace/t_invocation_env.py | 16 ++++------------ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index fd61960d..86005503 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -25,6 +25,11 @@ jobs: override: true #components: rustfmt, clippy + # TODO Invocations: Currently some problem with poetry/pip on Windows where dependencies on drives/mounts separate + # from where the pyproject is located cannot be built. Can workaround this in Windows by updating the + # AGENT_TOOLSDIRECTORY/RUNNER_TOOL_CACHE environment variables, but I'm unable to get these to stick across steps + # in GA. Next few steps are all messiness to debug/work around that. + # Not an issue in Linux, so Windows only will be moved. linux will maintained across different drives. - name: Pre-Python Install Setup (Windows-Only) if: matrix.os == 'windows-latest' run: | diff --git a/test_apps/no_workspace/t_invocation_env.py b/test_apps/no_workspace/t_invocation_env.py index d7c43914..b92b11f0 100644 --- a/test_apps/no_workspace/t_invocation_env.py +++ b/test_apps/no_workspace/t_invocation_env.py @@ -1,5 +1,5 @@ # FOR_PR clean up -# Use the dev version but actual tests should be done through 'eval'. +# Use the local origen/origen_metal - actual tests should be done through 'eval', which will use the installed packages. import sys, pathlib p = pathlib.Path(__file__).parent.parent.parent.joinpath("python/origen") sys.path.append(str(p)) @@ -53,13 +53,9 @@ def header(self): return "--Origen Eval--" def eval_and_parse(self, code): - # out = CLI.global_cmds.eval.run(code, "-vv", run_opts={"return_details": True}) if isinstance(code, str): code = [code] - print(code) - # out = CLI.global_cmds.eval.run(*code, run_opts={"return_details": True, "check": False}) out = CLI.global_cmds.eval.run(*code) - print(out) out = out.split("\n") idx = out.index(self.header) return eval(out[idx+1]) @@ -75,16 +71,12 @@ def test_invocation_from_pytest(self): assert origen.status["invocation"] is None def test_pyproject_and_invocation_set(self): - # code = f"print('{self.header}'); print(origen.status)" - # code = r"print\(\\\"Origen\ Status:\\\"\) print\(origen.status\)" status = self.get_status() print(status) assert status["pyproject"] == self.target_pyproj_toml assert status["invocation"] == self.invocation def test_cli_location(self): - # code = f"print('{self.header}'); print(origen.status)" - # status = self.eval_and_parse(code) status = self.get_status() assert status['cli_location'] == self.cli_location @@ -113,6 +105,7 @@ def setup_method(cls): print(f"Moving pyproject {cls._pyproj_src_file} to {target}") shutil.copy(cls._pyproj_src_file, target) if cls.target_pyproj_dir: + subprocess.run(["pip", "--version"], check=True, cwd=cls.target_pyproj_dir) subprocess.run(["poetry", "--version"], check=True, cwd=cls.target_pyproj_dir) subprocess.run(["poetry", "install"], check=True, cwd=cls.target_pyproj_dir) @@ -140,7 +133,7 @@ def gen_pyproj(cls): )) return pyproj - # TEST_NEEDED invocation origen/metal package locations + # TEST_NEEDED Invocations: origen/metal package locations # class TestBareEnv(CLI): # @pytest.mark.parameterize( # [origen, origen._origen, origen_metal, origen._origen_metal], @@ -161,14 +154,13 @@ def get_plugin_names(self): else: return self.eval_and_parse(f"print('{self.header}'); print(list(origen.plugins.keys()))") + # TEST_NEEDED Invocations: check 'origen -h' in various contexts? @pytest.mark.skip def test_origen_h(self): fail def test_plugins(self): - # code = f"print('{self.header}'); print(list(origen.plugins.keys()))" pls = self.get_plugin_names() - # pls = self.eval_and_parse(code) if self.has_pls: # TODO consistent plugin loading assert set(pls) == {'pl_ext_cmds', 'test_apps_shared_test_helpers', 'python_plugin'} From 989d4e16ad07d11616d5b68e56d662de08a58252 Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 8 Jul 2023 20:04:16 -0500 Subject: [PATCH 42/51] Minor cleanup --- test_apps/no_workspace/t_invocation_env.py | 1 - test_apps/no_workspace/test_user_install.py | 24 +-------------------- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/test_apps/no_workspace/t_invocation_env.py b/test_apps/no_workspace/t_invocation_env.py index b92b11f0..8340d1b4 100644 --- a/test_apps/no_workspace/t_invocation_env.py +++ b/test_apps/no_workspace/t_invocation_env.py @@ -1,4 +1,3 @@ -# FOR_PR clean up # Use the local origen/origen_metal - actual tests should be done through 'eval', which will use the installed packages. import sys, pathlib p = pathlib.Path(__file__).parent.parent.parent.joinpath("python/origen") diff --git a/test_apps/no_workspace/test_user_install.py b/test_apps/no_workspace/test_user_install.py index 0bf33202..c7030f70 100644 --- a/test_apps/no_workspace/test_user_install.py +++ b/test_apps/no_workspace/test_user_install.py @@ -1,24 +1,6 @@ import os from .t_invocation_env import T_InvocationEnv, no_workspace_test_dir, PyProjectSrc -# class TestGlobalNoPlugins(T_InvocationEnv): -# @classmethod -# def set_params(cls): -# cls.local_origen = True -# cls.has_pls = False -# cls.target_pyproj_dir = cls.site_packages_dir -# cls.invocation = PyProjectSrc.Global - -# class TestGlobalWithPluginsHigherLevel(T_InvocationEnv): -# @classmethod -# def set_params(cls): -# cls.local_origen = True -# cls.has_pls = False -# cls.target_pyproj_dir = cls.site_packages_dir.parent - -# class TestGlobalWithPlugins(T_InvocationEnv): -# ... - class TestUserInstall(T_InvocationEnv): user_install_dir = no_workspace_test_dir.joinpath("user_install") @@ -45,12 +27,8 @@ def test_exts_in_user_global_context(self): assert "Hi from python-plugin during 'eval'!" in out assert "Hi again from python-plugin during 'eval'!" in out -# class TestGlobalInstall(T_InvocationEnv): -# ... - -# class TestGlobalInstallWithPlugins(T_InvocationEnv): -# ... +# TEST_NEEDED User Invocations: Error Cases # @pytest.mark.skip # class TestErrorCases(T_InvocationEnv): # def test_origen_pkg_not_installed(self): From 5fd1692566db21ad2499fe124d94f12c63494cd9 Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 10 Jul 2023 20:55:49 -0500 Subject: [PATCH 43/51] Add some error cases that may fall back to a global install --- .github/workflows/regression_test.yml | 5 + test_apps/no_workspace/t_invocation_env.py | 5 +- test_apps/no_workspace/test_user_install.py | 108 ++++++++++++++++++-- 3 files changed, 109 insertions(+), 9 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 86005503..f0aa61b1 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -346,3 +346,8 @@ jobs: - name: Run Global No-Plugins At CLI Dir working-directory: test_apps/no_workspace run: pytest test_global_install.py::TestGlobalInstallAtCliDir -vv + + # With global origen available, test user install errors which fall back to the global install + - name: Run User Install Errors - Falling Back To Global Install + working-directory: test_apps/no_workspace + run: pytest test_user_install.py::TestErrorCasesWithFallback -vv diff --git a/test_apps/no_workspace/t_invocation_env.py b/test_apps/no_workspace/t_invocation_env.py index 8340d1b4..56f9b453 100644 --- a/test_apps/no_workspace/t_invocation_env.py +++ b/test_apps/no_workspace/t_invocation_env.py @@ -45,6 +45,10 @@ def setup(cls): if not hasattr(cls, "file_based_evals"): cls.file_based_evals = False + if not hasattr(cls, "error_case"): + cls.error_case = False + cls.error_case_global_fallback = False + cls.cli_location = cls.cli_dir.joinpath(f"origen{'.exe' if origen.running_on_windows else ''}") @property @@ -71,7 +75,6 @@ def test_invocation_from_pytest(self): def test_pyproject_and_invocation_set(self): status = self.get_status() - print(status) assert status["pyproject"] == self.target_pyproj_toml assert status["invocation"] == self.invocation diff --git a/test_apps/no_workspace/test_user_install.py b/test_apps/no_workspace/test_user_install.py index c7030f70..66db4d06 100644 --- a/test_apps/no_workspace/test_user_install.py +++ b/test_apps/no_workspace/test_user_install.py @@ -1,5 +1,5 @@ import os -from .t_invocation_env import T_InvocationEnv, no_workspace_test_dir, PyProjectSrc +from .t_invocation_env import T_InvocationEnv, T_InvocationBaseTests, no_workspace_test_dir, PyProjectSrc class TestUserInstall(T_InvocationEnv): user_install_dir = no_workspace_test_dir.joinpath("user_install") @@ -12,6 +12,7 @@ def set_params(cls): cls.move_pyproject = False cls.invocation = PyProjectSrc.UserGlobal cls.cli_dir = cls.debug_cli_dir + cls.file_based_evals = True @classmethod def setup_method(cls): @@ -27,12 +28,103 @@ def test_exts_in_user_global_context(self): assert "Hi from python-plugin during 'eval'!" in out assert "Hi again from python-plugin during 'eval'!" in out +class TestErrorCasesWithFallback(): + class TestInvalidPyProjectDir(T_InvocationBaseTests): + invalid_install_dir = no_workspace_test_dir.joinpath("no_dir") -# TEST_NEEDED User Invocations: Error Cases -# @pytest.mark.skip -# class TestErrorCases(T_InvocationEnv): -# def test_origen_pkg_not_installed(self): -# fail + @classmethod + def set_params(cls): + cls.local_origen = True + cls.has_pls = True + cls.move_pyproject = False + cls.file_based_evals = True + cls.error_case = f"Errors encountered resolving pyproject: ORIGEN_PYPROJECT '{cls.invalid_install_dir}' does not exists!" + cls.error_case_global_fallback = True -# def test_missing_pyproject(self): -# fail + cls.invocation = None + cls.cli_dir = cls.site_cli_dir + cls.target_pyproj_dir = None + + + @classmethod + def setup_method(cls): + super().setup() + os.environ["ORIGEN_PYPROJECT"] = str(cls.invalid_install_dir) + + @classmethod + def teardown_method(cls): + del os.environ["ORIGEN_PYPROJECT"] + + def test_error_message(self): + out = self.global_cmds.eval.run("1==1") + errors = self.extract_logged_errors(out) + assert errors[0] == f"Errors encountered resolving pyproject: ORIGEN_PYPROJECT '{self.invalid_install_dir.as_posix()}' does not exists!" + assert errors[1] == "Dependency source has not been set - defaulting to global Python installation" + assert errors[2] == "Dependency source has not been set - defaulting to global Python installation" + assert len(errors) == 3 + + class TestMissingPyProject(T_InvocationBaseTests): + missing_pyproject = no_workspace_test_dir + + @classmethod + def set_params(cls): + cls.local_origen = True + cls.has_pls = True + cls.move_pyproject = False + cls.file_based_evals = True + cls.error_case = f"Errors encountered resolving pyproject: Could not locate pyproject.toml from ORIGEN_PYPROJECT {cls.missing_pyproject.joinpath('pyproject.toml').as_posix()}" + cls.error_case_global_fallback = True + + cls.invocation = None + cls.cli_dir = cls.site_cli_dir + cls.target_pyproj_dir = None + + @classmethod + def setup_method(cls): + super().setup() + os.environ["ORIGEN_PYPROJECT"] = str(cls.missing_pyproject) + + @classmethod + def teardown_method(cls): + del os.environ["ORIGEN_PYPROJECT"] + + def test_error_message(self): + out = self.global_cmds.eval.run("1==1") + errors = self.extract_logged_errors(out) + print(out) + assert errors[0] == f"Errors encountered resolving pyproject: Could not locate pyproject.toml from ORIGEN_PYPROJECT {self.missing_pyproject.joinpath('pyproject.toml').as_posix()}" + assert errors[1] == "Dependency source has not been set - defaulting to global Python installation" + assert errors[2] == "Dependency source has not been set - defaulting to global Python installation" + assert len(errors) == 3 + + class TestMalformedPyProject(): + # Use the template pyproject as an example of a malformed one + malformed_pyproject = no_workspace_test_dir.joinpath("templates") + + @classmethod + def set_params(cls): + cls.local_origen = True + cls.has_pls = True + cls.move_pyproject = False + cls.file_based_evals = True + + cls.invocation = None + cls.cli_dir = cls.site_cli_dir + cls.target_pyproj_dir = None + + @classmethod + def setup_method(cls): + os.environ["ORIGEN_PYPROJECT"] = str(cls.malformed_pyproject) + + @classmethod + def teardown_method(cls): + del os.environ["ORIGEN_PYPROJECT"] + + def test_error_message(self): + # Pyproject found but malformed should print the poetry errors as it tries to run. + # Should not fall back to global install, even if its available. Pyproject should be fixed. + out = T_InvocationBaseTests.global_cmds.eval.run("1==1", run_opts={"return_details": True}) + err = f"Invalid TOML file {self.malformed_pyproject.joinpath('pyproject.toml')}" + assert err in out["stderr"] + errors = T_InvocationBaseTests.extract_logged_errors(out["stdout"]) + assert err in errors[1] From 86644439f4a122e447608672eb5c0b3ec5740598 Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 10 Jul 2023 21:42:33 -0500 Subject: [PATCH 44/51] GA: Debug --- .github/workflows/regression_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index f0aa61b1..c7ff8761 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -283,7 +283,7 @@ jobs: - name: Run User-Global Invocation Tests working-directory: test_apps/no_workspace - run: pytest test_user_install.py -vv + run: pytest test_user_install.py::TestUserInstall -vv # TODO GA: Regressions: eventually want to move this into a poetry build step # For now, manually move the binary. Also keeps us from having to mess with the path across OSs From 97b369c3f5a5170fdfc354e42726fcc61231f5d2 Mon Sep 17 00:00:00 2001 From: Corey Date: Tue, 11 Jul 2023 07:10:14 -0500 Subject: [PATCH 45/51] GA: Debug --- test_apps/no_workspace/test_user_install.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test_apps/no_workspace/test_user_install.py b/test_apps/no_workspace/test_user_install.py index 66db4d06..7bc24ddd 100644 --- a/test_apps/no_workspace/test_user_install.py +++ b/test_apps/no_workspace/test_user_install.py @@ -58,7 +58,7 @@ def teardown_method(cls): def test_error_message(self): out = self.global_cmds.eval.run("1==1") errors = self.extract_logged_errors(out) - assert errors[0] == f"Errors encountered resolving pyproject: ORIGEN_PYPROJECT '{self.invalid_install_dir.as_posix()}' does not exists!" + assert errors[0] == f"Errors encountered resolving pyproject: ORIGEN_PYPROJECT '{self.invalid_install_dir}' does not exists!" assert errors[1] == "Dependency source has not been set - defaulting to global Python installation" assert errors[2] == "Dependency source has not been set - defaulting to global Python installation" assert len(errors) == 3 @@ -72,7 +72,7 @@ def set_params(cls): cls.has_pls = True cls.move_pyproject = False cls.file_based_evals = True - cls.error_case = f"Errors encountered resolving pyproject: Could not locate pyproject.toml from ORIGEN_PYPROJECT {cls.missing_pyproject.joinpath('pyproject.toml').as_posix()}" + cls.error_case = f"Errors encountered resolving pyproject: Could not locate pyproject.toml from ORIGEN_PYPROJECT {cls.missing_pyproject.joinpath('pyproject.toml')}" cls.error_case_global_fallback = True cls.invocation = None @@ -92,7 +92,7 @@ def test_error_message(self): out = self.global_cmds.eval.run("1==1") errors = self.extract_logged_errors(out) print(out) - assert errors[0] == f"Errors encountered resolving pyproject: Could not locate pyproject.toml from ORIGEN_PYPROJECT {self.missing_pyproject.joinpath('pyproject.toml').as_posix()}" + assert errors[0] == f"Errors encountered resolving pyproject: Could not locate pyproject.toml from ORIGEN_PYPROJECT {self.missing_pyproject.joinpath('pyproject.toml')}" assert errors[1] == "Dependency source has not been set - defaulting to global Python installation" assert errors[2] == "Dependency source has not been set - defaulting to global Python installation" assert len(errors) == 3 From 5fec1068094f0db74d5eef2bf47535a2d94ca9b0 Mon Sep 17 00:00:00 2001 From: Corey Date: Tue, 11 Jul 2023 13:25:05 -0500 Subject: [PATCH 46/51] GA: Debug --- test_apps/no_workspace/test_user_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_apps/no_workspace/test_user_install.py b/test_apps/no_workspace/test_user_install.py index 7bc24ddd..a7beea1e 100644 --- a/test_apps/no_workspace/test_user_install.py +++ b/test_apps/no_workspace/test_user_install.py @@ -124,7 +124,7 @@ def test_error_message(self): # Pyproject found but malformed should print the poetry errors as it tries to run. # Should not fall back to global install, even if its available. Pyproject should be fixed. out = T_InvocationBaseTests.global_cmds.eval.run("1==1", run_opts={"return_details": True}) - err = f"Invalid TOML file {self.malformed_pyproject.joinpath('pyproject.toml')}" + err = f"Invalid TOML file {self.malformed_pyproject.joinpath('pyproject.toml').as_posix()}" assert err in out["stderr"] errors = T_InvocationBaseTests.extract_logged_errors(out["stdout"]) assert err in errors[1] From a6fd4b039c86ee079fd50213bdee324ceb9b846c Mon Sep 17 00:00:00 2001 From: Corey Date: Tue, 11 Jul 2023 21:01:45 -0500 Subject: [PATCH 47/51] See about moving Python version to repo variable --- .github/workflows/regression_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index c7ff8761..33fc9fb4 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -6,7 +6,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest] - python-version: [3.7, 3.8, 3.9, 3.10.5] + python-version: ${{ fromJSON(vars.PYTHON_VERSIONS) }} runs-on: ${{ matrix.os }} env: From 1b0bc2dff98406a7d484b6807e2fa070fcffac1b Mon Sep 17 00:00:00 2001 From: Corey Date: Wed, 12 Jul 2023 08:02:41 -0500 Subject: [PATCH 48/51] Move more into repo variables --- .github/workflows/regression_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 33fc9fb4..295ae2f6 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -5,7 +5,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest] + os: ${{ fromJSON(vars.SUPPORTED_OS) }} python-version: ${{ fromJSON(vars.PYTHON_VERSIONS) }} runs-on: ${{ matrix.os }} @@ -21,7 +21,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: "nightly-2022-05-17" + toolchain: ${{ fromJSON(vars.RUST_VERSION) }} override: true #components: rustfmt, clippy From 367ec1a49d6e065493657533e8e450a567c0b52a Mon Sep 17 00:00:00 2001 From: Corey Date: Wed, 12 Jul 2023 17:01:29 -0500 Subject: [PATCH 49/51] Try new rust install as current one causes deprecation warnings and appears unmaintained --- .github/workflows/regression_test.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index 295ae2f6..ad70f539 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -19,11 +19,10 @@ jobs: git --version - name: Install Rust - uses: actions-rs/toolchain@v1 + uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: ${{ fromJSON(vars.RUST_VERSION) }} - override: true - #components: rustfmt, clippy + - run: rustup override set ${{ fromJSON(vars.RUST_VERSION) }} # TODO Invocations: Currently some problem with poetry/pip on Windows where dependencies on drives/mounts separate # from where the pyproject is located cannot be built. Can workaround this in Windows by updating the From 3658eb4c51f2abe84885fbc2190f594a221a3c83 Mon Sep 17 00:00:00 2001 From: Corey Date: Wed, 12 Jul 2023 18:06:45 -0500 Subject: [PATCH 50/51] GA: Debug New Rust Setup --- .github/workflows/regression_test.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index ad70f539..b08af082 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -22,7 +22,14 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: ${{ fromJSON(vars.RUST_VERSION) }} - - run: rustup override set ${{ fromJSON(vars.RUST_VERSION) }} + + - name: Override Project Rust Version + run: rustup override set ${{ fromJSON(vars.RUST_VERSION) }} + + - name: Check Rust Version + run: | + rustc --version + cargo --version # TODO Invocations: Currently some problem with poetry/pip on Windows where dependencies on drives/mounts separate # from where the pyproject is located cannot be built. Can workaround this in Windows by updating the From 70369bd11a700faae9abac85398c7e359731e451 Mon Sep 17 00:00:00 2001 From: Corey Date: Wed, 12 Jul 2023 20:00:53 -0500 Subject: [PATCH 51/51] GA: Debug & Update checkout version --- .github/workflows/regression_test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index b08af082..fc5670a6 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -12,7 +12,7 @@ jobs: env: RUST_BACKTRACE: full steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Show Git Version run : | @@ -22,6 +22,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: ${{ fromJSON(vars.RUST_VERSION) }} + rustflags: - name: Override Project Rust Version run: rustup override set ${{ fromJSON(vars.RUST_VERSION) }}