Commit dbcc15da authored by Ole Streicher's avatar Ole Streicher

New upstream version 2.0.1

parent 05535b14
2.0.1 (2017-07-30)
==================
Bug Fixes
---------
astropy.constants
^^^^^^^^^^^^^^^^^
- Fixed Earth radius to be the IAU2015 value for the equatorial radius.
The polar value had erroneously been used in 2.0. [#6400]
astropy.coordinates
^^^^^^^^^^^^^^^^^^^
- Added old frame attribute classes back to top-level namespace of
``astropy.coordinates``. [#6357]
astropy.io.fits
^^^^^^^^^^^^^^^
- Scaling an image always uses user-supplied values when given. Added
defaults for scaling when bscale/bzero are not present (float images).
Fixed a small bug in when to reset ``_orig_bscale``. [#5955]
astropy.modeling
^^^^^^^^^^^^^^^^
- Fixed a bug in initializing compound models with units. [#6398]
astropy.nddata
^^^^^^^^^^^^^^
- Updating CCDData.read() to be more flexible with inputs, don't try to
delete keywords that are missing from the header. [#6388]
astropy.tests
^^^^^^^^^^^^^
- Fixed the test command that is run from ``setuptools`` to allow it to
gracefully handle keyboard interrupts and pass them on to the ``pytest``
subprocess. This prompts ``pytest`` to teardown and display useful traceback
and test information [#6369]
astropy.visualization
^^^^^^^^^^^^^^^^^^^^^
- Ticks and tick labels are now drawn in front of, rather than behind,
gridlines in WCS axes. This improves legibility in situations where
tick labels may be on the interior of the axes frame, such as the right
ascension axis of an all-sky Aitoff or Mollweide projection. [#6361]
astropy.wcs
^^^^^^^^^^^
- Fix the missing wcskey part in _read_sip_kw, this will cause error when reading sip wcs while there is no default CRPIX1 CRPIX2 keywords and only CRPIX1n CRPIX2n in header. [#6372]
2.0 (2017-07-07)
================
......
Metadata-Version: 1.2
Name: astropy
Version: 2.0
Version: 2.0.1
Summary: Community-developed python astronomy tools
Home-page: http://astropy.org
Author: The Astropy Developers
......
......@@ -5795,7 +5795,7 @@ def pmsafe(ra1, dec1, pmr1, pmd1, px1, rv1, ep1a, ep1b, ep2a, ep2b):
rv2_out = rv2_out.reshape(rv2_out.shape[1:])
return ra2_out, dec2_out, pmr2_out, pmd2_out, px2_out, rv2_out
STATUS_CODES['pmsafe'] = {0: 'no warnings or errors', 1: 'distance overridden (Note 6)', 2: 'excessive velocity (Note 7)', 4: "solution didn't converge (Note 8)", 'else': 'binary logical OR of the above warnings', -1: 'system error (should not occur)'}
STATUS_CODES['pmsafe'] = {0: 'no warnings or errors', 1: 'distance overridden (Note 6)', 2: 'excessive velocity (Note 7)', 'else': 'binary logical OR of the above warnings', 4: "solution didn't converge (Note 8)", -1: 'system error (should not occur)'}
......@@ -16800,7 +16800,7 @@ def starpv(ra, dec, pmr, pmd, px, rv):
pv_out = pv_out.reshape(pv_out.shape[1:])
return pv_out
STATUS_CODES['starpv'] = {0: 'no warnings', 1: 'distance overridden (Note 6)', 2: 'excessive speed (Note 7)', 4: "solution didn't converge (Note 8)", 'else': 'binary logical OR of the above'}
STATUS_CODES['starpv'] = {0: 'no warnings', 1: 'distance overridden (Note 6)', 2: 'excessive speed (Note 7)', 'else': 'binary logical OR of the above', 4: "solution didn't converge (Note 8)"}
......@@ -17566,7 +17566,7 @@ def starpm(ra1, dec1, pmr1, pmd1, px1, rv1, ep1a, ep1b, ep2a, ep2b):
rv2_out = rv2_out.reshape(rv2_out.shape[1:])
return ra2_out, dec2_out, pmr2_out, pmd2_out, px2_out, rv2_out
STATUS_CODES['starpm'] = {0: 'no warnings or errors', 1: 'distance overridden (Note 6)', 2: 'excessive velocity (Note 7)', 4: "solution didn't converge (Note 8)", 'else': 'binary logical OR of the above warnings', -1: 'system error (should not occur)'}
STATUS_CODES['starpm'] = {0: 'no warnings or errors', 1: 'distance overridden (Note 6)', 2: 'excessive velocity (Note 7)', 'else': 'binary logical OR of the above warnings', 4: "solution didn't converge (Note 8)", -1: 'system error (should not occur)'}
......
......@@ -92,5 +92,5 @@ M_earth = IAU2015('M_earth', "Earth mass",
"IAU 2015 Resolution B 3 + CODATA 2014", system='si')
# Earth equatorial radius
R_earth = IAU2015('R_earth', "Nominal Earth equatorial radius", 6.3568e6,
R_earth = IAU2015('R_earth', "Nominal Earth equatorial radius", 6.3781e6,
'm', 0.0, "IAU 2015 Resolution B 3", system='si')
......@@ -24,6 +24,11 @@ from .funcs import *
from .calculation import *
from .solar_system import *
# This is for backwards-compatibility -- can be removed in v3.0 when the
# deprecation warnings are removed
from .attributes import (TimeFrameAttribute, QuantityFrameAttribute,
CartesianRepresentationFrameAttribute)
__doc__ += builtin_frames._transform_graph_docs + """
.. note::
......
......@@ -467,3 +467,40 @@ def test_regression_6347_3d():
assert len(d2d_1) == 0
assert type(d2d_1) is type(d2d_10)
def test_regression_6300():
"""Check that importing old frame attribute names from astropy.coordinates
still works. See comments at end of #6300
"""
from ...utils.exceptions import AstropyDeprecationWarning
from .. import CartesianRepresentation
from .. import (TimeFrameAttribute, QuantityFrameAttribute,
CartesianRepresentationFrameAttribute)
with catch_warnings() as found_warnings:
attr = TimeFrameAttribute(default=Time("J2000"))
for w in found_warnings:
if issubclass(w.category, AstropyDeprecationWarning):
break
else:
assert False, "Deprecation warning not raised"
with catch_warnings() as found_warnings:
attr = QuantityFrameAttribute(default=5*u.km)
for w in found_warnings:
if issubclass(w.category, AstropyDeprecationWarning):
break
else:
assert False, "Deprecation warning not raised"
with catch_warnings() as found_warnings:
attr = CartesianRepresentationFrameAttribute(
default=CartesianRepresentation([5,6,7]*u.kpc))
for w in found_warnings:
if issubclass(w.category, AstropyDeprecationWarning):
break
else:
assert False, "Deprecation warning not raised"
......@@ -656,8 +656,7 @@ class FLRW(Cosmology):
return self._Ogamma0 * (1. + z) ** 4 * self.inv_efunc(z) ** 2
def Onu(self, z):
""" Return the density parameter for massless neutrinos at
redshift ``z``.
""" Return the density parameter for neutrinos at redshift ``z``.
Parameters
----------
......
......@@ -170,7 +170,7 @@ class _ImageBaseHDU(_ValidHDU):
# but there should be a BSCALE/BZERO now that the data has been set.
if not bzero_in_header:
self._orig_bzero = self._bzero
if bscale_in_header:
if not bscale_in_header:
self._orig_bscale = self._bscale
@classmethod
......@@ -427,7 +427,7 @@ class _ImageBaseHDU(_ValidHDU):
self._bitpix = self._header['BITPIX']
self._blank = self._header.pop('BLANK', None)
def scale(self, type=None, option='old', bscale=1, bzero=0):
def scale(self, type=None, option='old', bscale=None, bzero=None):
"""
Scale image data by using ``BSCALE``/``BZERO``.
......@@ -443,12 +443,12 @@ class _ImageBaseHDU(_ValidHDU):
dtype name, (e.g. ``'uint8'``, ``'int16'``, ``'float32'``
etc.). If is `None`, use the current data type.
option : str
How to scale the data: if ``"old"``, use the original
``BSCALE`` and ``BZERO`` values when the data was
read/created. If ``"minmax"``, use the minimum and maximum
of the data to scale. The option will be overwritten by
any user specified ``bscale``/``bzero`` values.
option : str, optional
How to scale the data: ``"old"`` uses the original ``BSCALE`` and
``BZERO`` values from when the data was read/created (defaulting to
1 and 0 if they don't exist). For integer data only, ``"minmax"``
uses the minimum and maximum of the data to scale. User-specified
``bscale``/``bzero`` values always take precedence.
bscale, bzero : int, optional
User-specified ``BSCALE`` and ``BZERO`` values
......@@ -458,7 +458,7 @@ class _ImageBaseHDU(_ValidHDU):
self._scale_internal(type=type, option=option, bscale=bscale,
bzero=bzero, blank=None)
def _scale_internal(self, type=None, option='old', bscale=1, bzero=0,
def _scale_internal(self, type=None, option='old', bscale=None, bzero=None,
blank=0):
"""
This is an internal implementation of the `scale` method, which
......@@ -485,31 +485,35 @@ class _ImageBaseHDU(_ValidHDU):
# Determine how to scale the data
# bscale and bzero takes priority
if (bscale != 1 or bzero != 0):
if bscale is not None and bzero is not None:
_scale = bscale
_zero = bzero
else:
if option == 'old':
_scale = self._orig_bscale
_zero = self._orig_bzero
elif option == 'minmax':
if issubclass(_type, np.floating):
_scale = 1
_zero = 0
else:
min = np.minimum.reduce(self.data.flat)
max = np.maximum.reduce(self.data.flat)
if _type == np.uint8: # uint8 case
_zero = min
_scale = (max - min) / (2.0 ** 8 - 1)
else:
_zero = (max + min) / 2.0
elif bscale is not None:
_scale = bscale
_zero = 0
elif bzero is not None:
_scale = 1
_zero = bzero
elif (option == 'old' and self._orig_bscale is not None and
self._orig_bzero is not None):
_scale = self._orig_bscale
_zero = self._orig_bzero
elif option == 'minmax' and not issubclass(_type, np.floating):
min = np.minimum.reduce(self.data.flat)
max = np.maximum.reduce(self.data.flat)
if _type == np.uint8: # uint8 case
_zero = min
_scale = (max - min) / (2.0 ** 8 - 1)
else:
_zero = (max + min) / 2.0
# throw away -2^N
nbytes = 8 * _type().itemsize
_scale = (max - min) / (2.0 ** nbytes - 2)
# throw away -2^N
nbytes = 8 * _type().itemsize
_scale = (max - min) / (2.0 ** nbytes - 2)
else:
_scale = 1
_zero = 0
# Do the scaling
if _zero != 0:
......
......@@ -641,6 +641,16 @@ class TestImageFunctions(FitsTestCase):
f = fits.open(self.temp('test_new.fits'), uint=True)
assert f[1].data.dtype == 'uint16'
def test_scale_with_explicit_bzero_bscale(self):
"""
Regression test for https://github.com/astropy/astropy/issues/6399
"""
hdu1 = fits.PrimaryHDU()
hdu2 = fits.ImageHDU(np.random.rand(100,100))
# The line below raised an exception in astropy 2.0, so if it does not
# raise an error here, that is progress.
hdu2.scale(type='uint8', bscale=1, bzero=0)
def test_uint_header_consistency(self):
"""
Regression test for https://github.com/astropy/astropy/issues/2305
......
......@@ -1788,6 +1788,7 @@ class Model(object):
total_size = 0
for name in self.param_names:
unit = None
param_descr = getattr(self, name)
if params.get(name) is None:
......@@ -1844,7 +1845,9 @@ class Model(object):
# out of Parameter and into Model (renaming them
# _get/set_parameter_value)
for name, value in params.items():
# value here may be a Quantity object.
param_descr = getattr(self, name)
unit = param_descr.unit
value = np.array(value)
orig_unit = param_metrics[name]['orig_unit']
if param_descr._setter is not None:
......
This diff is collapsed.
......@@ -11,10 +11,12 @@ import numpy as np
from ..core import Model, Fittable1DModel, InputParameterError
from ..parameters import Parameter, ParameterDefinitionError
from ..models import Gaussian1D
from ..models import (Gaussian1D, Pix2Sky_TAN, RotateNative2Celestial,
Rotation2D)
from ... import units as u
from ...units import UnitsError
from ...tests.helper import pytest, assert_quantity_allclose
from ... import coordinates as coord
class BaseTestModel(Fittable1DModel):
......@@ -328,3 +330,12 @@ def test_parameter_quantity_comparison():
"dimensionless quantities when other argument "
"is not a quantity (unless the latter is all "
"zero/infinity/nan)")
def test_parameters_compound_models():
tan = Pix2Sky_TAN()
sky_coords = coord.SkyCoord(ra=5.6, dec=-72, unit=u.deg)
lon_pole = 180 * u.deg
n2c = RotateNative2Celestial(sky_coords.ra, sky_coords.dec, lon_pole)
rot = Rotation2D(23)
m = rot | n2c
......@@ -416,7 +416,7 @@ def _generate_wcs_and_update_header(hdr):
wcs_header = wcs.to_header(relax=True)
for k in wcs_header:
if k not in _KEEP_THESE_KEYWORDS_IN_HEADER:
del new_hdr[k]
new_hdr.remove(k, ignore_missing=True)
return (new_hdr, wcs)
......
......@@ -3,8 +3,6 @@
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import os
import numpy as np
import pytest
......@@ -15,7 +13,8 @@ from ... import units as u
from ... import log
from ...wcs import WCS
from ...utils import NumpyRNGContext
from ...utils.data import get_pkg_data_filename, get_pkg_data_filenames, get_pkg_data_contents
from ...utils.data import (get_pkg_data_filename, get_pkg_data_filenames,
get_pkg_data_contents)
from ..ccddata import CCDData
......@@ -641,6 +640,11 @@ def test_wcs_keywords_removed_from_header():
wcs_header = ccd.wcs.to_header()
assert not (set(wcs_header) & set(ccd.meta) - keepers)
# Make sure that exceptions are not raised when trying to remove missing
# keywords. o4sp040b0_raw.fits of io.fits is missing keyword 'PC1_1'.
data_file1 = get_pkg_data_filename('../../io/fits/tests/data/o4sp040b0_raw.fits')
ccd = CCDData.read(data_file1, unit='count')
def test_wcs_keyword_removal_for_wcs_test_files():
"""
......
......@@ -222,9 +222,16 @@ class AstropyTest(Command, object):
# already done by another core. Compilation is an
# insignificant fraction of total testing time, though, so
# it's probably not worth worrying about.
retcode = subprocess.call([sys.executable, '-B', '-c', cmd],
cwd=self.testing_path, close_fds=False)
testproc = subprocess.Popen(
[sys.executable, '-B', '-c', cmd],
cwd=self.testing_path, close_fds=False)
retcode = testproc.wait()
except KeyboardInterrupt:
import signal
# If a keyboard interrupt is handled, pass it to the test
# subprocess to prompt pytest to initiate its teardown
testproc.send_signal(signal.SIGINT)
retcode = testproc.wait()
finally:
# Remove temporary directory
shutil.rmtree(self.tmp_dir)
......
......@@ -4,9 +4,6 @@ import matplotlib
MPL_VERSION = LooseVersion(matplotlib.__version__)
ROOT = "http://data.astropy.org/testing/astropy/2017-07-06T17:59:08.793939"
ROOT = "http://data.astropy.org/testing/astropy/2017-07-12T14:12:26.217559"
if MPL_VERSION >= LooseVersion('1.5.0'):
IMAGE_REFERENCE_DIR = ROOT + '/1.5.x/'
else:
IMAGE_REFERENCE_DIR = ROOT + '/1.4.x/'
IMAGE_REFERENCE_DIR = ROOT + '/1.5.x/'
......@@ -322,7 +322,7 @@ def set_enabled_units(units):
AU | 1.49598e+11 m | au, astronomical_unit ,
Angstrom | 1e-10 m | AA, angstrom ,
cm | 0.01 m | centimeter ,
earthRad | 6.3568e+06 m | R_earth, Rearth ,
earthRad | 6.3781e+06 m | R_earth, Rearth ,
jupiterRad | 7.1492e+07 m | R_jup, Rjup, R_jupiter, Rjupiter ,
lyr | 9.46073e+15 m | lightyear ,
m | irreducible | meter ,
......@@ -371,7 +371,7 @@ def add_enabled_units(units):
AU | 1.49598e+11 m | au, astronomical_unit ,
Angstrom | 1e-10 m | AA, angstrom ,
cm | 0.01 m | centimeter ,
earthRad | 6.3568e+06 m | R_earth, Rearth ,
earthRad | 6.3781e+06 m | R_earth, Rearth ,
ft | 0.3048 m | foot ,
fur | 201.168 m | furlong ,
inch | 0.0254 m | ,
......
# Autogenerated by Astropy's setup.py on 2017-07-07 15:20:25.870441
# Autogenerated by Astropy's setup.py on 2017-07-30 19:49:24.221570
from __future__ import unicode_literals
import datetime
version = "2.0"
githash = "35ef7fd46e81e2b787e6b849a0aa011a8805c02b"
version = "2.0.1"
githash = "640261b2de54562b92b447d75c44252545d4dfae"
major = 2
minor = 0
bugfix = 0
bugfix = 1
release = True
timestamp = datetime.datetime(2017, 7, 7, 15, 20, 25, 870441)
timestamp = datetime.datetime(2017, 7, 30, 19, 49, 24, 221570)
debug = False
try:
......
......@@ -427,16 +427,12 @@ class CoordinateHelper(object):
def formatter(self):
return self._formatter_locator.formatter
def _draw(self, renderer, bboxes, ticklabels_bbox):
def _draw_grid(self, renderer):
renderer.open_group('coordinate_axis')
renderer.open_group('grid lines')
self._update_ticks()
self.ticks.draw(renderer)
self.ticklabels.draw(renderer, bboxes=bboxes,
ticklabels_bbox=ticklabels_bbox)
if self.grid_lines_kwargs['visible']:
if self._grid_type == 'lines':
......@@ -458,7 +454,17 @@ class CoordinateHelper(object):
line.set(**self.grid_lines_kwargs)
line.draw(renderer)
renderer.close_group('coordinate_axis')
renderer.close_group('grid lines')
def _draw_ticks(self, renderer, bboxes, ticklabels_bbox):
renderer.open_group('ticks')
self.ticks.draw(renderer)
self.ticklabels.draw(renderer, bboxes=bboxes,
ticklabels_bbox=ticklabels_bbox)
renderer.close_group('ticks')
def _draw_axislabels(self, renderer, bboxes, ticklabels_bbox, visible_ticks):
......
......@@ -337,8 +337,13 @@ class WCSAxes(Axes):
coords.frame.update()
for coord in coords:
coord._draw(renderer, bboxes=self._bboxes,
ticklabels_bbox=self._ticklabels_bbox)
coord._draw_grid(renderer)
for coords in self._all_coords:
for coord in coords:
coord._draw_ticks(renderer, bboxes=self._bboxes,
ticklabels_bbox=self._ticklabels_bbox)
visible_ticks.extend(coord.ticklabels.get_visible_axes())
for coords in self._all_coords:
......
......@@ -1044,3 +1044,17 @@ def test_to_fits_1():
assert isinstance(wfits, fits.HDUList)
assert isinstance(wfits[0], fits.PrimaryHDU)
assert isinstance(wfits[1], fits.ImageHDU)
def test_keyedsip():
"""
Test sip reading with extra key.
"""
hdr_name = get_pkg_data_filename('data/sip-broken.hdr')
header = fits.Header.fromfile(hdr_name)
del header[str("CRPIX1")]
del header[str("CRPIX2")]
w=wcs.WCS(header=header,key="A")
assert isinstance( w.sip, wcs.Sip )
assert w.sip.crpix[0] == 2048
assert w.sip.crpix[1] == 1026
......@@ -1106,12 +1106,12 @@ reduce these to 2 dimensions using the naxis kwarg.
if a is None and b is None and ap is None and bp is None:
return None
if str("CRPIX1") not in header or str("CRPIX2") not in header:
if str("CRPIX1{0}".format(wcskey)) not in header or str("CRPIX2{0}".format(wcskey)) not in header:
raise ValueError(
"Header has SIP keywords without CRPIX keywords")
crpix1 = header.get("CRPIX1")
crpix2 = header.get("CRPIX2")
crpix1 = header.get("CRPIX1{0}".format(wcskey))
crpix2 = header.get("CRPIX2{0}".format(wcskey))
return Sip(a, b, ap, bp, (crpix1, crpix2))
......
astropy-helpers Changelog
=========================
*************************
2.0.1 (2017-07-28)
------------------
- Fix compatibility with Sphinx <1.5. [#326]
2.0 (2017-07-06)
----------------
......
Metadata-Version: 1.1
Name: astropy-helpers
Version: 2.0
Version: 2.0.1
Summary: Utilities for building and installing Astropy, Astropy affiliated packages, and their respective documentation.
Home-page: https://github.com/astropy/astropy-helpers
Author: The Astropy Developers
......
......@@ -70,9 +70,9 @@ class AstropyBuildDocs(SphinxBuildDoc):
self.warnings_returncode = False
def finalize_options(self):
SphinxBuildDoc.finalize_options(self)
# Clear out previous sphinx builds, if requested
if self.clean_docs:
dirstorm = [os.path.join(self.source_dir, 'api'),
......@@ -89,7 +89,7 @@ class AstropyBuildDocs(SphinxBuildDoc):
else:
log.info('Not cleaning directory ' + d + ' because '
'not present or not a directory')
def run(self):
# TODO: Break this method up into a few more subroutines and
......@@ -158,20 +158,21 @@ class AstropyBuildDocs(SphinxBuildDoc):
else:
subproccode[i] = repr(val)
subproccode = ''.join(subproccode)
optcode = textwrap.dedent("""
class Namespace(object): pass
self = Namespace()
self.pdb = {pdb!r}
self.verbosity = {verbosity!r}
self.traceback = {traceback!r}
""").format(pdb=self.pdb, verbosity=self.verbosity,
traceback=self.traceback)
""").format(pdb=getattr(self, 'pdb', False),
verbosity=getattr(self, 'verbosity', 0),
traceback=getattr(self, 'traceback', False))
subproccode = optcode + subproccode
# This is a quick gross hack, but it ensures that the code grabbed from
# SphinxBuildDoc.run will work in Python 2 if it uses the print
# function
......
# Autogenerated by Astropy-affiliated package astropy_helpers's setup.py on 2017-07-07 15:20:24.191794
# Autogenerated by Astropy-affiliated package astropy_helpers's setup.py on 2017-07-30 19:49:22.788427
from __future__ import unicode_literals
import datetime
version = "2.0"
githash = "ed2e7897862ae9e979b336df670d7a5541cdd8f0"
version = "2.0.1"
githash = "14ca346b0da3e92e65bdc398cc8f726cbd7be57d"
major = 2
minor = 0
bugfix = 0
bugfix = 1
release = True
timestamp = datetime.datetime(2017, 7, 7, 15, 20, 24, 191794)
timestamp = datetime.datetime(2017, 7, 30, 19, 49, 22, 788427)
debug = False
try:
......
......@@ -72,7 +72,7 @@ check_sphinx_version("1.2.1")
del intersphinx_mapping['astropy']
# add any custom intersphinx for astropy
intersphinx_mapping['pytest'] = ('https://pytest.org/en/latest/', None)
intersphinx_mapping['pytest'] = ('https://docs.pytest.org/en/latest/', None)
intersphinx_mapping['ipython'] = ('http://ipython.readthedocs.io/en/stable/', None)
intersphinx_mapping['pandas'] = ('http://pandas.pydata.org/pandas-docs/stable/', None)
intersphinx_mapping['sphinx_automodapi'] = ('https://sphinx-automodapi.readthedocs.io/en/stable/', None)
......
......@@ -94,7 +94,7 @@ and hence often do not round-trip.
.. _astropy-coordinates-transforming-ephemerides:
Transformations and Solar-system ephemerides
********************************************
============================================
Some transformations (e.g. the transformation between `~astropy.coordinates.ICRS` and
`~astropy.coordinates.GCRS`) require the use of a Solar-system ephemeris to calculate
......
......@@ -66,7 +66,7 @@ packages that use the full bugfix/maintenance branch approach.)
#. Obtain a *clean* version of the `astropy core repository`_. That is, one
where you don't have any intermediate build files. Either use a fresh
``git clone`` or do ``git clean -dfx``. If you choose to clean the working tree,
``git clone`` or do ``git clean -dfx``. If you choose to clean the working tree,
don't forget to clean the ``astropy_helpers`` submodule, too.
#. Be sure you're on the branch appropriate for the version you're about to
......@@ -119,12 +119,12 @@ packages that use the full bugfix/maintenance branch approach.)
$ git checkout v1.2.2
Don't forget to remove any non-committed files both from the main working tree
Don't forget to remove any non-committed files both from the main working tree
and ``astropy_helpers`` submodules with::
$ git clean -dfx
$ cd astropy_helpers; git clean -dfx; cd ..
#. Make sure the source distribution doesn't inherit limited permissions
following your default umask::
......@@ -177,13 +177,15 @@ packages that use the full bugfix/maintenance branch approach.)
* build and upload the Astropy wheels;
* make and upload the Astropy source release.
#. For the wheel build / upload, follow the `wheel builder README`_
instructions again. Edit the ``.travis.yml`` and ``appveyor.yml`` files
to give the release tag to build. Check the build has passed on on the
Travis-CI interface at https://travis-ci.org/MacPython/astropy-wheels. Now
follow the instructions in the page above to download the built wheels to a
local machine and upload to PyPI.
local machine and upload to PyPI. If you use the ``wheel_download.py`` script,
make sure you loop through all the available OS to get all the wheels.
#. Now the wheels are built and uploaded, you can upload the source release.
For safety's sake, you may want to clean the repo yet again to make sure
......@@ -194,10 +196,13 @@ packages that use the full bugfix/maintenance branch approach.)
#. Upload the source distribution to PyPI; this is preceded by re-running
the sdist command, which makes sure the source code is packaged up and ready
to be uploaded::
$ python setup.py build sdist upload --sign
to be uploaded. You also need to GPG sign the release, before using twine to
upload it to PyPI. (You may need to install `twine`_ if you haven't used it yet)::
$ python setup.py build sdist
$ gpg --detach-sign -a dist/astropy-<version>.tar.gz
$ twine upload dist/astropy-<version>*
#. Go to https://pypi.python.org/pypi?:action=pkg_edit&name=astropy
and ensure that only the most recent releases in each actively maintained
release line are *not* marked hidden. For example, if v1.2.2 was
......@@ -293,7 +298,7 @@ Modifications for a beta/release candidate release
If an RC goes well, there's no need for a "dev" stage, as the same version
will be released with only minor doc updates, and strings like "x.yrcz.dev"
confuse some version number parsing tools.
* Do not do step #22 or later, as those are tasks for an actual release.
* Do not do step #26 or later, as those are tasks for an actual release.