-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Fix Formatting Errors on black-primer CI #1446
Labels
Comments
pytest is the same as #1452, here's the relevant snippet from class TestTeeStdCapture(TestStdCapture):
captureclass = staticmethod(TeeStdCapture)
def test_capturing_error_recursive(self):
""" for TeeStdCapture since we passthrough stderr/stdout, cap1
should get all output, while cap2 should only get "cap2\n" """
with self.getcapture() as cap1:
print("cap1")
with self.getcapture() as cap2:
print("cap2")
out2, err2 = cap2.readouterr()
out1, err1 = cap1.readouterr()
assert out1 == "cap1\ncap2\n"
assert out2 == "cap2\n"
|
pandas has 3 errors: 1
--- src
+++ dst
@@ -7269,11 +7269,11 @@
body=
Expr(
value=
Constant(
value=
- 'Convert argument to datetime.\n\n Parameters\n ----------\n arg : int, float, str, datetime, list, tuple, 1-d array, Series, DataFrame/dict-like\n The object to convert to a datetime.\n errors : {\'ignore\', \'raise\', \'coerce\'}, default \'raise\'\n - If \'raise\', then invalid parsing will raise an exception.\n - If \'coerce\', then invalid parsing will be set as NaT.\n - If \'ignore\', then invalid parsing will return the input.\n dayfirst : bool, default False\n Specify a date parse order if `arg` is str or its list-likes.\n If True, parses dates with the day first, eg 10/11/12 is parsed as\n 2012-11-10.\n Warning: dayfirst=True is not strict, but will prefer to parse\n with day first (this is a known bug, based on dateutil behavior).\n yearfirst : bool, default False\n Specify a date parse order if `arg` is str or its list-likes.\n\n - If True parses dates with the year first, eg 10/11/12 is parsed as\n 2010-11-12.\n - If both dayfirst and yearfirst are True, yearfirst is preceded (same\n as dateutil).\n\n Warning: yearfirst=True is not strict, but will prefer to parse\n with year first (this is a known bug, based on dateutil behavior).\n utc : bool, default None\n Return UTC DatetimeIndex if True (converting any tz-aware\n datetime.datetime objects as well).\n format : str, default None\n The strftime to parse time, eg "%d/%m/%Y", note that "%f" will parse\n all the way up to nanoseconds.\n See strftime documentation for more information on choices:\n https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior.\n exact : bool, True by default\n Behaves as:\n - If True, require an exact format match.\n - If False, allow the format to match anywhere in the target string.\n\n unit : str, default \'ns\'\n The unit of the arg (D,s,ms,us,ns) denote the unit, which is an\n integer or float number. This will be based off the origin.\n Example, with unit=\'ms\' and origin=\'unix\' (the default), this\n would calculate the number of milliseconds to the unix epoch start.\n infer_datetime_format : bool, default False\n If True and no `format` is given, attempt to infer the format of the\n datetime strings based on the first non-NaN element,\n and if it can be inferred, switch to a faster method of parsing them.\n In some cases this can increase the parsing speed by ~5-10x.\n origin : scalar, default \'unix\'\n Define the reference date. The numeric values would be parsed as number\n of units (defined by `unit`) since this reference date.\n\n - If \'unix\' (or POSIX) time; origin is set to 1970-01-01.\n - If \'julian\', unit must be \'D\', and origin is set to beginning of\n Julian Calendar. Julian day number 0 is assigned to the day starting\n at noon on January 1, 4713 BC.\n - If Timestamp convertible, origin is set to Timestamp identified by\n origin.\n cache : bool, default True\n If True, use a cache of unique, converted dates to apply the datetime\n conversion. May produce significant speed-up when parsing duplicate\n date strings, especially ones with timezone offsets. The cache is only\n used when there are at least 50 values. The presence of out-of-bounds\n values will render the cache unusable and may slow down parsing.\n\n .. versionadded:: 0.23.0\n\n .. versionchanged:: 0.25.0\n - changed default value from False to True.\n\n Returns\n -------\n datetime\n If parsing succeeded.\n Return type depends on input:\n\n - list-like: DatetimeIndex\n - Series: Series of datetime64 dtype\n - scalar: Timestamp\n\n In case when it is not possible to return designated types (e.g. when\n any element of input is before Timestamp.min or after Timestamp.max)\n return will have datetime.datetime type (or corresponding\n array/Series).\n\n See Also\n --------\n DataFrame.astype : Cast argument to a specified dtype.\n to_timedelta : Convert argument to timedelta.\n convert_dtypes : Convert dtypes.\n\n Examples\n --------\n Assembling a datetime from multiple columns of a DataFrame. The keys can be\n common abbreviations like [\'year\', \'month\', \'day\', \'minute\', \'second\',\n \'ms\', \'us\', \'ns\']) or plurals of the same\n\n >>> df = pd.DataFrame({\'year\': [2015, 2016],\n ... \'month\': [2, 3],\n ... \'day\': [4, 5]})\n >>> pd.to_datetime(df)\n 0 2015-02-04\n 1 2016-03-05\n dtype: datetime64[ns]\n\n If a date does not meet the `timestamp limitations\n <https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html\n #timeseries-timestamp-limits>`_, passing errors=\'ignore\'\n will return the original input instead of raising any exception.\n\n Passing errors=\'coerce\' will force an out-of-bounds date to NaT,\n in addition to forcing non-dates (or non-parseable dates) to NaT.\n\n >>> pd.to_datetime(\'13000101\', format=\'%Y%m%d\', errors=\'ignore\')\n datetime.datetime(1300, 1, 1, 0, 0)\n >>> pd.to_datetime(\'13000101\', format=\'%Y%m%d\', errors=\'coerce\')\n NaT\n\n Passing infer_datetime_format=True can often-times speedup a parsing\n if its not an ISO8601 format exactly, but in a regular format.\n\n >>> s = pd.Series([\'3/11/2000\', \'3/12/2000\', \'3/13/2000\'] * 1000)\n >>> s.head()\n 0 3/11/2000\n 1 3/12/2000\n 2 3/13/2000\n 3 3/11/2000\n 4 3/12/2000\n dtype: object\n\n >>> %timeit pd.to_datetime(s, infer_datetime_format=True) # doctest: +SKIP\n 100 loops, best of 3: 10.4 ms per loop\n\n >>> %timeit pd.to_datetime(s, infer_datetime_format=False) # doctest: +SKIP\n 1 loop, best of 3: 471 ms per loop\n\n Using a unix epoch time\n\n >>> pd.to_datetime(1490195805, unit=\'s\')\n Timestamp(\'2017-03-22 15:16:45\')\n >>> pd.to_datetime(1490195805433502912, unit=\'ns\')\n Timestamp(\'2017-03-22 15:16:45.433502912\')\n\n .. warning:: For float arg, precision rounding might happen. To prevent\n unexpected behavior use a fixed-width exact type.\n\n Using a non-unix epoch origin\n\n >>> pd.to_datetime([1, 2, 3], unit=\'D\',\n ... origin=pd.Timestamp(\'1960-01-01\'))\n DatetimeIndex([\'1960-01-02\', \'1960-01-03\', \'1960-01-04\'], dtype=\'datetime64[ns]\', freq=None)', # str
+ 'Convert argument to datetime.\n\n Parameters\n ----------\n arg : int, float, str, datetime, list, tuple, 1-d array, Series, DataFrame/dict-like\n The object to convert to a datetime.\n errors : {\'ignore\', \'raise\', \'coerce\'}, default \'raise\'\n - If \'raise\', then invalid parsing will raise an exception.\n - If \'coerce\', then invalid parsing will be set as NaT.\n - If \'ignore\', then invalid parsing will return the input.\n dayfirst : bool, default False\n Specify a date parse order if `arg` is str or its list-likes.\n If True, parses dates with the day first, eg 10/11/12 is parsed as\n 2012-11-10.\n Warning: dayfirst=True is not strict, but will prefer to parse\n with day first (this is a known bug, based on dateutil behavior).\n yearfirst : bool, default False\n Specify a date parse order if `arg` is str or its list-likes.\n\n - If True parses dates with the year first, eg 10/11/12 is parsed as\n 2010-11-12.\n - If both dayfirst and yearfirst are True, yearfirst is preceded (same\n as dateutil).\n\n Warning: yearfirst=True is not strict, but will prefer to parse\n with year first (this is a known bug, based on dateutil behavior).\n utc : bool, default None\n Return UTC DatetimeIndex if True (converting any tz-aware\n datetime.datetime objects as well).\n format : str, default None\n The strftime to parse time, eg "%d/%m/%Y", note that "%f" will parse\n all the way up to nanoseconds.\n See strftime documentation for more information on choices:\n https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior.\n exact : bool, True by default\n Behaves as:\n - If True, require an exact format match.\n - If False, allow the format to match anywhere in the target string.\n\n unit : str, default \'ns\'\n The unit of the arg (D,s,ms,us,ns) denote the unit, which is an\n integer or float number. This will be based off the origin.\n Example, with unit=\'ms\' and origin=\'unix\' (the default), this\n would calculate the number of milliseconds to the unix epoch start.\n infer_datetime_format : bool, default False\n If True and no `format` is given, attempt to infer the format of the\n datetime strings based on the first non-NaN element,\n and if it can be inferred, switch to a faster method of parsing them.\n In some cases this can increase the parsing speed by ~5-10x.\n origin : scalar, default \'unix\'\n Define the reference date. The numeric values would be parsed as number\n of units (defined by `unit`) since this reference date.\n\n - If \'unix\' (or POSIX) time; origin is set to 1970-01-01.\n - If \'julian\', unit must be \'D\', and origin is set to beginning of\n Julian Calendar. Julian day number 0 is assigned to the day starting\n at noon on January 1, 4713 BC.\n - If Timestamp convertible, origin is set to Timestamp identified by\n origin.\n cache : bool, default True\n If True, use a cache of unique, converted dates to apply the datetime\n conversion. May produce significant speed-up when parsing duplicate\n date strings, especially ones with timezone offsets. The cache is only\n used when there are at least 50 values. The presence of out-of-bounds\n values will render the cache unusable and may slow down parsing.\n\n .. versionadded:: 0.23.0\n\n .. versionchanged:: 0.25.0\n - changed default value from False to True.\n\n Returns\n -------\n datetime\n If parsing succeeded.\n Return type depends on input:\n\n - list-like: DatetimeIndex\n - Series: Series of datetime64 dtype\n - scalar: Timestamp\n\n In case when it is not possible to return designated types (e.g. when\n any element of input is before Timestamp.min or after Timestamp.max)\n return will have datetime.datetime type (or corresponding\n array/Series).\n\n See Also\n --------\n DataFrame.astype : Cast argument to a specified dtype.\n to_timedelta : Convert argument to timedelta.\n convert_dtypes : Convert dtypes.\n\n Examples\n --------\n Assembling a datetime from multiple columns of a DataFrame. The keys can be\n common abbreviations like [\'year\', \'month\', \'day\', \'minute\', \'second\',\n \'ms\', \'us\', \'ns\']) or plurals of the same\n\n >>> df = pd.DataFrame({\'year\': [2015, 2016],\n ... \'month\': [2, 3],\n ... \'day\': [4, 5]})\n >>> pd.to_datetime(df)\n 0 2015-02-04\n 1 2016-03-05\n dtype: datetime64[ns]\n\n If a date does not meet the `timestamp limitations\n <https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html\n #timeseries-timestamp-limits>`_, passing errors=\'ignore\'\n will return the original input instead of raising any exception.\n\n Passing errors=\'coerce\' will force an out-of-bounds date to NaT,\n in addition to forcing non-dates (or non-parseable dates) to NaT.\n\n >>> pd.to_datetime(\'13000101\', format=\'%Y%m%d\', errors=\'ignore\')\n datetime.datetime(1300, 1, 1, 0, 0)\n >>> pd.to_datetime(\'13000101\', format=\'%Y%m%d\', errors=\'coerce\')\n NaT\n\n Passing infer_datetime_format=True can often-times speedup a parsing\n if its not an ISO8601 format exactly, but in a regular format.\n\n >>> s = pd.Series([\'3/11/2000\', \'3/12/2000\', \'3/13/2000\'] * 1000)\n >>> s.head()\n 0 3/11/2000\n 1 3/12/2000\n 2 3/13/2000\n 3 3/11/2000\n 4 3/12/2000\n dtype: object\n\n >>> %timeit pd.to_datetime(s, infer_datetime_format=True) # doctest: +SKIP\n 100 loops, best of 3: 10.4 ms per loop\n\n >>> %timeit pd.to_datetime(s, infer_datetime_format=False) # doctest: +SKIP\n 1 loop, best of 3: 471 ms per loop\n\n Using a unix epoch time\n\n >>> pd.to_datetime(1490195805, unit=\'s\')\n Timestamp(\'2017-03-22 15:16:45\')\n >>> pd.to_datetime(1490195805433502912, unit=\'ns\')\n Timestamp(\'2017-03-22 15:16:45.433502912\')\n\n .. warning:: For float arg, precision rounding might happen. To prevent\n unexpected behavior use a fixed-width exact type.\n\n Using a non-unix epoch origin\n\n >>> pd.to_datetime([1, 2, 3], unit=\'D\',\n ... origin=pd.Timestamp(\'1960-01-01\'))\n DatetimeIndex([\'1960-01-02\', \'1960-01-03\', \'1960-01-04\'], dtype=\'datetime64[ns]\', freq=None)', # str
) # /Constant
) # /Expr
If(
body=
Return( 2
--- src
+++ dst
@@ -12384,11 +12384,11 @@
body=
Expr(
value=
Constant(
value=
- "Localize tz-naive Datetime Array/Index to tz-aware\n Datetime Array/Index.\n\n This method takes a time zone (tz) naive Datetime Array/Index object\n and makes this time zone aware. It does not move the time to another\n time zone.\n Time zone localization helps to switch from time zone aware to time\n zone unaware objects.\n\n Parameters\n ----------\n tz : str, pytz.timezone, dateutil.tz.tzfile or None\n Time zone to convert timestamps to. Passing ``None`` will\n remove the time zone information preserving local time.\n ambiguous : 'infer', 'NaT', bool array, default 'raise'\n When clocks moved backward due to DST, ambiguous times may arise.\n For example in Central European Time (UTC+01), when going from\n 03:00 DST to 02:00 non-DST, 02:30:00 local time occurs both at\n 00:30:00 UTC and at 01:30:00 UTC. In such a situation, the\n `ambiguous` parameter dictates how ambiguous times should be\n handled.\n\n - 'infer' will attempt to infer fall dst-transition hours based on\n order\n - bool-ndarray where True signifies a DST time, False signifies a\n non-DST time (note that this flag is only applicable for\n ambiguous times)\n - 'NaT' will return NaT where there are ambiguous times\n - 'raise' will raise an AmbiguousTimeError if there are ambiguous\n times.\n\n nonexistent : 'shift_forward', 'shift_backward, 'NaT', timedelta, default 'raise'\n A nonexistent time does not exist in a particular timezone\n where clocks moved forward due to DST.\n\n - 'shift_forward' will shift the nonexistent time forward to the\n closest existing time\n - 'shift_backward' will shift the nonexistent time backward to the\n closest existing time\n - 'NaT' will return NaT where there are nonexistent times\n - timedelta objects will shift nonexistent times by the timedelta\n - 'raise' will raise an NonExistentTimeError if there are\n nonexistent times.\n\n .. versionadded:: 0.24.0\n\n Returns\n -------\n Same type as self\n Array/Index converted to the specified time zone.\n\n Raises\n ------\n TypeError\n If the Datetime Array/Index is tz-aware and tz is not None.\n\n See Also\n --------\n DatetimeIndex.tz_convert : Convert tz-aware DatetimeIndex from\n one time zone to another.\n\n Examples\n --------\n >>> tz_naive = pd.date_range('2018-03-01 09:00', periods=3)\n >>> tz_naive\n DatetimeIndex(['2018-03-01 09:00:00', '2018-03-02 09:00:00',\n '2018-03-03 09:00:00'],\n dtype='datetime64[ns]', freq='D')\n\n Localize DatetimeIndex in US/Eastern time zone:\n\n >>> tz_aware = tz_naive.tz_localize(tz='US/Eastern')\n >>> tz_aware\n DatetimeIndex(['2018-03-01 09:00:00-05:00',\n '2018-03-02 09:00:00-05:00',\n '2018-03-03 09:00:00-05:00'],\n dtype='datetime64[ns, US/Eastern]', freq=None)\n\n With the ``tz=None``, we can remove the time zone information\n while keeping the local time (not converted to UTC):\n\n >>> tz_aware.tz_localize(None)\n DatetimeIndex(['2018-03-01 09:00:00', '2018-03-02 09:00:00',\n '2018-03-03 09:00:00'],\n dtype='datetime64[ns]', freq=None)\n\n Be careful with DST changes. When there is sequential data, pandas can\n infer the DST time:\n\n >>> s = pd.to_datetime(pd.Series(['2018-10-28 01:30:00',\n ... '2018-10-28 02:00:00',\n ... '2018-10-28 02:30:00',\n ... '2018-10-28 02:00:00',\n ... '2018-10-28 02:30:00',\n ... '2018-10-28 03:00:00',\n ... '2018-10-28 03:30:00']))\n >>> s.dt.tz_localize('CET', ambiguous='infer')\n 0 2018-10-28 01:30:00+02:00\n 1 2018-10-28 02:00:00+02:00\n 2 2018-10-28 02:30:00+02:00\n 3 2018-10-28 02:00:00+01:00\n 4 2018-10-28 02:30:00+01:00\n 5 2018-10-28 03:00:00+01:00\n 6 2018-10-28 03:30:00+01:00\n dtype: datetime64[ns, CET]\n\n In some cases, inferring the DST is impossible. In such cases, you can\n pass an ndarray to the ambiguous parameter to set the DST explicitly\n\n >>> s = pd.to_datetime(pd.Series(['2018-10-28 01:20:00',\n ... '2018-10-28 02:36:00',\n ... '2018-10-28 03:46:00']))\n >>> s.dt.tz_localize('CET', ambiguous=np.array([True, True, False]))\n 0 2018-10-28 01:20:00+02:00\n 1 2018-10-28 02:36:00+02:00\n 2 2018-10-28 03:46:00+01:00\n dtype: datetime64[ns, CET]\n\n If the DST transition causes nonexistent times, you can shift these\n dates forward or backwards with a timedelta object or `'shift_forward'`\n or `'shift_backwards'`.\n\n >>> s = pd.to_datetime(pd.Series(['2015-03-29 02:30:00',\n ... '2015-03-29 03:30:00']))\n >>> s.dt.tz_localize('Europe/Warsaw', nonexistent='shift_forward')\n 0 2015-03-29 03:00:00+02:00\n 1 2015-03-29 03:30:00+02:00\n dtype: datetime64[ns, Europe/Warsaw]\n\n >>> s.dt.tz_localize('Europe/Warsaw', nonexistent='shift_backward')\n 0 2015-03-29 01:59:59.999999999+01:00\n 1 2015-03-29 03:30:00+02:00\n dtype: datetime64[ns, Europe/Warsaw]\n\n >>> s.dt.tz_localize('Europe/Warsaw', nonexistent=pd.Timedelta('1H'))\n 0 2015-03-29 03:30:00+02:00\n 1 2015-03-29 03:30:00+02:00\n dtype: datetime64[ns, Europe/Warsaw]", # str
+ "Localize tz-naive Datetime Array/Index to tz-aware\n Datetime Array/Index.\n\n This method takes a time zone (tz) naive Datetime Array/Index object\n and makes this time zone aware. It does not move the time to another\n time zone.\n Time zone localization helps to switch from time zone aware to time\n zone unaware objects.\n\n Parameters\n ----------\n tz : str, pytz.timezone, dateutil.tz.tzfile or None\n Time zone to convert timestamps to. Passing ``None`` will\n remove the time zone information preserving local time.\n ambiguous : 'infer', 'NaT', bool array, default 'raise'\n When clocks moved backward due to DST, ambiguous times may arise.\n For example in Central European Time (UTC+01), when going from\n 03:00 DST to 02:00 non-DST, 02:30:00 local time occurs both at\n 00:30:00 UTC and at 01:30:00 UTC. In such a situation, the\n `ambiguous` parameter dictates how ambiguous times should be\n handled.\n\n - 'infer' will attempt to infer fall dst-transition hours based on\n order\n - bool-ndarray where True signifies a DST time, False signifies a\n non-DST time (note that this flag is only applicable for\n ambiguous times)\n - 'NaT' will return NaT where there are ambiguous times\n - 'raise' will raise an AmbiguousTimeError if there are ambiguous\n times.\n\n nonexistent : 'shift_forward', 'shift_backward, 'NaT', timedelta, default 'raise'\n A nonexistent time does not exist in a particular timezone\n where clocks moved forward due to DST.\n\n - 'shift_forward' will shift the nonexistent time forward to the\n closest existing time\n - 'shift_backward' will shift the nonexistent time backward to the\n closest existing time\n - 'NaT' will return NaT where there are nonexistent times\n - timedelta objects will shift nonexistent times by the timedelta\n - 'raise' will raise an NonExistentTimeError if there are\n nonexistent times.\n\n .. versionadded:: 0.24.0\n\n Returns\n -------\n Same type as self\n Array/Index converted to the specified time zone.\n\n Raises\n ------\n TypeError\n If the Datetime Array/Index is tz-aware and tz is not None.\n\n See Also\n --------\n DatetimeIndex.tz_convert : Convert tz-aware DatetimeIndex from\n one time zone to another.\n\n Examples\n --------\n >>> tz_naive = pd.date_range('2018-03-01 09:00', periods=3)\n >>> tz_naive\n DatetimeIndex(['2018-03-01 09:00:00', '2018-03-02 09:00:00',\n '2018-03-03 09:00:00'],\n dtype='datetime64[ns]', freq='D')\n\n Localize DatetimeIndex in US/Eastern time zone:\n\n >>> tz_aware = tz_naive.tz_localize(tz='US/Eastern')\n >>> tz_aware\n DatetimeIndex(['2018-03-01 09:00:00-05:00',\n '2018-03-02 09:00:00-05:00',\n '2018-03-03 09:00:00-05:00'],\n dtype='datetime64[ns, US/Eastern]', freq=None)\n\n With the ``tz=None``, we can remove the time zone information\n while keeping the local time (not converted to UTC):\n\n >>> tz_aware.tz_localize(None)\n DatetimeIndex(['2018-03-01 09:00:00', '2018-03-02 09:00:00',\n '2018-03-03 09:00:00'],\n dtype='datetime64[ns]', freq=None)\n\n Be careful with DST changes. When there is sequential data, pandas can\n infer the DST time:\n\n >>> s = pd.to_datetime(pd.Series(['2018-10-28 01:30:00',\n ... '2018-10-28 02:00:00',\n ... '2018-10-28 02:30:00',\n ... '2018-10-28 02:00:00',\n ... '2018-10-28 02:30:00',\n ... '2018-10-28 03:00:00',\n ... '2018-10-28 03:30:00']))\n >>> s.dt.tz_localize('CET', ambiguous='infer')\n 0 2018-10-28 01:30:00+02:00\n 1 2018-10-28 02:00:00+02:00\n 2 2018-10-28 02:30:00+02:00\n 3 2018-10-28 02:00:00+01:00\n 4 2018-10-28 02:30:00+01:00\n 5 2018-10-28 03:00:00+01:00\n 6 2018-10-28 03:30:00+01:00\n dtype: datetime64[ns, CET]\n\n In some cases, inferring the DST is impossible. In such cases, you can\n pass an ndarray to the ambiguous parameter to set the DST explicitly\n\n >>> s = pd.to_datetime(pd.Series(['2018-10-28 01:20:00',\n ... '2018-10-28 02:36:00',\n ... '2018-10-28 03:46:00']))\n >>> s.dt.tz_localize('CET', ambiguous=np.array([True, True, False]))\n 0 2018-10-28 01:20:00+02:00\n 1 2018-10-28 02:36:00+02:00\n 2 2018-10-28 03:46:00+01:00\n dtype: datetime64[ns, CET]\n\n If the DST transition causes nonexistent times, you can shift these\n dates forward or backwards with a timedelta object or `'shift_forward'`\n or `'shift_backwards'`.\n\n >>> s = pd.to_datetime(pd.Series(['2015-03-29 02:30:00',\n ... '2015-03-29 03:30:00']))\n >>> s.dt.tz_localize('Europe/Warsaw', nonexistent='shift_forward')\n 0 2015-03-29 03:00:00+02:00\n 1 2015-03-29 03:30:00+02:00\n dtype: datetime64[ns, Europe/Warsaw]\n\n >>> s.dt.tz_localize('Europe/Warsaw', nonexistent='shift_backward')\n 0 2015-03-29 01:59:59.999999999+01:00\n 1 2015-03-29 03:30:00+02:00\n dtype: datetime64[ns, Europe/Warsaw]\n\n >>> s.dt.tz_localize('Europe/Warsaw', nonexistent=pd.Timedelta('1H'))\n 0 2015-03-29 03:30:00+02:00\n 1 2015-03-29 03:30:00+02:00\n dtype: datetime64[ns, Europe/Warsaw]", # str
) # /Constant
) # /Expr
Assign(
targets=
Name( 3
--- src
+++ dst
@@ -52354,11 +52354,11 @@
body=
Expr(
value=
Constant(
value=
- 'Return the first `n` rows ordered by `columns` in ascending order.\n\n Return the first `n` rows with the smallest values in `columns`, in\n ascending order. The columns that are not specified are returned as\n well, but not used for ordering.\n\n This method is equivalent to\n ``df.sort_values(columns, ascending=True).head(n)``, but more\n performant.\n\n Parameters\n ----------\n n : int\n Number of items to retrieve.\n columns : list or str\n Column name or names to order by.\n keep : {\'first\', \'last\', \'all\'}, default \'first\'\n Where there are duplicate values:\n\n - ``first`` : take the first occurrence.\n - ``last`` : take the last occurrence.\n - ``all`` : do not drop any duplicates, even it means\n selecting more than `n` items.\n\n .. versionadded:: 0.24.0\n\n Returns\n -------\n DataFrame\n\n See Also\n --------\n DataFrame.nlargest : Return the first `n` rows ordered by `columns` in\n descending order.\n DataFrame.sort_values : Sort DataFrame by the values.\n DataFrame.head : Return the first `n` rows without re-ordering.\n\n Examples\n --------\n >>> df = pd.DataFrame({\'population\': [59000000, 65000000, 434000,\n ... 434000, 434000, 337000, 337000,\n ... 11300, 11300],\n ... \'GDP\': [1937894, 2583560 , 12011, 4520, 12128,\n ... 17036, 182, 38, 311],\n ... \'alpha-2\': ["IT", "FR", "MT", "MV", "BN",\n ... "IS", "NR", "TV", "AI"]},\n ... index=["Italy", "France", "Malta",\n ... "Maldives", "Brunei", "Iceland",\n ... "Nauru", "Tuvalu", "Anguilla"])\n >>> df\n population GDP alpha-2\n Italy 59000000 1937894 IT\n France 65000000 2583560 FR\n Malta 434000 12011 MT\n Maldives 434000 4520 MV\n Brunei 434000 12128 BN\n Iceland 337000 17036 IS\n Nauru 337000 182 NR\n Tuvalu 11300 38 TV\n Anguilla 11300 311 AI\n\n In the following example, we will use ``nsmallest`` to select the\n three rows having the smallest values in column "population".\n\n >>> df.nsmallest(3, \'population\')\n population GDP alpha-2\n Tuvalu 11300 38 TV\n Anguilla 11300 311 AI\n Iceland 337000 17036\t IS\n\n When using ``keep=\'last\'``, ties are resolved in reverse order:\n\n >>> df.nsmallest(3, \'population\', keep=\'last\')\n population GDP alpha-2\n Anguilla 11300 311 AI\n Tuvalu 11300 38 TV\n Nauru 337000 182 NR\n\n When using ``keep=\'all\'``, all duplicate items are maintained:\n\n >>> df.nsmallest(3, \'population\', keep=\'all\')\n population GDP alpha-2\n Tuvalu 11300 38 TV\n Anguilla 11300 311 AI\n Iceland 337000 17036 IS\n Nauru 337000 182 NR\n\n To order by the smallest values in column "population" and then "GDP", we can\n specify multiple columns like in the next example.\n\n >>> df.nsmallest(3, [\'population\', \'GDP\'])\n population GDP alpha-2\n Tuvalu 11300 38 TV\n Anguilla 11300 311 AI\n Nauru 337000 182 NR', # str
+ 'Return the first `n` rows ordered by `columns` in ascending order.\n\n Return the first `n` rows with the smallest values in `columns`, in\n ascending order. The columns that are not specified are returned as\n well, but not used for ordering.\n\n This method is equivalent to\n ``df.sort_values(columns, ascending=True).head(n)``, but more\n performant.\n\n Parameters\n ----------\n n : int\n Number of items to retrieve.\n columns : list or str\n Column name or names to order by.\n keep : {\'first\', \'last\', \'all\'}, default \'first\'\n Where there are duplicate values:\n\n - ``first`` : take the first occurrence.\n - ``last`` : take the last occurrence.\n - ``all`` : do not drop any duplicates, even it means\n selecting more than `n` items.\n\n .. versionadded:: 0.24.0\n\n Returns\n -------\n DataFrame\n\n See Also\n --------\n DataFrame.nlargest : Return the first `n` rows ordered by `columns` in\n descending order.\n DataFrame.sort_values : Sort DataFrame by the values.\n DataFrame.head : Return the first `n` rows without re-ordering.\n\n Examples\n --------\n >>> df = pd.DataFrame({\'population\': [59000000, 65000000, 434000,\n ... 434000, 434000, 337000, 337000,\n ... 11300, 11300],\n ... \'GDP\': [1937894, 2583560 , 12011, 4520, 12128,\n ... 17036, 182, 38, 311],\n ... \'alpha-2\': ["IT", "FR", "MT", "MV", "BN",\n ... "IS", "NR", "TV", "AI"]},\n ... index=["Italy", "France", "Malta",\n ... "Maldives", "Brunei", "Iceland",\n ... "Nauru", "Tuvalu", "Anguilla"])\n >>> df\n population GDP alpha-2\n Italy 59000000 1937894 IT\n France 65000000 2583560 FR\n Malta 434000 12011 MT\n Maldives 434000 4520 MV\n Brunei 434000 12128 BN\n Iceland 337000 17036 IS\n Nauru 337000 182 NR\n Tuvalu 11300 38 TV\n Anguilla 11300 311 AI\n\n In the following example, we will use ``nsmallest`` to select the\n three rows having the smallest values in column "population".\n\n >>> df.nsmallest(3, \'population\')\n population GDP alpha-2\n Tuvalu 11300 38 TV\n Anguilla 11300 311 AI\n Iceland 337000 17036 IS\n\n When using ``keep=\'last\'``, ties are resolved in reverse order:\n\n >>> df.nsmallest(3, \'population\', keep=\'last\')\n population GDP alpha-2\n Anguilla 11300 311 AI\n Tuvalu 11300 38 TV\n Nauru 337000 182 NR\n\n When using ``keep=\'all\'``, all duplicate items are maintained:\n\n >>> df.nsmallest(3, \'population\', keep=\'all\')\n population GDP alpha-2\n Tuvalu 11300 38 TV\n Anguilla 11300 311 AI\n Iceland 337000 17036 IS\n Nauru 337000 182 NR\n\n To order by the smallest values in column "population" and then "GDP", we can\n specify multiple columns like in the next example.\n\n >>> df.nsmallest(3, [\'population\', \'GDP\'])\n population GDP alpha-2\n Tuvalu 11300 38 TV\n Anguilla 11300 311 AI\n Nauru 337000 182 NR', # str
) # /Constant
) # /Expr
Return(
value=
Call( |
Django has 2 errors: 1
2
--- source
+++ first pass
@@ -8,18 +8,25 @@
from django.apps import apps
from django.conf import settings
from django.contrib.admin.models import LogEntry
from django.contrib.auth import (
- BACKEND_SESSION_KEY, HASH_SESSION_KEY, REDIRECT_FIELD_NAME, SESSION_KEY,
+ BACKEND_SESSION_KEY,
+ HASH_SESSION_KEY,
+ REDIRECT_FIELD_NAME,
+ SESSION_KEY,
)
from django.contrib.auth.forms import (
- AuthenticationForm, PasswordChangeForm, SetPasswordForm,
+ AuthenticationForm,
+ PasswordChangeForm,
+ SetPasswordForm,
)
from django.contrib.auth.models import Permission, User
from django.contrib.auth.views import (
- INTERNAL_RESET_SESSION_TOKEN, LoginView, logout_then_login,
+ INTERNAL_RESET_SESSION_TOKEN,
+ LoginView,
+ logout_then_login,
redirect_to_login,
)
from django.contrib.contenttypes.models import ContentType
from django.contrib.sessions.middleware import SessionMiddleware
from django.contrib.sites.requests import RequestSite
@@ -36,87 +43,95 @@
from .models import CustomUser, UUIDUser
from .settings import AUTH_TEMPLATES
@override_settings(
- LANGUAGES=[('en', 'English')],
- LANGUAGE_CODE='en',
+ LANGUAGES=[("en", "English")],
+ LANGUAGE_CODE="en",
TEMPLATES=AUTH_TEMPLATES,
- ROOT_URLCONF='auth_tests.urls',
+ ROOT_URLCONF="auth_tests.urls",
)
class AuthViewsTestCase(TestCase):
"""
Helper base class for all the follow test cases.
"""
@classmethod
def setUpTestData(cls):
- cls.u1 = User.objects.create_user(username='testclient', password='password', email='[email protected]')
- cls.u3 = User.objects.create_user(username='staff', password='password', email='[email protected]')
-
- def login(self, username='testclient', password='password'):
- response = self.client.post('/login/', {
- 'username': username,
- 'password': password,
- })
+ cls.u1 = User.objects.create_user(
+ username="testclient", password="password", email="[email protected]"
+ )
+ cls.u3 = User.objects.create_user(
+ username="staff", password="password", email="[email protected]"
+ )
+
+ def login(self, username="testclient", password="password"):
+ response = self.client.post(
+ "/login/", {"username": username, "password": password,}
+ )
self.assertIn(SESSION_KEY, self.client.session)
return response
def logout(self):
- response = self.client.get('/admin/logout/')
+ response = self.client.get("/admin/logout/")
self.assertEqual(response.status_code, 200)
self.assertNotIn(SESSION_KEY, self.client.session)
def assertFormError(self, response, error):
"""Assert that error is found in response.context['form'] errors"""
- form_errors = list(itertools.chain(*response.context['form'].errors.values()))
+ form_errors = list(itertools.chain(*response.context["form"].errors.values()))
self.assertIn(str(error), form_errors)
-@override_settings(ROOT_URLCONF='django.contrib.auth.urls')
+@override_settings(ROOT_URLCONF="django.contrib.auth.urls")
class AuthViewNamedURLTests(AuthViewsTestCase):
-
def test_named_urls(self):
"Named URLs should be reversible"
expected_named_urls = [
- ('login', [], {}),
- ('logout', [], {}),
- ('password_change', [], {}),
- ('password_change_done', [], {}),
- ('password_reset', [], {}),
- ('password_reset_done', [], {}),
- ('password_reset_confirm', [], {
- 'uidb64': 'aaaaaaa',
- 'token': '1111-aaaaa',
- }),
- ('password_reset_complete', [], {}),
+ ("login", [], {}),
+ ("logout", [], {}),
+ ("password_change", [], {}),
+ ("password_change_done", [], {}),
+ ("password_reset", [], {}),
+ ("password_reset_done", [], {}),
+ (
+ "password_reset_confirm",
+ [],
+ {"uidb64": "aaaaaaa", "token": "1111-aaaaa",},
+ ),
+ ("password_reset_complete", [], {}),
]
for name, args, kwargs in expected_named_urls:
with self.subTest(name=name):
try:
reverse(name, args=args, kwargs=kwargs)
except NoReverseMatch:
- self.fail("Reversal of url named '%s' failed with NoReverseMatch" % name)
+ self.fail(
+ "Reversal of url named '%s' failed with NoReverseMatch" % name
+ )
class PasswordResetTest(AuthViewsTestCase):
-
def setUp(self):
self.client = PasswordResetConfirmClient()
def test_email_not_found(self):
"""If the provided email is not registered, don't raise any error but
also don't send any email."""
- response = self.client.get('/password_reset/')
+ response = self.client.get("/password_reset/")
self.assertEqual(response.status_code, 200)
- response = self.client.post('/password_reset/', {'email': '[email protected]'})
+ response = self.client.post(
+ "/password_reset/", {"email": "[email protected]"}
+ )
self.assertEqual(response.status_code, 302)
self.assertEqual(len(mail.outbox), 0)
def test_email_found(self):
"Email is sent if a valid email address is provided for password reset"
- response = self.client.post('/password_reset/', {'email': '[email protected]'})
+ response = self.client.post(
+ "/password_reset/", {"email": "[email protected]"}
+ )
self.assertEqual(response.status_code, 302)
self.assertEqual(len(mail.outbox), 1)
self.assertIn("http://", mail.outbox[0].body)
self.assertEqual(settings.DEFAULT_FROM_EMAIL, mail.outbox[0].from_email)
# optional multipart text/html email has been added. Make sure original,
@@ -126,37 +141,41 @@
def test_extra_email_context(self):
"""
extra_email_context should be available in the email template context.
"""
response = self.client.post(
- '/password_reset_extra_email_context/',
- {'email': '[email protected]'},
+ "/password_reset_extra_email_context/",
+ {"email": "[email protected]"},
)
self.assertEqual(response.status_code, 302)
self.assertEqual(len(mail.outbox), 1)
self.assertIn('Email email context: "Hello!"', mail.outbox[0].body)
- self.assertIn('http://custom.example.com/reset/', mail.outbox[0].body)
+ self.assertIn("http://custom.example.com/reset/", mail.outbox[0].body)
def test_html_mail_template(self):
"""
A multipart email with text/plain and text/html is sent
if the html_email_template parameter is passed to the view
"""
- response = self.client.post('/password_reset/html_email_template/', {'email': '[email protected]'})
+ response = self.client.post(
+ "/password_reset/html_email_template/", {"email": "[email protected]"}
+ )
self.assertEqual(response.status_code, 302)
self.assertEqual(len(mail.outbox), 1)
message = mail.outbox[0].message()
self.assertEqual(len(message.get_payload()), 2)
self.assertTrue(message.is_multipart())
- self.assertEqual(message.get_payload(0).get_content_type(), 'text/plain')
- self.assertEqual(message.get_payload(1).get_content_type(), 'text/html')
- self.assertNotIn('<html>', message.get_payload(0).get_payload())
- self.assertIn('<html>', message.get_payload(1).get_payload())
+ self.assertEqual(message.get_payload(0).get_content_type(), "text/plain")
+ self.assertEqual(message.get_payload(1).get_content_type(), "text/html")
+ self.assertNotIn("<html>", message.get_payload(0).get_payload())
+ self.assertIn("<html>", message.get_payload(1).get_payload())
def test_email_found_custom_from(self):
"Email is sent if a valid email address is provided for password reset when a custom from_email is provided."
- response = self.client.post('/password_reset_from_email/', {'email': '[email protected]'})
+ response = self.client.post(
+ "/password_reset_from_email/", {"email": "[email protected]"}
+ )
self.assertEqual(response.status_code, 302)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual("[email protected]", mail.outbox[0].from_email)
# Skip any 500 handler action (like sending more mail...)
@@ -168,35 +187,35 @@
# the colon is interpreted as part of a username for login purposes,
# making 'evil.com' the request domain. Since HTTP_HOST is used to
# produce a meaningful reset URL, we need to be certain that the
# HTTP_HOST header isn't poisoned. This is done as a check when get_host()
# is invoked, but we check here as a practical consequence.
- with self.assertLogs('django.security.DisallowedHost', 'ERROR'):
+ with self.assertLogs("django.security.DisallowedHost", "ERROR"):
response = self.client.post(
- '/password_reset/',
- {'email': '[email protected]'},
- HTTP_HOST='www.example:[email protected]'
+ "/password_reset/",
+ {"email": "[email protected]"},
+ HTTP_HOST="www.example:[email protected]",
)
self.assertEqual(response.status_code, 400)
self.assertEqual(len(mail.outbox), 0)
# Skip any 500 handler action (like sending more mail...)
@override_settings(DEBUG_PROPAGATE_EXCEPTIONS=True)
def test_poisoned_http_host_admin_site(self):
"Poisoned HTTP_HOST headers can't be used for reset emails on admin views"
- with self.assertLogs('django.security.DisallowedHost', 'ERROR'):
+ with self.assertLogs("django.security.DisallowedHost", "ERROR"):
response = self.client.post(
- '/admin_password_reset/',
- {'email': '[email protected]'},
- HTTP_HOST='www.example:[email protected]'
+ "/admin_password_reset/",
+ {"email": "[email protected]"},
+ HTTP_HOST="www.example:[email protected]",
)
self.assertEqual(response.status_code, 400)
self.assertEqual(len(mail.outbox), 0)
def _test_confirm_start(self):
# Start by creating the email
- self.client.post('/password_reset/', {'email': '[email protected]'})
+ self.client.post("/password_reset/", {"email": "[email protected]"})
self.assertEqual(len(mail.outbox), 1)
return self._read_signup_email(mail.outbox[0])
def _read_signup_email(self, email):
urlmatch = re.search(r"https?://[^/]*(/.*reset/\S*)", email.body)
@@ -218,197 +237,226 @@
response = self.client.get(path)
self.assertContains(response, "The password reset link was invalid")
def test_confirm_invalid_user(self):
# A nonexistent user returns a 200 response, not a 404.
- response = self.client.get('/reset/123456/1-1/')
+ response = self.client.get("/reset/123456/1-1/")
self.assertContains(response, "The password reset link was invalid")
def test_confirm_overflow_user(self):
# A base36 user id that overflows int returns a 200 response.
- response = self.client.get('/reset/zzzzzzzzzzzzz/1-1/')
+ response = self.client.get("/reset/zzzzzzzzzzzzz/1-1/")
self.assertContains(response, "The password reset link was invalid")
def test_confirm_invalid_post(self):
# Same as test_confirm_invalid, but trying to do a POST instead.
url, path = self._test_confirm_start()
path = path[:-5] + ("0" * 4) + path[-1]
- self.client.post(path, {
- 'new_password1': 'anewpassword',
- 'new_password2': ' anewpassword',
- })
+ self.client.post(
+ path, {"new_password1": "anewpassword", "new_password2": " anewpassword",}
+ )
# Check the password has not been changed
- u = User.objects.get(email='[email protected]')
+ u = User.objects.get(email="[email protected]")
self.assertTrue(not u.check_password("anewpassword"))
def test_confirm_invalid_hash(self):
"""A POST with an invalid token is rejected."""
- u = User.objects.get(email='[email protected]')
+ u = User.objects.get(email="[email protected]")
original_password = u.password
url, path = self._test_confirm_start()
- path_parts = path.split('-')
- path_parts[-1] = ("0") * 20 + '/'
- path = '-'.join(path_parts)
-
- response = self.client.post(path, {
- 'new_password1': 'anewpassword',
- 'new_password2': 'anewpassword',
- })
- self.assertIs(response.context['validlink'], False)
+ path_parts = path.split("-")
+ path_parts[-1] = "0" * 20 + "/"
+ path = "-".join(path_parts)
+
+ response = self.client.post(
+ path, {"new_password1": "anewpassword", "new_password2": "anewpassword",}
+ )
+ self.assertIs(response.context["validlink"], False)
u.refresh_from_db()
self.assertEqual(original_password, u.password) # password hasn't changed
def test_confirm_complete(self):
url, path = self._test_confirm_start()
- response = self.client.post(path, {'new_password1': 'anewpassword', 'new_password2': 'anewpassword'})
+ response = self.client.post(
+ path, {"new_password1": "anewpassword", "new_password2": "anewpassword"}
+ )
# Check the password has been changed
- u = User.objects.get(email='[email protected]')
+ u = User.objects.get(email="[email protected]")
self.assertTrue(u.check_password("anewpassword"))
# The reset token is deleted from the session.
self.assertNotIn(INTERNAL_RESET_SESSION_TOKEN, self.client.session)
# Check we can't use the link again
response = self.client.get(path)
self.assertContains(response, "The password reset link was invalid")
def test_confirm_different_passwords(self):
url, path = self._test_confirm_start()
- response = self.client.post(path, {'new_password1': 'anewpassword', 'new_password2': 'x'})
- self.assertFormError(response, SetPasswordForm.error_messages['password_mismatch'])
+ response = self.client.post(
+ path, {"new_password1": "anewpassword", "new_password2": "x"}
+ )
+ self.assertFormError(
+ response, SetPasswordForm.error_messages["password_mismatch"]
+ )
def test_reset_redirect_default(self):
- response = self.client.post('/password_reset/', {'email': '[email protected]'})
- self.assertRedirects(response, '/password_reset/done/', fetch_redirect_response=False)
+ response = self.client.post(
+ "/password_reset/", {"email": "[email protected]"}
+ )
+ self.assertRedirects(
+ response, "/password_reset/done/", fetch_redirect_response=False
+ )
def test_reset_custom_redirect(self):
- response = self.client.post('/password_reset/custom_redirect/', {'email': '[email protected]'})
- self.assertRedirects(response, '/custom/', fetch_redirect_response=False)
+ response = self.client.post(
+ "/password_reset/custom_redirect/", {"email": "[email protected]"}
+ )
+ self.assertRedirects(response, "/custom/", fetch_redirect_response=False)
def test_reset_custom_redirect_named(self):
- response = self.client.post('/password_reset/custom_redirect/named/', {'email': '[email protected]'})
- self.assertRedirects(response, '/password_reset/', fetch_redirect_response=False)
+ response = self.client.post(
+ "/password_reset/custom_redirect/named/",
+ {"email": "[email protected]"},
+ )
+ self.assertRedirects(
+ response, "/password_reset/", fetch_redirect_response=False
+ )
def test_confirm_redirect_default(self):
url, path = self._test_confirm_start()
- response = self.client.post(path, {'new_password1': 'anewpassword', 'new_password2': 'anewpassword'})
- self.assertRedirects(response, '/reset/done/', fetch_redirect_response=False)
+ response = self.client.post(
+ path, {"new_password1": "anewpassword", "new_password2": "anewpassword"}
+ )
+ self.assertRedirects(response, "/reset/done/", fetch_redirect_response=False)
def test_confirm_redirect_custom(self):
url, path = self._test_confirm_start()
- path = path.replace('/reset/', '/reset/custom/')
- response = self.client.post(path, {'new_password1': 'anewpassword', 'new_password2': 'anewpassword'})
- self.assertRedirects(response, '/custom/', fetch_redirect_response=False)
+ path = path.replace("/reset/", "/reset/custom/")
+ response = self.client.post(
+ path, {"new_password1": "anewpassword", "new_password2": "anewpassword"}
+ )
+ self.assertRedirects(response, "/custom/", fetch_redirect_response=False)
def test_confirm_redirect_custom_named(self):
url, path = self._test_confirm_start()
- path = path.replace('/reset/', '/reset/custom/named/')
- response = self.client.post(path, {'new_password1': 'anewpassword', 'new_password2': 'anewpassword'})
- self.assertRedirects(response, '/password_reset/', fetch_redirect_response=False)
+ path = path.replace("/reset/", "/reset/custom/named/")
+ response = self.client.post(
+ path, {"new_password1": "anewpassword", "new_password2": "anewpassword"}
+ )
+ self.assertRedirects(
+ response, "/password_reset/", fetch_redirect_response=False
+ )
def test_confirm_custom_reset_url_token(self):
url, path = self._test_confirm_start()
- path = path.replace('/reset/', '/reset/custom/token/')
- self.client.reset_url_token = 'set-passwordcustom'
- response = self.client.post(
- path,
- {'new_password1': 'anewpassword', 'new_password2': 'anewpassword'},
- )
- self.assertRedirects(response, '/reset/done/', fetch_redirect_response=False)
+ path = path.replace("/reset/", "/reset/custom/token/")
+ self.client.reset_url_token = "set-passwordcustom"
+ response = self.client.post(
+ path, {"new_password1": "anewpassword", "new_password2": "anewpassword"},
+ )
+ self.assertRedirects(response, "/reset/done/", fetch_redirect_response=False)
def test_confirm_login_post_reset(self):
url, path = self._test_confirm_start()
- path = path.replace('/reset/', '/reset/post_reset_login/')
- response = self.client.post(path, {'new_password1': 'anewpassword', 'new_password2': 'anewpassword'})
- self.assertRedirects(response, '/reset/done/', fetch_redirect_response=False)
+ path = path.replace("/reset/", "/reset/post_reset_login/")
+ response = self.client.post(
+ path, {"new_password1": "anewpassword", "new_password2": "anewpassword"}
+ )
+ self.assertRedirects(response, "/reset/done/", fetch_redirect_response=False)
self.assertIn(SESSION_KEY, self.client.session)
@override_settings(
AUTHENTICATION_BACKENDS=[
- 'django.contrib.auth.backends.ModelBackend',
- 'django.contrib.auth.backends.AllowAllUsersModelBackend',
+ "django.contrib.auth.backends.ModelBackend",
+ "django.contrib.auth.backends.AllowAllUsersModelBackend",
]
)
def test_confirm_login_post_reset_custom_backend(self):
# This backend is specified in the URL pattern.
- backend = 'django.contrib.auth.backends.AllowAllUsersModelBackend'
- url, path = self._test_confirm_start()
- path = path.replace('/reset/', '/reset/post_reset_login_custom_backend/')
- response = self.client.post(path, {'new_password1': 'anewpassword', 'new_password2': 'anewpassword'})
- self.assertRedirects(response, '/reset/done/', fetch_redirect_response=False)
+ backend = "django.contrib.auth.backends.AllowAllUsersModelBackend"
+ url, path = self._test_confirm_start()
+ path = path.replace("/reset/", "/reset/post_reset_login_custom_backend/")
+ response = self.client.post(
+ path, {"new_password1": "anewpassword", "new_password2": "anewpassword"}
+ )
+ self.assertRedirects(response, "/reset/done/", fetch_redirect_response=False)
self.assertIn(SESSION_KEY, self.client.session)
self.assertEqual(self.client.session[BACKEND_SESSION_KEY], backend)
def test_confirm_login_post_reset_already_logged_in(self):
url, path = self._test_confirm_start()
- path = path.replace('/reset/', '/reset/post_reset_login/')
- self.login()
- response = self.client.post(path, {'new_password1': 'anewpassword', 'new_password2': 'anewpassword'})
- self.assertRedirects(response, '/reset/done/', fetch_redirect_response=False)
+ path = path.replace("/reset/", "/reset/post_reset_login/")
+ self.login()
+ response = self.client.post(
+ path, {"new_password1": "anewpassword", "new_password2": "anewpassword"}
+ )
+ self.assertRedirects(response, "/reset/done/", fetch_redirect_response=False)
self.assertIn(SESSION_KEY, self.client.session)
def test_confirm_display_user_from_form(self):
url, path = self._test_confirm_start()
response = self.client.get(path)
# The password_reset_confirm() view passes the user object to the
# SetPasswordForm``, even on GET requests (#16919). For this test,
# {{ form.user }}`` is rendered in the template
# registration/password_reset_confirm.html.
- username = User.objects.get(email='[email protected]').username
+ username = User.objects.get(email="[email protected]").username
self.assertContains(response, "Hello, %s." % username)
# However, the view should NOT pass any user object on a form if the
# password reset link was invalid.
- response = self.client.get('/reset/zzzzzzzzzzzzz/1-1/')
+ response = self.client.get("/reset/zzzzzzzzzzzzz/1-1/")
self.assertContains(response, "Hello, .")
def test_confirm_link_redirects_to_set_password_page(self):
url, path = self._test_confirm_start()
# Don't use PasswordResetConfirmClient (self.client) here which
# automatically fetches the redirect page.
client = Client()
response = client.get(path)
- token = response.resolver_match.kwargs['token']
- uuidb64 = response.resolver_match.kwargs['uidb64']
- self.assertRedirects(response, '/reset/%s/set-password/' % uuidb64)
- self.assertEqual(client.session['_password_reset_token'], token)
+ token = response.resolver_match.kwargs["token"]
+ uuidb64 = response.resolver_match.kwargs["uidb64"]
+ self.assertRedirects(response, "/reset/%s/set-password/" % uuidb64)
+ self.assertEqual(client.session["_password_reset_token"], token)
def test_confirm_custom_reset_url_token_link_redirects_to_set_password_page(self):
url, path = self._test_confirm_start()
- path = path.replace('/reset/', '/reset/custom/token/')
+ path = path.replace("/reset/", "/reset/custom/token/")
client = Client()
response = client.get(path)
- token = response.resolver_match.kwargs['token']
- uuidb64 = response.resolver_match.kwargs['uidb64']
- self.assertRedirects(response, '/reset/custom/token/%s/set-passwordcustom/' % uuidb64)
- self.assertEqual(client.session['_password_reset_token'], token)
+ token = response.resolver_match.kwargs["token"]
+ uuidb64 = response.resolver_match.kwargs["uidb64"]
+ self.assertRedirects(
+ response, "/reset/custom/token/%s/set-passwordcustom/" % uuidb64
+ )
+ self.assertEqual(client.session["_password_reset_token"], token)
def test_invalid_link_if_going_directly_to_the_final_reset_password_url(self):
url, path = self._test_confirm_start()
- _, uuidb64, _ = path.strip('/').split('/')
- response = Client().get('/reset/%s/set-password/' % uuidb64)
- self.assertContains(response, 'The password reset link was invalid')
-
-
-@override_settings(AUTH_USER_MODEL='auth_tests.CustomUser')
+ _, uuidb64, _ = path.strip("/").split("/")
+ response = Client().get("/reset/%s/set-password/" % uuidb64)
+ self.assertContains(response, "The password reset link was invalid")
+
+
+@override_settings(AUTH_USER_MODEL="auth_tests.CustomUser")
class CustomUserPasswordResetTest(AuthViewsTestCase):
- user_email = '[email protected]'
+ user_email = "[email protected]"
@classmethod
def setUpTestData(cls):
cls.u1 = CustomUser.custom_objects.create(
- email='[email protected]',
- date_of_birth=datetime.date(1976, 11, 8),
- )
- cls.u1.set_password('password')
+ email="[email protected]", date_of_birth=datetime.date(1976, 11, 8),
+ )
+ cls.u1.set_password("password")
cls.u1.save()
def setUp(self):
self.client = PasswordResetConfirmClient()
def _test_confirm_start(self):
# Start by creating the email
- response = self.client.post('/password_reset/', {'email': self.user_email})
+ response = self.client.post("/password_reset/", {"email": self.user_email})
self.assertEqual(response.status_code, 302)
self.assertEqual(len(mail.outbox), 1)
return self._read_signup_email(mail.outbox[0])
def _read_signup_email(self, email):
@@ -420,238 +468,276 @@
url, path = self._test_confirm_start()
response = self.client.get(path)
# redirect to a 'complete' page:
self.assertContains(response, "Please enter your new password")
# then submit a new password
- response = self.client.post(path, {
- 'new_password1': 'anewpassword',
- 'new_password2': 'anewpassword',
- })
- self.assertRedirects(response, '/reset/done/')
-
-
-@override_settings(AUTH_USER_MODEL='auth_tests.UUIDUser')
+ response = self.client.post(
+ path, {"new_password1": "anewpassword", "new_password2": "anewpassword",}
+ )
+ self.assertRedirects(response, "/reset/done/")
+
+
+@override_settings(AUTH_USER_MODEL="auth_tests.UUIDUser")
class UUIDUserPasswordResetTest(CustomUserPasswordResetTest):
-
def _test_confirm_start(self):
# instead of fixture
UUIDUser.objects.create_user(
- email=self.user_email,
- username='foo',
- password='foo',
+ email=self.user_email, username="foo", password="foo",
)
return super()._test_confirm_start()
def test_confirm_invalid_uuid(self):
"""A uidb64 that decodes to a non-UUID doesn't crash."""
_, path = self._test_confirm_start()
- invalid_uidb64 = urlsafe_base64_encode(b'INVALID_UUID')
- first, _uuidb64_, second = path.strip('/').split('/')
- response = self.client.get('/' + '/'.join((first, invalid_uidb64, second)) + '/')
- self.assertContains(response, 'The password reset link was invalid')
+ invalid_uidb64 = urlsafe_base64_encode(b"INVALID_UUID")
+ first, _uuidb64_, second = path.strip("/").split("/")
+ response = self.client.get(
+ "/" + "/".join((first, invalid_uidb64, second)) + "/"
+ )
+ self.assertContains(response, "The password reset link was invalid")
class ChangePasswordTest(AuthViewsTestCase):
-
def fail_login(self):
- response = self.client.post('/login/', {
- 'username': 'testclient',
- 'password': 'password',
- })
- self.assertFormError(response, AuthenticationForm.error_messages['invalid_login'] % {
- 'username': User._meta.get_field('username').verbose_name
- })
+ response = self.client.post(
+ "/login/", {"username": "testclient", "password": "password",}
+ )
+ self.assertFormError(
+ response,
+ AuthenticationForm.error_messages["invalid_login"]
+ % {"username": User._meta.get_field("username").verbose_name},
+ )
def logout(self):
- self.client.get('/logout/')
+ self.client.get("/logout/")
def test_password_change_fails_with_invalid_old_password(self):
self.login()
- response = self.client.post('/password_change/', {
- 'old_password': 'donuts',
- 'new_password1': 'password1',
- 'new_password2': 'password1',
- })
- self.assertFormError(response, PasswordChangeForm.error_messages['password_incorrect'])
+ response = self.client.post(
+ "/password_change/",
+ {
+ "old_password": "donuts",
+ "new_password1": "password1",
+ "new_password2": "password1",
+ },
+ )
+ self.assertFormError(
+ response, PasswordChangeForm.error_messages["password_incorrect"]
+ )
def test_password_change_fails_with_mismatched_passwords(self):
self.login()
- response = self.client.post('/password_change/', {
- 'old_password': 'password',
- 'new_password1': 'password1',
- 'new_password2': 'donuts',
- })
- self.assertFormError(response, SetPasswordForm.error_messages['password_mismatch'])
+ response = self.client.post(
+ "/password_change/",
+ {
+ "old_password": "password",
+ "new_password1": "password1",
+ "new_password2": "donuts",
+ },
+ )
+ self.assertFormError(
+ response, SetPasswordForm.error_messages["password_mismatch"]
+ )
def test_password_change_succeeds(self):
self.login()
- self.client.post('/password_change/', {
- 'old_password': 'password',
- 'new_password1': 'password1',
- 'new_password2': 'password1',
- })
+ self.client.post(
+ "/password_change/",
+ {
+ "old_password": "password",
+ "new_password1": "password1",
+ "new_password2": "password1",
+ },
+ )
self.fail_login()
- self.login(password='password1')
+ self.login(password="password1")
def test_password_change_done_succeeds(self):
self.login()
- response = self.client.post('/password_change/', {
- 'old_password': 'password',
- 'new_password1': 'password1',
- 'new_password2': 'password1',
- })
- self.assertRedirects(response, '/password_change/done/', fetch_redirect_response=False)
-
- @override_settings(LOGIN_URL='/login/')
+ response = self.client.post(
+ "/password_change/",
+ {
+ "old_password": "password",
+ "new_password1": "password1",
+ "new_password2": "password1",
+ },
+ )
+ self.assertRedirects(
+ response, "/password_change/done/", fetch_redirect_response=False
+ )
+
+ @override_settings(LOGIN_URL="/login/")
def test_password_change_done_fails(self):
- response = self.client.get('/password_change/done/')
- self.assertRedirects(response, '/login/?next=/password_change/done/', fetch_redirect_response=False)
+ response = self.client.get("/password_change/done/")
+ self.assertRedirects(
+ response,
+ "/login/?next=/password_change/done/",
+ fetch_redirect_response=False,
+ )
def test_password_change_redirect_default(self):
self.login()
- response = self.client.post('/password_change/', {
- 'old_password': 'password',
- 'new_password1': 'password1',
- 'new_password2': 'password1',
- })
- self.assertRedirects(response, '/password_change/done/', fetch_redirect_response=False)
+ response = self.client.post(
+ "/password_change/",
+ {
+ "old_password": "password",
+ "new_password1": "password1",
+ "new_password2": "password1",
+ },
+ )
+ self.assertRedirects(
+ response, "/password_change/done/", fetch_redirect_response=False
+ )
def test_password_change_redirect_custom(self):
self.login()
- response = self.client.post('/password_change/custom/', {
- 'old_password': 'password',
- 'new_password1': 'password1',
- 'new_password2': 'password1',
- })
- self.assertRedirects(response, '/custom/', fetch_redirect_response=False)
+ response = self.client.post(
+ "/password_change/custom/",
+ {
+ "old_password": "password",
+ "new_password1": "password1",
+ "new_password2": "password1",
+ },
+ )
+ self.assertRedirects(response, "/custom/", fetch_redirect_response=False)
def test_password_change_redirect_custom_named(self):
self.login()
- response = self.client.post('/password_change/custom/named/', {
- 'old_password': 'password',
- 'new_password1': 'password1',
- 'new_password2': 'password1',
- })
- self.assertRedirects(response, '/password_reset/', fetch_redirect_response=False)
+ response = self.client.post(
+ "/password_change/custom/named/",
+ {
+ "old_password": "password",
+ "new_password1": "password1",
+ "new_password2": "password1",
+ },
+ )
+ self.assertRedirects(
+ response, "/password_reset/", fetch_redirect_response=False
+ )
class SessionAuthenticationTests(AuthViewsTestCase):
def test_user_password_change_updates_session(self):
"""
#21649 - Ensure contrib.auth.views.password_change updates the user's
session auth hash after a password change so the session isn't logged out.
"""
self.login()
original_session_key = self.client.session.session_key
- response = self.client.post('/password_change/', {
- 'old_password': 'password',
- 'new_password1': 'password1',
- 'new_password2': 'password1',
- })
+ response = self.client.post(
+ "/password_change/",
+ {
+ "old_password": "password",
+ "new_password1": "password1",
+ "new_password2": "password1",
+ },
+ )
# if the hash isn't updated, retrieving the redirection page will fail.
- self.assertRedirects(response, '/password_change/done/')
+ self.assertRedirects(response, "/password_change/done/")
# The session key is rotated.
self.assertNotEqual(original_session_key, self.client.session.session_key)
class LoginTest(AuthViewsTestCase):
-
def test_current_site_in_context_after_login(self):
- response = self.client.get(reverse('login'))
+ response = self.client.get(reverse("login"))
self.assertEqual(response.status_code, 200)
- if apps.is_installed('django.contrib.sites'):
- Site = apps.get_model('sites.Site')
+ if apps.is_installed("django.contrib.sites"):
+ Site = apps.get_model("sites.Site")
site = Site.objects.get_current()
- self.assertEqual(response.context['site'], site)
- self.assertEqual(response.context['site_name'], site.name)
+ self.assertEqual(response.context["site"], site)
+ self.assertEqual(response.context["site_name"], site.name)
else:
- self.assertIsInstance(response.context['site'], RequestSite)
- self.assertIsInstance(response.context['form'], AuthenticationForm)
+ self.assertIsInstance(response.context["site"], RequestSite)
+ self.assertIsInstance(response.context["form"], AuthenticationForm)
def test_security_check(self):
- login_url = reverse('login')
+ login_url = reverse("login")
# These URLs should not pass the security check.
bad_urls = (
- 'http://example.com',
- 'http:///example.com',
- 'https://example.com',
- 'ftp://example.com',
- '///example.com',
- '//example.com',
+ "http://example.com",
+ "http:///example.com",
+ "https://example.com",
+ "ftp://example.com",
+ "///example.com",
+ "//example.com",
'javascript:alert("XSS")',
)
for bad_url in bad_urls:
with self.subTest(bad_url=bad_url):
- nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
- 'url': login_url,
- 'next': REDIRECT_FIELD_NAME,
- 'bad_url': quote(bad_url),
+ nasty_url = "%(url)s?%(next)s=%(bad_url)s" % {
+ "url": login_url,
+ "next": REDIRECT_FIELD_NAME,
+ "bad_url": quote(bad_url),
}
- response = self.client.post(nasty_url, {
- 'username': 'testclient',
- 'password': 'password',
- })
+ response = self.client.post(
+ nasty_url, {"username": "testclient", "password": "password",}
+ )
self.assertEqual(response.status_code, 302)
- self.assertNotIn(bad_url, response.url, '%s should be blocked' % bad_url)
+ self.assertNotIn(
+ bad_url, response.url, "%s should be blocked" % bad_url
+ )
# These URLs should pass the security check.
good_urls = (
- '/view/?param=http://example.com',
- '/view/?param=https://example.com',
- '/view?param=ftp://example.com',
- 'view/?param=//example.com',
- 'https://testserver/',
- 'HTTPS://testserver/',
- '//testserver/',
- '/url%20with%20spaces/',
+ "/view/?param=http://example.com",
+ "/view/?param=https://example.com",
+ "/view?param=ftp://example.com",
+ "view/?param=//example.com",
+ "https://testserver/",
+ "HTTPS://testserver/",
+ "//testserver/",
+ "/url%20with%20spaces/",
)
for good_url in good_urls:
with self.subTest(good_url=good_url):
- safe_url = '%(url)s?%(next)s=%(good_url)s' % {
- 'url': login_url,
- 'next': REDIRECT_FIELD_NAME,
- 'good_url': quote(good_url),
+ safe_url = "%(url)s?%(next)s=%(good_url)s" % {
+ "url": login_url,
+ "next": REDIRECT_FIELD_NAME,
+ "good_url": quote(good_url),
}
- response = self.client.post(safe_url, {
- 'username': 'testclient',
- 'password': 'password',
- })
+ response = self.client.post(
+ safe_url, {"username": "testclient", "password": "password",}
+ )
self.assertEqual(response.status_code, 302)
- self.assertIn(good_url, response.url, '%s should be allowed' % good_url)
+ self.assertIn(good_url, response.url, "%s should be allowed" % good_url)
def test_security_check_https(self):
- login_url = reverse('login')
- non_https_next_url = 'http://testserver/path'
- not_secured_url = '%(url)s?%(next)s=%(next_url)s' % {
- 'url': login_url,
- 'next': REDIRECT_FIELD_NAME,
- 'next_url': quote(non_https_next_url),
+ login_url = reverse("login")
+ non_https_next_url = "http://testserver/path"
+ not_secured_url = "%(url)s?%(next)s=%(next_url)s" % {
+ "url": login_url,
+ "next": REDIRECT_FIELD_NAME,
+ "next_url": quote(non_https_next_url),
}
post_data = {
- 'username': 'testclient',
- 'password': 'password',
+ "username": "testclient",
+ "password": "password",
}
response = self.client.post(not_secured_url, post_data, secure=True)
self.assertEqual(response.status_code, 302)
self.assertNotEqual(response.url, non_https_next_url)
self.assertEqual(response.url, settings.LOGIN_REDIRECT_URL)
def test_login_form_contains_request(self):
# The custom authentication form for this login requires a request to
# initialize it.
- response = self.client.post('/custom_request_auth_login/', {
- 'username': 'testclient',
- 'password': 'password',
- })
+ response = self.client.post(
+ "/custom_request_auth_login/",
+ {"username": "testclient", "password": "password",},
+ )
# The login was successful.
- self.assertRedirects(response, settings.LOGIN_REDIRECT_URL, fetch_redirect_response=False)
+ self.assertRedirects(
+ response, settings.LOGIN_REDIRECT_URL, fetch_redirect_response=False
+ )
def test_login_csrf_rotate(self):
"""
Makes sure that a login rotates the currently-used CSRF token.
"""
+
def get_response(request):
return HttpResponse()
# Do a GET to establish a CSRF token
# The test client isn't used here as it's a test for middleware.
@@ -665,16 +751,22 @@
# Prepare the POST request
req = HttpRequest()
req.COOKIES[settings.CSRF_COOKIE_NAME] = token1
req.method = "POST"
- req.POST = {'username': 'testclient', 'password': 'password', 'csrfmiddlewaretoken': token1}
+ req.POST = {
+ "username": "testclient",
+ "password": "password",
+ "csrfmiddlewaretoken": token1,
+ }
# Use POST request to log in
SessionMiddleware(get_response).process_request(req)
CsrfViewMiddleware(get_response).process_view(req, LoginView.as_view(), (), {})
- req.META["SERVER_NAME"] = "testserver" # Required to have redirect work in login view
+ req.META["SERVER_NAME"] = ( # Required to have redirect work in login view
+ "testserver"
+ )
req.META["SERVER_PORT"] = 80
resp = CsrfViewMiddleware(LoginView.as_view())(req)
csrf_cookie = resp.cookies.get(settings.CSRF_COOKIE_NAME, None)
token2 = csrf_cookie.coded_value
@@ -688,11 +780,11 @@
user.
"""
self.login()
original_session_key = self.client.session.session_key
- self.login(username='staff')
+ self.login(username="staff")
self.assertNotEqual(original_session_key, self.client.session.session_key)
def test_session_key_flushed_on_login_after_password_change(self):
"""
As above, but same user logging in after a password change.
@@ -702,20 +794,20 @@
# If no password change, session key should not be flushed.
self.login()
self.assertEqual(original_session_key, self.client.session.session_key)
- user = User.objects.get(username='testclient')
- user.set_password('foobar')
+ user = User.objects.get(username="testclient")
+ user.set_password("foobar")
user.save()
- self.login(password='foobar')
+ self.login(password="foobar")
self.assertNotEqual(original_session_key, self.client.session.session_key)
def test_legacy_session_key_flushed_on_login(self):
# RemovedInDjango40Warning.
- user = User.objects.get(username='testclient')
+ user = User.objects.get(username="testclient")
engine = import_module(settings.SESSION_ENGINE)
session = engine.SessionStore()
session[SESSION_KEY] = user.id
session[HASH_SESSION_KEY] = user._legacy_get_session_auth_hash()
session.save()
@@ -723,23 +815,23 @@
self.client.cookies[settings.SESSION_COOKIE_NAME] = original_session_key
# Legacy session key is flushed on login.
self.login()
self.assertNotEqual(original_session_key, self.client.session.session_key)
# Legacy session key is flushed after a password change.
- user.set_password('password_2')
+ user.set_password("password_2")
user.save()
original_session_key = session.session_key
self.client.cookies[settings.SESSION_COOKIE_NAME] = original_session_key
- self.login(password='password_2')
+ self.login(password="password_2")
self.assertNotEqual(original_session_key, self.client.session.session_key)
def test_login_session_without_hash_session_key(self):
"""
Session without django.contrib.auth.HASH_SESSION_KEY should login
without an exception.
"""
- user = User.objects.get(username='testclient')
+ user = User.objects.get(username="testclient")
engine = import_module(settings.SESSION_ENGINE)
session = engine.SessionStore()
session[SESSION_KEY] = user.id
session.save()
original_session_key = session.session_key
@@ -749,147 +841,152 @@
self.assertNotEqual(original_session_key, self.client.session.session_key)
class LoginURLSettings(AuthViewsTestCase):
"""Tests for settings.LOGIN_URL."""
+
def assertLoginURLEquals(self, url):
- response = self.client.get('/login_required/')
+ response = self.client.get("/login_required/")
self.assertRedirects(response, url, fetch_redirect_response=False)
- @override_settings(LOGIN_URL='/login/')
+ @override_settings(LOGIN_URL="/login/")
def test_standard_login_url(self):
- self.assertLoginURLEquals('/login/?next=/login_required/')
-
- @override_settings(LOGIN_URL='login')
+ self.assertLoginURLEquals("/login/?next=/login_required/")
+
+ @override_settings(LOGIN_URL="login")
def test_named_login_url(self):
- self.assertLoginURLEquals('/login/?next=/login_required/')
-
- @override_settings(LOGIN_URL='http://remote.example.com/login')
+ self.assertLoginURLEquals("/login/?next=/login_required/")
+
+ @override_settings(LOGIN_URL="http://remote.example.com/login")
def test_remote_login_url(self):
- quoted_next = quote('http://testserver/login_required/')
- expected = 'http://remote.example.com/login?next=%s' % quoted_next
+ quoted_next = quote("http://testserver/login_required/")
+ expected = "http://remote.example.com/login?next=%s" % quoted_next
self.assertLoginURLEquals(expected)
- @override_settings(LOGIN_URL='https:///login/')
+ @override_settings(LOGIN_URL="https:///login/")
def test_https_login_url(self):
- quoted_next = quote('http://testserver/login_required/')
- expected = 'https:///login/?next=%s' % quoted_next
+ quoted_next = quote("http://testserver/login_required/")
+ expected = "https:///login/?next=%s" % quoted_next
self.assertLoginURLEquals(expected)
- @override_settings(LOGIN_URL='/login/?pretty=1')
+ @override_settings(LOGIN_URL="/login/?pretty=1")
def test_login_url_with_querystring(self):
- self.assertLoginURLEquals('/login/?pretty=1&next=/login_required/')
-
- @override_settings(LOGIN_URL='http://remote.example.com/login/?next=/default/')
+ self.assertLoginURLEquals("/login/?pretty=1&next=/login_required/")
+
+ @override_settings(LOGIN_URL="http://remote.example.com/login/?next=/default/")
def test_remote_login_url_with_next_querystring(self):
- quoted_next = quote('http://testserver/login_required/')
- expected = 'http://remote.example.com/login/?next=%s' % quoted_next
+ quoted_next = quote("http://testserver/login_required/")
+ expected = "http://remote.example.com/login/?next=%s" % quoted_next
self.assertLoginURLEquals(expected)
- @override_settings(LOGIN_URL=reverse_lazy('login'))
+ @override_settings(LOGIN_URL=reverse_lazy("login"))
def test_lazy_login_url(self):
- self.assertLoginURLEquals('/login/?next=/login_required/')
+ self.assertLoginURLEquals("/login/?next=/login_required/")
class LoginRedirectUrlTest(AuthViewsTestCase):
"""Tests for settings.LOGIN_REDIRECT_URL."""
+
def assertLoginRedirectURLEqual(self, url):
response = self.login()
self.assertRedirects(response, url, fetch_redirect_response=False)
def test_default(self):
- self.assertLoginRedirectURLEqual('/accounts/profile/')
-
- @override_settings(LOGIN_REDIRECT_URL='/custom/')
+ self.assertLoginRedirectURLEqual("/accounts/profile/")
+
+ @override_settings(LOGIN_REDIRECT_URL="/custom/")
def test_custom(self):
- self.assertLoginRedirectURLEqual('/custom/')
-
- @override_settings(LOGIN_REDIRECT_URL='password_reset')
+ self.assertLoginRedirectURLEqual("/custom/")
+
+ @override_settings(LOGIN_REDIRECT_URL="password_reset")
def test_named(self):
- self.assertLoginRedirectURLEqual('/password_reset/')
-
- @override_settings(LOGIN_REDIRECT_URL='http://remote.example.com/welcome/')
+ self.assertLoginRedirectURLEqual("/password_reset/")
+
+ @override_settings(LOGIN_REDIRECT_URL="http://remote.example.com/welcome/")
def test_remote(self):
- self.assertLoginRedirectURLEqual('http://remote.example.com/welcome/')
+ self.assertLoginRedirectURLEqual("http://remote.example.com/welcome/")
class RedirectToLoginTests(AuthViewsTestCase):
"""Tests for the redirect_to_login view"""
- @override_settings(LOGIN_URL=reverse_lazy('login'))
+
+ @override_settings(LOGIN_URL=reverse_lazy("login"))
def test_redirect_to_login_with_lazy(self):
- login_redirect_response = redirect_to_login(next='/else/where/')
- expected = '/login/?next=/else/where/'
+ login_redirect_response = redirect_to_login(next="/else/where/")
+ expected = "/login/?next=/else/where/"
self.assertEqual(expected, login_redirect_response.url)
- @override_settings(LOGIN_URL=reverse_lazy('login'))
+ @override_settings(LOGIN_URL=reverse_lazy("login"))
def test_redirect_to_login_with_lazy_and_unicode(self):
- login_redirect_response = redirect_to_login(next='/else/where/झ/')
- expected = '/login/?next=/else/where/%E0%A4%9D/'
+ login_redirect_response = redirect_to_login(next="/else/where/झ/")
+ expected = "/login/?next=/else/where/%E0%A4%9D/"
self.assertEqual(expected, login_redirect_response.url)
class LogoutThenLoginTests(AuthViewsTestCase):
"""Tests for the logout_then_login view"""
def confirm_logged_out(self):
self.assertNotIn(SESSION_KEY, self.client.session)
- @override_settings(LOGIN_URL='/login/')
+ @override_settings(LOGIN_URL="/login/")
def test_default_logout_then_login(self):
self.login()
req = HttpRequest()
- req.method = 'GET'
+ req.method = "GET"
req.session = self.client.session
response = logout_then_login(req)
self.confirm_logged_out()
- self.assertRedirects(response, '/login/', fetch_redirect_response=False)
+ self.assertRedirects(response, "/login/", fetch_redirect_response=False)
def test_logout_then_login_with_custom_login(self):
self.login()
req = HttpRequest()
- req.method = 'GET'
+ req.method = "GET"
req.session = self.client.session
- response = logout_then_login(req, login_url='/custom/')
+ response = logout_then_login(req, login_url="/custom/")
self.confirm_logged_out()
- self.assertRedirects(response, '/custom/', fetch_redirect_response=False)
+ self.assertRedirects(response, "/custom/", fetch_redirect_response=False)
class LoginRedirectAuthenticatedUser(AuthViewsTestCase):
- dont_redirect_url = '/login/redirect_authenticated_user_default/'
- do_redirect_url = '/login/redirect_authenticated_user/'
+ dont_redirect_url = "/login/redirect_authenticated_user_default/"
+ do_redirect_url = "/login/redirect_authenticated_user/"
def test_default(self):
"""Stay on the login page by default."""
self.login()
response = self.client.get(self.dont_redirect_url)
self.assertEqual(response.status_code, 200)
- self.assertEqual(response.context['next'], '')
+ self.assertEqual(response.context["next"], "")
def test_guest(self):
"""If not logged in, stay on the same page."""
response = self.client.get(self.do_redirect_url)
self.assertEqual(response.status_code, 200)
def test_redirect(self):
"""If logged in, go to default redirected URL."""
self.login()
response = self.client.get(self.do_redirect_url)
- self.assertRedirects(response, '/accounts/profile/', fetch_redirect_response=False)
-
- @override_settings(LOGIN_REDIRECT_URL='/custom/')
+ self.assertRedirects(
+ response, "/accounts/profile/", fetch_redirect_response=False
+ )
+
+ @override_settings(LOGIN_REDIRECT_URL="/custom/")
def test_redirect_url(self):
"""If logged in, go to custom redirected URL."""
self.login()
response = self.client.get(self.do_redirect_url)
- self.assertRedirects(response, '/custom/', fetch_redirect_response=False)
+ self.assertRedirects(response, "/custom/", fetch_redirect_response=False)
def test_redirect_param(self):
"""If next is specified as a GET parameter, go there."""
self.login()
- url = self.do_redirect_url + '?next=/custom_next/'
+ url = self.do_redirect_url + "?next=/custom_next/"
response = self.client.get(url)
- self.assertRedirects(response, '/custom_next/', fetch_redirect_response=False)
+ self.assertRedirects(response, "/custom_next/", fetch_redirect_response=False)
def test_redirect_loop(self):
"""
Detect a redirect loop if LOGIN_REDIRECT_URL is not correctly set,
with and without custom parameters.
@@ -901,426 +998,470 @@
)
with self.settings(LOGIN_REDIRECT_URL=self.do_redirect_url):
with self.assertRaisesMessage(ValueError, msg):
self.client.get(self.do_redirect_url)
- url = self.do_redirect_url + '?bla=2'
+ url = self.do_redirect_url + "?bla=2"
with self.assertRaisesMessage(ValueError, msg):
self.client.get(url)
def test_permission_required_not_logged_in(self):
# Not logged in ...
with self.settings(LOGIN_URL=self.do_redirect_url):
# redirected to login.
- response = self.client.get('/permission_required_redirect/', follow=True)
+ response = self.client.get("/permission_required_redirect/", follow=True)
self.assertEqual(response.status_code, 200)
# exception raised.
- response = self.client.get('/permission_required_exception/', follow=True)
+ response = self.client.get("/permission_required_exception/", follow=True)
self.assertEqual(response.status_code, 403)
# redirected to login.
- response = self.client.get('/login_and_permission_required_exception/', follow=True)
+ response = self.client.get(
+ "/login_and_permission_required_exception/", follow=True
+ )
self.assertEqual(response.status_code, 200)
def test_permission_required_logged_in(self):
self.login()
# Already logged in...
with self.settings(LOGIN_URL=self.do_redirect_url):
# redirect loop encountered.
- with self.assertRaisesMessage(RedirectCycleError, 'Redirect loop detected.'):
- self.client.get('/permission_required_redirect/', follow=True)
+ with self.assertRaisesMessage(
+ RedirectCycleError, "Redirect loop detected."
+ ):
+ self.client.get("/permission_required_redirect/", follow=True)
# exception raised.
- response = self.client.get('/permission_required_exception/', follow=True)
+ response = self.client.get("/permission_required_exception/", follow=True)
self.assertEqual(response.status_code, 403)
# exception raised.
- response = self.client.get('/login_and_permission_required_exception/', follow=True)
+ response = self.client.get(
+ "/login_and_permission_required_exception/", follow=True
+ )
self.assertEqual(response.status_code, 403)
class LoginSuccessURLAllowedHostsTest(AuthViewsTestCase):
def test_success_url_allowed_hosts_same_host(self):
- response = self.client.post('/login/allowed_hosts/', {
- 'username': 'testclient',
- 'password': 'password',
- 'next': 'https://testserver/home',
- })
+ response = self.client.post(
+ "/login/allowed_hosts/",
+ {
+ "username": "testclient",
+ "password": "password",
+ "next": "https://testserver/home",
+ },
+ )
self.assertIn(SESSION_KEY, self.client.session)
- self.assertRedirects(response, 'https://testserver/home', fetch_redirect_response=False)
+ self.assertRedirects(
+ response, "https://testserver/home", fetch_redirect_response=False
+ )
def test_success_url_allowed_hosts_safe_host(self):
- response = self.client.post('/login/allowed_hosts/', {
- 'username': 'testclient',
- 'password': 'password',
- 'next': 'https://otherserver/home',
- })
+ response = self.client.post(
+ "/login/allowed_hosts/",
+ {
+ "username": "testclient",
+ "password": "password",
+ "next": "https://otherserver/home",
+ },
+ )
self.assertIn(SESSION_KEY, self.client.session)
- self.assertRedirects(response, 'https://otherserver/home', fetch_redirect_response=False)
+ self.assertRedirects(
+ response, "https://otherserver/home", fetch_redirect_response=False
+ )
def test_success_url_allowed_hosts_unsafe_host(self):
- response = self.client.post('/login/allowed_hosts/', {
- 'username': 'testclient',
- 'password': 'password',
- 'next': 'https://evil/home',
- })
+ response = self.client.post(
+ "/login/allowed_hosts/",
+ {
+ "username": "testclient",
+ "password": "password",
+ "next": "https://evil/home",
+ },
+ )
self.assertIn(SESSION_KEY, self.client.session)
- self.assertRedirects(response, '/accounts/profile/', fetch_redirect_response=False)
+ self.assertRedirects(
+ response, "/accounts/profile/", fetch_redirect_response=False
+ )
class LogoutTest(AuthViewsTestCase):
-
def confirm_logged_out(self):
self.assertNotIn(SESSION_KEY, self.client.session)
def test_logout_default(self):
"Logout without next_page option renders the default template"
self.login()
- response = self.client.get('/logout/')
- self.assertContains(response, 'Logged out')
+ response = self.client.get("/logout/")
+ self.assertContains(response, "Logged out")
self.confirm_logged_out()
def test_logout_with_post(self):
self.login()
- response = self.client.post('/logout/')
- self.assertContains(response, 'Logged out')
+ response = self.client.post("/logout/")
+ self.assertContains(response, "Logged out")
self.confirm_logged_out()
def test_14377(self):
# Bug 14377
self.login()
- response = self.client.get('/logout/')
- self.assertIn('site', response.context)
+ response = self.client.get("/logout/")
+ self.assertIn("site", response.context)
def test_logout_doesnt_cache(self):
"""
The logout() view should send "no-cache" headers for reasons described
in #25490.
"""
- response = self.client.get('/logout/')
- self.assertIn('no-store', response['Cache-Control'])
+ response = self.client.get("/logout/")
+ self.assertIn("no-store", response["Cache-Control"])
def test_logout_with_overridden_redirect_url(self):
# Bug 11223
self.login()
- response = self.client.get('/logout/next_page/')
- self.assertRedirects(response, '/somewhere/', fetch_redirect_response=False)
-
- response = self.client.get('/logout/next_page/?next=/login/')
- self.assertRedirects(response, '/login/', fetch_redirect_response=False)
+ response = self.client.get("/logout/next_page/")
+ self.assertRedirects(response, "/somewhere/", fetch_redirect_response=False)
+
+ response = self.client.get("/logout/next_page/?next=/login/")
+ self.assertRedirects(response, "/login/", fetch_redirect_response=False)
self.confirm_logged_out()
def test_logout_with_next_page_specified(self):
"Logout with next_page option given redirects to specified resource"
self.login()
- response = self.client.get('/logout/next_page/')
- self.assertRedirects(response, '/somewhere/', fetch_redirect_response=False)
+ response = self.client.get("/logout/next_page/")
+ self.assertRedirects(response, "/somewhere/", fetch_redirect_response=False)
self.confirm_logged_out()
def test_logout_with_redirect_argument(self):
"Logout with query string redirects to specified resource"
self.login()
- response = self.client.get('/logout/?next=/login/')
- self.assertRedirects(response, '/login/', fetch_redirect_response=False)
+ response = self.client.get("/logout/?next=/login/")
+ self.assertRedirects(response, "/login/", fetch_redirect_response=False)
self.confirm_logged_out()
def test_logout_with_custom_redirect_argument(self):
"Logout with custom query string redirects to specified resource"
self.login()
- response = self.client.get('/logout/custom_query/?follow=/somewhere/')
- self.assertRedirects(response, '/somewhere/', fetch_redirect_response=False)
+ response = self.client.get("/logout/custom_query/?follow=/somewhere/")
+ self.assertRedirects(response, "/somewhere/", fetch_redirect_response=False)
self.confirm_logged_out()
def test_logout_with_named_redirect(self):
"Logout resolves names or URLs passed as next_page."
self.login()
- response = self.client.get('/logout/next_page/named/')
- self.assertRedirects(response, '/password_reset/', fetch_redirect_response=False)
+ response = self.client.get("/logout/next_page/named/")
+ self.assertRedirects(
+ response, "/password_reset/", fetch_redirect_response=False
+ )
self.confirm_logged_out()
def test_success_url_allowed_hosts_same_host(self):
self.login()
- response = self.client.get('/logout/allowed_hosts/?next=https://testserver/')
- self.assertRedirects(response, 'https://testserver/', fetch_redirect_response=False)
+ response = self.client.get("/logout/allowed_hosts/?next=https://testserver/")
+ self.assertRedirects(
+ response, "https://testserver/", fetch_redirect_response=False
+ )
self.confirm_logged_out()
def test_success_url_allowed_hosts_safe_host(self):
self.login()
- response = self.client.get('/logout/allowed_hosts/?next=https://otherserver/')
- self.assertRedirects(response, 'https://otherserver/', fetch_redirect_response=False)
+ response = self.client.get("/logout/allowed_hosts/?next=https://otherserver/")
+ self.assertRedirects(
+ response, "https://otherserver/", fetch_redirect_response=False
+ )
self.confirm_logged_out()
def test_success_url_allowed_hosts_unsafe_host(self):
self.login()
- response = self.client.get('/logout/allowed_hosts/?next=https://evil/')
- self.assertRedirects(response, '/logout/allowed_hosts/', fetch_redirect_response=False)
+ response = self.client.get("/logout/allowed_hosts/?next=https://evil/")
+ self.assertRedirects(
+ response, "/logout/allowed_hosts/", fetch_redirect_response=False
+ )
self.confirm_logged_out()
def test_security_check(self):
- logout_url = reverse('logout')
+ logout_url = reverse("logout")
# These URLs should not pass the security check.
bad_urls = (
- 'http://example.com',
- 'http:///example.com',
- 'https://example.com',
- 'ftp://example.com',
- '///example.com',
- '//example.com',
+ "http://example.com",
+ "http:///example.com",
+ "https://example.com",
+ "ftp://example.com",
+ "///example.com",
+ "//example.com",
'javascript:alert("XSS")',
)
for bad_url in bad_urls:
with self.subTest(bad_url=bad_url):
- nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
- 'url': logout_url,
- 'next': REDIRECT_FIELD_NAME,
- 'bad_url': quote(bad_url),
+ nasty_url = "%(url)s?%(next)s=%(bad_url)s" % {
+ "url": logout_url,
+ "next": REDIRECT_FIELD_NAME,
+ "bad_url": quote(bad_url),
}
self.login()
response = self.client.get(nasty_url)
self.assertEqual(response.status_code, 302)
- self.assertNotIn(bad_url, response.url, '%s should be blocked' % bad_url)
+ self.assertNotIn(
+ bad_url, response.url, "%s should be blocked" % bad_url
+ )
self.confirm_logged_out()
# These URLs should pass the security check.
good_urls = (
- '/view/?param=http://example.com',
- '/view/?param=https://example.com',
- '/view?param=ftp://example.com',
- 'view/?param=//example.com',
- 'https://testserver/',
- 'HTTPS://testserver/',
- '//testserver/',
- '/url%20with%20spaces/',
+ "/view/?param=http://example.com",
+ "/view/?param=https://example.com",
+ "/view?param=ftp://example.com",
+ "view/?param=//example.com",
+ "https://testserver/",
+ "HTTPS://testserver/",
+ "//testserver/",
+ "/url%20with%20spaces/",
)
for good_url in good_urls:
with self.subTest(good_url=good_url):
- safe_url = '%(url)s?%(next)s=%(good_url)s' % {
- 'url': logout_url,
- 'next': REDIRECT_FIELD_NAME,
- 'good_url': quote(good_url),
+ safe_url = "%(url)s?%(next)s=%(good_url)s" % {
+ "url": logout_url,
+ "next": REDIRECT_FIELD_NAME,
+ "good_url": quote(good_url),
}
self.login()
response = self.client.get(safe_url)
self.assertEqual(response.status_code, 302)
- self.assertIn(good_url, response.url, '%s should be allowed' % good_url)
+ self.assertIn(good_url, response.url, "%s should be allowed" % good_url)
self.confirm_logged_out()
def test_security_check_https(self):
- logout_url = reverse('logout')
- non_https_next_url = 'http://testserver/'
- url = '%(url)s?%(next)s=%(next_url)s' % {
- 'url': logout_url,
- 'next': REDIRECT_FIELD_NAME,
- 'next_url': quote(non_https_next_url),
+ logout_url = reverse("logout")
+ non_https_next_url = "http://testserver/"
+ url = "%(url)s?%(next)s=%(next_url)s" % {
+ "url": logout_url,
+ "next": REDIRECT_FIELD_NAME,
+ "next_url": quote(non_https_next_url),
}
self.login()
response = self.client.get(url, secure=True)
self.assertRedirects(response, logout_url, fetch_redirect_response=False)
self.confirm_logged_out()
def test_logout_preserve_language(self):
"""Language is preserved after logout."""
self.login()
- self.client.post('/setlang/', {'language': 'pl'})
- self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, 'pl')
- self.client.get('/logout/')
- self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, 'pl')
-
- @override_settings(LOGOUT_REDIRECT_URL='/custom/')
+ self.client.post("/setlang/", {"language": "pl"})
+ self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, "pl")
+ self.client.get("/logout/")
+ self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, "pl")
+
+ @override_settings(LOGOUT_REDIRECT_URL="/custom/")
def test_logout_redirect_url_setting(self):
self.login()
- response = self.client.get('/logout/')
- self.assertRedirects(response, '/custom/', fetch_redirect_response=False)
-
- @override_settings(LOGOUT_REDIRECT_URL='logout')
+ response = self.client.get("/logout/")
+ self.assertRedirects(response, "/custom/", fetch_redirect_response=False)
+
+ @override_settings(LOGOUT_REDIRECT_URL="logout")
def test_logout_redirect_url_named_setting(self):
self.login()
- response = self.client.get('/logout/')
- self.assertRedirects(response, '/logout/', fetch_redirect_response=False)
+ response = self.client.get("/logout/")
+ self.assertRedirects(response, "/logout/", fetch_redirect_response=False)
def get_perm(Model, perm):
ct = ContentType.objects.get_for_model(Model)
return Permission.objects.get(content_type=ct, codename=perm)
# Redirect in test_user_change_password will fail if session auth hash
# isn't updated after password change (#21649)
-@override_settings(ROOT_URLCONF='auth_tests.urls_admin')
+@override_settings(ROOT_URLCONF="auth_tests.urls_admin")
class ChangelistTests(AuthViewsTestCase):
-
@classmethod
def setUpTestData(cls):
super().setUpTestData()
# Make me a superuser before logging in.
- User.objects.filter(username='testclient').update(is_staff=True, is_superuser=True)
+ User.objects.filter(username="testclient").update(
+ is_staff=True, is_superuser=True
+ )
def setUp(self):
self.login()
# Get the latest last_login value.
self.admin = User.objects.get(pk=self.u1.pk)
def get_user_data(self, user):
return {
- 'username': user.username,
- 'password': user.password,
- 'email': user.email,
- 'is_active': user.is_active,
- 'is_staff': user.is_staff,
- 'is_superuser': user.is_superuser,
- 'last_login_0': user.last_login.strftime('%Y-%m-%d'),
- 'last_login_1': user.last_login.strftime('%H:%M:%S'),
- 'initial-last_login_0': user.last_login.strftime('%Y-%m-%d'),
- 'initial-last_login_1': user.last_login.strftime('%H:%M:%S'),
- 'date_joined_0': user.date_joined.strftime('%Y-%m-%d'),
- 'date_joined_1': user.date_joined.strftime('%H:%M:%S'),
- 'initial-date_joined_0': user.date_joined.strftime('%Y-%m-%d'),
- 'initial-date_joined_1': user.date_joined.strftime('%H:%M:%S'),
- 'first_name': user.first_name,
- 'last_name': user.last_name,
+ "username": user.username,
+ "password": user.password,
+ "email": user.email,
+ "is_active": user.is_active,
+ "is_staff": user.is_staff,
+ "is_superuser": user.is_superuser,
+ "last_login_0": user.last_login.strftime("%Y-%m-%d"),
+ "last_login_1": user.last_login.strftime("%H:%M:%S"),
+ "initial-last_login_0": user.last_login.strftime("%Y-%m-%d"),
+ "initial-last_login_1": user.last_login.strftime("%H:%M:%S"),
+ "date_joined_0": user.date_joined.strftime("%Y-%m-%d"),
+ "date_joined_1": user.date_joined.strftime("%H:%M:%S"),
+ "initial-date_joined_0": user.date_joined.strftime("%Y-%m-%d"),
+ "initial-date_joined_1": user.date_joined.strftime("%H:%M:%S"),
+ "first_name": user.first_name,
+ "last_name": user.last_name,
}
# #20078 - users shouldn't be allowed to guess password hashes via
# repeated password__startswith queries.
def test_changelist_disallows_password_lookups(self):
# A lookup that tries to filter on password isn't OK
- with self.assertLogs('django.security.DisallowedModelAdminLookup', 'ERROR'):
- response = self.client.get(reverse('auth_test_admin:auth_user_changelist') + '?password__startswith=sha1$')
+ with self.assertLogs("django.security.DisallowedModelAdminLookup", "ERROR"):
+ response = self.client.get(
+ reverse("auth_test_admin:auth_user_changelist")
+ + "?password__startswith=sha1$"
+ )
self.assertEqual(response.status_code, 400)
def test_user_change_email(self):
data = self.get_user_data(self.admin)
- data['email'] = 'new_' + data['email']
- response = self.client.post(
- reverse('auth_test_admin:auth_user_change', args=(self.admin.pk,)),
- data
- )
- self.assertRedirects(response, reverse('auth_test_admin:auth_user_changelist'))
- row = LogEntry.objects.latest('id')
- self.assertEqual(row.get_change_message(), 'Changed Email address.')
+ data["email"] = "new_" + data["email"]
+ response = self.client.post(
+ reverse("auth_test_admin:auth_user_change", args=(self.admin.pk,)), data
+ )
+ self.assertRedirects(response, reverse("auth_test_admin:auth_user_changelist"))
+ row = LogEntry.objects.latest("id")
+ self.assertEqual(row.get_change_message(), "Changed Email address.")
def test_user_not_change(self):
response = self.client.post(
- reverse('auth_test_admin:auth_user_change', args=(self.admin.pk,)),
- self.get_user_data(self.admin)
- )
- self.assertRedirects(response, reverse('auth_test_admin:auth_user_changelist'))
- row = LogEntry.objects.latest('id')
- self.assertEqual(row.get_change_message(), 'No fields changed.')
+ reverse("auth_test_admin:auth_user_change", args=(self.admin.pk,)),
+ self.get_user_data(self.admin),
+ )
+ self.assertRedirects(response, reverse("auth_test_admin:auth_user_changelist"))
+ row = LogEntry.objects.latest("id")
+ self.assertEqual(row.get_change_message(), "No fields changed.")
def test_user_change_password(self):
- user_change_url = reverse('auth_test_admin:auth_user_change', args=(self.admin.pk,))
- password_change_url = reverse('auth_test_admin:auth_user_password_change', args=(self.admin.pk,))
+ user_change_url = reverse(
+ "auth_test_admin:auth_user_change", args=(self.admin.pk,)
+ )
+ password_change_url = reverse(
+ "auth_test_admin:auth_user_password_change", args=(self.admin.pk,)
+ )
response = self.client.get(user_change_url)
# Test the link inside password field help_text.
rel_link = re.search(
r'you can change the password using <a href="([^"]*)">this form</a>',
- response.content.decode()
+ response.content.decode(),
)[1]
self.assertEqual(
os.path.normpath(user_change_url + rel_link),
- os.path.normpath(password_change_url)
- )
-
- response = self.client.post(
- password_change_url,
- {
- 'password1': 'password1',
- 'password2': 'password1',
- }
+ os.path.normpath(password_change_url),
+ )
+
+ response = self.client.post(
+ password_change_url, {"password1": "password1", "password2": "password1",}
)
self.assertRedirects(response, user_change_url)
- row = LogEntry.objects.latest('id')
- self.assertEqual(row.get_change_message(), 'Changed password.')
+ row = LogEntry.objects.latest("id")
+ self.assertEqual(row.get_change_message(), "Changed password.")
self.logout()
- self.login(password='password1')
+ self.login(password="password1")
def test_user_change_different_user_password(self):
- u = User.objects.get(email='[email protected]')
- response = self.client.post(
- reverse('auth_test_admin:auth_user_password_change', args=(u.pk,)),
- {
- 'password1': 'password1',
- 'password2': 'password1',
- }
- )
- self.assertRedirects(response, reverse('auth_test_admin:auth_user_change', args=(u.pk,)))
- row = LogEntry.objects.latest('id')
+ u = User.objects.get(email="[email protected]")
+ response = self.client.post(
+ reverse("auth_test_admin:auth_user_password_change", args=(u.pk,)),
+ {"password1": "password1", "password2": "password1",},
+ )
+ self.assertRedirects(
+ response, reverse("auth_test_admin:auth_user_change", args=(u.pk,))
+ )
+ row = LogEntry.objects.latest("id")
self.assertEqual(row.user_id, self.admin.pk)
self.assertEqual(row.object_id, str(u.pk))
- self.assertEqual(row.get_change_message(), 'Changed password.')
+ self.assertEqual(row.get_change_message(), "Changed password.")
def test_password_change_bad_url(self):
- response = self.client.get(reverse('auth_test_admin:auth_user_password_change', args=('foobar',)))
+ response = self.client.get(
+ reverse("auth_test_admin:auth_user_password_change", args=("foobar",))
+ )
self.assertEqual(response.status_code, 404)
- @mock.patch('django.contrib.auth.admin.UserAdmin.has_change_permission')
- def test_user_change_password_passes_user_to_has_change_permission(self, has_change_permission):
- url = reverse('auth_test_admin:auth_user_password_change', args=(self.admin.pk,))
- self.client.post(url, {'password1': 'password1', 'password2': 'password1'})
+ @mock.patch("django.contrib.auth.admin.UserAdmin.has_change_permission")
+ def test_user_change_password_passes_user_to_has_change_permission(
+ self, has_change_permission
+ ):
+ url = reverse(
+ "auth_test_admin:auth_user_password_change", args=(self.admin.pk,)
+ )
+ self.client.post(url, {"password1": "password1", "password2": "password1"})
(_request, user), _kwargs = has_change_permission.call_args
self.assertEqual(user.pk, self.admin.pk)
def test_view_user_password_is_readonly(self):
- u = User.objects.get(username='testclient')
+ u = User.objects.get(username="testclient")
u.is_superuser = False
u.save()
original_password = u.password
- u.user_permissions.add(get_perm(User, 'view_user'))
- response = self.client.get(reverse('auth_test_admin:auth_user_change', args=(u.pk,)),)
- algo, salt, hash_string = (u.password.split('$'))
+ u.user_permissions.add(get_perm(User, "view_user"))
+ response = self.client.get(
+ reverse("auth_test_admin:auth_user_change", args=(u.pk,)),
+ )
+ algo, salt, hash_string = u.password.split("$")
self.assertContains(response, '<div class="readonly">testclient</div>')
# ReadOnlyPasswordHashWidget is used to render the field.
self.assertContains(
response,
- '<strong>algorithm</strong>: %s\n\n'
- '<strong>salt</strong>: %s**********\n\n'
- '<strong>hash</strong>: %s**************************\n\n' % (
- algo, salt[:2], hash_string[:6],
- ),
+ "<strong>algorithm</strong>: %s\n\n"
+ "<strong>salt</strong>: %s**********\n\n"
+ "<strong>hash</strong>: %s**************************\n\n"
+ % (algo, salt[:2], hash_string[:6],),
html=True,
)
# Value in POST data is ignored.
data = self.get_user_data(u)
- data['password'] = 'shouldnotchange'
- change_url = reverse('auth_test_admin:auth_user_change', args=(u.pk,))
+ data["password"] = "shouldnotchange"
+ change_url = reverse("auth_test_admin:auth_user_change", args=(u.pk,))
response = self.client.post(change_url, data)
self.assertEqual(response.status_code, 403)
u.refresh_from_db()
self.assertEqual(u.password, original_password)
@override_settings(
- AUTH_USER_MODEL='auth_tests.UUIDUser',
- ROOT_URLCONF='auth_tests.urls_custom_user_admin',
+ AUTH_USER_MODEL="auth_tests.UUIDUser",
+ ROOT_URLCONF="auth_tests.urls_custom_user_admin",
)
class UUIDUserTests(TestCase):
-
def test_admin_password_change(self):
- u = UUIDUser.objects.create_superuser(username='uuid', email='[email protected]', password='test')
- self.assertTrue(self.client.login(username='uuid', password='test'))
-
- user_change_url = reverse('custom_user_admin:auth_tests_uuiduser_change', args=(u.pk,))
+ u = UUIDUser.objects.create_superuser(
+ username="uuid", email="[email protected]", password="test"
+ )
+ self.assertTrue(self.client.login(username="uuid", password="test"))
+
+ user_change_url = reverse(
+ "custom_user_admin:auth_tests_uuiduser_change", args=(u.pk,)
+ )
response = self.client.get(user_change_url)
self.assertEqual(response.status_code, 200)
- password_change_url = reverse('custom_user_admin:auth_user_password_change', args=(u.pk,))
+ password_change_url = reverse(
+ "custom_user_admin:auth_user_password_change", args=(u.pk,)
+ )
response = self.client.get(password_change_url)
# The action attribute is omitted.
self.assertContains(response, '<form method="post" id="uuiduser_form">')
# A LogEntry is created with pk=1 which breaks a FK constraint on MySQL
with connection.constraint_checks_disabled():
- response = self.client.post(password_change_url, {
- 'password1': 'password1',
- 'password2': 'password1',
- })
+ response = self.client.post(
+ password_change_url,
+ {"password1": "password1", "password2": "password1",},
+ )
self.assertRedirects(response, user_change_url)
- row = LogEntry.objects.latest('id')
+ row = LogEntry.objects.latest("id")
self.assertEqual(row.user_id, 1) # hardcoded in CustomUserAdmin.log_change()
self.assertEqual(row.object_id, str(u.pk))
- self.assertEqual(row.get_change_message(), 'Changed password.')
+ self.assertEqual(row.get_change_message(), "Changed password.")
# The LogEntry.user column isn't altered to a UUID type so it's set to
# an integer manually in CustomUserAdmin to avoid an error. To avoid a
# constraint error, delete the entry before constraints are checked
# after the test.
--- first pass
+++ second pass
@@ -760,13 +760,13 @@
}
# Use POST request to log in
SessionMiddleware(get_response).process_request(req)
CsrfViewMiddleware(get_response).process_view(req, LoginView.as_view(), (), {})
- req.META["SERVER_NAME"] = ( # Required to have redirect work in login view
- "testserver"
- )
+ req.META[
+ "SERVER_NAME"
+ ] = "testserver" # Required to have redirect work in login view
req.META["SERVER_PORT"] = 80
resp = CsrfViewMiddleware(LoginView.as_view())(req)
csrf_cookie = resp.cookies.get(settings.CSRF_COOKIE_NAME, None)
token2 = csrf_cookie.coded_value |
Thanks for looking into this @hugovk! The Django ones look weird—how could the attrs/dataclasses switch have caused those? |
This comment has been minimized.
This comment has been minimized.
alexmv
added a commit
to alexmv/black
that referenced
this issue
May 22, 2020
The PEP 257 algorithm used in psf#1053 results in trimming trailing whitespace in docstrings -- see psf#1415 and fixes in psf#1417. Removing trailing whitespace may result in four quotes in a row: def foo(): """"Some content and more "here" """ pass When closing the docstring, escape any trailing quote characters that it matches, if they are not already escaped. Fixes psf#1446.
alexmv
added a commit
to alexmv/black
that referenced
this issue
May 22, 2020
The PEP 257 algorithm used in psf#1053 results in trimming trailing whitespace in docstrings -- see psf#1415 and fixes in psf#1417. Removing trailing whitespace may result in four quotes in a row: def foo(): """"Some content and more "here" """ pass When closing the docstring, escape any trailing quote characters that it matches, if they are not already escaped. Fixes psf#1446.
This has been resolved since c1c2418 🎉 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Black Primer (black-primer) is now running on Black's CI. It
git clone
's some popular Python projects that use Black and ensure we don't hit errors. Today this is not true, and we hit invalid formatting on 3 projects. They are:They all return error 123.
Repro:
”disabled": false,
for the above projects insrc/black_primer/primer.json
to get the error output.The text was updated successfully, but these errors were encountered: