aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/parso/py2/parso/_compatibility.py
blob: c40a5fe05c53dd29b1843d94e72cdd511de1018c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
""" 
To ensure compatibility from Python ``2.7`` - ``3.3``, a module has been 
created. Clearly there is huge need to use conforming syntax. 
""" 
import os 
import sys 
import platform 
 
# unicode function 
try: 
    unicode = unicode 
except NameError: 
    unicode = str 
 
is_pypy = platform.python_implementation() == 'PyPy' 
 
 
def use_metaclass(meta, *bases): 
    """ Create a class with a metaclass. """ 
    if not bases: 
        bases = (object,) 
    return meta("HackClass", bases, {}) 
 
 
try: 
    encoding = sys.stdout.encoding 
    if encoding is None: 
        encoding = 'utf-8' 
except AttributeError: 
    encoding = 'ascii' 
 
 
def u(string): 
    """Cast to unicode DAMMIT! 
    Written because Python2 repr always implicitly casts to a string, so we 
    have to cast back to a unicode (and we know that we always deal with valid 
    unicode, because we check that in the beginning). 
    """ 
    if sys.version_info.major >= 3: 
        return str(string) 
 
    if not isinstance(string, unicode): 
        return unicode(str(string), 'UTF-8') 
    return string 
 
 
try: 
    # Python 3.3+ 
    FileNotFoundError = FileNotFoundError 
except NameError: 
    # Python 2.7 (both IOError + OSError) 
    FileNotFoundError = EnvironmentError 
try: 
    # Python 3.3+ 
    PermissionError = PermissionError 
except NameError: 
    # Python 2.7 (both IOError + OSError) 
    PermissionError = EnvironmentError 
 
 
def utf8_repr(func): 
    """ 
    ``__repr__`` methods in Python 2 don't allow unicode objects to be 
    returned. Therefore cast them to utf-8 bytes in this decorator. 
    """ 
    def wrapper(self): 
        result = func(self) 
        if isinstance(result, unicode): 
            return result.encode('utf-8') 
        else: 
            return result 
 
    if sys.version_info.major >= 3: 
        return func 
    else: 
        return wrapper 
 
 
if sys.version_info < (3, 5): 
    """ 
    A super-minimal shim around listdir that behave like 
    scandir for the information we need. 
    """ 
    class _DirEntry: 
 
        def __init__(self, name, basepath): 
            self.name = name 
            self.basepath = basepath 
 
        @property 
        def path(self): 
            return os.path.join(self.basepath, self.name) 
 
        def stat(self): 
            # won't follow symlinks 
            return os.lstat(os.path.join(self.basepath, self.name)) 
 
    def scandir(dir): 
        return [_DirEntry(name, dir) for name in os.listdir(dir)] 
else: 
    from os import scandir