Skip to content

chore: Bump pylint to v3.3.7 and astroid to v3.3.10 #895

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 26, 2025
Merged
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
105 changes: 40 additions & 65 deletions .pylintrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[MASTER]
[MAIN]

# Specify a configuration file.
#rcfile=
Expand All @@ -20,7 +20,9 @@ persistent=no

# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=pylint.extensions.docparams,pylint.extensions.docstyle
load-plugins=pylint.extensions.docparams,
pylint.extensions.docstyle,
pylint.extensions.bad_builtin,

# Use multiple processes to speed up Pylint.
jobs=1
Expand All @@ -34,15 +36,6 @@ unsafe-load-any-extension=no
# run arbitrary code
extension-pkg-whitelist=

# Allow optimization of some AST trees. This will activate a peephole AST
# optimizer, which will apply various small optimizations. For instance, it can
# be used to obtain the result of joining multiple strings with the addition
# operator. Joining a lot of strings can lead to a maximum recursion error in
# Pylint and this flag can prevent that. It has one side effect, the resulting
# AST will be different than the one from reality. This option is deprecated
# and it will be removed in Pylint 2.0.
optimize-ast=no


[MESSAGES CONTROL]

Expand All @@ -65,21 +58,31 @@ enable=indexing-exception,old-raise-syntax
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=design,similarities,no-self-use,attribute-defined-outside-init,locally-disabled,star-args,pointless-except,bad-option-value,global-statement,fixme,suppressed-message,useless-suppression,locally-enabled,file-ignored,missing-type-doc
disable=design,
similarities,
no-self-use,
attribute-defined-outside-init,
locally-disabled,
star-args,
pointless-except,
bad-option-value,
lobal-statement,
fixme,
suppressed-message,
useless-suppression,
locally-enabled,
file-ignored,
missing-type-doc,
c-extension-no-member,


[REPORTS]

# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html. You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text

# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]". This option is deprecated
# and it will be removed in Pylint 2.0.
files-output=no
# Set the output format. Available formats are: 'text', 'parseable',
# 'colorized', 'json2' (improved json format), 'json' (old json format), msvs
# (visual studio) and 'github' (GitHub actions). You can also give a reporter
# class, e.g. mypackage.mymodule.MyReporterClass.
output-format=colorized

# Tells whether to display a full report or only the messages
reports=no
Expand Down Expand Up @@ -176,9 +179,12 @@ logging-modules=logging
good-names=main,_

# Bad variable names which should always be refused, separated by a comma
bad-names=

bad-functions=input,apply,reduce
bad-names=foo,
bar,
baz,
toto,
tutu,
tata

# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
Expand All @@ -194,64 +200,33 @@ property-classes=abc.abstractproperty
# Regular expression matching correct function names
function-rgx=[a-z_][a-z0-9_]*$

# Naming hint for function names
function-name-hint=[a-z_][a-z0-9_]*$
Copy link
Member

Choose a reason for hiding this comment

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

could we add a comment on why all these are being removed (for paper-trail purposes) :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, Done!


# Regular expression matching correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for variable names
variable-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct constant names
const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$


# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$

# Regular expression matching correct attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for attribute names
attr-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct argument names
argument-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for argument names
argument-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$

# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$

# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$

# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$

# Regular expression matching correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$

# Naming hint for class names
class-name-hint=[A-Z_][a-zA-Z0-9]+$

# Regular expression matching correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$

# Naming hint for module names
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$

# Regular expression matching correct method names
method-rgx=[a-z_][a-z0-9_]*$

# Naming hint for method names
method-name-hint=[a-z_][a-z0-9_]*$

# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=(__.*__|main)
Expand Down Expand Up @@ -294,12 +269,6 @@ ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# else.
single-line-if-stmt=no

# List of optional constructs for which whitespace checking is disabled. `dict-
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
# `empty-line` allows space-only lines.
no-space-check=trailing-comma,dict-separator

# Maximum number of lines in a module
max-module-lines=1000

Expand Down Expand Up @@ -405,6 +374,12 @@ exclude-protected=_asdict,_fields,_replace,_source,_make

[EXCEPTIONS]

# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception
# Exceptions that will emit a warning when caught.
overgeneral-exceptions=builtins.BaseException,builtins.Exception

[DEPRECATED_BUILTINS]

# List of builtins function names that should not be used, separated by a comma
bad-functions=input,
apply,
reduce
47 changes: 24 additions & 23 deletions firebase_admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ def initialize_app(credential=None, options=None, name=_DEFAULT_APP_NAME):
'apps, pass a second argument to initialize_app() to give each app '
'a unique name.'))

raise ValueError((
'Firebase app named "{0}" already exists. This means you called '
raise ValueError(
f'Firebase app named "{name}" already exists. This means you called '
'initialize_app() more than once with the same app name as the '
'second argument. Make sure you provide a unique name every time '
'you call initialize_app().').format(name))
'you call initialize_app().')


def delete_app(app):
Expand All @@ -96,8 +96,7 @@ def delete_app(app):
ValueError: If the app is not initialized.
"""
if not isinstance(app, App):
raise ValueError('Illegal app argument type: "{}". Argument must be of '
'type App.'.format(type(app)))
raise ValueError(f'Illegal app argument type: "{type(app)}". Argument must be of type App.')
with _apps_lock:
if _apps.get(app.name) is app:
del _apps[app.name]
Expand All @@ -109,9 +108,9 @@ def delete_app(app):
'the default app by calling initialize_app().')

raise ValueError(
('Firebase app named "{0}" is not initialized. Make sure to initialize '
'the app by calling initialize_app() with your app name as the '
'second argument.').format(app.name))
f'Firebase app named "{app.name}" is not initialized. Make sure to initialize '
'the app by calling initialize_app() with your app name as the '
'second argument.')


def get_app(name=_DEFAULT_APP_NAME):
Expand All @@ -128,8 +127,8 @@ def get_app(name=_DEFAULT_APP_NAME):
app does not exist.
"""
if not isinstance(name, str):
raise ValueError('Illegal app name argument type: "{}". App name '
'must be a string.'.format(type(name)))
raise ValueError(
f'Illegal app name argument type: "{type(name)}". App name must be a string.')
with _apps_lock:
if name in _apps:
return _apps[name]
Expand All @@ -140,9 +139,9 @@ def get_app(name=_DEFAULT_APP_NAME):
'the SDK by calling initialize_app().')

raise ValueError(
('Firebase app named "{0}" does not exist. Make sure to initialize '
'the SDK by calling initialize_app() with your app name as the '
'second argument.').format(name))
f'Firebase app named "{name}" does not exist. Make sure to initialize '
'the SDK by calling initialize_app() with your app name as the '
'second argument.')


class _AppOptions:
Expand All @@ -153,8 +152,9 @@ def __init__(self, options):
options = self._load_from_environment()

if not isinstance(options, dict):
raise ValueError('Illegal Firebase app options type: {0}. Options '
'must be a dictionary.'.format(type(options)))
raise ValueError(
f'Illegal Firebase app options type: {type(options)}. '
'Options must be a dictionary.')
self._options = options

def get(self, key, default=None):
Expand All @@ -175,15 +175,15 @@ def _load_from_environment(self):
json_str = config_file
else:
try:
with open(config_file, 'r') as json_file:
with open(config_file, 'r', encoding='utf-8') as json_file:
json_str = json_file.read()
except Exception as err:
raise ValueError('Unable to read file {}. {}'.format(config_file, err)) from err
raise ValueError(f'Unable to read file {config_file}. {err}') from err
try:
json_data = json.loads(json_str)
except Exception as err:
raise ValueError(
'JSON string "{0}" is not valid json. {1}'.format(json_str, err)) from err
f'JSON string "{json_str}" is not valid json. {err}') from err
return {k: v for k, v in json_data.items() if k in _CONFIG_VALID_KEYS}


