Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't install Version 1.2.4 - No module named 'public' #241

Closed
manfred-kaiser opened this issue Feb 5, 2021 · 12 comments · Fixed by #242
Closed

Can't install Version 1.2.4 - No module named 'public' #241

manfred-kaiser opened this issue Feb 5, 2021 · 12 comments · Fixed by #242

Comments

@manfred-kaiser
Copy link
Contributor

manfred-kaiser commented Feb 5, 2021

System: CentOS 7
Python Version: 3.6 (from Software Collection)
PIP Version: 21.0.1
Virtualenv: yes

Description:

When I try to install version 1.2.4 from pypi, the install will be discarded and version 1.2.2 is insalled instead.

The reason is, that the module atpuplic is not installed. So the error "ModuleNotFoundError: No module named 'public'" is raised.

Stacktrace:

(testenv) [root@78e76264529c /]# pip install -i https://pypi.org/simple aiosmtpd
Collecting aiosmtpd
  Downloading aiosmtpd-1.2.4.tar.gz (83 kB)
     |################################| 83 kB 340 kB/s 
  Installing build dependencies ... done
  Getting requirements to build wheel ... error
  ERROR: Command errored out with exit status 1:
   command: /testenv/bin/python /testenv/lib64/python3.6/site-packages/pip/_vendor/pep517/_in_process.py get_requires_for_build_wheel /tmp/tmpxbr7mohf
       cwd: /tmp/pip-install-s4res86q/aiosmtpd_1b7979a5651c4ef48a1f5c635ab706a8
  Complete output (55 lines):
  Traceback (most recent call last):
    File "/tmp/pip-build-env-1ki9o5ff/overlay/lib/python3.6/site-packages/setuptools/config.py", line 387, in _parse_attr
      return getattr(StaticModule(module_name), attr_name)
    File "/tmp/pip-build-env-1ki9o5ff/overlay/lib/python3.6/site-packages/setuptools/config.py", line 26, in __init__
      src = strm.read()
    File "/opt/rh/rh-python36/root/usr/lib64/python3.6/encodings/ascii.py", line 26, in decode
      return codecs.ascii_decode(input, self.errors)[0]
  UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 30439: ordinal not in range(128)
  
  During handling of the above exception, another exception occurred:
  
  Traceback (most recent call last):
    File "/testenv/lib64/python3.6/site-packages/pip/_vendor/pep517/_in_process.py", line 280, in <module>
      main()
    File "/testenv/lib64/python3.6/site-packages/pip/_vendor/pep517/_in_process.py", line 263, in main
      json_out['return_val'] = hook(**hook_input['kwargs'])
    File "/testenv/lib64/python3.6/site-packages/pip/_vendor/pep517/_in_process.py", line 114, in get_requires_for_build_wheel
      return hook(config_settings)
    File "/tmp/pip-build-env-1ki9o5ff/overlay/lib/python3.6/site-packages/setuptools/build_meta.py", line 150, in get_requires_for_build_wheel
      config_settings, requirements=['wheel'])
    File "/tmp/pip-build-env-1ki9o5ff/overlay/lib/python3.6/site-packages/setuptools/build_meta.py", line 130, in _get_build_requires
      self.run_setup()
    File "/tmp/pip-build-env-1ki9o5ff/overlay/lib/python3.6/site-packages/setuptools/build_meta.py", line 145, in run_setup
      exec(compile(code, __file__, 'exec'), locals())
    File "setup.py", line 4, in <module>
      setup()
    File "/tmp/pip-build-env-1ki9o5ff/overlay/lib/python3.6/site-packages/setuptools/__init__.py", line 153, in setup
      return distutils.core.setup(**attrs)
    File "/opt/rh/rh-python36/root/usr/lib64/python3.6/distutils/core.py", line 121, in setup
      dist.parse_config_files()
    File "/tmp/pip-build-env-1ki9o5ff/overlay/lib/python3.6/site-packages/setuptools/dist.py", line 681, in parse_config_files
      ignore_option_errors=ignore_option_errors)
    File "/tmp/pip-build-env-1ki9o5ff/overlay/lib/python3.6/site-packages/setuptools/config.py", line 157, in parse_configuration
      meta.parse()
    File "/tmp/pip-build-env-1ki9o5ff/overlay/lib/python3.6/site-packages/setuptools/config.py", line 463, in parse
      section_parser_method(section_options)
    File "/tmp/pip-build-env-1ki9o5ff/overlay/lib/python3.6/site-packages/setuptools/config.py", line 436, in parse_section
      self[name] = value
    File "/tmp/pip-build-env-1ki9o5ff/overlay/lib/python3.6/site-packages/setuptools/config.py", line 220, in __setitem__
      value = parser(value)
    File "/tmp/pip-build-env-1ki9o5ff/overlay/lib/python3.6/site-packages/setuptools/config.py", line 552, in _parse_version
      version = self._parse_attr(value, self.package_dir)
    File "/tmp/pip-build-env-1ki9o5ff/overlay/lib/python3.6/site-packages/setuptools/config.py", line 390, in _parse_attr
      module = importlib.import_module(module_name)
    File "/opt/rh/rh-python36/root/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
      return _bootstrap._gcd_import(name[level:], package, level)
    File "<frozen importlib._bootstrap>", line 994, in _gcd_import
    File "<frozen importlib._bootstrap>", line 971, in _find_and_load
    File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
    File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
    File "<frozen importlib._bootstrap_external>", line 678, in exec_module
    File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
    File "/tmp/pip-install-s4res86q/aiosmtpd_1b7979a5651c4ef48a1f5c635ab706a8/aiosmtpd/smtp.py", line 15, in <module>
      from public import public
  ModuleNotFoundError: No module named 'public'
  ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/68/00/736583da7ce52b0ff3e8ce9045d2c1a183d1877a59a4362be50f49e49b03/aiosmtpd-1.2.4.tar.gz#sha256=34cea0ecd0495f752e1c4bfe5f541676d7aab29674390c007834a63fe7ba0bda (from https://pypi.org/simple/aiosmtpd/) (requires-python:~=3.6). Command errored out with exit status 1: /testenv/bin/python /testenv/lib64/python3.6/site-packages/pip/_vendor/pep517/_in_process.py get_requires_for_build_wheel /tmp/tmpxbr7mohf Check the logs for full command output.
  Downloading aiosmtpd-1.2.2.tar.gz (170 kB)
     |################################| 170 kB 12.4 MB/s 
