Giter VIP home page Giter VIP logo

pyerfa's Introduction

PyERFA

PyPI Status DOI 10.5281/zenodo.3940699 GitHub Actions CI Status Documentation Status

PyERFA is the Python wrapper for the ERFA library (Essential Routines for Fundamental Astronomy), a C library containing key algorithms for astronomy, which is based on the SOFA library published by the International Astronomical Union (IAU). All C routines are wrapped as Numpy universal functions, so that they can be called with scalar or array inputs.

The project is a split of astropy._erfa module, developed in the context of Astropy project, into a standalone package. It contains the ERFA C source code as a git submodule. The wrapping is done with help of the Jinja2 template engine.

If you use this package in your research, please cita it via DOI 10.5281/zenodo.3940699.

Installation instructions

The package can be installed from the package directory using a simple:

$ pip install .

and similarly a wheel can be created with:

$ pip wheel .

Note

If you already have the C library liberfa on your system, you can use that by setting environment variable PYERFA_USE_SYSTEM_LIBERFA=1.

The package can be obtained from PyPI or directly from the git repository:

$ git clone --recursive https://github.com/liberfa/pyerfa/

The package also has nightly wheel that can be obtained as follows:

$ pip install --upgrade --index-url https://pypi.anaconda.org/liberfa/simple pyerfa --pre

Testing

For testing, one can install the packages together with its testing dependencies and then test it with:

$ pip install .[test]
$ pytest

Alternatively, one can use tox, which will set up a separate testing environment for you, with:

$ tox -e test

Usage

The package can be imported as erfa which has all ERFA ufuncs wrapped with python code that tallies errors and warnings. Also exposed are the constants defined by ERFA in erfam.h, as well as numpy.dtype corresponding to structures used by ERFA. Examples:

>>> import erfa
>>> erfa.jd2cal(2460000., [0, 1, 2, 3])
(array([2023, 2023, 2023, 2023], dtype=int32),
 array([2, 2, 2, 2], dtype=int32),
 array([24, 25, 26, 27], dtype=int32),
 array([0.5, 0.5, 0.5, 0.5]))
>>> erfa.plan94(2460000., [0, 1, 2, 3], 1)
array([([ 0.09083713, -0.39041392, -0.21797389], [0.02192341, 0.00705449, 0.00149618]),
       ([ 0.11260694, -0.38275202, -0.21613731], [0.02160375, 0.00826891, 0.00217806]),
       ([ 0.13401992, -0.37387798, -0.21361622], [0.0212094 , 0.00947838, 0.00286503]),
       ([ 0.15500031, -0.36379788, -0.21040601], [0.02073822, 0.01068061, 0.0035561 ])],
      dtype={'names': ['p', 'v'], 'formats': [('<f8', (3,)), ('<f8', (3,))], 'offsets': [0, 24], 'itemsize': 48, 'aligned': True})
>>> erfa.dt_pv
dtype([('p', '<f8', (3,)), ('v', '<f8', (3,))], align=True)
>>> erfa.dt_eraLDBODY
dtype([('bm', '<f8'), ('dl', '<f8'), ('pv', [('p', '<f8', (3,)), ('v', '<f8', (3,))])], align=True)
>>> erfa.DAYSEC
86400.0

It is also possible to use the ufuncs directly, though then one has to deal with the warning and error states explicitly. For instance, compare:

>>> erfa.jd2cal(-600000., [0, 1, 2, 3])
Traceback (most recent call last):
...
ErfaError: ERFA function "jd2cal" yielded 4 of "unacceptable date (Note 1)"
>>> erfa.ufunc.jd2cal(-600000., [0, 1, 2, 3])
(array([-1, -1, -1, -1], dtype=int32),
 ...,
 array([-1, -1, -1, -1], dtype=int32))

License

PyERFA is licensed under a 3-clause BSD style license - see the LICENSE.rst file.

pyerfa's People

Contributors

adrn avatar astrofrog avatar avalentino avatar bsipocz avatar cadair avatar cdeil avatar daria-cara avatar dasdachs avatar dcrichton avatar dependabot[bot] avatar embray avatar eteq avatar hoodmane avatar jiffyclub avatar jwoillez avatar lamby avatar mdboom avatar mhvk avatar migueldvb avatar mseifert04 avatar neutrinoceros avatar pllim avatar saimn avatar sergiopasra avatar smarshy avatar stefan-heimersheim avatar stuartlittlefair avatar taldcroft avatar tbabej avatar vn-ki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyerfa's Issues

Prepare release?

