Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Semiprime 4.x issue518 #529

Merged
merged 10 commits into from
Sep 6, 2023
83 changes: 71 additions & 12 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,31 @@ on:
workflow_dispatch:

jobs:
build:
run-tests:
strategy:
matrix:
config:
# [Python version, tox env, OS ]
# see for version: https://github.com/raw/actions/python-versions/main/versions-manifest.json
# see for runners: https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
- ["2.7", "py27", "ubuntu-latest"]
- ["pypy-2.7", "pypy", "ubuntu-latest"]
- ["3.4.10", "py34", "ubuntu-18.04"]
- ["3.5.10", "py35", "ubuntu-latest"]
- ["3.6", "py36", "ubuntu-latest"]
- ["3.7", "py37", "ubuntu-latest"]
- ["3.8", "py38", "ubuntu-latest"]
# If you change this, maybe you need to change the coverage version.
# - ["2.7", "py27", "ubuntu-22.04"]
- ["pypy2.7", "pypy", "ubuntu-22.04"]
# - ["3.4.10", "py34", "ubuntu-18.04"] # there seem to be no 18.04 runners any more
- ["3.5.10", "py35", "ubuntu-20.04"]
- ["3.6.15", "py36", "ubuntu-20.04"]
- ["3.7.17", "py37", "ubuntu-22.04"]
- ["3.8.18", "py38", "ubuntu-latest"]
- ["3.9", "py39", "ubuntu-latest"]
- ["3.10", "py310", "ubuntu-latest"]
- ["pypy3", "pypy3", "ubuntu-latest"]
- ["pypy3.9", "pypy3", "ubuntu-latest"]

runs-on: ${{ matrix.config[2] }}
name: ${{ matrix.config[1] }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.config[0] }}
- name: Pip cache
Expand All @@ -50,9 +51,67 @@ jobs:
- name: Test
run: tox -e ${{ matrix.config[1] }}
- name: Coverage
if: matrix.config[0] != '2.7' && matrix.config[0] != 'pypy-2.7' && matrix.config[0] != '3.4.10'
if: matrix.config[0] != '2.7' && matrix.config[0] != 'pypy2.7' && matrix.config[0] != '3.4.10'
run: |
pip install coveralls coverage-python-version
coveralls --service=github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

