Skip to content

Commit

Permalink
Merge branch 'master' into watcher
Browse files Browse the repository at this point in the history
  • Loading branch information
Borda authored Sep 20, 2024
2 parents b34ef51 + 5b2dadd commit 692f6a2
Show file tree
Hide file tree
Showing 49 changed files with 216 additions and 469 deletions.
31 changes: 31 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Basic dependabot.yml file with minimum configuration for two package managers

version: 2
updates:
# Enable version updates for python
- package-ecosystem: "pip"
directory: ".github/scripts/"
schedule:
interval: "monthly"
labels: ["dependabot"]
pull-request-branch-name:
separator: "-"
open-pull-requests-limit: 5
reviewers:
- "dbieber"

# Enable version updates for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
groups:
gh-actions:
patterns:
- "*" # Check all dependencies
labels: ["dependabot"]
pull-request-branch-name:
separator: "-"
open-pull-requests-limit: 5
reviewers:
- "dbieber"
2 changes: 1 addition & 1 deletion .github/scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# Exit when any command fails.
set -e

PYTHON_VERSION=${PYTHON_VERSION:-2.7}
PYTHON_VERSION=${PYTHON_VERSION:-3.7}

pip install -U -r .github/scripts/requirements.txt
python setup.py develop
Expand Down
20 changes: 8 additions & 12 deletions .github/scripts/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
setuptools <65.7.0 ; python_version == '2.7'
setuptools <=69.1.1 ; python_version >= '3.8'
pip <23.0 ; python_version == '2.7'
pip ; python_version >= '3.5'
pylint <2.15.10
pytest <=7.2.1
setuptools <=75.1.0
pip
pylint <3.2.8
pytest <=8.3.3
pytest-pylint <=1.1.2
pytest-runner <6.0.0
termcolor <2.2.0
hypothesis <6.62.0
python-Levenshtein <0.20.9 ; python_version == '2.7'
levenshtein <=0.25.0 ; python_version >= '3.5'
mock <5.0.0
pytest-runner <7.0.0
termcolor <2.5.0
hypothesis <6.113.0
levenshtein <=0.26.0
12 changes: 8 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
name: Python Fire

on: [push, pull_request]
on:
push:
branches: ["master"]
pull_request:
branches: ["master"]

jobs:
build:
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: ["3.5", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]

steps:
# Checkout the repo.
- name: Checkout Python Fire repository
uses: actions/checkout@v3
uses: actions/checkout@v4

# Set up Python environment.
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

Expand Down
29 changes: 24 additions & 5 deletions docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ the program to the command line.
import fire

def hello(name):
return 'Hello {name}!'.format(name=name)
return f'Hello {name}!'

if __name__ == '__main__':
fire.Fire()
Expand All @@ -52,7 +52,7 @@ command line.
import fire

def hello(name):
return 'Hello {name}!'.format(name=name)
return f'Hello {name}!'

if __name__ == '__main__':
fire.Fire(hello)
Expand All @@ -76,7 +76,7 @@ We can alternatively write this program like this:
import fire

def hello(name):
return 'Hello {name}!'.format(name=name)
return f'Hello {name}!'

def main():
fire.Fire(hello)
Expand All @@ -93,7 +93,7 @@ then simply this:
import fire

def hello(name):
return 'Hello {name}!'.format(name=name)
return f'Hello {name}!'

def main():
fire.Fire(hello)
Expand All @@ -105,7 +105,7 @@ If you have a file `example.py` that doesn't even import fire:

```python
def hello(name):
return 'Hello {name}!'.format(name=name)
return f'Hello {name}!'
```

Then you can use it with Fire like this:
Expand Down Expand Up @@ -589,6 +589,25 @@ default values that you don't want to specify. It is also important to remember
to change the separator if you want to pass `-` as an argument.


##### Async Functions

Fire supports calling async functions too. Here's a simple example.

```python
import asyncio

async def count_to_ten():
for i in range(1, 11):
await asyncio.sleep(1)
print(i)

if __name__ == '__main__':
fire.Fire(count_to_ten)
```

Whenever fire encounters a coroutine function, it runs it, blocking until it completes.


### Argument Parsing

The types of the arguments are determined by their values, rather than by the
Expand Down
2 changes: 1 addition & 1 deletion examples/widget/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def whack(self, n=1):

def bang(self, noise='bang'):
"""Makes a loud noise."""
return '{noise} bang!'.format(noise=noise)
return f'{noise} bang!'


def main():
Expand Down
4 changes: 0 additions & 4 deletions fire/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@