Collecting atpublic
  Downloading atpublic-2.1.2.tar.gz (16 kB)
Collecting typing_extensions
  Downloading typing_extensions-3.7.4.3-py3-none-any.whl (22 kB)
Using legacy 'setup.py install' for aiosmtpd, since package 'wheel' is not installed.
Using legacy 'setup.py install' for atpublic, since package 'wheel' is not installed.
Installing collected packages: typing-extensions, atpublic, aiosmtpd
    Running setup.py install for atpublic ... done
    Running setup.py install for aiosmtpd ... done
Successfully installed aiosmtpd-1.2.2 atpublic-2.1.2 typing-extensions-3.7.4.3
@manfred-kaiser
Copy link
Contributor Author

I have created a pull request #242 with a fix for this issue.

Adding setup_requires solved the problem, when installing the package.

setup_requires =
    atpublic
    attrs

@pepoluan
Copy link
Collaborator

pepoluan commented Feb 5, 2021

Hmmm... interesting.

The documentation explicitly says that pip needs install_requires. ... but apparently, pip needs setup_requires instead?

@pepoluan
Copy link
Collaborator

pepoluan commented Feb 5, 2021

Just to add, this is what happened when I tried installing on Ubuntu 18.04 in a new virtualenv:

% pip install -U setuptools pkg_resources pip wheel

Requirement already satisfied: setuptools in ./Venvs/test-01/lib/python3.6/site-packages (53.0.0)
Requirement already satisfied: pkg_resources in ./Venvs/test-01/lib/python3.6/site-packages (0.0.0)
Requirement already satisfied: pip in ./Venvs/test-01/lib/python3.6/site-packages (21.0.1)
Requirement already satisfied: wheel in ./Venvs/test-01/lib/python3.6/site-packages (0.36.2)

% pip install aiosmtpd
Collecting aiosmtpd
  Downloading aiosmtpd-1.2.4.tar.gz (83 kB)
     |████████████████████████████████| 83 kB 466 kB/s
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
    Preparing wheel metadata ... done
Collecting atpublic
  Using cached atpublic-2.1.2-py3-none-any.whl
Collecting typing-extensions
  Using cached typing_extensions-3.7.4.3-py3-none-any.whl (22 kB)
Building wheels for collected packages: aiosmtpd
  Building wheel for aiosmtpd (PEP 517) ... done
  Created wheel for aiosmtpd: filename=aiosmtpd-1.2.4-py3-none-any.whl size=83241 sha256=b435cba329a8b793a1d4c9c6dfaf5233db77250a104e6c3ed1eff6035f38318c
  Stored in directory: /home/pepoluan/.cache/pip/wheels/f8/b3/83/1e8522a8cbcd5d9f5e033f212b3eb628ab8a90d3c627b61e1e
