Skip to content
This repository has been archived by the owner on Feb 17, 2022. It is now read-only.

New timeit feature #24

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 40 additions & 5 deletions commandr/commandr.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,19 @@
# main:
# If set, Commandr will use the supplied value as the command name to run
# if no command name is supplied. It will override any previous values.
#
# extra_options:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of "extra_options", I think "instrumentation_options" is a better name for the feature.

# If True, extra options will be made available to commands.
# Default is False.


from collections import namedtuple
import inspect
import itertools
from optparse import OptionParser, SUPPRESS_HELP
import sys
from timeit import Timer
from datetime import timedelta

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: alphabetic ordering of imports (datetime should be on line 132).


class CommandInfo(
namedtuple('BaseCommandInfo',
Expand Down Expand Up @@ -158,6 +165,7 @@ def __init__(self):
self.ignore_self = False
self.main_docs = True
self.main = None
self.extra_options = False

# Internal flag indicating whether to expect the command name as the first
# command line argument.
Expand Down Expand Up @@ -240,7 +248,8 @@ def SetOptions(self,
show_all_help_variants=None,
ignore_self=None,
main_docs=None,
main=None):
main=None,
extra_options=None):
"""Set commandr options. Any argument not set to None will be applied
(otherwise it will retain its current value).

Expand All @@ -258,6 +267,8 @@ def SetOptions(self,
command is specified. Default is True.
main - If set, it will use the supplied value as the command name to run
if no command name is supplied. It will override any previous values.
extra_options - If True, extra options will be made available to commands.
Default is False.
"""
# Anything added here should also be added to the RunFunction interface.
if hyphenate is not None:
Expand All @@ -270,6 +281,8 @@ def SetOptions(self,
self.main_docs = main_docs
if main is not None:
self.main = main
if extra_options is not None:
self.extra_options = extra_options

def Run(self, *args, **kwargs):
"""Main function to take command line arguments, and parse them into a
Expand Down Expand Up @@ -314,7 +327,8 @@ def RunFunction(self,
show_all_help_variants=None,
ignore_self=None,
main_doc=None,
main=None):
main=None,
extra_options=None):
"""Method to explicitly execute a given function against the command line
arguments. If this method is called directly, the command name will not be
expected in the arguments.
Expand All @@ -332,6 +346,8 @@ def RunFunction(self,
command is specified. Default is True.
main - If set, it will use the supplied value as the command name to run
if no command name is supplied. It will override any previous values.
extra_options - If True, extra options will be made available to commands.
Default is False.
"""
info = self._all_commands.get(cmd_name)
if not info:
Expand All @@ -353,6 +369,11 @@ def RunFunction(self,
elif 'help' in options_dict:
del options_dict['help']

timeit = False

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid naming variables the same as built-in modules.

if 'timeit' in options_dict:
timeit = options_dict['timeit']
del options_dict['timeit']

ignore = (info.ignore_self
if info.ignore_self is not None
else self.ignore_self)
Expand Down Expand Up @@ -410,15 +431,24 @@ def RunFunction(self,
for key, value in options_dict.iteritems():
if value is None:
if key not in defaults_dict:
self._HelpExitCommand(
"All options without default values must be specified",
self._HelpExitCommand("Option '" + key + "' is missing.\n" +
"All options without default values must be specified.",
info.name, info.callable, options_dict, argspec.args)
elif defaults_dict[key] is not None:
options_dict[key] = defaults_dict[key]

self.current_command = info
try:
result = info.callable(**options_dict)
self.temp_result = "" # use an instance var to store result from wrapper

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Use a consistent quotation mark format. The style for the project is (mostly) single quotes.

if timeit:
def wrapper():
self.temp_result = info.callable(**options_dict)
timer = Timer(wrapper)
delta = timer.timeit(1)
print "Time taken is: ", timedelta(seconds = delta)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no spaces around '=' in args lists.

result=self.temp_result

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: spaces around '=' for regular statements.

else:
result = info.callable(**options_dict)
except CommandrUsageError as e:
self.Usage(str(e) or None)

Expand Down Expand Up @@ -516,6 +546,11 @@ def _BuildOptParse(self, info):
else:
self._AddOption(args, dest=arg)

if self.extra_options:
defaults_dict["timeit"]=False

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Use consistent quotation marks.

self._AddOption(['--timeit'], dest='timeit', action='store_true',
default=False, help="Time the duration of the command.")

return argspec, defaults_dict

def _AddOption(self, args, **kwargs):
Expand Down
55 changes: 55 additions & 0 deletions example_extra.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/python
#
# Copyright 2013 TellApart, Inc.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/2013/2014/

#
# 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.
#
# =============================================================================
"""
Example usage of commandr with extra options.

To time a command, try running the example with
./example_extra.py greet --timeit John

Output:
Hi Mr. John!
Time taken is: 0:00:00.000027

This indicates that it took 27 microseconds to execute the command

The timeit command is only available when the extra_options parameter
is set to True
"""

from commandr import command, Run, CommandrUsageError, wraps

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unused imports.


@command('greet')
def SayGreeting(name, title='Mr.', times=1, comma=False, caps_lock=False):
"""Greet someone.

Arguments:
name - Name to greet.
title - Title of the person to greet.
times - Number of time to say the greeting.
comma - Whether to add a comma after the greeting.
caps_lock - Whether to output in ALL CAPS.
"""
message = 'Hi%s %s %s!' % (',' if comma else '', title, name)
if caps_lock:
message = message.upper()

for _ in xrange(times):
print message

if __name__ == '__main__':
Run(hyphenate=True, extra_options=True)