generated from PlexSheep/baserepo
working logger in python with stub
was a mess until it wasnt anymore, yay
This commit is contained in:
parent
7da4e18456
commit
4fc6ac7e0a
|
@ -0,0 +1 @@
|
||||||
|
from ._libpt import *
|
|
@ -0,0 +1,12 @@
|
||||||
|
"""
|
||||||
|
# libpt python bindings
|
||||||
|
|
||||||
|
`libpt` is originally implemented in rust, but offers a python module too.
|
||||||
|
"""
|
||||||
|
from . import logger
|
||||||
|
|
||||||
|
def is_loaded() -> bool:
|
||||||
|
"""
|
||||||
|
returns true if `libpt` has been loaded
|
||||||
|
"""
|
||||||
|
...
|
|
@ -0,0 +1,12 @@
|
||||||
|
"""
|
||||||
|
# libpt python bindings
|
||||||
|
|
||||||
|
`libpt` is originally implemented in rust, but offers a python module too.
|
||||||
|
"""
|
||||||
|
from . import logger
|
||||||
|
|
||||||
|
def is_loaded() -> bool:
|
||||||
|
"""
|
||||||
|
returns true if `libpt` has been loaded
|
||||||
|
"""
|
||||||
|
...
|
|
@ -0,0 +1,65 @@
|
||||||
|
"""
|
||||||
|
# A specialized Logger for `libpt`
|
||||||
|
"""
|
||||||
|
|
||||||
|
""" the default log level """
|
||||||
|
DEFAULT_LOG_LEVEL = "INFO"
|
||||||
|
""" Set the value of this key as envar to set a loglevel """
|
||||||
|
LOGGER_ENV_KEY = "LIBPT_LOGLEVEL"
|
||||||
|
|
||||||
|
class Logger:
|
||||||
|
"""
|
||||||
|
`libpt` logger
|
||||||
|
|
||||||
|
Call `init` once before usage, else all logging attempts will be ignored.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
"""
|
||||||
|
get a new logger
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def init():
|
||||||
|
"""
|
||||||
|
initialize the logger before the first usage
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def init_specialized(color: bool):
|
||||||
|
"""
|
||||||
|
initialize the logger before the first usage, but with the ability to tweak things a bit
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def error(self, printable: str):
|
||||||
|
"""
|
||||||
|
log at level `error`
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def warn(self, printable: str):
|
||||||
|
"""
|
||||||
|
log at level `error`
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def info(self, printable: str):
|
||||||
|
"""
|
||||||
|
log at level `error`
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def debug(self, printable: str):
|
||||||
|
"""
|
||||||
|
log at level `error`
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def trace(self, printable: str):
|
||||||
|
"""
|
||||||
|
log at level `error`
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
python -m unittest discover -fs tests/python
|
|
@ -35,7 +35,7 @@ use pyo3::prelude::*;
|
||||||
///
|
///
|
||||||
/// Always returns `true` if you can execute it.
|
/// Always returns `true` if you can execute it.
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
pub fn libpt_loaded() -> bool {
|
pub fn is_loaded() -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,12 +50,13 @@ fn py_logger(py: Python, m: &PyModule) -> PyResult<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// ## Python module: root
|
/// ## Python module: root
|
||||||
///
|
///
|
||||||
/// This function is the entry point of [`PyO3`](pyo3). This is where the main module is built.
|
/// This function is the entry point of [`PyO3`](pyo3). This is where the main module is built.
|
||||||
#[pymodule]
|
#[pymodule]
|
||||||
fn libpt(py: Python, m: &PyModule) -> PyResult<()> {
|
fn _libpt(py: Python, m: &PyModule) -> PyResult<()> {
|
||||||
m.add_function(wrap_pyfunction!(libpt_loaded, m)?)?;
|
m.add_function(wrap_pyfunction!(is_loaded, m)?)?;
|
||||||
|
|
||||||
// load logger module
|
// load logger module
|
||||||
py_logger(py, m)?;
|
py_logger(py, m)?;
|
||||||
|
|
|
@ -15,12 +15,10 @@
|
||||||
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
|
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
|
||||||
use std::{
|
use std::{
|
||||||
fmt,
|
fmt,
|
||||||
io::Write,
|
|
||||||
sync::atomic::{AtomicBool, Ordering},
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
use env_logger::{
|
use env_logger::{
|
||||||
fmt::{Formatter, Style},
|
|
||||||
Env, Target, WriteStyle,
|
Env, Target, WriteStyle,
|
||||||
};
|
};
|
||||||
use log::{debug, error, info, trace, warn, Level};
|
use log::{debug, error, info, trace, warn, Level};
|
||||||
|
@ -29,7 +27,7 @@ use pyo3::prelude::*;
|
||||||
//// CONSTANTS /////////////////////////////////////////////////////////////////////////////////////
|
//// CONSTANTS /////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// The log level used when none is specified
|
/// The log level used when none is specified
|
||||||
pub const DEFAULT_LOG_LEVEL: Level = Level::Info;
|
pub const DEFAULT_LOG_LEVEL: Level = Level::Info;
|
||||||
/// Register your level to this ENVAR to override the used level
|
/// Register your level to this environment variable to override the used level
|
||||||
pub const LOGGER_ENV_KEY: &'static str = "LIBPT_LOGLEVEL";
|
pub const LOGGER_ENV_KEY: &'static str = "LIBPT_LOGLEVEL";
|
||||||
|
|
||||||
//// STATICS ///////////////////////////////////////////////////////////////////////////////////////
|
//// STATICS ///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -43,7 +41,8 @@ static INITIALIZED: AtomicBool = AtomicBool::new(false);
|
||||||
///
|
///
|
||||||
/// ### Setting a [`Level`](log::Level)
|
/// ### Setting a [`Level`](log::Level)
|
||||||
///
|
///
|
||||||
/// To set a [`Level`](log::Level), you need to set the ENVAR `LIBPT_LOGLEVEL` to either of
|
/// To set a [`Level`](log::Level), you need to set the environment variable `LIBPT_LOGLEVEL`
|
||||||
|
/// to either of:
|
||||||
///
|
///
|
||||||
/// - `Trace`
|
/// - `Trace`
|
||||||
/// - `Debug`
|
/// - `Debug`
|
||||||
|
@ -54,6 +53,7 @@ static INITIALIZED: AtomicBool = AtomicBool::new(false);
|
||||||
pub struct Logger {}
|
pub struct Logger {}
|
||||||
|
|
||||||
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
|
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// ## Main implementation
|
||||||
impl Logger {
|
impl Logger {
|
||||||
/// ## create a `Logger`
|
/// ## create a `Logger`
|
||||||
///
|
///
|
||||||
|
@ -138,6 +138,7 @@ impl Logger {
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// ## Implementation of the python interface
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Logger {
|
impl Logger {
|
||||||
/// ## Python version of [`new()`](Logger::new)
|
/// ## Python version of [`new()`](Logger::new)
|
||||||
|
@ -151,6 +152,12 @@ impl Logger {
|
||||||
pub fn py_init() {
|
pub fn py_init() {
|
||||||
Self::init()
|
Self::init()
|
||||||
}
|
}
|
||||||
|
/// ## Python version of [`init_specialized()`](Logger::init_specialized)
|
||||||
|
#[pyo3(name = "init_specialized")]
|
||||||
|
#[staticmethod]
|
||||||
|
pub fn py_init_specialized(color: bool) {
|
||||||
|
Self::init_specialized(false, color, Target::Stdout)
|
||||||
|
}
|
||||||
/// ## Python version of [`error()`](Logger::error)
|
/// ## Python version of [`error()`](Logger::error)
|
||||||
#[pyo3(name = "error")]
|
#[pyo3(name = "error")]
|
||||||
pub fn py_error(&self, printable: String) {
|
pub fn py_error(&self, printable: String) {
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
// IMPORTS /////////////////////////////////////////////////////////////////////////////////////////
|
// IMPORTS /////////////////////////////////////////////////////////////////////////////////////////
|
||||||
use libpt;
|
use libpt;
|
||||||
|
|
||||||
|
/// ## check if libpt is loaded
|
||||||
#[test]
|
#[test]
|
||||||
fn loaded_libpt() {
|
fn test_libpt_is_loaded() {
|
||||||
assert!(libpt::libpt_loaded())
|
assert!(libpt::is_loaded())
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
"""
|
||||||
|
tests for the general behaviour of the libraries availability
|
||||||
|
"""
|
||||||
|
import unittest
|
||||||
|
import libpt
|
||||||
|
|
||||||
|
class TestLibptGeneral(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_loaded(self):
|
||||||
|
assert libpt.is_loaded()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
"""
|
||||||
|
test the logger
|
||||||
|
"""
|
||||||
|
import unittest
|
||||||
|
from libpt import logger
|
||||||
|
|
||||||
|
class TestLogger(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_basic_logging(self):
|
||||||
|
logger.Logger.init()
|
||||||
|
l = logger.Logger()
|
||||||
|
l.trace("MSG")
|
||||||
|
l.debug("MSG")
|
||||||
|
l.info("MSG")
|
||||||
|
l.warn("MSG")
|
||||||
|
l.error("MSG")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ mod test_logger_struct {
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
|
/// ## setup that's needed before testing the logger struct
|
||||||
fn setup() {
|
fn setup() {
|
||||||
// we don't want to log messages during our tests!
|
// we don't want to log messages during our tests!
|
||||||
Logger::init_specialized(false, false, env_logger::Target::Stdout);
|
Logger::init_specialized(false, false, env_logger::Target::Stdout);
|
||||||
|
@ -45,6 +46,9 @@ mod test_logger_struct {
|
||||||
/// - [`Logger::info`]
|
/// - [`Logger::info`]
|
||||||
/// - [`Logger::warn`]
|
/// - [`Logger::warn`]
|
||||||
/// - [`Logger::error`]
|
/// - [`Logger::error`]
|
||||||
|
///
|
||||||
|
/// After those methods have Successfully been executed, their outputs gets stored in a single
|
||||||
|
/// [`String`] and a [`Regex`] checks if we have five correctly formatted messages.
|
||||||
#[test]
|
#[test]
|
||||||
fn test_log_basic() {
|
fn test_log_basic() {
|
||||||
std::env::set_var(LOGGER_ENV_KEY, "Trace");
|
std::env::set_var(LOGGER_ENV_KEY, "Trace");
|
||||||
|
@ -62,12 +66,15 @@ mod test_logger_struct {
|
||||||
print!("{}", combined);
|
print!("{}", combined);
|
||||||
|
|
||||||
// too long, so i split into two lines.
|
// too long, so i split into two lines.
|
||||||
|
// this matches the format of the env_logger perfectly, but make sure that color is off,
|
||||||
|
// else the ANSI escape sequences break this test
|
||||||
let regex = Regex::new(concat!(
|
let regex = Regex::new(concat!(
|
||||||
r"(?m)\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z ",
|
r"(?m)\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z ",
|
||||||
r"(TRACE|DEBUG|INFO|WARN|ERROR) +libpt::logger\] MSG"
|
r"(TRACE|DEBUG|INFO|WARN|ERROR) +libpt::logger\] MSG"
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// we have 5 log levels, therefore we should have 5 captures
|
||||||
assert_eq!(regex.captures_iter(&combined).count(), 5);
|
assert_eq!(regex.captures_iter(&combined).count(), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue