Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.493
diff -u -p -r1.493 form.inc
--- includes/form.inc	16 Sep 2010 20:14:49 -0000	1.493
+++ includes/form.inc	16 Sep 2010 23:24:47 -0000
@@ -1142,6 +1142,18 @@ function _form_validate(&$elements, &$fo
             }
           }
         }
+        // Non-multiple select fields always have a value in HTML. If the user
+        // does not change the form, it will be the value of the first option.
+        // Because of this, if the field is set to #required, it will almost
+        // always pass, even if the user did not select anything. The only case
+        // when the required check fails is if the value of the first option is
+        // an empty string. To enforce this behaviour, forms without a
+        // #default_value get an additional, first "<Select>" option via
+        // form_select_options() by default, which needs special treatment.
+        elseif ($elements['#type'] == 'select' && $elements['#required'] && !$elements['#multiple'] && !isset($elements['#default_value']) && $elements['#value'] === '') {
+          // Set the value to NULL to trigger #required handling below.
+          $elements['#value'] = NULL;
+        }
         elseif (!isset($options[$elements['#value']])) {
           form_error($elements, $t('An illegal choice has been detected. Please contact the site administrator.'));
           watchdog('form', 'Illegal choice %choice in %name element.', array('%choice' => $elements['#value'], '%name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title']), WATCHDOG_ERROR);
@@ -2278,6 +2290,15 @@ function theme_select($variables) {
  *   An HTML string of options for the select form element.
  */
 function form_select_options($element, $choices = NULL) {
+  $options = '';
+  // Add a first, always invalid default option on the top-level for required,
+  // non-multiple select lists that do not have a #default_value. By default,
+  // all select lists in Drupal are #required (TRUE), but normally, select lists
+  // are optional by design. A required and multiple select list does not get
+  // this option, since it would be illogical, user interface-wise.
+  if (!isset($choices) && $element['#required'] && !$element['#multiple'] && !isset($element['#default_value'])) {
+    $options .= '<option value="">' . check_plain(t('<Select>')) . '</option>';
+  }
   if (!isset($choices)) {
     $choices = $element['#options'];
   }
@@ -2285,7 +2306,6 @@ function form_select_options($element, $
   // isset() fails in this situation.
   $value_valid = isset($element['#value']) || array_key_exists('#value', $element);
   $value_is_array = $value_valid && is_array($element['#value']);
-  $options = '';
   foreach ($choices as $key => $choice) {
     if (is_array($choice)) {
       $options .= '<optgroup label="' . $key . '">';
Index: includes/install.core.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/install.core.inc,v
retrieving revision 1.30
diff -u -p -r1.30 install.core.inc
--- includes/install.core.inc	14 Sep 2010 21:42:05 -0000	1.30
+++ includes/install.core.inc	16 Sep 2010 23:27:45 -0000
@@ -1719,6 +1719,7 @@ function _install_configure_form($form, 
   $form['server_settings']['site_default_country'] = array(
     '#type' => 'select',
     '#title' => t('Default country'),
+    '#required' => FALSE,
     '#default_value' => variable_get('site_default_country', ''),
     '#options' => $countries,
     '#description' => st('Select the default country for the site.'),
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.960
diff -u -p -r1.960 system.module
--- modules/system/system.module	11 Sep 2010 06:03:12 -0000	1.960
+++ modules/system/system.module	16 Sep 2010 21:07:02 -0000
@@ -399,6 +399,7 @@ function system_element_info() {
   );
   $types['select'] = array(
     '#input' => TRUE,
+    '#required' => TRUE,
     '#size' => 0,
     '#multiple' => FALSE,
     '#process' => array('ajax_process_form'),
