Python tempfile.TemporaryDirectory contextmanager不使用/tmp文件夹

Python tempfile.TemporaryDirectory contextmanager不使用/tmp文件夹,python,python-3.x,linux,python-3.6,redhat,Python,Python 3.x,Linux,Python 3.6,Redhat,我使用tempfile.TemporaryDirectory类作为contextmanager。默认情况下,它应该使用/tmp文件夹。我尝试使用默认值,也尝试强制使用/tmp文件夹。它创建调用方脚本所在的临时文件夹 设立: 红帽7 Linux Python 3.6.6 这个脚本是从詹金斯那里调用的 代码: 输出: 我的问题是: 有人知道我怎么解决吗 怎么可能呢?我已经检查了TemporaryDirectory类的实现,但是我看不出任何原因。如果有人能解释原因,我会非常高兴 我已经阅读了相关的官方

我使用tempfile.TemporaryDirectory类作为contextmanager。默认情况下,它应该使用/tmp文件夹。我尝试使用默认值,也尝试强制使用/tmp文件夹。它创建调用方脚本所在的临时文件夹

设立:

红帽7 Linux Python 3.6.6 这个脚本是从詹金斯那里调用的 代码:

输出:

我的问题是:

有人知道我怎么解决吗

怎么可能呢?我已经检查了TemporaryDirectory类的实现,但是我看不出任何原因。如果有人能解释原因,我会非常高兴

我已经阅读了相关的官方文档以及tempfile模块的实现,但是我没有找到任何可能导致此类问题的相关代码部分

注意:如果可能的话,我不想继承和更改本模块的许多元素,但我愿意接受这些想法

编辑:

从Jenkins运行的完整回溯:

编辑2:

我无法在本地复制它。这个问题只会经常发生在詹金斯身上

编辑3:

新增行:

logging.info(tempfile._sanitize_params("my_test_", None, None))
詹金斯的产出:

2019-11-08 15:09:26 [Thread-1] [INFO] ('my_test_', '', '/tmp', <class 'str'>)
2019-11-08 15:13:46 [Thread-1] [INFO] ('my_test_', '', '/tmp', <class 'str'>)
在Jenkins中添加:

2019-11-08 15:09:26 [Thread-1] [INFO] ('my_test_', '', '/tmp', <class 'str'>)
2019-11-08 15:13:46 [Thread-1] [INFO] ('my_test_', '', '/tmp', <class 'str'>)
tempfile.TemporaryDirectory对象用于根据传入的参数创建临时目录。如果您不给它一个dir参数,那么它将反过来使用

如果您正在传递一个dir='/tmp',但仍然没有看到在/tmp中创建的目录,那么有两种可能:

前缀值不是您认为的值,而是以/ 系统上的tempfile模块已被更改,不再以与相同的方式运行。这些更改可能是在磁盘上进行的,或者是由其他动态更改行为的Python代码进行的。 mkdtemp函数的正常行为是调用名为的内部函数,如果设置该函数,则返回dir unchanged,否则返回gettempdir的值:

>>> import tempfile
>>> tempfile._sanitize_params('my_test_', None, '/tmp')
('my_test_', '', '/tmp', <class 'str'>)
>>> tempfile._sanitize_params('my_test_', None, None)
('my_test_', '', '/tmp', <class 'str'>)
>>> tempfile.gettempdir()
'/tmp'
要将dir路径与前缀、候选名称随机值和后缀空字符串(在您的案例中)连接起来。但请注意,将丢弃以/斜杠开头的参数之前的所有路径元素:

因此,您看到的行为也可以用前缀以斜杠开头来解释,因此:

TMP_DIR_PREFIX = "/home/my_home/my_test_"
将立即产生相同的结果:

>>> TMP_DIR_PREFIX = "/home/my_home/my_test_"
>>> tempfile.mkdtemp(prefix=TMP_DIR_PREFIX, dir="/tmp")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/.../lib/python3.6/tempfile.py", line 368, in mkdtemp
    _os.mkdir(file, 0o700)
PermissionError: [Errno 13] Permission denied: '/home/my_home/my_test_v4cqpamm'
或者,您可以计算文件的校验和:

import hashlib
with open(tempfile.__file__, 'rb') as file_to_hash:
    tempfile_checksum = hashlib.sha1(file_to_hash.read()).hexdigest()
并将该校验和值与已发布文件的校验和值进行比较:

$ curl -s https://raw.githubusercontent.com/python/cpython/v3.6.0/Lib/tempfile.py | \
> sha1sum
38ad01ccc5972e193e1b96a1de8b7ba1bd8d289d  -

如果没有显示任何结果,您可以使用调试器逐步完成调用,或者查看相关函数的_模块________________________________。例如,如果动态修改了“清理”参数,则会修补tempfile.“清理”参数.“模块”将不会设置为“tempfile”。但是,请注意,回溯已经显示TemporaryDirectory.\uuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,我认为这会有帮助。如果我不提供dir参数,我会得到相同的结果。我不明白,怎么可能…您的回溯没有显示TMP_DIR_前缀设置为什么。如果像这样硬编码,您确定该值,还是该前缀的值已更改?TMP_DIR_前缀是一个常量,不会更改。首先,感谢您的回答,了解该行为对我非常有用。我正在检查_sanitize_params函数的返回值。我需要在Jenkins中测试它,因为正如我在问题编辑2中提到的,这个问题只能在Jenkins中复制。@milanbalazs:是的,我已经看到了,还有更多的问题要问你。@milanbalazs:我已经安排了一点答案,因为我越来越确信这是由于TMP_DIR_前缀值与假设值不同造成的。但是前缀机制工作正常,因为目录名包含提供的前缀。我认为这不是问题所在。不知何故,这条路是不正确的。。。但是这个问题对我来说越来越奇怪了…@milanbalazs:我在回答中展示了如何重现完全相同的问题。TMP_DIR_前缀仅以my_test_结尾,因此是的,最终结果包含my_test_,但导致问题的是TMP_DIR_前缀值的其余部分。
TMP_DIR_PREFIX = "/home/my_home/my_test_"
>>> TMP_DIR_PREFIX = "/home/my_home/my_test_"
>>> tempfile.mkdtemp(prefix=TMP_DIR_PREFIX, dir="/tmp")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/.../lib/python3.6/tempfile.py", line 368, in mkdtemp
    _os.mkdir(file, 0o700)
PermissionError: [Errno 13] Permission denied: '/home/my_home/my_test_v4cqpamm'
import hashlib
with open(tempfile.__file__, 'rb') as file_to_hash:
    tempfile_checksum = hashlib.sha1(file_to_hash.read()).hexdigest()
$ curl -s https://raw.githubusercontent.com/python/cpython/v3.6.0/Lib/tempfile.py | \
> sha1sum
38ad01ccc5972e193e1b96a1de8b7ba1bd8d289d  -