"""The Python Fire module."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from fire.core import Fire

__all__ = ['Fire']
Expand Down
29 changes: 6 additions & 23 deletions fire/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,8 @@
This allows using Fire with third-party libraries without modifying their code.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import importlib
from importlib import util
import os
import sys

Expand Down Expand Up @@ -61,27 +58,13 @@ def import_from_file_path(path):

module_name = os.path.basename(path)

if sys.version_info.major == 3 and sys.version_info.minor < 5:
loader = importlib.machinery.SourceFileLoader( # pylint: disable=no-member
fullname=module_name,
path=path,
)

module = loader.load_module(module_name) # pylint: disable=deprecated-method

elif sys.version_info.major == 3:
from importlib import util # pylint: disable=g-import-not-at-top,import-outside-toplevel,no-name-in-module
spec = util.spec_from_file_location(module_name, path)

if spec is None:
raise IOError('Unable to load module from specified path.')
spec = util.spec_from_file_location(module_name, path)

module = util.module_from_spec(spec) # pylint: disable=no-member
spec.loader.exec_module(module) # pytype: disable=attribute-error
if spec is None:
raise IOError('Unable to load module from specified path.')

else:
import imp # pylint: disable=g-import-not-at-top,import-outside-toplevel,deprecated-module,import-error
module = imp.load_source(module_name, path)
module = util.module_from_spec(spec) # pylint: disable=no-member
spec.loader.exec_module(module) # pytype: disable=attribute-error

return module, module_name

Expand Down
28 changes: 9 additions & 19 deletions fire/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import inspect

from fire import inspectutils
import six


def Script(name, component, default_options=None, shell='bash'):
Expand Down Expand Up @@ -278,10 +277,7 @@ def _FishScript(name, commands, default_options=None):
)

return fish_source.format(
global_options=' '.join(
'"{option}"'.format(option=option)
for option in global_options
)
global_options=' '.join(f'"{option}"' for option in global_options)
)


Expand All @@ -308,18 +304,19 @@ def MemberVisible(component, name, member, class_attrs=None, verbose=False):
Returns
A boolean value indicating whether the member should be included.
"""
if isinstance(name, six.string_types) and name.startswith('__'):
if isinstance(name, str) and name.startswith('__'):
return False
if verbose:
return True
if (member is absolute_import
or member is division
or member is print_function):
return False
if isinstance(member, type(absolute_import)) and six.PY34:
if isinstance(member, type(absolute_import)):
return False
if inspect.ismodule(member) and member is six:
# TODO(dbieber): Determine more generally which modules to hide.
# TODO(dbieber): Determine more generally which modules to hide.
modules_to_hide = []
if inspect.ismodule(member) and member in modules_to_hide:
return False
if inspect.isclass(component):
# If class_attrs has not been provided, compute it.
Expand All @@ -336,14 +333,7 @@ def MemberVisible(component, name, member, class_attrs=None, verbose=False):
tuplegetter = getattr(collections, '_tuplegetter', type(None))
if isinstance(class_attr.object, tuplegetter):
return False
if (six.PY2 and inspect.isfunction(component)
and name in ('func_closure', 'func_code', 'func_defaults',
'func_dict', 'func_doc', 'func_globals', 'func_name')):
return False
if (six.PY2 and inspect.ismethod(component)
and name in ('im_class', 'im_func', 'im_self')):
return False
if isinstance(name, six.string_types):
if isinstance(name, str):
return not name.startswith('_')
return True # Default to including the member

Expand Down Expand Up @@ -392,7 +382,7 @@ def _CompletionsFromArgs(fn_args):
completions = []
for arg in fn_args:
arg = arg.replace('_', '-')
completions.append('--{arg}'.format(arg=arg))
completions.append(f'--{arg}')
return completions


Expand Down Expand Up @@ -438,7 +428,7 @@ def _FormatForCommand(token):
Returns:
The transformed token.
"""
if not isinstance(token, six.string_types):
if not isinstance(token, str):
token = str(token)

if token.startswith('_'):
Expand Down
7 changes: 1 addition & 6 deletions fire/completion_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@

"""Tests for the completion module."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from fire import completion
from fire import test_components as tc
from fire import testutils
Expand All @@ -37,9 +33,8 @@ def testCompletionBashScript(self):
self.assertIn('command', script)
self.assertIn('halt', script)

assert_template = '{command})'
for last_command in ['command', 'halt']:
self.assertIn(assert_template.format(command=last_command), script)
self.assertIn(f'{last_command})', script)

def testCompletionFishScript(self):
# A sanity check test to make sure the fish completion script satisfies
Expand Down
18 changes: 8 additions & 10 deletions fire/console/console_attr.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@
from fire.console import encoding as encoding_util
from fire.console import text

import six


# TODO: Unify this logic with console.style.mappings
class BoxLineCharacters(object):
Expand Down Expand Up @@ -355,9 +353,9 @@ def ConvertOutputToUnicode(self, buf):
Returns:
The console output string buf converted to unicode.
"""
if isinstance(buf, six.text_type):
if isinstance(buf, str):
buf = buf.encode(self._encoding)
return six.text_type(buf, self._encoding, 'replace')
return str(buf, self._encoding, 'replace')

def GetBoxLineCharacters(self):
"""Returns the box/line drawing characters object.
Expand Down Expand Up @@ -480,7 +478,7 @@ def DisplayWidth(self, buf):
Returns:
The display width of buf, handling unicode and ANSI controls.
"""
if not isinstance(buf, six.string_types):
if not isinstance(buf, str):
# Handle non-string objects like Colorizer().
return len(buf)

Expand Down Expand Up @@ -595,16 +593,16 @@ def __init__(self, string, color, justify=None):
self._justify = justify

def __eq__(self, other):
return self._string == six.text_type(other)
return self._string == str(other)

def __ne__(self, other):
return not self == other

def __gt__(self, other):
return self._string > six.text_type(other)
return self._string > str(other)

def __lt__(self, other):
return self._string < six.text_type(other)
return self._string < str(other)

def __ge__(self, other):
return not self < other
Expand Down Expand Up @@ -692,7 +690,7 @@ def GetCharacterDisplayWidth(char):
Returns:
The monospaced terminal display width of char: either 0, 1, or 2.
"""
if not isinstance(char, six.text_type):
if not isinstance(char, str):
# Non-unicode chars have width 1. Don't use this function on control chars.
return 1

Expand Down Expand Up @@ -779,7 +777,7 @@ def EncodeToBytes(data):
return data

# Coerce to text that will be converted to bytes.
s = six.text_type(data)
s = str(data)

try:
# Assume the text can be directly converted to bytes (8-bit ascii).
Expand Down
Loading

0 comments on commit 692f6a2

Please sign in to comment.