Completed
Push — develop ( 3606a5...c5328e )
by Kale
01:06
created

ChangePath.__enter__()   A

Complexity

Conditions 1

Size

Total Lines 4

Duplication

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