Expand All @@ -206,8 +206,9 @@ def __init__(self, name, credential, options):
ValueError: If an argument is None or invalid.
"""
if not name or not isinstance(name, str):
raise ValueError('Illegal Firebase app name "{0}" provided. App name must be a '
'non-empty string.'.format(name))
raise ValueError(
f'Illegal Firebase app name "{name}" provided. App name must be a '
'non-empty string.')
self._name = name

if isinstance(credential, GoogleAuthCredentials):
Expand All @@ -228,7 +229,7 @@ def __init__(self, name, credential, options):
def _validate_project_id(cls, project_id):
if project_id is not None and not isinstance(project_id, str):
raise ValueError(
'Invalid project ID: "{0}". project ID must be a string.'.format(project_id))
f'Invalid project ID: "{project_id}". project ID must be a string.')

@property
def name(self):
Expand Down Expand Up @@ -293,11 +294,11 @@ def _get_service(self, name, initializer):
"""
if not name or not isinstance(name, str):
raise ValueError(
'Illegal name argument: "{0}". Name must be a non-empty string.'.format(name))
f'Illegal name argument: "{name}". Name must be a non-empty string.')
with self._lock:
if self._services is None:
raise ValueError(
'Service requested from deleted Firebase App: "{0}".'.format(self._name))
f'Service requested from deleted Firebase App: "{self._name}".')
if name not in self._services:
self._services[name] = initializer(self)
return self._services[name]
Expand Down
15 changes: 8 additions & 7 deletions firebase_admin/_auth_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def __init__(self, app, tenant_id=None):
3. set the project ID via the GOOGLE_CLOUD_PROJECT environment variable.""")

credential = None
version_header = 'Python/Admin/{0}'.format(firebase_admin.__version__)
version_header = f'Python/Admin/{firebase_admin.__version__}'
timeout = app.options.get('httpTimeout', _http_client.DEFAULT_TIMEOUT_SECONDS)
# Non-default endpoint URLs for emulator support are set in this dict later.
endpoint_urls = {}
Expand All @@ -48,7 +48,7 @@ def __init__(self, app, tenant_id=None):
# endpoint URLs to use the emulator. Additionally, use a fake credential.
emulator_host = _auth_utils.get_emulator_host()
if emulator_host:
base_url = 'http://{0}/identitytoolkit.googleapis.com'.format(emulator_host)
base_url = f'http://{emulator_host}/identitytoolkit.googleapis.com'
endpoint_urls['v1'] = base_url + '/v1'
endpoint_urls['v2'] = base_url + '/v2'
credential = _utils.EmulatorAdminCredentials()
Expand Down Expand Up @@ -123,15 +123,16 @@ def verify_id_token(self, id_token, check_revoked=False, clock_skew_seconds=0):
"""
if not isinstance(check_revoked, bool):
# guard against accidental wrong assignment.
raise ValueError('Illegal check_revoked argument. Argument must be of type '
' bool, but given "{0}".'.format(type(check_revoked)))
raise ValueError(
'Illegal check_revoked argument. Argument must be of type bool, but given '
f'"{type(check_revoked)}".')

verified_claims = self._token_verifier.verify_id_token(id_token, clock_skew_seconds)
if self.tenant_id:
token_tenant_id = verified_claims.get('firebase', {}).get('tenant')
if self.tenant_id != token_tenant_id:
raise _auth_utils.TenantIdMismatchError(
'Invalid tenant ID: {0}'.format(token_tenant_id))
f'Invalid tenant ID: {token_tenant_id}')

if check_revoked:
self._check_jwt_revoked_or_disabled(
Expand Down Expand Up @@ -249,7 +250,7 @@ def _matches(identifier, user_record):
if identifier.provider_id == user_info.provider_id
and identifier.provider_uid == user_info.uid
), False)
raise TypeError("Unexpected type: {}".format(type(identifier)))
raise TypeError(f"Unexpected type: {type(identifier)}")

def _is_user_found(identifier, user_records):
return any(_matches(identifier, user_record) for user_record in user_records)
Expand Down Expand Up @@ -757,4 +758,4 @@ def _check_jwt_revoked_or_disabled(self, verified_claims, exc_type, label):
if user.disabled:
raise _auth_utils.UserDisabledError('The user record is disabled.')
if verified_claims.get('iat') * 1000 < user.tokens_valid_after_timestamp:
raise exc_type('The Firebase {0} has been revoked.'.format(label))
raise exc_type(f'The Firebase {label} has been revoked.')
Loading