Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Unified Diff: tools/telemetry/third_party/gsutilz/third_party/protorpc/protorpc/util.py

Issue 1493973002: Remove telemetry/third_party/gsutilz (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gsutil_changes
Patch Set: rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/third_party/gsutilz/third_party/protorpc/protorpc/util.py
diff --git a/tools/telemetry/third_party/gsutilz/third_party/protorpc/protorpc/util.py b/tools/telemetry/third_party/gsutilz/third_party/protorpc/protorpc/util.py
deleted file mode 100755
index 50893c9e14b642a861745825b97537d13808a119..0000000000000000000000000000000000000000
--- a/tools/telemetry/third_party/gsutilz/third_party/protorpc/protorpc/util.py
+++ /dev/null
@@ -1,492 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2010 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""Common utility library."""
-
-from __future__ import with_statement
-import six
-
-__author__ = ['rafek@google.com (Rafe Kaplan)',
- 'guido@google.com (Guido van Rossum)',
-]
-
-import cgi
-import datetime
-import inspect
-import os
-import re
-import sys
-
-__all__ = ['AcceptItem',
- 'AcceptError',
- 'Error',
- 'choose_content_type',
- 'decode_datetime',
- 'get_package_for_module',
- 'pad_string',
- 'parse_accept_header',
- 'positional',
- 'PROTORPC_PROJECT_URL',
- 'TimeZoneOffset',
- 'total_seconds',
-]
-
-
-class Error(Exception):
- """Base class for protorpc exceptions."""
-
-
-class AcceptError(Error):
- """Raised when there is an error parsing the accept header."""
-
-
-PROTORPC_PROJECT_URL = 'http://code.google.com/p/google-protorpc'
-
-_TIME_ZONE_RE_STRING = r"""
- # Examples:
- # +01:00
- # -05:30
- # Z12:00
- ((?P<z>Z) | (?P<sign>[-+])
- (?P<hours>\d\d) :
- (?P<minutes>\d\d))$
-"""
-_TIME_ZONE_RE = re.compile(_TIME_ZONE_RE_STRING, re.IGNORECASE | re.VERBOSE)
-
-
-def pad_string(string):
- """Pad a string for safe HTTP error responses.
-
- Prevents Internet Explorer from displaying their own error messages
- when sent as the content of error responses.
-
- Args:
- string: A string.
-
- Returns:
- Formatted string left justified within a 512 byte field.
- """
- return string.ljust(512)
-
-
-def positional(max_positional_args):
- """A decorator to declare that only the first N arguments may be positional.
-
- This decorator makes it easy to support Python 3 style keyword-only
- parameters. For example, in Python 3 it is possible to write:
-
- def fn(pos1, *, kwonly1=None, kwonly1=None):
- ...
-
- All named parameters after * must be a keyword:
-
- fn(10, 'kw1', 'kw2') # Raises exception.
- fn(10, kwonly1='kw1') # Ok.
-
- Example:
- To define a function like above, do:
-
- @positional(1)
- def fn(pos1, kwonly1=None, kwonly2=None):
- ...
-
- If no default value is provided to a keyword argument, it becomes a required
- keyword argument:
-
- @positional(0)
- def fn(required_kw):
- ...
-
- This must be called with the keyword parameter:
-
- fn() # Raises exception.
- fn(10) # Raises exception.
- fn(required_kw=10) # Ok.
-
- When defining instance or class methods always remember to account for
- 'self' and 'cls':
-
- class MyClass(object):
-
- @positional(2)
- def my_method(self, pos1, kwonly1=None):
- ...
-
- @classmethod
- @positional(2)
- def my_method(cls, pos1, kwonly1=None):
- ...
-
- One can omit the argument to 'positional' altogether, and then no
- arguments with default values may be passed positionally. This
- would be equivalent to placing a '*' before the first argument
- with a default value in Python 3. If there are no arguments with
- default values, and no argument is given to 'positional', an error
- is raised.
-
- @positional
- def fn(arg1, arg2, required_kw1=None, required_kw2=0):
- ...
-
- fn(1, 3, 5) # Raises exception.
- fn(1, 3) # Ok.
- fn(1, 3, required_kw1=5) # Ok.
-
- Args:
- max_positional_arguments: Maximum number of positional arguments. All
- parameters after the this index must be keyword only.
-
- Returns:
- A decorator that prevents using arguments after max_positional_args from
- being used as positional parameters.
-
- Raises:
- TypeError if a keyword-only argument is provided as a positional parameter.
- ValueError if no maximum number of arguments is provided and the function
- has no arguments with default values.
- """
- def positional_decorator(wrapped):
- def positional_wrapper(*args, **kwargs):
- if len(args) > max_positional_args:
- plural_s = ''
- if max_positional_args != 1:
- plural_s = 's'
- raise TypeError('%s() takes at most %d positional argument%s '
- '(%d given)' % (wrapped.__name__,
- max_positional_args,
- plural_s, len(args)))
- return wrapped(*args, **kwargs)
- return positional_wrapper
-
- if isinstance(max_positional_args, six.integer_types):
- return positional_decorator
- else:
- args, _, _, defaults = inspect.getargspec(max_positional_args)
- if defaults is None:
- raise ValueError(
- 'Functions with no keyword arguments must specify '
- 'max_positional_args')
- return positional(len(args) - len(defaults))(max_positional_args)
-
-
-# TODO(rafek): Support 'level' from the Accept header standard.
-class AcceptItem(object):
- """Encapsulate a single entry of an Accept header.
-
- Parses and extracts relevent values from an Accept header and implements
- a sort order based on the priority of each requested type as defined
- here:
-
- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
-
- Accept headers are normally a list of comma separated items. Each item
- has the format of a normal HTTP header. For example:
-
- Accept: text/plain, text/html, text/*, */*
-
- This header means to prefer plain text over HTML, HTML over any other
- kind of text and text over any other kind of supported format.
-
- This class does not attempt to parse the list of items from the Accept header.
- The constructor expects the unparsed sub header and the index within the
- Accept header that the fragment was found.
-
- Properties:
- index: The index that this accept item was found in the Accept header.
- main_type: The main type of the content type.
- sub_type: The sub type of the content type.
- q: The q value extracted from the header as a float. If there is no q
- value, defaults to 1.0.
- values: All header attributes parsed form the sub-header.
- sort_key: A tuple (no_main_type, no_sub_type, q, no_values, index):
- no_main_type: */* has the least priority.
- no_sub_type: Items with no sub-type have less priority.
- q: Items with lower q value have less priority.
- no_values: Items with no values have less priority.
- index: Index of item in accept header is the last priority.
- """
-
- __CONTENT_TYPE_REGEX = re.compile(r'^([^/]+)/([^/]+)$')
-
- def __init__(self, accept_header, index):
- """Parse component of an Accept header.
-
- Args:
- accept_header: Unparsed sub-expression of accept header.
- index: The index that this accept item was found in the Accept header.
- """
- accept_header = accept_header.lower()
- content_type, values = cgi.parse_header(accept_header)
- match = self.__CONTENT_TYPE_REGEX.match(content_type)
- if not match:
- raise AcceptError('Not valid Accept header: %s' % accept_header)
- self.__index = index
- self.__main_type = match.group(1)
- self.__sub_type = match.group(2)
- self.__q = float(values.get('q', 1))
- self.__values = values
-
- if self.__main_type == '*':
- self.__main_type = None
-
- if self.__sub_type == '*':
- self.__sub_type = None
-
- self.__sort_key = (not self.__main_type,
- not self.__sub_type,
- -self.__q,
- not self.__values,
- self.__index)
-
- @property
- def index(self):
- return self.__index
-
- @property
- def main_type(self):
- return self.__main_type
-
- @property
- def sub_type(self):
- return self.__sub_type
-
- @property
- def q(self):
- return self.__q
-
- @property
- def values(self):
- """Copy the dictionary of values parsed from the header fragment."""
- return dict(self.__values)
-
- @property
- def sort_key(self):
- return self.__sort_key
-
- def match(self, content_type):
- """Determine if the given accept header matches content type.
-
- Args:
- content_type: Unparsed content type string.
-
- Returns:
- True if accept header matches content type, else False.
- """
- content_type, _ = cgi.parse_header(content_type)
- match = self.__CONTENT_TYPE_REGEX.match(content_type.lower())
- if not match:
- return False
-
- main_type, sub_type = match.group(1), match.group(2)
- if not(main_type and sub_type):
- return False
-
- return ((self.__main_type is None or self.__main_type == main_type) and
- (self.__sub_type is None or self.__sub_type == sub_type))
-
-
- def __cmp__(self, other):
- """Comparison operator based on sort keys."""
- if not isinstance(other, AcceptItem):
- return NotImplemented
- return cmp(self.sort_key, other.sort_key)
-
- def __str__(self):
- """Rebuilds Accept header."""
- content_type = '%s/%s' % (self.__main_type or '*', self.__sub_type or '*')
- values = self.values
-
- if values:
- value_strings = ['%s=%s' % (i, v) for i, v in values.items()]
- return '%s; %s' % (content_type, '; '.join(value_strings))
- else:
- return content_type
-
- def __repr__(self):
- return 'AcceptItem(%r, %d)' % (str(self), self.__index)
-
-
-def parse_accept_header(accept_header):
- """Parse accept header.
-
- Args:
- accept_header: Unparsed accept header. Does not include name of header.
-
- Returns:
- List of AcceptItem instances sorted according to their priority.
- """
- accept_items = []
- for index, header in enumerate(accept_header.split(',')):
- accept_items.append(AcceptItem(header, index))
- return sorted(accept_items)
-
-
-def choose_content_type(accept_header, supported_types):
- """Choose most appropriate supported type based on what client accepts.
-
- Args:
- accept_header: Unparsed accept header. Does not include name of header.
- supported_types: List of content-types supported by the server. The index
- of the supported types determines which supported type is prefered by
- the server should the accept header match more than one at the same
- priority.
-
- Returns:
- The preferred supported type if the accept header matches any, else None.
- """
- for accept_item in parse_accept_header(accept_header):
- for supported_type in supported_types:
- if accept_item.match(supported_type):
- return supported_type
- return None
-
-
-@positional(1)
-def get_package_for_module(module):
- """Get package name for a module.
-
- Helper calculates the package name of a module.
-
- Args:
- module: Module to get name for. If module is a string, try to find
- module in sys.modules.
-
- Returns:
- If module contains 'package' attribute, uses that as package name.
- Else, if module is not the '__main__' module, the module __name__.
- Else, the base name of the module file name. Else None.
- """
- if isinstance(module, six.string_types):
- try:
- module = sys.modules[module]
- except KeyError:
- return None
-
- try:
- return six.text_type(module.package)
- except AttributeError:
- if module.__name__ == '__main__':
- try:
- file_name = module.__file__
- except AttributeError:
- pass
- else:
- base_name = os.path.basename(file_name)
- split_name = os.path.splitext(base_name)
- if len(split_name) == 1:
- return six.text_type(base_name)
- else:
- return u'.'.join(split_name[:-1])
-
- return six.text_type(module.__name__)
-
-
-def total_seconds(offset):
- """Backport of offset.total_seconds() from python 2.7+."""
- seconds = offset.days * 24 * 60 * 60 + offset.seconds
- microseconds = seconds * 10**6 + offset.microseconds
- return microseconds / (10**6 * 1.0)
-
-
-class TimeZoneOffset(datetime.tzinfo):
- """Time zone information as encoded/decoded for DateTimeFields."""
-
- def __init__(self, offset):
- """Initialize a time zone offset.
-
- Args:
- offset: Integer or timedelta time zone offset, in minutes from UTC. This
- can be negative.
- """
- super(TimeZoneOffset, self).__init__()
- if isinstance(offset, datetime.timedelta):
- offset = total_seconds(offset) / 60
- self.__offset = offset
-
- def utcoffset(self, dt):
- """Get the a timedelta with the time zone's offset from UTC.
-
- Returns:
- The time zone offset from UTC, as a timedelta.
- """
- return datetime.timedelta(minutes=self.__offset)
-
- def dst(self, dt):
- """Get the daylight savings time offset.
-
- The formats that ProtoRPC uses to encode/decode time zone information don't
- contain any information about daylight savings time. So this always
- returns a timedelta of 0.
-
- Returns:
- A timedelta of 0.
- """
- return datetime.timedelta(0)
-
-
-def decode_datetime(encoded_datetime):
- """Decode a DateTimeField parameter from a string to a python datetime.
-
- Args:
- encoded_datetime: A string in RFC 3339 format.
-
- Returns:
- A datetime object with the date and time specified in encoded_datetime.
-
- Raises:
- ValueError: If the string is not in a recognized format.
- """
- # Check if the string includes a time zone offset. Break out the
- # part that doesn't include time zone info. Convert to uppercase
- # because all our comparisons should be case-insensitive.
- time_zone_match = _TIME_ZONE_RE.search(encoded_datetime)
- if time_zone_match:
- time_string = encoded_datetime[:time_zone_match.start(1)].upper()
- else:
- time_string = encoded_datetime.upper()
-
- if '.' in time_string:
- format_string = '%Y-%m-%dT%H:%M:%S.%f'
- else:
- format_string = '%Y-%m-%dT%H:%M:%S'
-
- decoded_datetime = datetime.datetime.strptime(time_string, format_string)
-
- if not time_zone_match:
- return decoded_datetime
-
- # Time zone info was included in the parameter. Add a tzinfo
- # object to the datetime. Datetimes can't be changed after they're
- # created, so we'll need to create a new one.
- if time_zone_match.group('z'):
- offset_minutes = 0
- else:
- sign = time_zone_match.group('sign')
- hours, minutes = [int(value) for value in
- time_zone_match.group('hours', 'minutes')]
- offset_minutes = hours * 60 + minutes
- if sign == '-':
- offset_minutes *= -1
-
- return datetime.datetime(decoded_datetime.year,
- decoded_datetime.month,
- decoded_datetime.day,
- decoded_datetime.hour,
- decoded_datetime.minute,
- decoded_datetime.second,
- decoded_datetime.microsecond,
- TimeZoneOffset(offset_minutes))

Powered by Google App Engine
This is Rietveld 408576698