mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	Backport fix for bug #1643943.
This commit is contained in:
		
							parent
							
								
									817b489422
								
							
						
					
					
						commit
						6d8e5ad09d
					
				
					 3 changed files with 36 additions and 31 deletions
				
			
		| 
						 | 
					@ -273,6 +273,27 @@ _TimeRE_cache = TimeRE()
 | 
				
			||||||
_CACHE_MAX_SIZE = 5 # Max number of regexes stored in _regex_cache
 | 
					_CACHE_MAX_SIZE = 5 # Max number of regexes stored in _regex_cache
 | 
				
			||||||
_regex_cache = {}
 | 
					_regex_cache = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon):
 | 
				
			||||||
 | 
					    """Calculate the Julian day based on the year, week of the year, and day of
 | 
				
			||||||
 | 
					    the week, with week_start_day representing whether the week of the year
 | 
				
			||||||
 | 
					    assumes the week starts on Sunday or Monday (6 or 0)."""
 | 
				
			||||||
 | 
					    first_weekday = datetime_date(year, 1, 1).weekday()
 | 
				
			||||||
 | 
					    # If we are dealing with the %U directive (week starts on Sunday), it's
 | 
				
			||||||
 | 
					    # easier to just shift the view to Sunday being the first day of the
 | 
				
			||||||
 | 
					    # week.
 | 
				
			||||||
 | 
					    if not week_starts_Mon:
 | 
				
			||||||
 | 
					        first_weekday = (first_weekday + 1) % 7
 | 
				
			||||||
 | 
					        day_of_week = (day_of_week + 1) % 7
 | 
				
			||||||
 | 
					    # Need to watch out for a week 0 (when the first day of the year is not
 | 
				
			||||||
 | 
					    # the same as that specified by %U or %W).
 | 
				
			||||||
 | 
					    week_0_length = (7 - first_weekday) % 7
 | 
				
			||||||
 | 
					    if week_of_year == 0:
 | 
				
			||||||
 | 
					        return 1 + day_of_week - first_weekday
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        days_to_week = week_0_length + (7 * (week_of_year - 1))
 | 
				
			||||||
 | 
					        return 1 + days_to_week + day_of_week
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
 | 
					def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
 | 
				
			||||||
    """Return a time struct based on the input string and the format string."""
 | 
					    """Return a time struct based on the input string and the format string."""
 | 
				
			||||||
    global _TimeRE_cache, _regex_cache
 | 
					    global _TimeRE_cache, _regex_cache
 | 
				
			||||||
| 
						 | 
					@ -385,10 +406,10 @@ def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
 | 
				
			||||||
        elif group_key in ('U', 'W'):
 | 
					        elif group_key in ('U', 'W'):
 | 
				
			||||||
            week_of_year = int(found_dict[group_key])
 | 
					            week_of_year = int(found_dict[group_key])
 | 
				
			||||||
            if group_key == 'U':
 | 
					            if group_key == 'U':
 | 
				
			||||||
                # U starts week on Sunday
 | 
					                # U starts week on Sunday.
 | 
				
			||||||
                week_of_year_start = 6
 | 
					                week_of_year_start = 6
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                # W starts week on Monday
 | 
					                # W starts week on Monday.
 | 
				
			||||||
                week_of_year_start = 0
 | 
					                week_of_year_start = 0
 | 
				
			||||||
        elif group_key == 'Z':
 | 
					        elif group_key == 'Z':
 | 
				
			||||||
            # Since -1 is default value only need to worry about setting tz if
 | 
					            # Since -1 is default value only need to worry about setting tz if
 | 
				
			||||||