deploy-tag-to-pypi:
# only deploy on tags, see https://stackoverflow.com/a/58478262/1320237
if: startsWith(github.ref, 'refs/tags/v')
needs:
- run-tests
runs-on: ubuntu-latest
# This environment stores the TWINE_USERNAME and TWINE_PASSWORD
# see https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment
environment:
name: PyPI
url: https://pypi.org/project/icalendar/
# after using the environment, we need to make the secrets available
# see https://docs.github.com/en/actions/security-guides/encrypted-secrets#example-using-bash
env:
TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }}
TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }}
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.9"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install wheel twine
- name: Check the tag
run: |
PACKAGE_VERSION=`python setup.py --version`
TAG_NAME=v$PACKAGE_VERSION
echo "Package version $PACKAGE_VERSION with possible tag name $TAG_NAME on $GITHUB_REF_NAME"
# test that the tag represents the version
# see https://docs.github.com/en/actions/learn-github-actions/environment-variables
if [ "$TAG_NAME" != "$GITHUB_REF_NAME" ]; then
echo "ERROR: This tag is for the wrong version. Got \"$GITHUB_REF_NAME\" expected \"$TAG_NAME\"."
exit 1
fi
- name: remove old files
run: rm -rf dist/*
- name: build distribution files
run: python setup.py bdist_wheel sdist
- name: deploy to pypi
run: |
# You will have to set the variables TWINE_USERNAME and TWINE_PASSWORD
# You can use a token specific to your project by setting the user name to
# __token__ and the password to the token given to you by the PyPI project.
# sources:
# - https://shambu2k.hashnode.dev/gitlab-to-pypi
# - http://blog.octomy.org/2020/11/deploying-python-pacakges-to-pypi-using.html?m=1
if [ -z "$TWINE_USERNAME" ]; then
echo "WARNING: TWINE_USERNAME not set!"
fi
if [ -z "$TWINE_PASSWORD" ]; then
echo "WARNING: TWINE_PASSWORD not set!"
fi
twine check dist/*
twine upload dist/*
4 changes: 3 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ Changelog
4.1.1 (unreleased)
------------------

- Nothing changed yet.
Bug fixes:

- to_ical() now accepts RRULE BYDAY values>=10 (Issue #518)


4.1.0 (2022-07-11)
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ files.
:Code: https://github.com/collective/icalendar
:Mailing list: https://github.com/collective/icalendar/issues
:Dependencies: `python-dateutil`_ and `pytz`_.
:Compatible with: Python 2.7 and 3.4+
:Compatible with: Python 2.7 & 3.4 untested; 3.5+, Pypy2 and Pypy3 tested
:License: `BSD`_

----
Expand Down
1 change: 1 addition & 0 deletions docs/credits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ icalendar contributors
- Clive Stevens <clivest2@gmail.com>
- Dalton Durst <github@daltondur.st>
- Kamil Mańkowski <kam193@wp.pl>
- Matt Lewis <git@semiprime.com>

Find out who contributed::

Expand Down
2 changes: 1 addition & 1 deletion src/icalendar/prop.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
WEEKS_PART = r'(\d+)W'
DURATION_REGEX = re.compile(r'([-+]?)P(?:%s|%s)$'
% (WEEKS_PART, DATETIME_PART))
WEEKDAY_RULE = re.compile(r'(?P<signal>[+-]?)(?P<relative>[\d]?)'
WEEKDAY_RULE = re.compile(r'(?P<signal>[+-]?)(?P<relative>[\d]{0,2})'
r'(?P<weekday>[\w]{2})$')


Expand Down
38 changes: 38 additions & 0 deletions src/icalendar/tests/test_recurrence.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,41 @@ def test_recurrence_exdates_multiple_lines(self):
self.assertEqual(exdate[0].to_ical(), b'20120529T100000')

# TODO: test for embedded timezone information!

def test_byday_to_ical(self):
'Test the BYDAY rule is correctly processed by to_ical().'
TEST_CASES = (
# Test some YEARLY BYDAY repeats
('YEARLY', '1SU', datetime.date(2016,1,3), # 1st Sunday in year
b'BEGIN:VEVENT\r\nSUMMARY:Event YEARLY 1SU\r\nDTSTART;VALUE=DATE:20160103\r\nRRULE:FREQ=YEARLY;BYDAY=1SU\r\nEND:VEVENT\r\n'),
('YEARLY', '53MO', datetime.date(1984,12,31), # 53rd Mon in (leap) year
b'BEGIN:VEVENT\r\nSUMMARY:Event YEARLY 53MO\r\nDTSTART;VALUE=DATE:19841231\r\nRRULE:FREQ=YEARLY;BYDAY=53MO\r\nEND:VEVENT\r\n'),
('YEARLY', '-1TU', datetime.date(1999,12,28), # Last Tues in year
b'BEGIN:VEVENT\r\nSUMMARY:Event YEARLY -1TU\r\nDTSTART;VALUE=DATE:19991228\r\nRRULE:FREQ=YEARLY;BYDAY=-1TU\r\nEND:VEVENT\r\n'),
('YEARLY', '-17WE', datetime.date(2000,9,6), # 17th-last Wed in year
b'BEGIN:VEVENT\r\nSUMMARY:Event YEARLY -17WE\r\nDTSTART;VALUE=DATE:20000906\r\nRRULE:FREQ=YEARLY;BYDAY=-17WE\r\nEND:VEVENT\r\n'),
# Test some MONTHLY BYDAY repeats
('MONTHLY', '2TH', datetime.date(2003,4,10), # 2nd Thurs in month
b'BEGIN:VEVENT\r\nSUMMARY:Event MONTHLY 2TH\r\nDTSTART;VALUE=DATE:20030410\r\nRRULE:FREQ=MONTHLY;BYDAY=2TH\r\nEND:VEVENT\r\n'),
('MONTHLY', '-3FR', datetime.date(2017,5,12), # 3rd-last Fri in month
b'BEGIN:VEVENT\r\nSUMMARY:Event MONTHLY -3FR\r\nDTSTART;VALUE=DATE:20170512\r\nRRULE:FREQ=MONTHLY;BYDAY=-3FR\r\nEND:VEVENT\r\n'),
('MONTHLY', '-5SA', datetime.date(2053,11,1), # 5th-last Sat in month
b'BEGIN:VEVENT\r\nSUMMARY:Event MONTHLY -5SA\r\nDTSTART;VALUE=DATE:20531101\r\nRRULE:FREQ=MONTHLY;BYDAY=-5SA\r\nEND:VEVENT\r\n'),
# Specifically test examples from the report of Issue #518
# https://github.com/collective/icalendar/issues/518
('YEARLY', '9MO', datetime.date(2023,2,27), # 9th Monday in year
b'BEGIN:VEVENT\r\nSUMMARY:Event YEARLY 9MO\r\nDTSTART;VALUE=DATE:20230227\r\nRRULE:FREQ=YEARLY;BYDAY=9MO\r\nEND:VEVENT\r\n'),
('YEARLY', '10MO', datetime.date(2023,3,6), # 10th Monday in year
b'BEGIN:VEVENT\r\nSUMMARY:Event YEARLY 10MO\r\nDTSTART;VALUE=DATE:20230306\r\nRRULE:FREQ=YEARLY;BYDAY=10MO\r\nEND:VEVENT\r\n'),
)
for c in TEST_CASES:
self._dotest_byday_to_ical(*c)

def _dotest_byday_to_ical(self, freq, byday, dtstart, expected):
'Called by test_byday_to_ical() with various parameters'
event = icalendar.Event()
event.add('SUMMARY', ' '.join(['Event', freq, byday]))
event.add('DTSTART', dtstart)
event.add('RRULE', {'FREQ':[freq], 'BYDAY':byday})
ical = event.to_ical()
self.assertEqual(ical, expected)
Loading