Fix closes issue 1673007 urllib.request to support HEAD requests with a new method arg.
diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst
index c08cbc6..ecb357e 100644
--- a/Doc/library/urllib.request.rst
+++ b/Doc/library/urllib.request.rst
@@ -132,7 +132,7 @@
 
 The following classes are provided:
 
-.. class:: Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False)
+.. class:: Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
 
    This class is an abstraction of a URL request.
 
@@ -140,8 +140,8 @@
 
    *data* may be a string specifying additional data to send to the
    server, or ``None`` if no such data is needed.  Currently HTTP
-   requests are the only ones that use *data*; the HTTP request will
-   be a POST instead of a GET when the *data* parameter is provided.
+   requests are the only ones that use *data*, in order to choose between
+   ``'GET'`` and ``'POST'`` when *method* is not specified.
    *data* should be a buffer in the standard
    :mimetype:`application/x-www-form-urlencoded` format.  The
    :func:`urllib.parse.urlencode` function takes a mapping or sequence
@@ -157,8 +157,8 @@
    :mod:`urllib`'s default user agent string is
    ``"Python-urllib/2.6"`` (on Python 2.6).
 
-   The final two arguments are only of interest for correct handling
-   of third-party HTTP cookies:
+   The following two arguments, *origin_req_host* and *unverifiable*,
+   are only of interest for correct handling of third-party HTTP cookies:
 
    *origin_req_host* should be the request-host of the origin
    transaction, as defined by :rfc:`2965`.  It defaults to
@@ -175,6 +175,13 @@
    document, and the user had no option to approve the automatic
    fetching of the image, this should be true.
 
+   *method* should be a string that indicates the HTTP request method that
+   will be used (e.g. ``'HEAD'``).  Its value is stored in the
+   :attr:`Request.method` attribute and is used by :meth:`Request.get_method()`.
+
+   .. versionchanged:: 3.3
+    :attr:`Request.method` argument is added to the Request class.
+
 
 .. class:: OpenerDirector()
 
@@ -369,6 +376,15 @@
    boolean, indicates whether the request is unverifiable as defined
    by RFC 2965.
 
+.. attribute:: Request.method
+
+   The HTTP request method to use.  This value is used by
+   :meth:`Request.get_method` to override the computed HTTP request
+   method that would otherwise be returned.  This attribute is
+   initialized with the value of the *method* argument passed to the constructor.
+
+   ..versionadded:: 3.3
+
 .. method:: Request.add_data(data)
 
    Set the :class:`Request` data to *data*.  This is ignored by all handlers except
@@ -378,8 +394,13 @@
 
 .. method:: Request.get_method()
 
-   Return a string indicating the HTTP request method.  This is only meaningful for
-   HTTP requests, and currently always returns ``'GET'`` or ``'POST'``.
+   Return a string indicating the HTTP request method.  If
+   :attr:`Request.method` is not ``None``, return its value, otherwise return
+   ``'GET'`` if :attr:`Request.data` is ``None``, or ``'POST'`` if it's not.
+   This is only meaningful for HTTP requests.
+
+    .. versionchanged:: 3.3
+    get_method now looks at the value of :attr:`Request.method` first.
 
 
 .. method:: Request.has_data()
diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst
index 6c57d72..945aa97 100644
--- a/Doc/whatsnew/3.3.rst
+++ b/Doc/whatsnew/3.3.rst
@@ -474,6 +474,16 @@
     path also specifying the user/group names and not only their numeric
     ids. (Contributed by Sandro Tosi in :issue:`12191`)
 
+urllib
+------
+
+The :class:`~urllib.request.Request` class, now accepts a *method* argument
+used by :meth:`~urllib.request.Request.get_method` to determine what HTTP method
+should be used.  For example, this will send an ``'HEAD'`` request::
+
+   >>> urlopen(Request('http://www.python.org', method='HEAD'))
+
+(:issue:`1673007`)
 
 Optimizations
 =============
diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py
index 77637a6..4e34ae5 100644
--- a/Lib/test/test_urllib.py
+++ b/Lib/test/test_urllib.py
@@ -1157,6 +1157,28 @@
 #         self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
 #         ftp.close()
 
+class RequestTests(unittest.TestCase):
+    """Unit tests for urllib.request.Request."""
+
+    def test_default_values(self):
+        Request = urllib.request.Request
+        request = Request("http://www.python.org")
+        self.assertEqual(request.get_method(), 'GET')
+        request = Request("http://www.python.org", {})
+        self.assertEqual(request.get_method(), 'POST')
+
+    def test_with_method_arg(self):
+        Request = urllib.request.Request
+        request = Request("http://www.python.org", method='HEAD')
+        self.assertEqual(request.method, 'HEAD')
+        self.assertEqual(request.get_method(), 'HEAD')
+        request = Request("http://www.python.org", {}, method='HEAD')
+        self.assertEqual(request.method, 'HEAD')
+        self.assertEqual(request.get_method(), 'HEAD')
+        request = Request("http://www.python.org", method='GET')
+        self.assertEqual(request.get_method(), 'GET')
+        request.method = 'HEAD'
+        self.assertEqual(request.get_method(), 'HEAD')
 
 
 def test_main():
@@ -1172,6 +1194,7 @@
         Utility_Tests,
         URLopener_Tests,
         #FTPWrapperTests,
+        RequestTests,
     )
 
 
diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py
index a947608..65ce287 100644
--- a/Lib/urllib/request.py
+++ b/Lib/urllib/request.py
@@ -177,7 +177,8 @@
 class Request:
 
     def __init__(self, url, data=None, headers={},
-                 origin_req_host=None, unverifiable=False):
+                 origin_req_host=None, unverifiable=False,
+                 method=None):
         # unwrap('<URL:type://host/path>') --> 'type://host/path'
         self.full_url = unwrap(url)
         self.full_url, self.fragment = splittag(self.full_url)
@@ -191,6 +192,7 @@
             origin_req_host = request_host(self)
         self.origin_req_host = origin_req_host
         self.unverifiable = unverifiable
+        self.method = method
         self._parse()
 
     def _parse(self):
@@ -202,7 +204,10 @@
             self.host = unquote(self.host)
 
     def get_method(self):
-        if self.data is not None:
+        """Return a string indicating the HTTP request method."""
+        if self.method is not None:
+            return self.method
+        elif self.data is not None:
             return "POST"
         else:
             return "GET"
diff --git a/Misc/NEWS b/Misc/NEWS
index f02e878..f490a7a 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -304,6 +304,10 @@
 
 Library
 -------
+
+- issue #1673007: urllib2  to support HEAD request via new method argument.
+  Patch contributions by David Stanek, Patrick Westerhoff and Ezio Melotti.
+
 - Issue #12386: packaging does not fail anymore when writing the RESOURCES
   file.