diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -155,16 +155,20 @@ of which this module provides three diff .. attribute:: responses This variable contains a mapping of error code integers to two-element tuples containing a short and long message. For example, ``{code: (shortmessage, longmessage)}``. The *shortmessage* is usually used as the *message* key in an error response, and *longmessage* as the *explain* key (see the :attr:`error_message_format` class variable). + .. versionchanged:: 3.6 + Previously undocumented ``weekdayname`` and ``monthname`` attributes were + deprecated. + A :class:`BaseHTTPRequestHandler` instance has the following methods: .. method:: handle() Calls :meth:`handle_one_request` once (or, if persistent connections are enabled, multiple times) to handle incoming HTTP requests. You should never need to override it; instead, implement appropriate :meth:`do_\*` methods. diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -125,17 +125,19 @@ New Keywords ``async`` and ``await`` are not recommended to be used as variable, class, function or module names. Introduced by :pep:`492` in Python 3.5, they will become proper keywords in Python 3.7. Deprecated Python modules, functions and methods ------------------------------------------------ -* None yet. +* Previously undocumented ``weekdayname`` and ``monthname`` attributes of + :class:`http.server.BaseHTTPRequestHandler` are now deprecated. + (Contributed by karlcow and Berker Peksag in :issue:`747320`.) Deprecated functions and types of the C API ------------------------------------------- * None yet. diff --git a/Lib/http/server.py b/Lib/http/server.py --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -82,31 +82,33 @@ XXX To do: __version__ = "0.6" __all__ = [ "HTTPServer", "BaseHTTPRequestHandler", "SimpleHTTPRequestHandler", "CGIHTTPRequestHandler", ] +import email.utils import html import http.client import io import mimetypes import os import posixpath import select import shutil import socket # For gethostbyaddr() import socketserver import sys import time import urllib.parse import copy import argparse +import warnings from http import HTTPStatus # Default error message template DEFAULT_ERROR_MESSAGE = """\ @@ -561,36 +563,37 @@ class BaseHTTPRequestHandler(socketserve def version_string(self): """Return the server software version string.""" return self.server_version + ' ' + self.sys_version def date_time_string(self, timestamp=None): """Return the current date and time formatted for a message header.""" if timestamp is None: timestamp = time.time() - year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp) - s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % ( - self.weekdayname[wd], - day, self.monthname[month], year, - hh, mm, ss) + s = email.utils.formatdate(timestamp, localtime=False, usegmt=True) return s def log_date_time_string(self): """Return the current time formatted for logging.""" - now = time.time() - year, month, day, hh, mm, ss, x, y, z = time.localtime(now) - s = "%02d/%3s/%04d %02d:%02d:%02d" % ( - day, self.monthname[month], year, hh, mm, ss) + s = time.strftime("%d/%b/%Y %H:%M:%S", time.localtime()) return s - weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + @property + def weekdayname(self): + warnings.warn("'weekdayname' is deprecated", DeprecationWarning, + stacklevel=2) + return ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] - monthname = [None, - 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + @property + def monthname(self): + warnings.warn("'monthname' is deprecated", DeprecationWarning, + stacklevel=2) + return [None, + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] def address_string(self): """Return the client address.""" return self.client_address[0] # Essentially static class variables diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -3,25 +3,28 @@ Written by Cody A.W. Somerville , Josip Dzolonga, and Michael Otteneder for the 2007/08 GHOP contest. """ from http.server import BaseHTTPRequestHandler, HTTPServer, \ SimpleHTTPRequestHandler, CGIHTTPRequestHandler from http import server, HTTPStatus +import email.utils import os import sys import re import base64 import shutil import urllib.parse import html import http.client import tempfile +import time +import warnings from io import BytesIO import unittest from test import support threading = support.import_module('threading') class NoLogRequestHandler: def log_message(self, *args): @@ -837,16 +840,39 @@ class BaseHTTPRequestHandlerTestCase(uni close_values = iter((True,)) self.handler.handle() self.assertRaises(StopIteration, next, close_values) close_values = iter((False, False, True)) self.handler.handle() self.assertRaises(StopIteration, next, close_values) + def test_date_time_string(self): + now = time.time() + # this is the old code that formats the timestamp + year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + expected = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % ( + self.handler.weekdayname[wd], + day, + self.handler.monthname[month], + year, hh, mm, ss + ) + self.assertEqual(self.handler.date_time_string(timestamp=now), expected) + + def test_deprecate_unused_attributes(self): + with self.assertWarnsRegex(DeprecationWarning, + "'weekdayname' is deprecated"): + self.handler.weekdayname + with self.assertWarnsRegex(DeprecationWarning, + "'monthname' is deprecated"): + self.handler.monthname + + class SimpleHTTPRequestHandlerTestCase(unittest.TestCase): """ Test url parsing """ def setUp(self): self.translated = os.getcwd() self.translated = os.path.join(self.translated, 'filename') self.handler = SocketlessRequestHandler() def test_query_arguments(self):