I think we're quite close to releasing... To do

  • Set up authors (#21)
  • Set up version and document it (see #30)
  • Decide whether to use setuptools_scm for version number. see #28. [yes]
  • Expose liberfa version? I.e., port astropy/astropy#9324; see #28 [yes]
  • Document the two C routines that are not part of liberfa - pav2pv and pv2pav (I've tried to get them up to SOFA, and probably should send a reminder). Remove the two extra routines, since we should not add stuff not in SOFA, and SOFA is unlikely to need it (could not find a single place where they would be useful). see #32.
  • Create change-log. See #34
  • Add minimal usage instructions, which make distinction between ufunc and python wrapper. see #33
  • Check with Debian/redhat/conda, that we're making things easy enough (cc @olebole, @sergiopasra)
  • Document how to build with system liberfa library. See #28
  • Set up auto-release pipeline (#8; see #27)

@avalentino, @astrofrog - am I missing anything? If so, just edit this comment and add items.

Add a logo?

I know, this is not the most pressing issue, and it it also more related to ERFA itself: I'd like to have a logo for both, since this makes it easy for me to find ERFA package on longer package lists.

Just if somewone would have a good idea…

Local headers and c sources still needed despite PYERFA_USE_SYSTEM_LIBERFA

erfa_generator.py uses the locally provided headers and c sources despite PYERFA_USE_SYSTEM_LIBERFA is specified. The way it is described, one would expect that only the global headers form the system's erfa-devel, liberfa-dev or whatever it is called in the distribution package would be needed. But erfa_generator.py is called with ERFA_SRC before the check for the library.

pyerfa/setup.py

Lines 29 to 40 in 85a3794

def get_extensions():
cmd = [sys.executable, 'erfa_generator.py', ERFA_SRC, '--quiet']
subprocess.run(cmd, check=True)
sources = [os.path.join('erfa', 'ufunc.c')]
include_dirs = []
libraries = []
if int(os.environ.get('PYERFA_USE_SYSTEM_LIBERFA', 0)):
libraries.append('erfa')

Steps to reproduce:

rm -rf liberfa/
export PYERFA_USE_SYSTEM_LIBERFA=1
pip install .

Output from rpm build:

+ exec rpmbuild -ba --define '_srcdefattr (-,root,root)' --nosignature /home/abuild/rpmbuild/SOURCES/python-pyerfa.spec
[    3s] sh: python2: command not found
[    3s] setting SOURCE_DATE_EPOCH=1593993600
[    3s] Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.ZmaaIS
[    3s] + umask 022
[    3s] + cd /home/abuild/rpmbuild/BUILD
[    3s] + cd /home/abuild/rpmbuild/BUILD
[    3s] + rm -rf pyerfa-1.7.0
[    3s] + /usr/bin/gzip -dc /home/abuild/rpmbuild/SOURCES/pyerfa-1.7.0.tar.gz
[    3s] + /usr/bin/tar -xof -
[    3s] + STATUS=0
[    3s] + '[' 0 -ne 0 ']'
[    3s] + cd pyerfa-1.7.0
[    3s] + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
[    3s] + rm -rf liberfa
[    3s] + RPM_EC=0
[    3s] ++ jobs -p
[    3s] + exit 0
[    3s] Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.ozRTVW
[    3s] + umask 022
[    3s] + cd /home/abuild/rpmbuild/BUILD
[    3s] + /usr/bin/rm -rf /home/abuild/rpmbuild/BUILDROOT/python-pyerfa-1.7.0-0.x86_64
[    3s] ++ dirname /home/abuild/rpmbuild/BUILDROOT/python-pyerfa-1.7.0-0.x86_64
[    3s] + /usr/bin/mkdir -p /home/abuild/rpmbuild/BUILDROOT
[    3s] + /usr/bin/mkdir /home/abuild/rpmbuild/BUILDROOT/python-pyerfa-1.7.0-0.x86_64
[    3s] + cd pyerfa-1.7.0
[    3s] + export PYERFA_USE_SYSTEM_LIBERFA=1
[    3s] + PYERFA_USE_SYSTEM_LIBERFA=1
[    3s] ++ '[' -f _current_flavor ']'
[    3s] ++ true
[    3s] + python_flavor=
[    3s] + '[' -z '' ']'
[    3s] + python_flavor=tmp
[    3s] + '[' tmp '!=' python3 ']'
[    3s] + '[' -d build ']'
[    3s] + '[' -d _build.python3 ']'
[    3s] + echo python3
[    3s] + /usr/bin/python3 setup.py build '--executable=/usr/bin/python3 -s'
[    3s] Traceback (most recent call last):
[    3s]   File "erfa_generator.py", line 682, in <module>
[    3s]     main(args.srcdir, args.output, args.ufunc, args.template_loc, args.verbose)
[    3s]   File "erfa_generator.py", line 575, in main
[    3s]     with open(erfahfn, "r") as f:
[    3s] FileNotFoundError: [Errno 2] No such file or directory: 'liberfa/erfa/erfa.h'
[    3s] Traceback (most recent call last):
[    3s]   File "setup.py", line 123, in <module>
[    3s]     ext_modules=get_extensions())
[    3s]   File "setup.py", line 31, in get_extensions
[    3s]     subprocess.run(cmd, check=True)
[    3s]   File "/usr/lib64/python3.8/subprocess.py", line 512, in run
[    3s]     raise CalledProcessError(retcode, process.args,
[    3s] subprocess.CalledProcessError: Command '['/usr/bin/python3', 'erfa_generator.py', 'liberfa/erfa/src', '--quiet']' returned non-zero exit status 1.
[    3s] error: Bad exit status from /var/tmp/rpm-tmp.ozRTVW (%build)
[    3s] 
[    3s] 
[    3s] RPM build errors:
[    3s]     Bad exit status from /var/tmp/rpm-tmp.ozRTVW (%build)
[    3s] 
[    3s] greinerT450s failed "build python-pyerfa.spec" at Mon Jul  6 09:40:03 UTC 2020.

BUG: rxp does not work correctly if given slice as matrix

As found in astropy/astropy#15503,

import numpy as np
import erfa
matrix = np.array([[1, 0, 0, 5], [0, 1, 0, 6], [0, 0, 1, 7]], dtype='float')[:, :3]
erfa.rxp(matrix, np.array([1., 2., 3.]))
# array([ 1.,  8., 12.])
matrix @ np.array([1., 2., 3.])
# array([1., 2., 3.])

Clearly, rxp internally assumes it is getting a contiguous matrix. Almost certainly not rxp specific, but how (3,3) data are dealt with.

__version__ is broken with 1.7.1

I updated to version 1.7.1 and __version__ reports '0.0.0', which then breaks astropy import because the version requirement is not met. cc @mhvk and @astrofrog @embray for the setuptools-scm knowledge.

In [3]: erfa.__version__
Out[3]: '0.0.0'

Fix up "fork" status if needed

I populated the initial master branch of this repo by pushing from https://github.com/avalentino/pyerfa/tree/pyerfa-standalone . That made sense at the time as a way to keep only the pyerfa part, but as a result neither one appears as a "fork" of the other. Maybe that's fine, but @avalentino, I thought I'd check to see if you care. I think there's a few options:

  1. Start over and have liberfa/pyerfa be a fork of avalentino/pyerfa
  2. Delete avalentino/pyerfa and replace it with a fork
  3. If we switch to erfapy in #1, it's easy enough to have a separate avalentino/erfapy fork
  4. Send a github support request for them to set up the "fork" status (I have a hazy memory that they'll do this if you have a reason).

Any could work, but I think I prefer either 3 or 4, or just leaving things as they stand.

Remove constraint on numpy in pyproject.toml?

In #111, a constraint on numpy was added to pyproject,toml,

"numpy>=1.25,<2"

This has as a consequence that pyerfa cannot be installed from source any more using older/newer numpy, even though the code itself allows this without problem. And that contributed to it no longer being possible to use the latest version of pyerfa with astropy LTS any more (see astropy/astropy#15481 (comment) and following).

I think this is bad and I would like to remove that constraint while still ensuring that for the wheel builds we do, it is enforced, so that those work with old and new numpy. That should not be difficult but raising this issue to ensure I understand any problems before I do so...

cc @liberfa/pyerfa-maintainers, @pllim

New minor release?

Would it be possible to do a new minor release of pyerfa? @Cadair added a set of new wheel architectures in #78 but these will only actually be built when a new release is done, and it would be nice to have this in time for the upcoming 5.0 release of core astropy. Thanks!

Should erfa ufuncs accept correctly structured input independent of field names?

EDIT: note it is not completely obvious what is right, since it may not be so easy to ensure that, e.g., erfa.cpv produces output with the same field names as the input.

Right now, the erfa functions insist on the correct field names:

In [14]: pv1 = np.array([([0.,1.,2.], [3.,4.,5.])], dtype=np.dtype([('p', '3f8'), ('v', '3f8')]))

In [15]: pv2 = np.array(([5.,4.,3.], [2.,1.,0.]), dtype=np.dtype([('pos', '3f8'), ('vel', '3f8')]))

In [16]: erfa.cpv(pv1)
Out[16]: 
array([([0., 1., 2.], [3., 4., 5.])],
      dtype={'names':['p','v'], 'formats':[('<f8', (3,)),('<f8', (3,))], 'offsets':[0,24], 'itemsize':48, 'aligned':True})

In [17]: erfa.cpv(pv2)
TypeError: ufunc 'cpv' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''same_kind''

Yet, numpy works by position and allows e.g. the following:

In [18]: pv1[:] = pv2

In [19]: pv1
Out[19]: 
array([([5., 4., 3.], [2., 1., 0.])],
      dtype=[('p', '<f8', (3,)), ('v', '<f8', (3,))])

liberfa version number test too tight

On Debian, we have pyerfa and erfa in separate packages and update them independently (and by different people). However, there is one test that fails when doing so:

def test_version(self):
assert hasattr(erfa, '__version__')
version = erfa.__version__
assert version is erfa.version.version
# Oops, we had the wrong version for quite a while...
assert (erfa.version.erfa_version == '1.6.0' and version.startswith('1.7.0')
or version.startswith(erfa.version.erfa_version))

Specifically, I now updated erfa to 1.7.1, and pyerfa-1.7.0 fails on this test now. It would IMO be better if the test would just check the backward compatibility, i.e. that pyerfa uses a version that is too old (incompatible) with the current version. But in principle, if all other tests succeed (and have sufficient code coverage) there would be no need to have this test at all?

Having too strong dependencies on the package (even for testing) makes it much harder to maintain them.

Cc: @avalentino as the Debian maintainer of pyerfa

Documentation now less good...

@avalentino, @astrofrog - Oops, I should not just have merged: the documentation is now really not so nice any more, in particular the way the API is listed as an ugly very wide-spaced table and the actual python arguments (see below). Shall I revert?

image

ErfaWarning message has changed

Thanks to 00c3334 the warning message for an ErfaWarning has changed from e.g.

ERFA function "pmsafe" yielded 1 of "distance overridden (Note 6)"

to

ERFA function 'pmsafe' yielded 1 of "distance overridden (Note 6)"

Note the change in quotation around the function name. This change is causing upstream issues in astropy testing - see astropy/astropy#10648 for details

pyerfa install fails with pip 22.2 and python 3.10.5

Hi everyone !

I am building an app that requires pyerfa (via poliastro actually), and it turns out that with python 3.10.5 and pip 22.2, the install with pip fails because of a metadata inconsistency.

Collecting pyerfa
  Downloading pyerfa-2.0.0.1.tar.gz (808 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 808.5/808.5 kB 5.6 MB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Discarding https://files.pythonhosted.org/packages/78/fd/0148f0e54f0c6f48a141409df65d74a5f1dae2e139f23d50a43c58c16098/pyerfa-2.0.0.1.tar.gz (from https://pypi.org/simple/pyerfa/) (requires-python:>=3.7): Requested pyerfa from https://files.pythonhosted.org/packages/78/fd/0148f0e54f0c6f48a141409df65d74a5f1dae2e139f23d50a43c58c16098/pyerfa-2.0.0.1.tar.gz has inconsistent version: filename has '2.0.0.1', but metadata has '0.0.0'
  Downloading pyerfa-2.0.0.tar.gz (808 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 808.3/808.3 kB 12.0 MB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Discarding https://files.pythonhosted.org/packages/03/71/47b58cbbf8350209f0be27177d9ecc15df8956bbf00af74cb9cd2abc5df1/pyerfa-2.0.0.tar.gz (from https://pypi.org/simple/pyerfa/) (requires-python:>=3.7): Requested pyerfa from https://files.pythonhosted.org/packages/03/71/47b58cbbf8350209f0be27177d9ecc15df8956bbf00af74cb9cd2abc5df1/pyerfa-2.0.0.tar.gz has inconsistent version: filename has '2.0.0', but metadata has '0.0.0'
  Downloading pyerfa-1.7.3.tar.gz (768 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 768.3/768.3 kB 9.7 MB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Discarding https://files.pythonhosted.org/packages/2f/87/a3a31eddf7952c2741e2871aed365aca21423b546a51fd0375306f66e460/pyerfa-1.7.3.tar.gz (from https://pypi.org/simple/pyerfa/) (requires-python:>=3.6): Requested pyerfa from https://files.pythonhosted.org/packages/2f/87/a3a31eddf7952c2741e2871aed365aca21423b546a51fd0375306f66e460/pyerfa-1.7.3.tar.gz has inconsistent version: filename has '1.7.3', but metadata has '0.0.0'
  Downloading pyerfa-1.7.2.tar.gz (1.3 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.3/1.3 MB 8.6 MB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Discarding https://files.pythonhosted.org/packages/e3/af/ae39c2b1f652895238888f186579b7eedb9f55fdbde78ad75f34597059bc/pyerfa-1.7.2.tar.gz (from https://pypi.org/simple/pyerfa/) (requires-python:>=3.6): Requested pyerfa from https://files.pythonhosted.org/packages/e3/af/ae39c2b1f652895238888f186579b7eedb9f55fdbde78ad75f34597059bc/pyerfa-1.7.2.tar.gz has inconsistent version: filename has '1.7.2', but metadata has '0.0.0'
  Downloading pyerfa-1.7.1.1.tar.gz (1.3 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.3/1.3 MB 13.0 MB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Discarding https://files.pythonhosted.org/packages/3b/37/0ff81021f6405e4f6f627bb4aed32d22569fe016376dccee14e5eca947d1/pyerfa-1.7.1.1.tar.gz (from https://pypi.org/simple/pyerfa/) (requires-python:>=3.6): Requested pyerfa from https://files.pythonhosted.org/packages/3b/37/0ff81021f6405e4f6f627bb4aed32d22569fe016376dccee14e5eca947d1/pyerfa-1.7.1.1.tar.gz has inconsistent version: filename has '1.7.1.1', but metadata has '0.0.0'
  Downloading pyerfa-1.7.1.tar.gz (1.3 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.3/1.3 MB 15.6 MB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Discarding https://files.pythonhosted.org/packages/d6/58/f18be3ace5066283f8e8cb7385301aebb0adacda70a09235c4f5675bd673/pyerfa-1.7.1.tar.gz (from https://pypi.org/simple/pyerfa/) (requires-python:>=3.6): Requested pyerfa from https://files.pythonhosted.org/packages/d6/58/f18be3ace5066283f8e8cb7385301aebb0adacda70a09235c4f5675bd673/pyerfa-1.7.1.tar.gz has inconsistent version: filename has '1.7.1', but metadata has '0.0.0'
  Downloading pyerfa-1.7.0.tar.gz (490 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 490.7/490.7 kB 4.2 MB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Discarding https://files.pythonhosted.org/packages/86/5d/f4cc5804744f7ab14b54059ebd44969e4f6af9eb6909f56d112bf9f0730b/pyerfa-1.7.0.tar.gz (from https://pypi.org/simple/pyerfa/) (requires-python:>=3.6): Requested pyerfa from https://files.pythonhosted.org/packages/86/5d/f4cc5804744f7ab14b54059ebd44969e4f6af9eb6909f56d112bf9f0730b/pyerfa-1.7.0.tar.gz has inconsistent version: filename has '1.7.0', but metadata has '0.0.0'
ERROR: Could not find a version that satisfies the requirement pyerfa (from versions: 1.7.0, 1.7.1, 1.7.1.1, 1.7.2, 1.7.3, 2.0.0, 2.0.0.1)
ERROR: No matching distribution found for pyerfa

I have tried downgrading pip but to no avail.
Anyone knows what is happening ?

Thank you so much for pyerfa and your support !!

Consider using Azure pipelines template for auto-releasing package

@Cadair and I have created an Azure pipelines template for auto-releasing Python packages, including wheels for all the different platforms:

https://openastronomy-azure-pipelines.readthedocs.io/en/latest/

With this, pushing a tag to GitHub results in the release happening automatically. Since this is a new project, it might be worth setting this up here. An alternative would be to figure out how to do this as a GitHub action, but that would require more work for now. I do want to try and do this at some point, but if we wanted something soon we could start with the Azure pipelines version.

I'd be happy to set this up if others are interested. I use this for reproject and sunpy use it for the main sunpy package, and it works great. I also want us to use something like this for the core package in the long term.

Need to set up version

Likely not the only thing, but needs a bit of thought on numbering: we could simply stick to the erfa version, but that means that if there is a bug in the python wrapper, we would need to deviate.

@avalentino, @astrofrog, @eteq - any suggestions? I guess we could let the bug-fix part deviate from erfa itself.

EDIT: for the post-fix, we can use the version-getting function from #28 (comment)

Try to switch to a non-distutils/setuptools extension build system

Distutils is going away (https://peps.python.org/pep-0632/ ), setuptools has a questionable future without distutils in the stdlib, and perhaps most relevantly, as a result it seems a lot of the scientific python ecosystem (e.g. scipy and numpy) are moving to other build systems for c extensions. So I think we need to consider whether we should/will need to switch to one of the build systems those packages are using.

I think the main options are meson, scikit-build (which is build on cmake) or CMake directly. Based purely on trying to not fracture the ecosystem, I'm inclined to look into meson, since that's the way scipy has gone, and the rumor at least I hear is that numpy is thinking that way too (@rgommers might have some insight or thoughts to add on that).

Problem with importing erfa and astropy or photutils in iPython/Spyder

Hi,
I'm a newbie - sorry for my inexperience. I'm running iPython inside Spyder and trying to use astropy and photutils. I installed pyerfa, astropy, and photutils inside iPython using '!pip install pyerfa' but I get the following error when I try to import erfa.

import erfa
[autoreload of erfa.version failed: Traceback (most recent call last):
File "C:\Users\kbagnall\AppData\Local\Programs\Spyder\pkgs\IPython\extensions\autoreload.py", line 245, in check
superreload(m, reload, self.old_objects)
File "C:\Users\kbagnall\AppData\Local\Programs\Spyder\pkgs\IPython\extensions\autoreload.py", line 394, in superreload
module = reload(module)
File "imp.py", line 314, in reload
File "importlib_init
.py", line 159, in reload
ImportError: parent 'erfa' not in sys.modules
]
Traceback (most recent call last):

File "C:\Users\kbagnall\AppData\Local\Temp\ipykernel_14788\3657507462.py", line 1, in <cell line: 1>
import erfa

File "C:\Users\kbagnall\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\erfa_init_.py", line 5, in
from .version import version as version # noqa

File "C:\Users\kbagnall\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\erfa\version.py", line 25, in
from . import ufunc

ImportError: cannot import name 'ufunc' from partially initialized module 'erfa' (most likely due to a circular import) (C:\Users\kbagnall\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\erfa_init_.py)

Some overrides do not quite work right if output is given

Probably mostly because they are not used in astropy, but would be good to fix:

import numpy as np
from erfa import ufunc as erfa_ufunc

p = np.array([[1., 2., 3.], [4., 5., 6.]])
pv = erfa_ufunc.p2pv(p)
pv  # this is OK
# array([([1., 2., 3.], [0., 0., 0.]), ([4., 5., 6.], [0., 0., 0.])],
#       dtype={'names':['p','v'], 'formats':[('<f8', (3,)),('<f8', (3,))], 'offsets':[0,24], 'itemsize':48, 'aligned':True})
erfa_ufunc.p2pv(p, out=pv)  # Oops
# TypeError: ufunc 'p2pv' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''same_kind''

Similarly,

erfa_ufunc.zpv(out=pv)
# TypeError: ufunc 'zpv' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''same_kind''

Test failed: erfa/tests/helper.py:36: AttributeError

Hi!

During preparation the project for the Guix downstream I've faced with one failing test:

  • version :: 2.0.1.1

Inputs

=================================== FAILURES ===================================
____________________________ test_errwarn_reporting ____________________________

    def test_errwarn_reporting():
        """
        Test that the ERFA error reporting mechanism works as it should
        """

        # no warning
        erfa.dat(1990, 1, 1, 0.5)

        # check warning is raised for a scalar
>       with catch_warnings() as w:

erfa/tests/test_erfa.py:175:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
erfa/tests/helper.py:112: in __enter__
    treat_deprecations_as_exceptions()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

    def treat_deprecations_as_exceptions():
        """
        Turn all DeprecationWarnings (which indicate deprecated uses of
        Python itself or Numpy) into exceptions so that we find
        out about them early.

        This completely resets the warning filters and any "already seen"
        warning state.
        """
        # First, totally reset the warning state. The modules may change during
        # this iteration thus we copy the original state to a list to iterate
        # on. See https://github.com/astropy/astropy/pull/5513.
        for module in list(sys.modules.values()):
            # We don't want to deal with six.MovedModules, only "real"
            # modules. FIXME: we no more use six, this should be useless ?
            if (isinstance(module, types.ModuleType) and
                    hasattr(module, '__warningregistry__')):
>               del module.__warningregistry__
E               AttributeError: __warningregistry__

erfa/tests/helper.py:36: AttributeError
=========================== short test summary info ============================
FAILED erfa/tests/test_erfa.py::test_errwarn_reporting - AttributeError: __wa...
============= 1 failed, 273 passed, 2 skipped, 5 xfailed in 1.47s ==============

Add support for Python 3.12

In my work in #107 , I saw failures with py312 in the wheels, so I had to exclude it. You should:

  1. Add a CI job testing for Python 3.12.
  2. Add py312 to your wheels job.

Building wheel fails on MacOS: ModuleNotFoundError: No module named 'packaging'

Running on an M1 Macbook Air. The packaging module is installed, but installing pyerfa fails complaining about it:
#pip3 --version
pip 22.2.2 from /opt/homebrew/lib/python3.10/site-packages/pip (python 3.10)
#python3
Python 3.10.6 (main, Aug 11 2022, 13:36:31) [Clang 13.1.6 (clang-1316.0.21.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

import packaging

#python3 -m pip install --user pyerfa
Collecting pyerfa
Using cached pyerfa-2.0.0.1.tar.gz (808 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... error
error: subprocess-exited-with-error

× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> [17 lines of output]
Error in sitecustomize; set PYTHONVERBOSE for traceback:
AssertionError:
Traceback (most recent call last):
File "/opt/homebrew/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 363, in
main()
File "/opt/homebrew/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 345, in main
json_out['return_val'] = hook(**hook_input['kwargs'])
File "/opt/homebrew/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 130, in get_requires_for_build_wheel
return hook(config_settings)
File "/opt/homebrew/Cellar/[email protected]/3.10.6_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/setuptools/build_meta.py", line 177, in get_requires_for_build_wheel
return self._get_build_requires(
File "/opt/homebrew/Cellar/[email protected]/3.10.6_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/setuptools/build_meta.py", line 159, in _get_build_requires
self.run_setup()
File "/opt/homebrew/Cellar/[email protected]/3.10.6_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/setuptools/build_meta.py", line 174, in run_setup
exec(code, locals())
File "", line 12, in
ModuleNotFoundError: No module named 'packaging'
[end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.

note: This error originates from a subprocess, and is likely not a problem with pip.

Trigger a new release to build Mac arm64 wheels?

While installing astropy on an M1 mac, I noticed that pyerfa had to be built from source. I see that the wheel CI job now does already include the arm64 wheels, so it might be good to do a new release to push these to PyPI (the latest build is also so old that the artifact has expired, so one can't even download the wheel here). Would also solve #93.

Post-1.7.0 release nits

  • Authors on pypi is still "the astropy developers", as is the e-mail. Fix in #43.
  • A logo would still be nice (#26)
  • Should also publish to Zenodo;
  • Add zenodo badge; see #44
  • Might want to have travis badge; fix in #43.
  • Also a readthedocs badge? Fix in #43.
  • Add link to readthedocs documentation in README.rst (and don't expose it in docs...); fix by adding a badge in #43

Set up pyerfa on conda-forge

It would be good to set up pyerfa on conda-forge soon now that there is a stable release of pyerfa - this will then give time to iron out any issues and allow us to ask for it to be included in the defaults conda channel ahead of the next major astropy release (meaning v4.2).

@mwcraig - is this something you have time to help with? (setting up the conda recipe)

ValueError: Invalid data-type for array with Python 3.11

While installing pyerfa from source (as an Astropy dependency) on Python 3.11, I get this error with the ufunc calls.
For exemple, running tests from the installed package results in these errors:

❯ pytest ~/.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests

=================================== short test summary info ====================================
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_erfa.py::test_erfa_wrapper - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_erfa.py::test_errwarn_reporting - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_erfa.py::test_vector_inouts - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_erfa.py::test_rz - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_erfa.py::test_float32_input - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_erfa.py::TestLeapSeconds::test_set_leap_seconds - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_erfa.py::TestLeapSeconds::test_validation[table0-January] - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_erfa.py::TestLeapSeconds::test_validation[table1-jump] - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_erfa.py::TestLeapSeconds::test_validation[table2-dimension] - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_erfa.py::TestLeapSeconds::test_update_leap_seconds - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_ab - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_c2ibpn - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_c2ixy - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_c2tcio - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_c2teqx - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_cal2jd - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_dat - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_eform - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_eors - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_epj - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_gc2gd - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_gc2gde - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_gd2gc - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_gst06 - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_ld - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_ldsun - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_num00b - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_num06a - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_pmpx - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_ppsp - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_pr00 - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_rx - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_ry - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_rz - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_sxp - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_tporv - ValueError: Invalid data-type for array
FAILED ../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py::test_tpstv - ValueError: Invalid data-type for array
==================== 37 failed, 236 passed, 5 xfailed, 22 warnings in 3.10s ====================

Failure example:

__________________________________________ test_tporv __________________________________________

    def test_tporv():
        v = np.empty((3,), float)
        vz1 = np.empty((3,), float)
        vz2 = np.empty((3,), float)
        xi = -0.03
        eta = 0.07
        ra = 1.3
        dec = 1.5
        v = erfa_ufunc.s2c(ra, dec)
>       vz1, vz2, n = erfa_ufunc.tporv(xi, eta, v)
E       ValueError: Invalid data-type for array

../../../.pyenv/versions/3.11.0/lib/python3.11/site-packages/erfa/tests/test_ufunc.py:3511: ValueError

Astropy's CI on Python 3.11 is not failing, so I don't know, maybe something due to the GCC version ?

❯ gcc --version                                           
gcc (GCC) 12.2.0

When building from source I get many "incompatible pointer type" warnings, and a "dangling pointer" one:

      |         void (*)(char **, npy_intp *, npy_intp *, void *) {aka void (*)(char **, long int *, long int *, void *)}
  erfa/ufunc.c:14046:9: note: expected ‘PyUFuncGenericFunction’ {aka ‘void (*)(char **, const long int *, const long int *, void *)’} but argument is of type ‘void (*)(char **, npy_intp *, npy_intp *, void *)’ {aka ‘void (*)(char **, long int *, long int *, void *)’}
  erfa/ufunc.c:14080:9: warning: passing argument 3 of ‘(int (*)(PyUFuncObject *, PyArray_Descr *, void (*)(char **, const npy_intp *, const npy_intp *, void *), PyArray_Descr **, void *))*(PyUFunc_API + 328)’ from incompatible pointer type [-Wincompatible-pointer-types]
  14080 |         ufunc_loop_sxpv, dtypes, NULL);
        |         ^~~~~~~~~~~~~~~
        |         |
        |         void (*)(char **, npy_intp *, npy_intp *, void *) {aka void (*)(char **, long int *, long int *, void *)}
  erfa/ufunc.c:14080:9: note: expected ‘PyUFuncGenericFunction’ {aka ‘void (*)(char **, const long int *, const long int *, void *)’} but argument is of type ‘void (*)(char **, npy_intp *, npy_intp *, void *)’ {aka ‘void (*)(char **, long int *, long int *, void *)’}
  erfa/ufunc.c: In function ‘ErfaUFuncTypeResolver’:
  erfa/ufunc.c:9729:16: warning: dangling pointer ‘types’ to ‘types_array’ may be used [-Wdangling-pointer=]
   9729 |         return set_ufunc_loop_data_types(ufunc, operands, out_dtypes,
        |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   9730 |                                          types, dtypes);
        |                                          ~~~~~~~~~~~~~~
  erfa/ufunc.c:9715:13: note: ‘types_array’ declared here
   9715 |         int types_array[NPY_MAXARGS];
        |             ^~~~~~~~~~~

Cannot build from source: 'Version' object has no attribute 'tag'

I started seeing this in astropy that has dev job that builds pyerfa from source.

Last successful on main (the failures were caused by something else): https://github.com/astropy/astropy/runs/6943091688?check_suite_focus=true

Example failure: https://github.com/astropy/astropy/runs/7010907314?check_suite_focus=true

Collecting pyerfa
  Cloning https://github.com/liberfa/pyerfa.git to /tmp/...
  Running command git clone --filter=blob:none --quiet https://github.com/liberfa/pyerfa.git /tmp/...
  Resolved https://github.com/liberfa/pyerfa.git to commit 2ded04a8d699db3228f29ddca7912498276ac839
  Running command git submodule update --init --recursive -q
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Getting requirements to build wheel: started
  Getting requirements to build wheel: finished with status 'done'
  Preparing metadata (pyproject.toml): started
  Preparing metadata (pyproject.toml): finished with status 'error'
  error: subprocess-exited-with-error
  × Preparing metadata (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [40 lines of output]
      Traceback (most recent call last):
        File ".../pep517/in_process/_in_process.py", line 363, in <module>
          main()
        File ".../pep517/in_process/_in_process.py", line 345, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
        File ".../pep517/in_process/_in_process.py", line 164, in prepare_metadata_for_build_wheel
          return hook(metadata_directory, config_settings)
        File ".../setuptools/build_meta.py", line 188, in prepare_metadata_for_build_wheel
          self.run_setup()
        File ".../setuptools/build_meta.py", line 174, in run_setup
          exec(compile(code, __file__, 'exec'), locals())
        File "setup.py", line 165, in <module>
          setuptools.setup(use_scm_version=use_scm_version, ext_modules=get_extensions())
        File ".../setuptools/__init__.py", line 87, in setup
          return distutils.core.setup(**attrs)
        File ".../setuptools/_distutils/core.py", line 139, in setup
          _setup_distribution = dist = klass(attrs)
        File ".../setuptools/dist.py", line 477, in __init__
          _Distribution.__init__(
        File ".../setuptools/_distutils/dist.py", line 275, in __init__
          self.finalize_options()
        File ".../setuptools/dist.py", line 901, in finalize_options
          ep(self)
        File ".../setuptools/dist.py", line 922, in _finalize_setup_keywords
          ep.load()(self, ep.name, value)
        File ".../setuptools_scm/integration.py", line 88, in version_keyword
          _assign_version(dist, config)
        File ".../setuptools_scm/integration.py", line 57, in _assign_version
          maybe_version = _get_version(config)
        File ".../setuptools_scm/__init__.py", line 157, in _get_version
          version_string = format_version(
        File ".../setuptools_scm/version.py", line 554, in format_version
          main_version = _call_version_scheme(
        File ".../setuptools_scm/version.py", line 542, in _call_version_scheme
          result = scheme(version)
        File "erfa/_dev/scm_version.py", line 36, in _guess_next_dev
          return guess_next_version(version.tag)
        File ".../setuptools_scm/version.py", line 243, in guess_next_version
          version = _strip_local(str(tag_version.tag))
      AttributeError: 'Version' object has no attribute 'tag'
      [end of output]
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

version_string = str(version.tag)

Revisit need for our own ufunc type resolver

Currently, we override the standard numpy type resolver, because, as seen in this extract:

pyerfa/erfa/ufunc.c.templ

Lines 535 to 545 in e33ee55

* We provide our own type resolver, since the default one,
* PyUFunc_DefaultTypeResolver from
* numpy/core/src/umath/ufunc_type_resolution.c, has problems:
* 1. It only looks for userloops if any of the operands have a user
* type, which does not work if the inputs are normal and no explicit
* output is given (see https://github.com/numpy/numpy/issues/11109).
* 2. It only allows "safe" casting of inputs, which annoyingly prevents
* passing in a python int for int32 input.
* The resolver below solves both, and speeds up the process by
* explicitly assuming that a ufunc has only one function built in,
* either a regular one or a userloop (for structured dtype).

However, as noted in numpy/numpy#11109 (comment), things should now work for us. So, this is a reminder to try removing our work-around.

Set up authors?

We could leave authors as "the astropy developers", or should it go to be more erfa specific? From git shortlog, I'd infer that the contributors are (alphabetical):

  • Antonio Valentino
  • Erik Tollerud
  • Julien Woillez
  • Marten van Kerkwijk
  • Michael Droettboom
  • Thomas Robitaille

And maybe

  • Erik M. Bray(?)
  • Stuart Littlefair(?)

Version not available on fresh install from pypi when setuptools_scm is installed in environment

❯ python -m venv test_erfa
❯ source test_erfa/bin/activate
❯ pip install pyerfa
Collecting pyerfa
  Using cached pyerfa-1.7.1-cp38-cp38-manylinux2010_x86_64.whl (727 kB)
Collecting numpy>=1.16
  Using cached numpy-1.19.4-cp38-cp38-manylinux2010_x86_64.whl (14.5 MB)
Installing collected packages: numpy, pyerfa
Successfully installed numpy-1.19.4 pyerfa-1.7.1
WARNING: You are using pip version 20.2.1; however, version 20.2.4 is available.
You should consider upgrading via the '/home/maxnoe/test_erfa/bin/python -m pip install --upgrade pip' command.
❯ python
Python 3.8.6 (default, Sep 30 2020, 04:00:38) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import erfa
>>> erfa.version.version
'1.7.1'
❯ pip install setuptools_scm
Collecting setuptools_scm
  Using cached setuptools_scm-4.1.2-py2.py3-none-any.whl (27 kB)
Requirement already satisfied: setuptools in ./test_erfa/lib/python3.8/site-packages (from setuptools_scm) (49.2.1)
Installing collected packages: setuptools-scm
Successfully installed setuptools-scm-4.1.2
WARNING: You are using pip version 20.2.1; however, version 20.2.4 is available.
You should consider upgrading via the '/home/maxnoe/test_erfa/bin/python -m pip install --upgrade pip' command.
❯ python
Python 3.8.6 (default, Sep 30 2020, 04:00:38) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import erfa
/home/maxnoe/test_erfa/lib/python3.8/site-packages/erfa/version.py:15: UserWarning: could not determine erfa package version; this indicates a broken installation
  warnings.warn(
>>> erfa.version.version
'0.0.0'

pip install pyerfa does not work

(qtest310)>pip install pyerfa
Looking in indexes: https://pypi.org/simple
Collecting pyerfa
Using cached pyerfa-2.0.0.1.tar.gz (808 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Collecting numpy>=1.17
Using cached numpy-1.23.4-cp311-cp311-win_amd64.whl (14.6 MB)
Building wheels for collected packages: pyerfa
Building wheel for pyerfa (pyproject.toml) ... error
error: subprocess-exited-with-error

× Building wheel for pyerfa (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [21 lines of output]
C:\Users\maxime_rattier\AppData\Local\Temp\pip-build-env-ujxvzouq\overlay\Lib\site-packages\setuptools\config\setupcfg.py:508: SetuptoolsDeprecationWarning: The license_file parameter is deprecated, use license_files instead.
warnings.warn(msg, warning_class)
running bdist_wheel
running build
running build_py
creating build
creating build\lib.win-amd64-cpython-311
creating build\lib.win-amd64-cpython-311\erfa
copying erfa\core.py -> build\lib.win-amd64-cpython-311\erfa
copying erfa\helpers.py -> build\lib.win-amd64-cpython-311\erfa
copying erfa\version.py -> build\lib.win-amd64-cpython-311\erfa
copying erfa_version.py -> build\lib.win-amd64-cpython-311\erfa
copying erfa_init_.py -> build\lib.win-amd64-cpython-311\erfa
creating build\lib.win-amd64-cpython-311\erfa\tests
copying erfa\tests\helper.py -> build\lib.win-amd64-cpython-311\erfa\tests
copying erfa\tests\test_erfa.py -> build\lib.win-amd64-cpython-311\erfa\tests
copying erfa\tests\test_ufunc.py -> build\lib.win-amd64-cpython-311\erfa\tests
copying erfa\tests_init_.py -> build\lib.win-amd64-cpython-311\erfa\tests
running build_ext
building 'erfa.ufunc' extension
error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
[end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for pyerfa
Failed to build pyerfa
ERROR: Could not build wheels for pyerfa, which is required to install pyproject.toml-based projects

Set up test with external library

Mostly to remind myself: add a test run with apt which also uses Debian's liberfa-dev, to show that that works. Would have PYERFA_USE_SYSTEM_ERFA environment variable set. Even better if there is some way to show that compilation did not happen...
...
That would be something like:

nm -u .tox/test/lib/python3.8/site-packages/erfa/ufunc.cpython-38-x86_64-linux-gnu.so | grep eraA2af

which is empty if the routine is inside the .so, and present if it is from an external library.

Consider whether erfapy is a better name

pyerfa seems like a natural name given liberfa, but with a bit of thought, I think I slightly prefer the name erfapy over pyerfa, because there's a lot of py<something> packages. I can rename the repo easily enough but of course we'd also need to update references to it in the code itself. What do you think, @mhvk or @avalentino

Installing from tarball fails

Using a stock Python38 (system python from Arch Linux) doing pip install -v --no-binary :all: pyerfa fails with

  Given no hashes to check 0 links for project 'oldest-supported-numpy': discarding no candidates
  ERROR: Could not find a version that satisfies the requirement oldest-supported-numpy (from versions: none)
  ERROR: No matching distribution found for oldest-supported-numpy
  Exception information:
  Traceback (most recent call last):
    File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/cli/base_command.py", line 216, in _main
      status = self.run(options, args)
    File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/cli/req_command.py", line 182, in wrapper
      return func(self, options, args)
    File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/commands/install.py", line 324, in run
      requirement_set = resolver.resolve(
    File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/resolution/legacy/resolver.py", line 183, in resolve
      discovered_reqs.extend(self._resolve_one(requirement_set, req))
    File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/resolution/legacy/resolver.py", line 388, in _resolve_one
      abstract_dist = self._get_abstract_dist_for(req_to_install)
    File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/resolution/legacy/resolver.py", line 339, in _get_abstract_dist_for
      self._populate_link(req)
    File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/resolution/legacy/resolver.py", line 305, in _populate_link
      req.link = self._find_requirement_link(req)
    File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/resolution/legacy/resolver.py", line 270, in _find_requirement_link
      best_candidate = self.finder.find_requirement(req, upgrade)
    File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/index/package_finder.py", line 926, in find_requirement
      raise DistributionNotFound(
  pip._internal.exceptions.DistributionNotFound: No matching distribution found for oldest-supported-numpy
  Removed build tracker: '/tmp/pip-req-tracker-34xcv9k5'
  Installing build dependencies ... error
Exception information:
Traceback (most recent call last):
  File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/cli/base_command.py", line 216, in _main
    status = self.run(options, args)
  File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/cli/req_command.py", line 182, in wrapper
    return func(self, options, args)
  File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/commands/install.py", line 324, in run
    requirement_set = resolver.resolve(
  File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/resolution/legacy/resolver.py", line 183, in resolve
    discovered_reqs.extend(self._resolve_one(requirement_set, req))
  File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/resolution/legacy/resolver.py", line 388, in _resolve_one
    abstract_dist = self._get_abstract_dist_for(req_to_install)
  File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/resolution/legacy/resolver.py", line 340, in _get_abstract_dist_for
    abstract_dist = self.preparer.prepare_linked_requirement(req)
  File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/operations/prepare.py", line 482, in prepare_linked_requirement
    abstract_dist = _get_prepared_distribution(
  File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/operations/prepare.py", line 91, in _get_prepared_distribution
    abstract_dist.prepare_distribution_metadata(finder, build_isolation)
  File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/distributions/sdist.py", line 38, in prepare_distribution_metadata
    self._setup_isolation(finder)
  File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/distributions/sdist.py", line 66, in _setup_isolation
    self.req.build_env.install_requirements(
  File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/build_env.py", line 205, in install_requirements
    call_subprocess(args, spinner=spinner)
  File "/home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip/_internal/utils/subprocess.py", line 242, in call_subprocess
    raise InstallationError(exc_msg)
pip._internal.exceptions.InstallationError: Command errored out with exit status 1: /home/tcaswell/.virtualenvs/sys38/bin/python /home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip install --ignore-installed --no-user --prefix /tmp/pip-build-env-s0_eu0jn/overlay --no-warn-script-location -v --no-binary :all: --only-binary :none: -i https://pypi.org/simple -- 'setuptools>=42' 'setuptools_scm[toml]>=3.4' wheel 'jinja2>=2.10.3' oldest-supported-numpy Check the logs for full command output.
ERROR: Command errored out with exit status 1: /home/tcaswell/.virtualenvs/sys38/bin/python /home/tcaswell/.virtualenvs/sys38/lib/python3.8/site-packages/pip install --ignore-installed --no-user --prefix /tmp/pip-build-env-s0_eu0jn/overlay --no-warn-script-location -v --no-binary :all: --only-binary :none: -i https://pypi.org/simple -- 'setuptools>=42' 'setuptools_scm[toml]>=3.4' wheel 'jinja2>=2.10.3' oldest-supported-numpy Check the logs for full command output.
Removed pyerfa from https://files.pythonhosted.org/packages/86/5d/f4cc5804744f7ab14b54059ebd44969e4f6af9eb6909f56d112bf9f0730b/pyerfa-1.7.0.tar.gz#sha256=58cd5fbc27e31211102568f952fdbac410b184563be4da57743cbe5e5ccebe47 from build tracker '/tmp/pip-req-tracker-34xcv9k5'
Removed build tracker: '/tmp/pip-req-tracker-34xcv9k5'

Doing

pip install -v --no-binary :all: pyerfa --no-build-isolation

instead installs without error.

liberfa files missing in release and repository

The liberfa/erfa directory is empty, both in the release archive and the git repository:

cd pyerfa-2.0.0.1/
ls liberfa/erfa

and git submodule update does not do anything for me.

One can clone the erfa repo manually and move the files into that directory -- I would suggest adding this to the documentation (maybe as a sequence of command lines) to help new users :)

Cheers,
Stefan

Provide nightly wheels for downstream

Would be nice if astropy can pull your dev wheel instead of building pyerfa from source every time. You already have CI set up for it, so just a matter of uploading it somewhere.

Need to be on default conda channel before astropy 4.2 is released

astropy is shipped to conda default channel. Given that astropy 4.2 and later would require this package, it would be desirable for this package also be in conda default channel. Otherwise, it might break astropy in conda default channel.

See discussions at astropy/ci-helpers#451 (comment) . xref astropy/astropy#10329

When this is done, please either open an issue, or better yet, a pull request, to let ci-helpers grab pyerfa from conda too, instead of pip (especially for Appveyor). However, this would be moot if we retire ci-helpers before this happens (which is very unlikely).

p.s. See https://github.com/astropy/astropy/wiki/Release-Calendar for astropy release timeline.

cc @mwcraig and @bsipocz

NumPy 1.24 lets XPASS ufunc tests

The test suite fails with NumPy 1.24 because 5 ufunc tests unexpectedly XPASS:


[   16s] + pytest-3.8 --ignore=_build.python38 --ignore=_build.python39 --ignore=_build.python310 -v --pyargs erfa -k 'not test_version_with_embedded_liberfa'
[   17s] ============================= test session starts ==============================
[   17s] platform linux -- Python 3.8.16, pytest-7.1.2, pluggy-1.0.0 -- /usr/bin/python3.8
[   17s] cachedir: .pytest_cache
[   17s] rootdir: /home/abuild/rpmbuild/BUILD/pyerfa-2.0.0.1, configfile: setup.cfg
[   17s] plugins: doctestplus-0.12.0
[   17s] collecting ... collected 279 items / 1 deselected / 278 selected
[   17s] 
...
[   17s] =================================== FAILURES ===================================
[   17s] __________________________________ test_bi00 ___________________________________
[   17s] [XPASS(strict)] do not yet support no-input ufuncs
[   17s] _________________________________ test_fk5hip __________________________________
[   17s] [XPASS(strict)] do not yet support no-input ufuncs
[   17s] ___________________________________ test_ir ____________________________________
[   17s] [XPASS(strict)] do not yet support no-input ufuncs
[   17s] ___________________________________ test_zp ____________________________________
[   17s] [XPASS(strict)] do not yet support no-input ufuncs
[   17s] ___________________________________ test_zr ____________________________________
[   17s] [XPASS(strict)] do not yet support no-input ufuncs
[   17s] =========================== short test summary info ============================
[   17s] FAILED tests/test_ufunc.py::test_bi00
[   17s] FAILED tests/test_ufunc.py::test_fk5hip
[   17s] FAILED tests/test_ufunc.py::test_ir
[   17s] FAILED tests/test_ufunc.py::test_zp
[   17s] FAILED tests/test_ufunc.py::test_zr
[   17s] ============ 5 failed, 272 passed, 1 skipped, 1 deselected in 0.83s ============

pyerfa build is broken with setuptools_scm 8

  File "erfa/_dev/scm_version.py", line 18, in _guess_next_dev
    erfa_version = git.parse(liberfadir)
                   ^^^^^^^^^^^^^^^^^^^^^
TypeError: parse() missing 1 required positional argument: 'config'

Simplify python wrapper generation

(Partially inspired by an old issue I raised over at astropy/astropy#6073)

It is not obvious one always needs all erfa functions available, and at least the python wrappers could be auto-generated (especially with the new module level __getattr__).

Though in fact all that do not have a warning/error flag could just omitted altogether (i.e., one would call the ufunc directly).

pyerfa build fails on Arm64 Mac with Python 3.8.9

I am building a library which uses Astropy, and therefore pyerfa, and attempting to build wheel files for M1 Mac on Python 3.8.9.
I get the following error:

Building wheels for collected packages: pyerfa
  Building wheel for pyerfa (pyproject.toml) ... error
  error: subprocess-exited-with-error

  × Building wheel for pyerfa (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [31 lines of output]
      running bdist_wheel
      running build
      running build_py
      creating build
      creating build/lib.macosx-10.14-arm64-cpython-38
      creating build/lib.macosx-10.14-arm64-cpython-38/erfa
      copying erfa/version.py -> build/lib.macosx-10.14-arm64-cpython-38/erfa
      copying erfa/_version.py -> build/lib.macosx-10.14-arm64-cpython-38/erfa
      copying erfa/__init__.py -> build/lib.macosx-10.14-arm64-cpython-38/erfa
      copying erfa/core.py -> build/lib.macosx-10.14-arm64-cpython-38/erfa
      copying erfa/helpers.py -> build/lib.macosx-10.14-arm64-cpython-38/erfa
      creating build/lib.macosx-10.14-arm64-cpython-38/erfa/tests
      copying erfa/tests/__init__.py -> build/lib.macosx-10.14-arm64-cpython-38/erfa/tests
      copying erfa/tests/helper.py -> build/lib.macosx-10.14-arm64-cpython-38/erfa/tests
      copying erfa/tests/test_ufunc.py -> build/lib.macosx-10.14-arm64-cpython-38/erfa/tests
      copying erfa/tests/test_erfa.py -> build/lib.macosx-10.14-arm64-cpython-38/erfa/tests
      running build_ext
      building 'erfa.ufunc' extension
      creating build/temp.macosx-10.14-arm64-cpython-38
      creating build/temp.macosx-10.14-arm64-cpython-38/erfa
      creating build/temp.macosx-10.14-arm64-cpython-38/liberfa
      creating build/temp.macosx-10.14-arm64-cpython-38/liberfa/erfa
      creating build/temp.macosx-10.14-arm64-cpython-38/liberfa/erfa/src
      clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -iwithsysroot/System/Library/Frameworks/System.framework/PrivateHeaders -iwithsysroot/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/Headers -arch arm64 -arch x86_64 -Werror=implicit-function-declaration -DHAVE_CONFIG_H=1 -Iliberfa/erfa/src -Iliberfa/erfa -I/private/var/folders/wc/0r5w973d4tddmgdh7c206ypc0000gp/T/pip-build-env-xixxfag3/overlay/lib/python3.8/site-packages/numpy/core/include -I/Users/ageifman/venvs/include -I/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/Headers -c erfa/ufunc.c -o build/temp.macosx-10.14-arm64-cpython-38/erfa/ufunc.o
      erfa/ufunc.c:13:10: fatal error: 'Python.h' file not found
      #include "Python.h"
               ^~~~~~~~~~
      1 error generated.
      /private/var/folders/wc/0r5w973d4tddmgdh7c206ypc0000gp/T/pip-build-env-xixxfag3/overlay/lib/python3.8/site-packages/setuptools/config/setupcfg.py:508: SetuptoolsDeprecationWarning: The license_file parameter is deprecated, use license_files instead.
        warnings.warn(msg, warning_class)
      error: command '/usr/bin/clang' failed with exit code 1

pyerfa builds for x86 on Arm64 Mac with Python 3.10, but not for 3.9 and 3.8

I am building a library which uses Astropy, and therefore pyerfa, and attempting to build wheel files for M1 Mac on Python 3.8, 3.9 and 3.10. Python versions 3.8 and 3.9 build just fine, but for Python 3.10 I get the following error

../../Environments/py310/lib/python3.10/site-packages/astropy/utils/exceptions.py:11: in <module>
    from erfa import ErfaError, ErfaWarning  # noqa
../../Environments/py310/lib/python3.10/site-packages/erfa/__init__.py:5: in <module>
    from .version import version as __version__  # noqa
../../Environments/py310/lib/python3.10/site-packages/erfa/version.py:25: in <module>
    from . import ufunc
E   ImportError: dlopen(/Users/mgiammar/Environments/py310/lib/python3.10/site-packages/erfa/ufunc.cpython-310-darwin.so, 0x0002): tried: '/Users/mgiammar/Environments/py310/lib/python3.10/site-packages/erfa/ufunc.cpython-310-darwin.so' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e'))

I've confirmed my terminal is using the Arm64 architecture and all my Python executables (3.8, 3.9, 3.10) are for arm64 via running

>>> import platform; print(platform.platform())
macOS-12.3-arm64-arm-64bit

The version of pyerfa installed when the error is thrown is 2.0.0.1, confirmed by

(py310) user@computer ~ % pip show pyerfa 
Name: pyerfa
Version: 2.0.0.1
Summary: Python bindings for ERFA
Home-page: https://github.com/liberfa/pyerfa
Author: The PyERFA Developers
Author-email: 
License: BSD 3-Clause License
Location: /Users/mgiammar/Environments/py310/lib/python3.10/site-packages
Requires: numpy
Required-by: astropy

Installing pyerfa 2.0.0 no longer causes the incompatible architecture error on import and pyerfa seems to be installed correctly for my arm64 M1 Mac. I suspect something in the build pipelines may have inadvertently changed when comparing v2.0.0 to v2.0.0.1 (see azure-pipelines.yml)

https://github.com/liberfa/pyerfa/compare/v2.0.0..v2.0.0.1#diff-7915b9b726a397ae7ba6af7b9703633d21c031ebf21682f3ee7e6a4ec52837a5

Although this bug doesn't adversely affect me or other users, it still would be useful to have fixed eventually. Let me know if I can be of any help while trying to address this issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.