Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

""" support for providing temporary directories to test functions.  """ 

import re 

 

import pytest 

import py 

from _pytest.monkeypatch import monkeypatch 

 

 

class TempdirFactory: 

    """Factory for temporary directories under the common base temp directory. 

 

    The base directory can be configured using the ``--basetemp`` option. 

    """ 

 

    def __init__(self, config): 

        self.config = config 

        self.trace = config.trace.get("tmpdir") 

 

    def ensuretemp(self, string, dir=1): 

        """ (deprecated) return temporary directory path with 

            the given string as the trailing part.  It is usually 

            better to use the 'tmpdir' function argument which 

            provides an empty unique-per-test-invocation directory 

            and is guaranteed to be empty. 

        """ 

        #py.log._apiwarn(">1.1", "use tmpdir function argument") 

        return self.getbasetemp().ensure(string, dir=dir) 

 

    def mktemp(self, basename, numbered=True): 

        """Create a subdirectory of the base temporary directory and return it. 

        If ``numbered``, ensure the directory is unique by adding a number 

        prefix greater than any existing one. 

        """ 

        basetemp = self.getbasetemp() 

        if not numbered: 

            p = basetemp.mkdir(basename) 

        else: 

            p = py.path.local.make_numbered_dir(prefix=basename, 

                keep=0, rootdir=basetemp, lock_timeout=None) 

        self.trace("mktemp", p) 

        return p 

 

    def getbasetemp(self): 

        """ return base temporary directory. """ 

        try: 

            return self._basetemp 

        except AttributeError: 

            basetemp = self.config.option.basetemp 

            if basetemp: 

                basetemp = py.path.local(basetemp) 

                if basetemp.check(): 

                    basetemp.remove() 

                basetemp.mkdir() 

            else: 

                temproot = py.path.local.get_temproot() 

                user = get_user() 

                if user: 

                    # use a sub-directory in the temproot to speed-up 

                    # make_numbered_dir() call 

                    rootdir = temproot.join('pytest-of-%s' % user) 

                else: 

                    rootdir = temproot 

                rootdir.ensure(dir=1) 

                basetemp = py.path.local.make_numbered_dir(prefix='pytest-', 

                                                           rootdir=rootdir) 

            self._basetemp = t = basetemp.realpath() 

            self.trace("new basetemp", t) 

            return t 

 

    def finish(self): 

        self.trace("finish") 

 

 

def get_user(): 

    """Return the current user name, or None if getuser() does not work 

    in the current environment (see #1010). 

    """ 

    import getpass 

    try: 

        return getpass.getuser() 

    except (ImportError, KeyError): 

        return None 

 

# backward compatibility 

TempdirHandler = TempdirFactory 

 

 

def pytest_configure(config): 

    """Create a TempdirFactory and attach it to the config object. 

 

    This is to comply with existing plugins which expect the handler to be 

    available at pytest_configure time, but ideally should be moved entirely 

    to the tmpdir_factory session fixture. 

    """ 

    mp = monkeypatch() 

    t = TempdirFactory(config) 

    config._cleanup.extend([mp.undo, t.finish]) 

    mp.setattr(config, '_tmpdirhandler', t, raising=False) 

    mp.setattr(pytest, 'ensuretemp', t.ensuretemp, raising=False) 

 

 

@pytest.fixture(scope='session') 

def tmpdir_factory(request): 

    """Return a TempdirFactory instance for the test session. 

    """ 

    return request.config._tmpdirhandler 

 

 

@pytest.fixture 

def tmpdir(request, tmpdir_factory): 

    """return a temporary directory path object 

    which is unique to each test function invocation, 

    created as a sub directory of the base temporary 

    directory.  The returned object is a `py.path.local`_ 

    path object. 

    """ 

    name = request.node.name 

    name = re.sub("[\W]", "_", name) 

    MAXVAL = 30 

    if len(name) > MAXVAL: 

        name = name[:MAXVAL] 

    x = tmpdir_factory.mktemp(name, numbered=True) 

    return x