ChangePath   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 14
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 10
c 0
b 0
f 0
wmc 5

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __init__() 0 4 3
A __enter__() 0 4 1
A __exit__() 0 2 1
1
# -*- coding: utf-8 -*-
2
from __future__ import print_function, division, absolute_import
3
from distutils.sysconfig import get_python_lib
4
from logging import getLogger
5
from os import chdir, getcwd
6
from os.path import abspath, dirname, exists, expanduser, expandvars, isdir, isfile, join, sep
7
try:
8
    import pkg_resources
9
except ImportError:
10
    pkg_resources = None
11
import sys
12
13
log = getLogger(__name__)
14
15
16
ROOT_PATH = abspath(sep)
17
18
19
def site_packages_paths():
20
    if hasattr(sys, 'real_prefix'):
21
        # in a virtualenv
22
        log.debug('searching virtualenv')
23
        return tuple(p for p in sys.path if p.endswith('site-packages'))
24
    else:
25
        # not in a virtualenv
26
        log.debug('searching outside virtualenv')  # pragma: no cover
27
        return tuple(get_python_lib(), )  # pragma: no cover
28
29
30
class PackageFile(object):
31
32
    def __init__(self, file_path, package_name):
33
        self.file_path = file_path
34
        self.package_name = package_name
35
36
    def __enter__(self):
37
        self.file_handle = open_package_file(self.file_path, self.package_name)
38
        return self.file_handle
39
40
    def __exit__(self, *args):
41
        self.file_handle.close()
42
43
44
class ChangePath(object):
45
46
    def __init__(self, path):
47
        self.dirpath = dirname(path) if isfile(path) else path
48
        if not isdir(self.dirpath):
49
            raise IOError('File or directory not found: {0}'.format(path))
50
51
    def __enter__(self):
52
        self.cwd = getcwd()
53
        chdir(self.dirpath)
54
        return self
55
56
    def __exit__(self, *args):
57
        chdir(self.cwd)
58
59
60
def open_package_file(file_path, package_name):
61
    file_path = expand(file_path)
62
63
    # look for file at relative path
64
    if exists(file_path):
65
        log.info("found real file {0}".format(file_path))
66
        return open(file_path)
67
68
    # look for file in package resources
69
    if (package_name and pkg_resources is not None and
70
            pkg_resources.resource_exists(package_name, file_path)):
71
        log.info("found package resource file {0} for package {1}".format(file_path, package_name))
72
        return pkg_resources.resource_stream(package_name, file_path)
73
74
    # look for file in site-packages
75
    package_path = find_file_in_site_packages(file_path, package_name)
76
    if package_path:
77
        return open(package_path)  # pragma: no cover
78
79
    msg = "file for module [{0}] cannot be found at path {1}".format(package_name, file_path)
80
    log.error(msg)
81
    raise IOError(msg)
82
83
84
def find_file_in_site_packages(file_path, package_name):
85
    package_path = package_name.replace('.', '/')
86
    for site_packages_path in site_packages_paths():
87
        test_path = join(site_packages_path, package_path, file_path)
88
        if exists(test_path):
89
            log.info("found site-package file {0} for package {1}".format(file_path, package_name))
90
            return test_path
91
        else:
92
            log.error("No file found at {0}.".format(test_path))
93
    return None
94
95
96
def expand(path):
97
    return abspath(expanduser(expandvars(path)))
98
99
100
def absdirname(path):
101
    return abspath(expanduser(dirname(path)))
102