Skip to content

Commit

Permalink
presents initial instructions for importing modules
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielfalcao committed Aug 13, 2023
1 parent 18f3487 commit 3d9ede2
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 20 deletions.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
six==1.16.0
click==8.1.6
5 changes: 2 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ def read_readme():
url="http://github.com/gabrielfalcao/sure",
author="Gabriel Falcao",
author_email="gabriel@nacaolivre.org",
maintainer="Timo Furrer",
maintainer_email="tuxtimo@gmail.com",
maintainer="Gabriel Falcao",
maintainer_email="gabrielteratos@gmail.com",
include_package_data=True,
packages=find_packages(exclude=["*tests*"]),
install_requires=install_requires,
Expand All @@ -114,7 +114,6 @@ def read_readme():
"Operating System :: POSIX :: Linux",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
Expand Down
12 changes: 10 additions & 2 deletions sure/cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import os
from pathlib import Path
import click

from sure.version import version
from sure.runner import Runner
from sure.importer import resolve_path


def entrypoint():
@click.command()
@click.argument("paths", nargs=-1)
@click.option("-r", "--reporter", default="spec")
def entrypoint(paths, reporter):
runner = Runner(resolve_path(os.getcwd()), reporter)
runner.run(paths)
67 changes: 67 additions & 0 deletions sure/importer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import sys
import importlib
import importlib.util
from importlib.machinery import PathFinder
from pathlib import Path


__MODULES__ = {}
__ROOTS__ = {}


def resolve_path(path, relative_to="~") -> Path:
return Path(path).absolute().relative_to(Path(relative_to).expanduser())


def get_root_python_module(path) -> Path:
if not isinstance(path, Path):
path = Path(path)

if not path.is_dir():
path = path.parent

counter = 0
found = None
while not found:
counter += 1
if not path.parent.joinpath('__init__.py').exists():
found = path
path = path.parent

return found


class importer(object):
@classmethod
def load_recursive(cls, path, ignore_errors=True, glob_pattern='*.py'):
base_path = Path(path).expanduser().absolute()
targets = list(base_path.glob(glob_pattern))
for file in targets:
if file.is_dir():
logger.debug(f'ignoring directory {file}')
continue

if file.name.startswith('_') or file.name.endswith('_'):
continue

module, root = cls.dig_to_root(file)
__ROOTS__[str(root)] = root

return list(__MODULES__.values())

@classmethod
def dig_to_root(cls, file):
root = get_root_python_module(file)
module_is_not_artificial = file.name != '__init__.py' and file.parent.joinpath('__init__.py').exists()
if module_is_not_artificial:
module_name = file.parent.name
import ipdb;ipdb.set_trace()
else:
module_name = file.parent.name

spec = importlib.util.spec_from_file_location(module_name, file)
module = importlib.util.module_from_spec(spec)
__MODULES__[module_name] = module
sys.modules[module_name] = module
spec.loader.exec_module(module)
return module, root.absolute()
43 changes: 43 additions & 0 deletions sure/meta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# <sure - utility belt for automated testing in python>
# Copyright (C) <2010-2023> Gabriel Falcão <gabriel@nacaolivre.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals

from pathlib import Path
from sure.importer import importer

__path__ = Path(__file__).parent.absolute()

REPORTERS = {}


def add_reporter(reporter: type) -> type:
REPORTERS[reporter.name] = reporter
return reporter


def get_reporter(name: str) -> type:
return REPORTERS.get(name)


class MetaReporter(type):
def __init__(cls, name, bases, attrs):
if cls.__module__ != __name__:
cls = add_reporter(cls)
attrs['importer'] = cls.importer = importer

super(MetaReporter, cls).__init__(name, bases, attrs)
17 changes: 4 additions & 13 deletions sure/reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
from sure import importer
_registry = {}
from sure.meta import get_reporter, MetaReporter

__path__ = os.path.abspath(os.path.dirname(__file__))


class MetaReporter(type):
def __init__(cls, name, bases, attrs):
if cls.__module__ != __name__:
_registry[cls.name] = cls

super(MetaReporter, cls).__init__(name, bases, attrs)


class Reporter(object):
class Reporter(object, metaclass=MetaReporter):
"""# Base class for implementing reporters.
To create a reporter all you need is to inherit from this class
Expand Down Expand Up @@ -236,7 +227,7 @@ def from_name(cls, name):
```
"""

found = _registry.get(name)
found = get_reporter(name)
if not found:
raise RuntimeError(
'no Reporter found for name {}, options are: {}'.format(
Expand Down Expand Up @@ -267,7 +258,7 @@ def from_name_and_runner(cls, name, runner):
```python
reporter = Reporter.from_name_and_runner('spec', runner)
```"""
importer.load_recursive(
cls.importer.load_recursive(
os.path.join(__path__, 'reporters'),
ignore_errors=False,
)
Expand Down
7 changes: 5 additions & 2 deletions sure/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import inspect
import traceback

from sure import importer
from sure.importer import importer
from sure.reporter import Reporter
from mock import Mock

Expand Down Expand Up @@ -194,7 +194,10 @@ def get_reporter(self, name):
def find_candidates(self, lookup_paths):
candidate_modules = []
for path in map(os.path.abspath, lookup_paths):
candidate_modules.extend(importer.load_recursive(path))
modules = importer.load_recursive(path)
modules = importer.load_recursive(path)
# import ipdb;ipdb.set_trace()
candidate_modules.extend(modules)

return candidate_modules

Expand Down

0 comments on commit 3d9ede2

Please sign in to comment.