Repository: pandas-dev/pandas

Issue:
With MacOS and PyPy installation fails: AttributeError: 'LooseVersion' object has no attribute 'version'
On MacOS 10.14, PyPy3.6-7.1.1 installation fails:
```
$ pip3 install pandas
Collecting pandas
  Using cached https://files.pythonhosted.org/packages/b2/4c/b6f966ac91c5670ba4ef0b0b5613b5379e3c7abdfad4e7b89a87d73bae13/pandas-0.24.2.tar.gz
    ERROR: Complete output from command python setup.py egg_info:
    ERROR: Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/private/var/folders/50/8j9r2pm93n15lw18936l7zkc0000gn/T/pip-install-96rmqzke/pandas/setup.py", line 438, in <module>
        if python_target < '10.9' and current_system >= '10.9':
      File "/Users/haoyu/.pyenv/versions/pypy3.6-7.1.1/lib-python/3/distutils/version.py", line 52, in __lt__
        c = self._cmp(other)
      File "/Users/haoyu/.pyenv/versions/pypy3.6-7.1.1/lib-python/3/distutils/version.py", line 335, in _cmp
        if self.version == other.version:
    AttributeError: 'LooseVersion' object has no attribute 'version'
```

A workaround is to install with:
`MACOSX_DEPLOYMENT_TARGET=10.14.4 pip3 install pandas`

The cause for this is that in pandas `setup.py`, `get_config_var('MACOSX_DEPLOYMENT_TARGET')` will return `None` on PyPy, while a version number like `10.9` is expected. (See https://github.com/pandas-dev/pandas/blob/master/setup.py#L453).






Discussion:
@bhy Thanks for the report.

PyPy is not included in our CI or distributed binaries for PyPy. (not tested / officially supported).

May be worth raising this on the PyPy issue tracker. Closing this as we don't make any guarantees about PyPy.
@simonjayhawkins we still accept patches for PyPy compatibility. This may be on us, but that's not clear yet.

@bhy is that never defined for pypy? If so, do you know why?

cc @robbuckley just as an FYI.
> This may be on us, but that's not clear yet.

@TomAugspurger : ok. i'll reopen for now.


a quick fix could be to change the indicated line from

```
if is_platform_mac():
    if 'MACOSX_DEPLOYMENT_TARGET' not in os.environ:
        current_system = LooseVersion(platform.mac_ver()[0])
        python_target = LooseVersion(
            get_config_var('MACOSX_DEPLOYMENT_TARGET'))
        if python_target < '10.9' and current_system >= '10.9':
            os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.9'
```
to

```
if is_platform_mac():
    if 'MACOSX_DEPLOYMENT_TARGET' not in os.environ:
        current_system = LooseVersion(platform.mac_ver()[0])
        python_target = LooseVersion(
            get_config_vars().get('MACOSX_DEPLOYMENT_TARGET', current_system))
        if python_target < '10.9' and current_system >= '10.9':
            os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.9'
```

Also changing this line: https://github.com/pandas-dev/pandas/blob/7629a182f34d0374cb329e07076fba16605853ee/setup.py#L14

to:

`from distutils.sysconfig import get_config_vars`

Note the additonal 's'. This shouldnt break CPython (caveat: no tests done yet!). I have no easy way to test this on PyPy, but Im happy to submit  a patch and test on CPython if that helps.
yeah, that seems like an option @robbuckley. But let's wait to hear more from @bhy to better understand what's going wrong with PyPy here before we change anything.
@TomAugspurger I never saw it defined across the versions of PyPy I tried with (6.0 and 7.1). I'm not familiar with PyPy development, but their document mentions (http://doc.pypy.org/en/latest/cpython_differences.html):

> The get_config_vars method of sysconfig and distutils.sysconfig are not complete. On POSIX platforms, CPython fishes configuration variables from the Makefile used to build the interpreter. PyPy should bake the values in during compilation, but does not do that yet.

Thanks. Given that I think that @robbuckley's proposal is reasonable. @bhy can you test it out locally, and perhaps submit a PR?

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,7 @@
 
 import pkg_resources
 import platform
-from distutils.sysconfig import get_config_var
+from distutils.sysconfig import get_config_vars
 import sys
 import shutil
 from distutils.version import LooseVersion
@@ -442,19 +442,19 @@ def run(self):
     if debugging_symbols_requested:
         extra_compile_args.append('-g')
 
-# For mac, ensure extensions are built for macos 10.9 when compiling on a
-# 10.9 system or above, overriding distuitls behaviour which is to target
-# the version that python was built for. This may be overridden by setting
+# Build for at least macOS 10.9 when compiling on a 10.9 system or above,
+# overriding CPython distuitls behaviour which is to target the version that
+# python was built for. This may be overridden by setting
 # MACOSX_DEPLOYMENT_TARGET before calling setup.py
 if is_platform_mac():
     if 'MACOSX_DEPLOYMENT_TARGET' not in os.environ:
-        current_system = LooseVersion(platform.mac_ver()[0])
-        python_target = LooseVersion(
-            get_config_var('MACOSX_DEPLOYMENT_TARGET'))
-        if python_target < '10.9' and current_system >= '10.9':
+        current_system = platform.mac_ver()[0]
+        python_target = get_config_vars().get('MACOSX_DEPLOYMENT_TARGET',
+                                              current_system)
+        if (LooseVersion(python_target) < '10.9' and
+                LooseVersion(current_system) >= '10.9'):
             os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.9'
 
-
 # enable coverage by building cython files by setting the environment variable
 # "PANDAS_CYTHON_COVERAGE" (with a Truthy value) or by running build_ext
 # with `--with-cython-coverage`enabled


Test patch: