Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixing issues #40

Merged
merged 16 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
version: '{build}-{branch}'
build: false

branches:
only:
- master

cache:
- '%LOCALAPPDATA%\pip\Cache'

Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ jobs:
matrix:
name:
- ubuntu-py310-lintcov
- ubuntu-py310-pytest6
- ubuntu-py310-pytest7
- ubuntu-py37
- ubuntu-py38
- ubuntu-py39
Expand All @@ -32,6 +34,12 @@ jobs:
python: "3.10"
tox_env: check,coverage
coverage: true
- name: ubuntu-py310-pytest6
python: "3.10"
tox_env: py310-pytest6
- name: ubuntu-py310-pytest7
python: "3.10"
tox_env: py310-pytest7
- name: ubuntu-py37
python: "3.7"
tox_env: py37
Expand Down
2 changes: 0 additions & 2 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
future==0.18.3
py==1.11.0
pytest==7.4.4
sphinx==7.2.6
sphinx_rtd_theme==2.0.0
71 changes: 37 additions & 34 deletions pytest_logger/plugin.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import os
import sys
import re
import py
import pytest
import logging
import time
import datetime
import argparse
from builtins import object, int
from past.builtins import basestring
import shutil
from pathlib import Path


def pytest_addhooks(pluginmanager):
Expand Down Expand Up @@ -51,15 +50,18 @@ def pytest_configure(config):
config.pluginmanager.register(LoggerPlugin(config, early_logger._logcfg), '_logger')


class EarlyLoggerPlugin(object):
class EarlyLoggerPlugin:
def __init__(self, logcfg):
self._logcfg = logcfg


class LoggerPlugin(object):
class LoggerPlugin:
def __init__(self, config, logcfg):
def prepare_logdirlink(path: Path):
return path if path.is_absolute() else config.rootpath / path

self._config = config
self._logdirlinks = config.hook.pytest_logger_logdirlink(config=config)
self._logdirlinks = [prepare_logdirlink(Path(d)) for d in config.hook.pytest_logger_logdirlink(config=config)]
self._loggers = _loggers_from_logcfg(logcfg, config.getoption('loggers')) if logcfg._enabled else None
self._formatter_class = logcfg._formatter_class or DefaultFormatter
self._logsdir = None
Expand Down Expand Up @@ -101,25 +103,25 @@ def pytest_runtest_teardown(self, item, nextitem):
if logger:
logger.on_teardown()

@pytest.hookimpl(hookwrapper=True)
@pytest.hookimpl(wrapper=True)
def pytest_runtest_makereport(self, item, call):
outcome = yield
tr = outcome.get_result()
report = yield
logger = getattr(item, '_logger', None)
if logger:
if self._logsdir and self._split_by_outcome_subdir and tr.outcome in self._split_by_outcome_outcomes:
split_by_outcome_logdir = self._logsdir.join(self._split_by_outcome_subdir, tr.outcome)
if self._logsdir and self._split_by_outcome_subdir and report.outcome in self._split_by_outcome_outcomes:
split_by_outcome_logdir = self._logsdir / self._split_by_outcome_subdir / report.outcome
nodeid = _sanitize_nodeid(item.nodeid)
nodepath = os.path.dirname(nodeid)
split_by_outcome_logdir.join(nodepath).ensure(dir=1)
destdir_relpath = os.path.relpath(str(self._logsdir.join(nodeid)),
str(split_by_outcome_logdir.join(nodepath)))
_refresh_link(destdir_relpath, str(split_by_outcome_logdir.join(nodeid)))
outcomedir = split_by_outcome_logdir / nodepath
outcomedir.mkdir(parents=True, exist_ok=True)
destdir_relpath = os.path.relpath(self._logsdir / nodeid, outcomedir)
_refresh_link(destdir_relpath, split_by_outcome_logdir / nodeid)
if call.when == 'teardown':
logger.on_makereport()
return report


class LoggerState(object):
class LoggerState:
def __init__(self, item, stdoutloggers, fileloggers, formatter):
self._put_newlines = bool(item.config.option.capture == 'no' and stdoutloggers)
self.handlers = _make_handlers(stdoutloggers, fileloggers, item, formatter)
Expand All @@ -142,7 +144,7 @@ def on_makereport(self):
_disable(self.handlers)


class RootEnabler(object):
class RootEnabler:
def __init__(self, enabled):
self._enabled = enabled
self._root_level = logging.root.level
Expand All @@ -157,7 +159,7 @@ def disable(self):
logging.root.setLevel(self._root_level)


class Loggers(object):
class Loggers:
def __init__(self, stdout, file_):
self.stdout = stdout
self.file = file_
Expand All @@ -166,7 +168,7 @@ def __bool__(self):
return bool(self.stdout) or bool(self.file)


class LoggerConfig(object):
class LoggerConfig:
"""Configuration of logging to stdout and filesystem."""

def __init__(self):
Expand Down Expand Up @@ -230,7 +232,7 @@ def split_by_outcome(self, outcomes=None, subdir='by_outcome'):
self._split_by_outcome_subdir = subdir


class LoggerHookspec(object):
class LoggerHookspec:
def pytest_logger_config(self, logger_config):
""" called before cmdline options parsing. Accepts terse configuration
of both stdout and file logging, adds cmdline options to manipulate
Expand Down Expand Up @@ -268,7 +270,8 @@ def pytest_logger_logdirlink(self, config):

:arg config: pytest config object, holds e.g. options

:return string: Absolute path of requested link to logs directory.
:return string: Path of requested link to logs directory.
When relative, it's relative to pytest session rootdir
"""

@pytest.hookspec(firstresult=True)
Expand Down Expand Up @@ -315,6 +318,7 @@ def format(self, record):

@pytest.fixture
def logdir(request):
""" Return a path to log directory for the test function """
return _make_logdir(request._pyfuncitem)


Expand All @@ -328,7 +332,7 @@ def _sanitize_nodeid(node_id):


def _sanitize_level(level, raises=True):
if isinstance(level, basestring):
if isinstance(level, str):
try:
return int(level)
except ValueError:
Expand Down Expand Up @@ -357,21 +361,20 @@ def _make_logsdir_tmpdir(tmpdirhandler):
if logsdir.basename.startswith('popen-gw'):
logsdir = logsdir.join('..')
logsdir = logsdir.join('logs').ensure(dir=1)
return logsdir
return Path(logsdir)


def _make_logsdir_dir(dstname, cleandir=True):
logsdir = py.path.local(dstname)
if cleandir:
if logsdir.check():
logsdir.remove()
logsdir.mkdir()
return logsdir
def _make_logsdir_dir(dstname):
shutil.rmtree(dstname, ignore_errors=True)
os.mkdir(dstname)
return Path(dstname)


def _make_logdir(item):
plugin = item.config.pluginmanager.getplugin('_logger')
return plugin.logsdir().join(_sanitize_nodeid(item.nodeid)).ensure(dir=1)
logdir = plugin.logsdir() / _sanitize_nodeid(item.nodeid)
logdir.mkdir(parents=True)
return logdir


def _enable(handlers):
Expand Down Expand Up @@ -422,7 +425,7 @@ def bad_level(level):
def _loggers_from_logcfg(logcfg, logopt):
def to_stdout(loggers, opt):
def one(loggers, one):
if isinstance(one, basestring):
if isinstance(one, str):
return one, next(row for row in loggers if one in row[0])[1]
else:
return one
Expand All @@ -440,7 +443,7 @@ def to_file(loggers):
def _loggers_from_hooks(item):
def to_loggers(configs_lists):
def to_logger_and_level(cfg):
if isinstance(cfg, basestring):
if isinstance(cfg, str):
name, level = cfg, logging.NOTSET
else:
name, level = cfg
Expand Down Expand Up @@ -486,7 +489,7 @@ def make_handler(logdir, logger_and_level, fmt):
name, level = logger_and_level
logger = logging.getLogger(name)
name = name or 'logs'
logfile = str(logdir.join(name))
logfile = str(logdir / name)
handler = logging.FileHandler(filename=logfile, mode='w', delay=True)
handler.setFormatter(fmt)
handler.setLevel(level)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def read(fname):
long_description=read('README.rst'),
long_description_content_type='text/x-rst',
packages=['pytest_logger'],
install_requires=['pytest>=3.2', 'future', 'py'],
install_requires=['pytest>=3.2'],
keywords='py.test pytest logging',
classifiers=[
'Development Status :: 5 - Production/Stable',
Expand Down
Loading
Loading