Successfully built aiosmtpd
Installing collected packages: typing-extensions, atpublic, aiosmtpd
Successfully installed aiosmtpd-1.2.4 atpublic-2.1.2 typing-extensions-3.7.4.3

%

@pepoluan
Copy link
Collaborator

pepoluan commented Feb 5, 2021

Here's an asciinema recording:

https://asciinema.org/a/B2cQtPJFCuCQ1X43lWNCQPHIc

@manfred-kaiser
Copy link
Contributor Author

The problem is, that you are reading the version with version = attr: aiosmtpd.smtp.__version__

This imports the module aiosmtpd.smtp and this module requires from public import public. But atpublic is not installed at this time.

Using setup_requires fixes this problem,

In the future, it's better to refactor the modules an move __version__ in another module. Some packages use __about__ as module name. But refactoring the modules could break existing applications and should be added to issue #229

Single-sourcing the package version: https://packaging.python.org/guides/single-sourcing-package-version/

@pepoluan
Copy link
Collaborator

pepoluan commented Feb 5, 2021

Why does it work on a clean virtualenv then?

@pepoluan
Copy link
Collaborator

pepoluan commented Feb 5, 2021

Here's another asciinema recording:

https://asciinema.org/a/dxkG88PnxvjVkmC0Htwycql0b

You can see me creating a brand new virtualenv, ensure import public does not work, then outright install aiosmtpd without using pip's cache.

@pepoluan
Copy link
Collaborator

pepoluan commented Feb 5, 2021

I think your setuptools is too old.

This issue seems to have been fixed in setuptools v46.4.0

@manfred-kaiser
Copy link
Contributor Author

v46.4.0
#1753: attr: now extracts variables through rudimentary examination of the AST, thereby supporting modules with third-party imports. If examining the AST fails to find the variable, attr: falls back to the old behavior of importing the module. Works on Python 3 only.

This could be the problem.

I will try it on monday, when I'm back at work.

@manfred-kaiser
Copy link
Contributor Author

Thanks for the help

@pepoluan
Copy link
Collaborator

pepoluan commented Feb 5, 2021

Thanks for the help

No problem! :-)

This issue made me think though ... it seems that moving __version__ to __init__.py seems to be a good idea anyways...

After all, it's a version for all aiosmtpd, not just smtp.py. To maintain backward compat, smtp.py can simply re-import __version__ and put that in __all__.

@waynew
Copy link
Collaborator

waynew commented Feb 5, 2021

Another thing I noticed is that it looks like the root exception was ascii - was your LANG et al not set to utf8?

pepoluan added a commit to pepoluan/aiosmtpd that referenced this issue Feb 5, 2021
This should solve issue aio-libs#241, in which setuptools < 46.4.0 tries to
naively import smtp.py (due to version being specified as "attr:
aiosmtpd.smtp.__version__" and barfs when encountering "from public
import public"

Moving __version__ to __init__.py seems to be the wisest -- and most
semantically accurate -- decision. Not only can setuptools < 46.4.0
simply do a naive import of __init__.py (which contains no deps), but
this signifies the version number applies to the _whole_ aiosmtpd
package instead of just the smtp.py module.

This impacts the following files
* setup.cfg -- scan inside aiosmtpd instead of aiosmtpd.smtp
* smtp.py -- it now needs to import
* conf.py -- no longer scan smtp.py; import from __init__ instead
pepoluan added a commit to pepoluan/aiosmtpd that referenced this issue Feb 6, 2021
To temporarily work around issue aio-libs#241, until a more permanent fix in
v1.3.0

Also moved "License" section to its customary place at the end.
pepoluan pushed a commit that referenced this issue Feb 7, 2021
* Move __version__ to __init__.py

This should solve issue #241, in which setuptools < 46.4.0 tries to
naively import smtp.py (due to version being specified as "attr:
aiosmtpd.smtp.__version__" and barfs when encountering "from public
import public"

Moving __version__ to __init__.py seems to be the wisest -- and most
semantically accurate -- decision. Not only can setuptools < 46.4.0
simply do a naive import of __init__.py (which contains no deps), but
this signifies the version number applies to the _whole_ aiosmtpd
package instead of just the smtp.py module.

This impacts the following files
  * setup.cfg -- scan inside aiosmtpd instead of aiosmtpd.smtp
  * smtp.py -- it now needs to import
  * conf.py -- no longer scan smtp.py; import from __init__ instead

* Add Compatibility Test

In this case, ensure __version__ from __init__.py is exact same object
as __version__ from smtp.py

* Update NEWS.rst
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants