Bug 40388

Summary: load_entry_point загружает бинарники из /usr/bin
Product: Sisyphus Reporter: Vitaly Lipatov <lav>
Component: python3-module-pkg_resourcesAssignee: Stanislav Levin <slev>
Status: CLOSED NOTABUG QA Contact: qa-sisyphus
Severity: normal    
Priority: P5 CC: antohami, cas, cow, evg, george, grenka, imz, kotopesutility, lav, nbr, qa_viy, rider, sem, shaba, sin, slev, toni, vitty, viy
Version: unstable   
Hardware: x86_64   
OS: Linux   

Description Vitaly Lipatov 2021-07-07 02:04:36 MSK
Схема с entry_points.txt вызывает проблемы пересечения с *.py файлами из /usr/bin/

Например
$ cat entry_points.txt 
[console_scripts]
html2text = html2text.cli:main
из пакета python3.module-html2text

приводит к попытке загрузить /usr/bin/html2text.py (от python2 модуля), и в итоге провал:

$ python3 
...
>>> from pkg_resources import load_entry_point
>>> load_entry_point('html2text==2020.1.16', 'console_scripts', 'html2text')()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3/site-packages/pkg_resources/__init__.py", line 489, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python3/site-packages/pkg_resources/__init__.py", line 2793, in load_entry_point
    return ep.load()
  File "/usr/lib/python3/site-packages/pkg_resources/__init__.py", line 2411, in load
    return self.resolve()
  File "/usr/lib/python3/site-packages/pkg_resources/__init__.py", line 2417, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
ModuleNotFoundError: No module named 'html2text.cli'; 'html2text' is not a package
>>> 


Начинает с текущего каталога (с каталога, откуда вызван скрипт, то есть /usr/bin/):

stat("/usr/lib/python3/site-packages/html2text-2020.1.16-py3.7.egg-info/entry_points.txt", {st_mode=S_IFREG|0644, st_size=50, ...}) = 0
openat(AT_FDCWD, "/usr/lib/python3/site-packages/html2text-2020.1.16-py3.7.egg-info/entry_points.txt", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=50, ...}) = 0
ioctl(3, TCGETS, 0x7fff5e33dfd0)        = -1 ENOTTY (Неприменимый к данному устройству ioctl)
lseek(3, 0, SEEK_CUR)                   = 0
lseek(3, 0, SEEK_CUR)                   = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=50, ...}) = 0
read(3, "[console_scripts]\nhtml2text = ht"..., 51) = 50
read(3, "", 1)                          = 0
close(3)                                = 0
stat("/usr/bin", {st_mode=S_IFDIR|0755, st_size=147456, ...}) = 0
stat("/usr/bin/html2text/__init__.cpython-37m.so", 0x7fff5e33cfc0) = -1 ENOTDIR (Это не каталог)
stat("/usr/bin/html2text/__init__.cpython-37m-x86_64-linux-gnu.so", 0x7fff5e33cfc0) = -1 ENOTDIR (Это не каталог)
stat("/usr/bin/html2text/__init__.abi3.so", 0x7fff5e33cfc0) = -1 ENOTDIR (Это не каталог)
stat("/usr/bin/html2text/__init__.so", 0x7fff5e33cfc0) = -1 ENOTDIR (Это не каталог)
stat("/usr/bin/html2text/__init__.py", 0x7fff5e33cfc0) = -1 ENOTDIR (Это не каталог)
stat("/usr/bin/html2text/__init__.pyc", 0x7fff5e33cfc0) = -1 ENOTDIR (Это не каталог)
stat("/usr/bin/html2text", {st_mode=S_IFREG|0755, st_size=182312, ...}) = 0
stat("/usr/bin/html2text.py", {st_mode=S_IFREG|0755, st_size=32121, ...}) = 0

Мне кажется, для дистрибутива это вредное свойство — загружать модули из /usr/bin.
Comment 1 Stanislav Levin 2021-07-19 14:43:46 MSK
Механизм entrypoints от setuptools здесь ни при чем.

Это ожидаемое поведение Python:
https://docs.python.org/3/tutorial/modules.html#the-module-search-path

То есть директория, содержащая входящий скрипт, - это '/usr/bin'.
Например,

```console
[root@localhost .in]# cat /usr/bin/some_python_script
#!/usr/bin/python3

import os
import sys


print(os.getcwd())
print(sys.path)
[root@localhost .in]# /usr/bin/some_python_script
/.in
['/usr/bin', '/usr/lib64/python39.zip', '/usr/lib64/python3.9', '/usr/lib64/python3.9/lib-dynload', '/usr/lib64/python3/site-packages', '/usr/lib/python3/site-packages']
```

Существует режим "изоляции":
```
       -I     Run Python in isolated mode. This also implies -E and -s. In isolated
              mode sys.path contains neither the script's directory nor the  user's
              site-packages   directory.  All  PYTHON*  environment  variables  are
              ignored, too.  Further restrictions may be  imposed  to  prevent  the
              user from injecting malicious code.
```

Определение module в Python:
> A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py appended.


На мой взгляд, не стоит помещать модули Python в '/usr/bin' в общем случае.
Comment 2 Vitaly Lipatov 2021-08-31 01:41:29 MSK
(Ответ для Stanislav Levin на комментарий #1)
...
> На мой взгляд, не стоит помещать модули Python в '/usr/bin' в общем случае.
Правильно ли я понимаю, что в нашем случае это означает,
что в /usr/bin не должно быть файлов *.py ?
Comment 3 Stanislav Levin 2021-09-06 11:18:24 MSK
(Ответ для Vitaly Lipatov на комментарий #2)
> (Ответ для Stanislav Levin на комментарий #1)
> ...
> > На мой взгляд, не стоит помещать модули Python в '/usr/bin' в общем случае.
> Правильно ли я понимаю, что в нашем случае это означает,
> что в /usr/bin не должно быть файлов *.py ?

Такого ограничения нет. Чтобы не шарахаться от всех неожиданных импортов, существует режим изоляции.