| 
						 | 
					@ -406,42 +427,20 @@ def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
 | 
				
			||||||
                        tz = value
 | 
					                        tz = value
 | 
				
			||||||
                        break
 | 
					                        break
 | 
				
			||||||
    # If we know the week of the year and what day of that week, we can figure
 | 
					    # If we know the week of the year and what day of that week, we can figure
 | 
				
			||||||
    # out the Julian day of the year
 | 
					    # out the Julian day of the year.
 | 
				
			||||||
    # Calculations below assume 0 is a Monday
 | 
					 | 
				
			||||||
    if julian == -1 and week_of_year != -1 and weekday != -1:
 | 
					    if julian == -1 and week_of_year != -1 and weekday != -1:
 | 
				
			||||||
        # Calculate how many days in week 0
 | 
					        week_starts_Mon = True if week_of_year_start == 0 else False
 | 
				
			||||||
        first_weekday = datetime_date(year, 1, 1).weekday()
 | 
					        julian = _calc_julian_from_U_or_W(year, week_of_year, weekday,
 | 
				
			||||||
        preceeding_days = 7 - first_weekday
 | 
					                                            week_starts_Mon)
 | 
				
			||||||
        if preceeding_days == 7:
 | 
					 | 
				
			||||||
            preceeding_days = 0
 | 
					 | 
				
			||||||
        # Adjust for U directive so that calculations are not dependent on
 | 
					 | 
				
			||||||
        # directive used to figure out week of year
 | 
					 | 
				
			||||||
        if weekday == 6 and week_of_year_start == 6:
 | 
					 | 
				
			||||||
            week_of_year -= 1
 | 
					 | 
				
			||||||
        # If a year starts and ends on a Monday but a week is specified to
 | 
					 | 
				
			||||||
        # start on a Sunday we need to up the week to counter-balance the fact
 | 
					 | 
				
			||||||
        # that with %W that first Monday starts week 1 while with %U that is
 | 
					 | 
				
			||||||
        # week 0 and thus shifts everything by a week
 | 
					 | 
				
			||||||
        if weekday == 0 and first_weekday == 0 and week_of_year_start == 6:
 | 
					 | 
				
			||||||
            week_of_year += 1
 | 
					 | 
				
			||||||
        # If in week 0, then just figure out how many days from Jan 1 to day of
 | 
					 | 
				
			||||||
        # week specified, else calculate by multiplying week of year by 7,
 | 
					 | 
				
			||||||
        # adding in days in week 0, and the number of days from Monday to the
 | 
					 | 
				
			||||||
        # day of the week
 | 
					 | 
				
			||||||
        if week_of_year == 0:
 | 
					 | 
				
			||||||
            julian = 1 + weekday - first_weekday
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            days_to_week = preceeding_days + (7 * (week_of_year - 1))
 | 
					 | 
				
			||||||
            julian = 1 + days_to_week + weekday
 | 
					 | 
				
			||||||
    # Cannot pre-calculate datetime_date() since can change in Julian
 | 
					    # Cannot pre-calculate datetime_date() since can change in Julian
 | 
				
			||||||
    #calculation and thus could have different value for the day of the week
 | 
					    # calculation and thus could have different value for the day of the week
 | 
				
			||||||
    #calculation
 | 
					    # calculation.
 | 
				
			||||||
    if julian == -1:
 | 
					    if julian == -1:
 | 
				
			||||||
        # Need to add 1 to result since first day of the year is 1, not 0.
 | 
					        # Need to add 1 to result since first day of the year is 1, not 0.
 | 
				
			||||||
        julian = datetime_date(year, month, day).toordinal() - \
 | 
					        julian = datetime_date(year, month, day).toordinal() - \
 | 
				
			||||||
                  datetime_date(year, 1, 1).toordinal() + 1
 | 
					                  datetime_date(year, 1, 1).toordinal() + 1
 | 
				
			||||||
    else:  # Assume that if they bothered to include Julian day it will
 | 
					    else:  # Assume that if they bothered to include Julian day it will
 | 
				
			||||||
           #be accurate
 | 
					           # be accurate.
 | 
				
			||||||
        datetime_result = datetime_date.fromordinal((julian - 1) + datetime_date(year, 1, 1).toordinal())
 | 
					        datetime_result = datetime_date.fromordinal((julian - 1) + datetime_date(year, 1, 1).toordinal())
 | 
				
			||||||
        year = datetime_result.year
 | 
					        year = datetime_result.year
 | 
				
			||||||
        month = datetime_result.month
 | 
					        month = datetime_result.month
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -463,6 +463,10 @@ class CalculationTests(unittest.TestCase):
 | 
				
			||||||
                                        "of the year")
 | 
					                                        "of the year")
 | 
				
			||||||
        test_helper((1917, 12, 31), "Dec 31 on Monday with year starting and "
 | 
					        test_helper((1917, 12, 31), "Dec 31 on Monday with year starting and "
 | 
				
			||||||
                                        "ending on Monday")
 | 
					                                        "ending on Monday")
 | 
				
			||||||
 | 
					        test_helper((2007, 01, 07), "First Sunday of 2007")
 | 
				
			||||||
 | 
					        test_helper((2007, 01, 14), "Second Sunday of 2007")
 | 
				
			||||||
 | 
					        test_helper((2006, 12, 31), "Last Sunday of 2006")
 | 
				
			||||||
 | 
					        test_helper((2006, 12, 24), "Second to last Sunday of 2006")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CacheTests(unittest.TestCase):
 | 
					class CacheTests(unittest.TestCase):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -154,6 +154,8 @@ Extension Modules
 | 
				
			||||||
Library
 | 
					Library
 | 
				
			||||||
-------
 | 
					-------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Bug #1643943: Fix %U handling for time.strptime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Patch #1643874: memory leak in ctypes fixed.
 | 
					- Patch #1643874: memory leak in ctypes fixed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Bug #1598181: Avoid O(N**2) bottleneck in subprocess communicate(). 
 | 
					- Bug #1598181: Avoid O(N**2) bottleneck in subprocess communicate(). 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue