)]}'
{"keystone/common/utils.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"32dc9e9b9521f91a2b7289505754dec1957d90d6","unresolved":false,"context_lines":[{"line_number":519,"context_line":"    @functools.wraps(func)"},{"line_number":520,"context_line":"    def wrapper(*args, **kwargs):"},{"line_number":521,"context_line":"        msg \u003d _(\"%s is deprecated and will be removed in future releases\")"},{"line_number":522,"context_line":"        warnings.warn(msg % func.__name__, DeprecationWarning, stacklevel\u003d2)"},{"line_number":523,"context_line":"        return func(*args, **kwargs)"},{"line_number":524,"context_line":"    return wrapper"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATH%2F%2F2mU%3D","line":522,"updated":"2013-10-08 23:27:38.000000000","message":"Does our logging system use CaptureWarnings?  I am not seeing it referenced in our sample logging.conf or as a defaulted-on oslo option.  This could mean that warnings will not be captured in all cases for deprecation.  If we aren\u0027t capturing warnings (in one-way or another) we should be using a standard log call here instead.\n\nhttp://docs.python.org/2/library/logging.html#logging.captureWarnings","commit_id":"6c2be9244cc074f50801dc284fe7a2ecbc4a92f0"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"15b1dca87ee0cf2e70d8559359adb7c4c232338a","unresolved":false,"context_lines":[{"line_number":515,"context_line":"    set_permissions(path, mode, user, group, log)"},{"line_number":516,"context_line":""},{"line_number":517,"context_line":""},{"line_number":518,"context_line":"def deprecate(message_or_func):"},{"line_number":519,"context_line":"    \"\"\"A decorator warning user\u0027s about deprecating callables."},{"line_number":520,"context_line":""},{"line_number":521,"context_line":"    deprecate can be used without arguments to warn using the default"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATH%2F%2Fzbk%3D","line":518,"updated":"2013-10-09 16:09:15.000000000","message":"i feel like this reads better as a decorator if it\u0027s past tense:\n\n  @deprecated","commit_id":"4dd9c7a3744c61686be1ea37c2ec550f192987e5"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"7b5fdab7f9ef6708434567e8c0ed4928547a88af","unresolved":false,"context_lines":[{"line_number":515,"context_line":"    set_permissions(path, mode, user, group, log)"},{"line_number":516,"context_line":""},{"line_number":517,"context_line":""},{"line_number":518,"context_line":"def deprecate(message_or_func):"},{"line_number":519,"context_line":"    \"\"\"A decorator warning user\u0027s about deprecating callables."},{"line_number":520,"context_line":""},{"line_number":521,"context_line":"    deprecate can be used without arguments to warn using the default"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATH%2F%2Fy64%3D","line":518,"in_reply_to":"AAAATH%2F%2Fzbk%3D","updated":"2013-10-09 21:47:38.000000000","message":"Done.  I agree and it also matches the oslo logging terminology.","commit_id":"4dd9c7a3744c61686be1ea37c2ec550f192987e5"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"15b1dca87ee0cf2e70d8559359adb7c4c232338a","unresolved":false,"context_lines":[{"line_number":526,"context_line":"    Using the default warning message:"},{"line_number":527,"context_line":""},{"line_number":528,"context_line":"    \u003e\u003e\u003e @deprecate"},{"line_number":529,"context_line":"    ... def a(): pass"},{"line_number":530,"context_line":""},{"line_number":531,"context_line":"    Using a custom warning message:"},{"line_number":532,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATH%2F%2FzX8%3D","line":529,"updated":"2013-10-09 16:09:15.000000000","message":"same issue as in https://review.openstack.org/#/c/50186/ -- by default there\u0027s no recommendation for an alternative (see an example in comment on L548)","commit_id":"4dd9c7a3744c61686be1ea37c2ec550f192987e5"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"7b5fdab7f9ef6708434567e8c0ed4928547a88af","unresolved":false,"context_lines":[{"line_number":526,"context_line":"    Using the default warning message:"},{"line_number":527,"context_line":""},{"line_number":528,"context_line":"    \u003e\u003e\u003e @deprecate"},{"line_number":529,"context_line":"    ... def a(): pass"},{"line_number":530,"context_line":""},{"line_number":531,"context_line":"    Using a custom warning message:"},{"line_number":532,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATH%2F%2Fyr8%3D","line":529,"in_reply_to":"AAAATH%2F%2FzX8%3D","updated":"2013-10-09 21:47:38.000000000","message":"Will we ever have a case where something would be deprecated with no replacement?  I was thinking of this as the base case.  Like some of the things currently marked as Folson/Essex bugs.","commit_id":"4dd9c7a3744c61686be1ea37c2ec550f192987e5"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"15b1dca87ee0cf2e70d8559359adb7c4c232338a","unresolved":false,"context_lines":[{"line_number":537,"context_line":"    def decorator(func):"},{"line_number":538,"context_line":"        @functools.wraps(func)"},{"line_number":539,"context_line":"        def wrapped(*args, **kwargs):"},{"line_number":540,"context_line":"            warnings.warn(msg % dict(name\u003dfunc.__name__),"},{"line_number":541,"context_line":"                          DeprecationWarning,"},{"line_number":542,"context_line":"                          stacklevel\u003d2)"},{"line_number":543,"context_line":"            return func(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATH%2F%2Fzaw%3D","line":540,"updated":"2013-10-09 16:09:15.000000000","message":"i\u0027m not familiar with how it\u0027s handled, but i believe oslo logging also provides for:\n\n  LOG.deprecated()","commit_id":"4dd9c7a3744c61686be1ea37c2ec550f192987e5"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"7b5fdab7f9ef6708434567e8c0ed4928547a88af","unresolved":false,"context_lines":[{"line_number":537,"context_line":"    def decorator(func):"},{"line_number":538,"context_line":"        @functools.wraps(func)"},{"line_number":539,"context_line":"        def wrapped(*args, **kwargs):"},{"line_number":540,"context_line":"            warnings.warn(msg % dict(name\u003dfunc.__name__),"},{"line_number":541,"context_line":"                          DeprecationWarning,"},{"line_number":542,"context_line":"                          stacklevel\u003d2)"},{"line_number":543,"context_line":"            return func(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATH%2F%2FyhY%3D","line":540,"in_reply_to":"AAAATH%2F%2Fzaw%3D","updated":"2013-10-09 21:47:38.000000000","message":"I changed my patch to use that primarily because they already had support for logging messages and a config option to force deprecations to be considered errors.\n\nI don\u0027t like the messaging, but I\u0027ll save that for a rainy day.","commit_id":"4dd9c7a3744c61686be1ea37c2ec550f192987e5"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"15b1dca87ee0cf2e70d8559359adb7c4c232338a","unresolved":false,"context_lines":[{"line_number":545,"context_line":""},{"line_number":546,"context_line":"    if callable(message_or_func):"},{"line_number":547,"context_line":"        msg \u003d _(\"%(name)s is deprecated and will be removed \""},{"line_number":548,"context_line":"                \"in future releases\")"},{"line_number":549,"context_line":"        return decorator(message_or_func)"},{"line_number":550,"context_line":""},{"line_number":551,"context_line":"    msg \u003d str(message_or_func)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATH%2F%2FzVM%3D","line":548,"updated":"2013-10-09 16:09:15.000000000","message":"(wishlist) it\u0027d be nice to be able to specify the earliest release where a feature can be removed (both for our own sake and for end users).\n\nthe openstack convention is to be release - 2 backwards compatible on the service side, which implies that a deprecated feature can be removed in release + 2 after being officially deprecated. so i\u0027m envisioning something like:\n\n  @deprecated(as_of\u003dICEHOUSE, in_favor_of\u003d\u0027the v3 API\u0027)\n  def some_api_method(self):\n    pass\n\nresulting in a log such as:\n\n  WARNING: some_api_method is deprecated in favor\n  of v3 API and may be removed in Icehouse + 2 releases.\n\nThis is obviously verbose for deprecating the entire v2 API method by method, so you could have a helper decorator that has the correct arguments pre-set, e.g.:\n\n  @v2_api_deprecated","commit_id":"4dd9c7a3744c61686be1ea37c2ec550f192987e5"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"7b5fdab7f9ef6708434567e8c0ed4928547a88af","unresolved":false,"context_lines":[{"line_number":545,"context_line":""},{"line_number":546,"context_line":"    if callable(message_or_func):"},{"line_number":547,"context_line":"        msg \u003d _(\"%(name)s is deprecated and will be removed \""},{"line_number":548,"context_line":"                \"in future releases\")"},{"line_number":549,"context_line":"        return decorator(message_or_func)"},{"line_number":550,"context_line":""},{"line_number":551,"context_line":"    msg \u003d str(message_or_func)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATH%2F%2FyY0%3D","line":548,"in_reply_to":"AAAATH%2F%2FzVM%3D","updated":"2013-10-09 21:47:38.000000000","message":"I added a convenience decorator to output the type of error message.","commit_id":"4dd9c7a3744c61686be1ea37c2ec550f192987e5"},{"author":{"_account_id":994,"name":"Arvind Tiwari","email":"arvindt7@gmail.com","username":"arvind-tiwari"},"change_message_id":"fa9f3fa79303fe1e5ad9db7df6e09fb37a10d3e0","unresolved":false,"context_lines":[{"line_number":520,"context_line":""},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"def deprecated(message_or_func):"},{"line_number":523,"context_line":"    \"\"\"A decorator warning user\u0027s about deprecating callables."},{"line_number":524,"context_line":""},{"line_number":525,"context_line":"    deprecated can be used without arguments to warn using the default"},{"line_number":526,"context_line":"    warning message or a custom warning message can be specified.  If"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATH%2F%2FqUU%3D","line":523,"updated":"2013-10-11 15:41:11.000000000","message":"can we rephrase line #523 to make it more generic \n\"A decorator to specify a function is deprecated\"","commit_id":"5a2033c6ad23512e6ab2dab320c9ff2fa1894758"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2d0f0eca80235aa29aad4c96f0a953d3498e7994","unresolved":false,"context_lines":[{"line_number":520,"context_line":""},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"def deprecated(message_or_func):"},{"line_number":523,"context_line":"    \"\"\"A decorator warning user\u0027s about deprecating callables."},{"line_number":524,"context_line":""},{"line_number":525,"context_line":"    deprecated can be used without arguments to warn using the default"},{"line_number":526,"context_line":"    warning message or a custom warning message can be specified.  If"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATH%2F%2FqX0%3D","line":523,"updated":"2013-10-11 15:30:16.000000000","message":"users*","commit_id":"5a2033c6ad23512e6ab2dab320c9ff2fa1894758"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2d0f0eca80235aa29aad4c96f0a953d3498e7994","unresolved":false,"context_lines":[{"line_number":555,"context_line":"    return decorator"},{"line_number":556,"context_line":""},{"line_number":557,"context_line":""},{"line_number":558,"context_line":"def deprecated_in_release(when, in_favor_of, what\u003d\u0027%(name)s\u0027):"},{"line_number":559,"context_line":"    \"\"\"A decorator for logging a release deprecation message."},{"line_number":560,"context_line":""},{"line_number":561,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATH%2F%2FqW4%3D","line":558,"updated":"2013-10-11 15:30:16.000000000","message":"Here we might be able to be a little more explicit in the variable naming, changing \u0027when\u0027 to \u0027release\u0027 and \u0027in_favor_of\u0027 to \u0027replacement\u0027.. or something similar.","commit_id":"5a2033c6ad23512e6ab2dab320c9ff2fa1894758"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"d2b91cca3189a2a150658985d6cea7ed82f5d96c","unresolved":false,"context_lines":[{"line_number":555,"context_line":"    return decorator"},{"line_number":556,"context_line":""},{"line_number":557,"context_line":""},{"line_number":558,"context_line":"def deprecated_in_release(when, in_favor_of, what\u003d\u0027%(name)s\u0027):"},{"line_number":559,"context_line":"    \"\"\"A decorator for logging a release deprecation message."},{"line_number":560,"context_line":""},{"line_number":561,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATH%2F%2Fjk4%3D","line":558,"in_reply_to":"AAAATH%2F%2FqW4%3D","updated":"2013-10-14 15:39:12.000000000","message":"I do like in_favor_of better, but if it\u0027s a blocker I could change it too.","commit_id":"5a2033c6ad23512e6ab2dab320c9ff2fa1894758"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"f6a60d322832d1f4ec41ce1bd3a5b007215dc1ea","unresolved":false,"context_lines":[{"line_number":542,"context_line":"    def decorator(func):"},{"line_number":543,"context_line":"        @functools.wraps(func)"},{"line_number":544,"context_line":"        def wrapped(*args, **kwargs):"},{"line_number":545,"context_line":"            LOG.deprecated(msg % dict(name\u003dfunc.__name__))"},{"line_number":546,"context_line":"            return func(*args, **kwargs)"},{"line_number":547,"context_line":"        return wrapped"},{"line_number":548,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAATH%2F%2FiSA%3D","line":545,"updated":"2013-10-14 20:59:44.000000000","message":"Is the use of % correct with LOG?  This seems like an artifact of the use of warning.warn where you couldn\u0027t use \u0027,\u0027 to separate the replacement dict with.\n\nSince this is being used for more than simple debugging, this should be fixed to use the correct style.","commit_id":"a3181b16de5f873df6ee18bcb1bf93ca272e2413"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"e4afe57316e345880850d46b8d7c3434d4cdeae1","unresolved":false,"context_lines":[{"line_number":542,"context_line":"    def decorator(func):"},{"line_number":543,"context_line":"        @functools.wraps(func)"},{"line_number":544,"context_line":"        def wrapped(*args, **kwargs):"},{"line_number":545,"context_line":"            LOG.deprecated(msg % dict(name\u003dfunc.__name__))"},{"line_number":546,"context_line":"            return func(*args, **kwargs)"},{"line_number":547,"context_line":"        return wrapped"},{"line_number":548,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAATH%2F%2Fh7U%3D","line":545,"updated":"2013-10-14 22:32:30.000000000","message":"Use the python warnings module for deprecation warnings http://docs.python.org/2/library/warnings.html and then elsewhere in the project use captureWarnings to handle the logging http://docs.python.org/2/library/logging.html#logging.captureWarnings","commit_id":"a3181b16de5f873df6ee18bcb1bf93ca272e2413"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"2ddec35852673288567af4022f0287e528d17378","unresolved":false,"context_lines":[{"line_number":542,"context_line":"    def decorator(func):"},{"line_number":543,"context_line":"        @functools.wraps(func)"},{"line_number":544,"context_line":"        def wrapped(*args, **kwargs):"},{"line_number":545,"context_line":"            LOG.deprecated(msg % dict(name\u003dfunc.__name__))"},{"line_number":546,"context_line":"            return func(*args, **kwargs)"},{"line_number":547,"context_line":"        return wrapped"},{"line_number":548,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAATH%2F%2Ff1A%3D","line":545,"in_reply_to":"AAAATH%2F%2Fh7U%3D","updated":"2013-10-15 13:44:05.000000000","message":"My original review last week used warnings, but in chat we decided to use the oslo deprecation support in logger.  Other projects are already using it and it already has support to turn warnings into errors.  We would have had to add extra code to log warnings to a file anyway.","commit_id":"a3181b16de5f873df6ee18bcb1bf93ca272e2413"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"2ddec35852673288567af4022f0287e528d17378","unresolved":false,"context_lines":[{"line_number":542,"context_line":"    def decorator(func):"},{"line_number":543,"context_line":"        @functools.wraps(func)"},{"line_number":544,"context_line":"        def wrapped(*args, **kwargs):"},{"line_number":545,"context_line":"            LOG.deprecated(msg % dict(name\u003dfunc.__name__))"},{"line_number":546,"context_line":"            return func(*args, **kwargs)"},{"line_number":547,"context_line":"        return wrapped"},{"line_number":548,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAATH%2F%2Ff1Y%3D","line":545,"in_reply_to":"AAAATH%2F%2FiSA%3D","updated":"2013-10-15 13:44:05.000000000","message":"Good catch.  It was left over after switching away from warnings.","commit_id":"a3181b16de5f873df6ee18bcb1bf93ca272e2413"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"5f43f853b01d845c7b8cccd5dbceb7dbcd306a2d","unresolved":false,"context_lines":[{"line_number":559,"context_line":"    \"\"\"A decorator for logging a release deprecation message."},{"line_number":560,"context_line":""},{"line_number":561,"context_line":"    \"\"\""},{"line_number":562,"context_line":"    msg \u003d (\u0027%(what)s is deprecated in favor of %(in_favor_of)s \u0027"},{"line_number":563,"context_line":"           \u0027and may be removed in %(release)s\u0027 %"},{"line_number":564,"context_line":"           dict(what\u003dwhat, release\u003drelease, in_favor_of\u003din_favor_of))"},{"line_number":565,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAATH%2F%2Ffbg%3D","line":562,"updated":"2013-10-15 13:58:28.000000000","message":"_(i18n)","commit_id":"6a17209884721889c66cc06df579d3d672cb236f"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"258f2ba6e7d9d7f9d6673049d5234fd1c1f1aa23","unresolved":false,"context_lines":[{"line_number":519,"context_line":"    set_permissions(path, mode, user, group, log)"},{"line_number":520,"context_line":""},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"def deprecated(message_or_func):"},{"line_number":523,"context_line":"    \"\"\"A decorator to mark callables as deprecated."},{"line_number":524,"context_line":""},{"line_number":525,"context_line":"    deprecated can be used without arguments to warn using the default"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAATH%2F%2FdBs%3D","line":522,"updated":"2013-10-15 23:32:54.000000000","message":"can this be made private? i\u0027d much rather encourage the self-documenting decorator below\n\nif we need to occasionally deprecate things without an \"in_favor_of\", then i think that should be a separate method, to the effect of deprecated_without_being_superseded() \u003c-- i have no idea how to name that concisely.","commit_id":"9ea4133bd84c4a36881ca06fcea7da741ac849ca"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"f6c0277fad60b8181b1926aa7a3fe8e7c75adcca","unresolved":false,"context_lines":[{"line_number":519,"context_line":"    set_permissions(path, mode, user, group, log)"},{"line_number":520,"context_line":""},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"def deprecated(message_or_func):"},{"line_number":523,"context_line":"    \"\"\"A decorator to mark callables as deprecated."},{"line_number":524,"context_line":""},{"line_number":525,"context_line":"    deprecated can be used without arguments to warn using the default"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAATH%2F%2FIig%3D","line":522,"in_reply_to":"AAAATH%2F%2FLts%3D","updated":"2013-10-22 17:46:21.000000000","message":"++ To this.  We should actually always indicate when the deprecation will happen.  If we don\u0027t, I\u0027d be inclined to say we\u0027ve done a bad job in letting something be marked as deprecated.","commit_id":"9ea4133bd84c4a36881ca06fcea7da741ac849ca"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"3cd4f6c7107e9d77cf292b0266199ab8e4246639","unresolved":false,"context_lines":[{"line_number":519,"context_line":"    set_permissions(path, mode, user, group, log)"},{"line_number":520,"context_line":""},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"def deprecated(message_or_func):"},{"line_number":523,"context_line":"    \"\"\"A decorator to mark callables as deprecated."},{"line_number":524,"context_line":""},{"line_number":525,"context_line":"    deprecated can be used without arguments to warn using the default"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAATH%2F%2FHO4%3D","line":522,"in_reply_to":"AAAATH%2F%2FLts%3D","updated":"2013-10-23 01:25:52.000000000","message":"Done","commit_id":"9ea4133bd84c4a36881ca06fcea7da741ac849ca"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"d10aedbd0f2e9438d6f08db0bf541cb5beef7263","unresolved":false,"context_lines":[{"line_number":519,"context_line":"    set_permissions(path, mode, user, group, log)"},{"line_number":520,"context_line":""},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"def deprecated(message_or_func):"},{"line_number":523,"context_line":"    \"\"\"A decorator to mark callables as deprecated."},{"line_number":524,"context_line":""},{"line_number":525,"context_line":"    deprecated can be used without arguments to warn using the default"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAATH%2F%2FLts%3D","line":522,"in_reply_to":"AAAATH%2F%2FcLw%3D","updated":"2013-10-21 20:26:37.000000000","message":"yes, it doesn\u0027t have to be private necessarily, but my point was that the bare method should never be used.\n\nthe release indicating when something was deprecated (and therefore dictates when it\u0027s allowed to be removed, via release+2) should *always* be provided. otherwise, users are left in the dark.\n\n  old_method() is deprecated as of Icehouse in favor of new_method() and may be removed in the \"K\" release.\n\nbut there may not always be a new_method()... i\u0027m tempted to say we should be super explicit about the consequences of not providing an in_favor_of though:\n\n  old_method() is deprecated as of Icehouse and may be removed in the \"K\" release. It will not be superseded.\n\nthe \"K\" bit is sort of a nice-to-have (sort of a reminder / threat, but you can fairly easily generate that based on the name of the release it\u0027s being deprecated in:\n\n  release_plus_two \u003d chr(ord(release[0]) + 2).upper()\n\nor just use constants for release names, e.g.\n\n  deprecated(as_of\u003dICEHOUSE)\n\nand then do the computation however you want (you\u0027d also be able trivially start rendering a real name for \"K\" when a name was chosen..). that would also discourage antipatterns like:\n\n  deprecated(\u0027when \u003cbug-number\u003e is fixed\u0027)","commit_id":"9ea4133bd84c4a36881ca06fcea7da741ac849ca"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"a52b77af4030903060451c5e2f86abfe1ea4ca0d","unresolved":false,"context_lines":[{"line_number":519,"context_line":"    set_permissions(path, mode, user, group, log)"},{"line_number":520,"context_line":""},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"def deprecated(message_or_func):"},{"line_number":523,"context_line":"    \"\"\"A decorator to mark callables as deprecated."},{"line_number":524,"context_line":""},{"line_number":525,"context_line":"    deprecated can be used without arguments to warn using the default"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAATH%2F%2FcLw%3D","line":522,"in_reply_to":"AAAATH%2F%2FdBs%3D","updated":"2013-10-16 06:04:59.000000000","message":"Sure. This can be made private.  I can then get rid of the code that allows it to function with or without the argument.  Are you thinking that a bare deprecated would never be used?\n\nIf we end up needing that new usecase the existing decorator below can be change to default in_favor_of to None and use that to drive the error message.","commit_id":"9ea4133bd84c4a36881ca06fcea7da741ac849ca"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"6106fd67f840d11b9209997d4ce88996aedc2c6a","unresolved":false,"context_lines":[{"line_number":552,"context_line":""},{"line_number":553,"context_line":"    _deprecated_msg_with_alternative \u003d ("},{"line_number":554,"context_line":"        \u0027%(what)s is deprecated as of %(as_of)s in favor of \u0027"},{"line_number":555,"context_line":"        \u0027%(in_favor_of)s and may be removed in %(removed_in)s.\u0027)"},{"line_number":556,"context_line":""},{"line_number":557,"context_line":"    _deprecated_msg_no_alternative \u003d ("},{"line_number":558,"context_line":"        \u0027%(what)s is deprecated as of %(as_of)s and may be \u0027"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAATH%2F%2FHMY%3D","line":555,"updated":"2013-10-23 01:38:33.000000000","message":"strings should be translatable with _()","commit_id":"9f0e4d9639da2d0b0f2666b8eeee6d3a26475950"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"6106fd67f840d11b9209997d4ce88996aedc2c6a","unresolved":false,"context_lines":[{"line_number":556,"context_line":""},{"line_number":557,"context_line":"    _deprecated_msg_no_alternative \u003d ("},{"line_number":558,"context_line":"        \u0027%(what)s is deprecated as of %(as_of)s and may be \u0027"},{"line_number":559,"context_line":"        \u0027removed in %(removed_in)s. It will not be superseded.\u0027)"},{"line_number":560,"context_line":""},{"line_number":561,"context_line":"    def __init__(self, as_of, in_favor_of\u003dNone, what\u003dNone):"},{"line_number":562,"context_line":"        self.as_of \u003d as_of"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAATH%2F%2FHME%3D","line":559,"updated":"2013-10-23 01:38:33.000000000","message":"same as line 555","commit_id":"9f0e4d9639da2d0b0f2666b8eeee6d3a26475950"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"6106fd67f840d11b9209997d4ce88996aedc2c6a","unresolved":false,"context_lines":[{"line_number":574,"context_line":"            return func(*args, **kwargs)"},{"line_number":575,"context_line":"        return wrapped"},{"line_number":576,"context_line":""},{"line_number":577,"context_line":"    def _get_release_plus_2(self, release):"},{"line_number":578,"context_line":"        new_release \u003d chr(ord(release) + 2)"},{"line_number":579,"context_line":"        if new_release in self._RELEASES:"},{"line_number":580,"context_line":"            return self._RELEASES[new_release]"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAATH%2F%2FHL0%3D","line":577,"updated":"2013-10-23 01:38:33.000000000","message":"we might need an alternative to +2 releases (maybe less for internal API changes if that is agreed on, or more in some cases).  2 should be the default for sure.","commit_id":"9f0e4d9639da2d0b0f2666b8eeee6d3a26475950"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"6106fd67f840d11b9209997d4ce88996aedc2c6a","unresolved":false,"context_lines":[{"line_number":575,"context_line":"        return wrapped"},{"line_number":576,"context_line":""},{"line_number":577,"context_line":"    def _get_release_plus_2(self, release):"},{"line_number":578,"context_line":"        new_release \u003d chr(ord(release) + 2)"},{"line_number":579,"context_line":"        if new_release in self._RELEASES:"},{"line_number":580,"context_line":"            return self._RELEASES[new_release]"},{"line_number":581,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAATH%2F%2FHLw%3D","line":578,"updated":"2013-10-23 01:38:33.000000000","message":"as discussed on IRC, a TODO to note what happens when we hit the Y release... y+2 is ???","commit_id":"9f0e4d9639da2d0b0f2666b8eeee6d3a26475950"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"419e827dd0be1455d45e3d910ac70fa84941879e","unresolved":false,"context_lines":[{"line_number":547,"context_line":"    \"\"\""},{"line_number":548,"context_line":""},{"line_number":549,"context_line":"    FOLSOM \u003d \u0027F\u0027"},{"line_number":550,"context_line":"    GRIZZLY \u003d \u0027G\u0027"},{"line_number":551,"context_line":"    ICEHOUSE \u003d \u0027I\u0027"},{"line_number":552,"context_line":""},{"line_number":553,"context_line":"    _RELEASES \u003d {"}],"source_content_type":"text/x-python","patch_set":14,"id":"AAAATX%2F%2F89M%3D","line":550,"updated":"2013-10-23 18:43:17.000000000","message":"HAVANA?","commit_id":"420e25fa82a98c9f32013f9c7b457330dfff53c8"}],"keystone/tests/test_utils.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2d0f0eca80235aa29aad4c96f0a953d3498e7994","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        self.assertEqual(data.read_args[0], 10)"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"class TestDeprecating(tests.TestCase):"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def setUp(self):"},{"line_number":138,"context_line":"        super(TestDeprecating, self).setUp()"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATH%2F%2FqWI%3D","line":135,"updated":"2013-10-11 15:30:16.000000000","message":"(NIT): Suggest using DeprecatedDecoratorTestCase to match one of the conventions in this test module.","commit_id":"5a2033c6ad23512e6ab2dab320c9ff2fa1894758"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"d2b91cca3189a2a150658985d6cea7ed82f5d96c","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        self.assertEqual(data.read_args[0], 10)"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"class TestDeprecating(tests.TestCase):"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def setUp(self):"},{"line_number":138,"context_line":"        super(TestDeprecating, self).setUp()"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATH%2F%2Fjkg%3D","line":135,"in_reply_to":"AAAATH%2F%2FqWI%3D","updated":"2013-10-14 15:39:12.000000000","message":"I chose this name because it is not testing the deprecated decorator.  It\u0027s testing the deprecation functionality including  both decorators.","commit_id":"5a2033c6ad23512e6ab2dab320c9ff2fa1894758"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"f6a60d322832d1f4ec41ce1bd3a5b007215dc1ea","unresolved":false,"context_lines":[{"line_number":175,"context_line":""},{"line_number":176,"context_line":"        @utils.deprecated(\u0027A custom error message\u0027)"},{"line_number":177,"context_line":"        def do_outdated_stuff():"},{"line_number":178,"context_line":"            return"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"        do_outdated_stuff()"},{"line_number":181,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAATH%2F%2FiSQ%3D","line":178,"updated":"2013-10-14 20:59:44.000000000","message":"(NIT): suggest adding in a test for a method/function that does more than return  with a custom method (similar to something on line 165), this would ensure that code is executed with the custom message (and you could validate the output is as expected).","commit_id":"a3181b16de5f873df6ee18bcb1bf93ca272e2413"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"2ddec35852673288567af4022f0287e528d17378","unresolved":false,"context_lines":[{"line_number":175,"context_line":""},{"line_number":176,"context_line":"        @utils.deprecated(\u0027A custom error message\u0027)"},{"line_number":177,"context_line":"        def do_outdated_stuff():"},{"line_number":178,"context_line":"            return"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"        do_outdated_stuff()"},{"line_number":181,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAATH%2F%2Ffk0%3D","line":178,"in_reply_to":"AAAATH%2F%2FiSQ%3D","updated":"2013-10-15 13:44:05.000000000","message":"Done","commit_id":"a3181b16de5f873df6ee18bcb1bf93ca272e2413"}]}
