Source code for falcon.util.misc

# Copyright 2013 by Rackspace Hosting, 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.

import datetime
import functools
import inspect
import warnings

import six

__all__ = (
    'deprecated',
    'dt_to_http',
    'http_date_to_dt',
    'to_query_str',
    'get_bound_method',
)


# NOTE(kgriffs): We don't want our deprecations to be ignored by default,
# so create our own type.
#
# TODO(kgriffs): Revisit this decision if users complain.
class DeprecatedWarning(UserWarning):
    pass


[docs]def deprecated(instructions): """Flags a method as deprecated. This function returns a decorator which can be used to mark deprecated functions. Applying this decorator will result in a warning being emitted when the function is used. Args: instructions (str): Specific guidance for the developer, e.g.: 'Please migrate to add_proxy(...)'' """ def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): message = 'Call to deprecated function {0}(...). {1}'.format( func.__name__, instructions) frame = inspect.currentframe().f_back warnings.warn_explicit(message, category=DeprecatedWarning, filename=inspect.getfile(frame.f_code), lineno=frame.f_lineno) return func(*args, **kwargs) return wrapper return decorator
[docs]def dt_to_http(dt): """Converts a ``datetime`` instance to an HTTP date string. Args: dt (datetime): A ``datetime`` instance to convert, assumed to be UTC. Returns: str: An RFC 1123 date string, e.g.: "Tue, 15 Nov 1994 12:45:26 GMT". """ # Tue, 15 Nov 1994 12:45:26 GMT return dt.strftime('%a, %d %b %Y %H:%M:%S GMT')
[docs]def http_date_to_dt(http_date): """Converts an HTTP date string to a datetime instance. Args: http_date (str): An RFC 1123 date string, e.g.: "Tue, 15 Nov 1994 12:45:26 GMT". Returns: datetime: A UTC datetime instance corresponding to the given HTTP date. """ return datetime.datetime.strptime( http_date, '%a, %d %b %Y %H:%M:%S %Z')
[docs]def to_query_str(params): """Converts a dictionary of params to a query string. Args: params (dict): A dictionary of parameters, where each key is a parameter name, and each value is either a ``str`` or something that can be converted into a ``str``. If `params` is a ``list``, it will be converted to a comma-delimited string of values (e.g., 'thing=1,2,3') Returns: str: A URI query string including the '?' prefix, or an empty string if no params are given (the ``dict`` is empty). """ if not params: return '' # PERF: This is faster than a list comprehension and join, mainly # because it allows us to inline the value transform. query_str = '?' for k, v in params.items(): if v is True: v = 'true' elif v is False: v = 'false' elif isinstance(v, list): v = ','.join(map(str, v)) else: v = str(v) query_str += k + '=' + v + '&' return query_str[:-1]
def get_bound_method(obj, method_name): """Get a bound method of the given object by name. Args: obj: Object on which to look up the method. method_name: Name of the method to retrieve. Returns: Bound method, or ``None`` if the method does not exist on the object. Raises: AttributeError: The method exists, but it isn't bound (most likely a class was passed, rather than an instance of that class). """ method = getattr(obj, method_name, None) if method is not None: # NOTE(kgriffs): Ensure it is a bound method if six.get_method_self(method) is None: # pragma nocover # NOTE(kgriffs): In Python 3 this code is unreachable # because the above will raise AttributeError on its # own. msg = '{0} must be a bound method'.format(method) raise AttributeError(msg) return method