diff --git a/firebase_admin/__init__.py b/firebase_admin/__init__.py index eae68bd06..400396266 100644 --- a/firebase_admin/__init__.py +++ b/firebase_admin/__init__.py @@ -18,8 +18,6 @@ import os import threading -import six - from firebase_admin import credentials from firebase_admin.__about__ import __version__ @@ -126,7 +124,7 @@ def get_app(name=_DEFAULT_APP_NAME): ValueError: If the specified name is not a string, or if the specified app does not exist. """ - if not isinstance(name, six.string_types): + if not isinstance(name, str): raise ValueError('Illegal app name argument type: "{}". App name ' 'must be a string.'.format(type(name))) with _apps_lock: @@ -203,7 +201,7 @@ def __init__(self, name, credential, options): Raises: ValueError: If an argument is None or invalid. """ - if not name or not isinstance(name, six.string_types): + 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)) self._name = name @@ -221,7 +219,7 @@ def __init__(self, name, credential, options): @classmethod def _validate_project_id(cls, project_id): - if project_id is not None and not isinstance(project_id, six.string_types): + 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)) @@ -286,7 +284,7 @@ def _get_service(self, name, initializer): Raises: ValueError: If the provided name is invalid, or if the App is already deleted. """ - if not name or not isinstance(name, six.string_types): + if not name or not isinstance(name, str): raise ValueError( 'Illegal name argument: "{0}". Name must be a non-empty string.'.format(name)) with self._lock: diff --git a/firebase_admin/_auth_utils.py b/firebase_admin/_auth_utils.py index b54e7d480..2f7383c0b 100644 --- a/firebase_admin/_auth_utils.py +++ b/firebase_admin/_auth_utils.py @@ -16,9 +16,7 @@ import json import re - -import six -from six.moves import urllib +from urllib import parse from firebase_admin import exceptions from firebase_admin import _utils @@ -35,7 +33,7 @@ def validate_uid(uid, required=False): if uid is None and not required: return None - if not isinstance(uid, six.string_types) or not uid or len(uid) > 128: + if not isinstance(uid, str) or not uid or len(uid) > 128: raise ValueError( 'Invalid uid: "{0}". The uid must be a non-empty string with no more than 128 ' 'characters.'.format(uid)) @@ -44,7 +42,7 @@ def validate_uid(uid, required=False): def validate_email(email, required=False): if email is None and not required: return None - if not isinstance(email, six.string_types) or not email: + if not isinstance(email, str) or not email: raise ValueError( 'Invalid email: "{0}". Email must be a non-empty string.'.format(email)) parts = email.split('@') @@ -61,7 +59,7 @@ def validate_phone(phone, required=False): """ if phone is None and not required: return None - if not isinstance(phone, six.string_types) or not phone: + if not isinstance(phone, str) or not phone: raise ValueError('Invalid phone number: "{0}". Phone number must be a non-empty ' 'string.'.format(phone)) if not phone.startswith('+') or not re.search('[a-zA-Z0-9]', phone): @@ -72,7 +70,7 @@ def validate_phone(phone, required=False): def validate_password(password, required=False): if password is None and not required: return None - if not isinstance(password, six.string_types) or len(password) < 6: + if not isinstance(password, str) or len(password) < 6: raise ValueError( 'Invalid password string. Password must be a string at least 6 characters long.') return password @@ -80,14 +78,14 @@ def validate_password(password, required=False): def validate_bytes(value, label, required=False): if value is None and not required: return None - if not isinstance(value, six.binary_type) or not value: + if not isinstance(value, bytes) or not value: raise ValueError('{0} must be a non-empty byte sequence.'.format(label)) return value def validate_display_name(display_name, required=False): if display_name is None and not required: return None - if not isinstance(display_name, six.string_types) or not display_name: + if not isinstance(display_name, str) or not display_name: raise ValueError( 'Invalid display name: "{0}". Display name must be a non-empty ' 'string.'.format(display_name)) @@ -96,7 +94,7 @@ def validate_display_name(display_name, required=False): def validate_provider_id(provider_id, required=True): if provider_id is None and not required: return None - if not isinstance(provider_id, six.string_types) or not provider_id: + if not isinstance(provider_id, str) or not provider_id: raise ValueError( 'Invalid provider ID: "{0}". Provider ID must be a non-empty ' 'string.'.format(provider_id)) @@ -106,12 +104,12 @@ def validate_photo_url(photo_url, required=False): """Parses and validates the given URL string.""" if photo_url is None and not required: return None - if not isinstance(photo_url, six.string_types) or not photo_url: + if not isinstance(photo_url, str) or not photo_url: raise ValueError( 'Invalid photo URL: "{0}". Photo URL must be a non-empty ' 'string.'.format(photo_url)) try: - parsed = urllib.parse.urlparse(photo_url) + parsed = parse.urlparse(photo_url) if not parsed.netloc: raise ValueError('Malformed photo URL: "{0}".'.format(photo_url)) return photo_url diff --git a/firebase_admin/_messaging_encoder.py b/firebase_admin/_messaging_encoder.py index aefaf3e2f..c4da53f0d 100644 --- a/firebase_admin/_messaging_encoder.py +++ b/firebase_admin/_messaging_encoder.py @@ -20,8 +20,6 @@ import numbers import re -import six - import firebase_admin._messaging_utils as _messaging_utils @@ -99,7 +97,7 @@ def check_string(cls, label, value, non_empty=False): """Checks if the given value is a string.""" if value is None: return None - if not isinstance(value, six.string_types): + if not isinstance(value, str): if non_empty: raise ValueError('{0} must be a non-empty string.'.format(label)) raise ValueError('{0} must be a string.'.format(label)) @@ -122,10 +120,10 @@ def check_string_dict(cls, label, value): return None if not isinstance(value, dict): raise ValueError('{0} must be a dictionary.'.format(label)) - non_str = [k for k in value if not isinstance(k, six.string_types)] + non_str = [k for k in value if not isinstance(k, str)] if non_str: raise ValueError('{0} must not contain non-string keys.'.format(label)) - non_str = [v for v in value.values() if not isinstance(v, six.string_types)] + non_str = [v for v in value.values() if not isinstance(v, str)] if non_str: raise ValueError('{0} must not contain non-string values.'.format(label)) return value @@ -137,7 +135,7 @@ def check_string_list(cls, label, value): return None if not isinstance(value, list): raise ValueError('{0} must be a list of strings.'.format(label)) - non_str = [k for k in value if not isinstance(k, six.string_types)] + non_str = [k for k in value if not isinstance(k, str)] if non_str: raise ValueError('{0} must not contain non-string values.'.format(label)) return value @@ -570,7 +568,7 @@ def encode_aps_sound(cls, sound): """Encodes an APNs sound configuration into JSON.""" if sound is None: return None - if sound and isinstance(sound, six.string_types): + if sound and isinstance(sound, str): return sound if not isinstance(sound, _messaging_utils.CriticalSound): raise ValueError( @@ -593,7 +591,7 @@ def encode_aps_alert(cls, alert): """Encodes an ``ApsAlert`` instance into JSON.""" if alert is None: return None - if isinstance(alert, six.string_types): + if isinstance(alert, str): return alert if not isinstance(alert, _messaging_utils.ApsAlert): raise ValueError('Aps.alert must be a string or an instance of ApsAlert class.') diff --git a/firebase_admin/_token_gen.py b/firebase_admin/_token_gen.py index 471630cca..4234bfa7b 100644 --- a/firebase_admin/_token_gen.py +++ b/firebase_admin/_token_gen.py @@ -19,7 +19,6 @@ import cachecontrol import requests -import six from google.auth import credentials from google.auth import iam from google.auth import jwt @@ -149,7 +148,7 @@ def create_custom_token(self, uid, developer_claims=None): ', '.join(disallowed_keys))) raise ValueError(error_message) - if not uid or not isinstance(uid, six.string_types) or len(uid) > 128: + if not uid or not isinstance(uid, str) or len(uid) > 128: raise ValueError('uid must be a string between 1 and 128 characters.') signing_provider = self.signing_provider @@ -174,8 +173,8 @@ def create_custom_token(self, uid, developer_claims=None): def create_session_cookie(self, id_token, expires_in): """Creates a session cookie from the provided ID token.""" - id_token = id_token.decode('utf-8') if isinstance(id_token, six.binary_type) else id_token - if not isinstance(id_token, six.text_type) or not id_token: + id_token = id_token.decode('utf-8') if isinstance(id_token, bytes) else id_token + if not isinstance(id_token, str) or not id_token: raise ValueError( 'Illegal ID token provided: {0}. ID token must be a non-empty ' 'string.'.format(id_token)) @@ -256,8 +255,8 @@ def __init__(self, **kwargs): def verify(self, token, request): """Verifies the signature and data for the provided JWT.""" - token = token.encode('utf-8') if isinstance(token, six.text_type) else token - if not isinstance(token, six.binary_type) or not token: + token = token.encode('utf-8') if isinstance(token, str) else token + if not isinstance(token, bytes) or not token: raise ValueError( 'Illegal {0} provided: {1}. {0} must be a non-empty ' 'string.'.format(self.short_name, token)) @@ -308,7 +307,7 @@ def verify(self, token, request): 'Firebase {0} has incorrect "iss" (issuer) claim. Expected "{1}" but ' 'got "{2}". {3} {4}'.format(self.short_name, expected_issuer, issuer, project_id_match_msg, verify_id_token_msg)) - elif subject is None or not isinstance(subject, six.string_types): + elif subject is None or not isinstance(subject, str): error_message = ( 'Firebase {0} has no "sub" (subject) claim. ' '{1}'.format(self.short_name, verify_id_token_msg)) diff --git a/firebase_admin/_user_mgt.py b/firebase_admin/_user_mgt.py index 5b33abb39..533259e70 100644 --- a/firebase_admin/_user_mgt.py +++ b/firebase_admin/_user_mgt.py @@ -16,9 +16,9 @@ import base64 import json +from urllib import parse + import requests -import six -from six.moves import urllib from firebase_admin import _auth_utils from firebase_admin import _user_import @@ -397,7 +397,7 @@ def encode_action_code_settings(settings): raise ValueError("Dynamic action links url is mandatory") try: - parsed = urllib.parse.urlparse(settings.url) + parsed = parse.urlparse(settings.url) if not parsed.netloc: raise ValueError('Malformed dynamic action links url: "{0}".'.format(settings.url)) parameters['continueUrl'] = settings.url @@ -413,14 +413,14 @@ def encode_action_code_settings(settings): # dynamic_link_domain if settings.dynamic_link_domain is not None: - if not isinstance(settings.dynamic_link_domain, six.string_types): + if not isinstance(settings.dynamic_link_domain, str): raise ValueError('Invalid value provided for dynamic_link_domain: {0}' .format(settings.dynamic_link_domain)) parameters['dynamicLinkDomain'] = settings.dynamic_link_domain # ios_bundle_id if settings.ios_bundle_id is not None: - if not isinstance(settings.ios_bundle_id, six.string_types): + if not isinstance(settings.ios_bundle_id, str): raise ValueError('Invalid value provided for ios_bundle_id: {0}' .format(settings.ios_bundle_id)) parameters['iosBundleId'] = settings.ios_bundle_id @@ -431,13 +431,13 @@ def encode_action_code_settings(settings): raise ValueError("Android package name is required when specifying other Android settings") if settings.android_package_name is not None: - if not isinstance(settings.android_package_name, six.string_types): + if not isinstance(settings.android_package_name, str): raise ValueError('Invalid value provided for android_package_name: {0}' .format(settings.android_package_name)) parameters['androidPackageName'] = settings.android_package_name if settings.android_minimum_version is not None: - if not isinstance(settings.android_minimum_version, six.string_types): + if not isinstance(settings.android_minimum_version, str): raise ValueError('Invalid value provided for android_minimum_version: {0}' .format(settings.android_minimum_version)) parameters['androidMinimumVersion'] = settings.android_minimum_version @@ -486,7 +486,7 @@ def get_user(self, **kwargs): def list_users(self, page_token=None, max_results=MAX_LIST_USERS_RESULTS): """Retrieves a batch of users.""" if page_token is not None: - if not isinstance(page_token, six.string_types) or not page_token: + if not isinstance(page_token, str) or not page_token: raise ValueError('Page token must be a non-empty string.') if not isinstance(max_results, int): raise ValueError('Max results must be an integer.') diff --git a/firebase_admin/_utils.py b/firebase_admin/_utils.py index 7ec1b8fb8..2c4cec868 100644 --- a/firebase_admin/_utils.py +++ b/firebase_admin/_utils.py @@ -14,13 +14,13 @@ """Internal utilities common to all modules.""" +import io import json import socket import googleapiclient import httplib2 import requests -import six import firebase_admin from firebase_admin import exceptions @@ -255,7 +255,7 @@ def handle_googleapiclient_error(error, message=None, code=None, http_response=N def _http_response_from_googleapiclient_error(error): """Creates a requests HTTP Response object from the given googleapiclient error.""" resp = requests.models.Response() - resp.raw = six.BytesIO(error.content) + resp.raw = io.BytesIO(error.content) resp.status_code = error.resp.status return resp diff --git a/firebase_admin/credentials.py b/firebase_admin/credentials.py index e930675bd..8f9c504f0 100644 --- a/firebase_admin/credentials.py +++ b/firebase_admin/credentials.py @@ -15,7 +15,6 @@ """Firebase credentials module.""" import collections import json -import six import google.auth from google.auth.transport import requests @@ -79,7 +78,7 @@ def __init__(self, cert): ValueError: If the specified certificate is invalid. """ super(Certificate, self).__init__() - if isinstance(cert, six.string_types): + if isinstance(cert, str): with open(cert) as json_file: json_data = json.load(json_file) elif isinstance(cert, dict): @@ -180,7 +179,7 @@ def __init__(self, refresh_token): ValueError: If the refresh token configuration is invalid. """ super(RefreshToken, self).__init__() - if isinstance(refresh_token, six.string_types): + if isinstance(refresh_token, str): with open(refresh_token) as json_file: json_data = json.load(json_file) elif isinstance(refresh_token, dict): diff --git a/firebase_admin/db.py b/firebase_admin/db.py index 2fb8b3a74..9092a955c 100644 --- a/firebase_admin/db.py +++ b/firebase_admin/db.py @@ -25,11 +25,10 @@ import os import sys import threading +from urllib import parse import google.auth import requests -import six -from six.moves import urllib import firebase_admin from firebase_admin import exceptions @@ -73,7 +72,7 @@ def reference(path='/', app=None, url=None): def _parse_path(path): """Parses a path string into a set of segments.""" - if not isinstance(path, six.string_types): + if not isinstance(path, str): raise ValueError('Invalid path: "{0}". Path must be a string.'.format(path)) if any(ch in path for ch in _INVALID_PATH_CHARACTERS): raise ValueError( @@ -185,7 +184,7 @@ def child(self, path): Raises: ValueError: If the child path is not a string, not well-formed or begins with '/'. """ - if not path or not isinstance(path, six.string_types): + if not path or not isinstance(path, str): raise ValueError( 'Invalid path argument: "{0}". Path must be a non-empty string.'.format(path)) if path.startswith('/'): @@ -239,7 +238,7 @@ def get_if_changed(self, etag): ValueError: If the ETag is not a string. FirebaseError: If an error occurs while communicating with the remote database server. """ - if not isinstance(etag, six.string_types): + if not isinstance(etag, str): raise ValueError('ETag must be a string.') resp = self._client.request('get', self._add_suffix(), headers={'if-none-match': etag}) @@ -285,7 +284,7 @@ def set_if_unchanged(self, expected_etag, value): FirebaseError: If an error occurs while communicating with the remote database server. """ # pylint: disable=missing-raises-doc - if not isinstance(expected_etag, six.string_types): + if not isinstance(expected_etag, str): raise ValueError('Expected ETag must be a string.') if value is None: raise ValueError('Value must not be none.') @@ -488,7 +487,7 @@ class Query: def __init__(self, **kwargs): order_by = kwargs.pop('order_by') - if not order_by or not isinstance(order_by, six.string_types): + if not order_by or not isinstance(order_by, str): raise ValueError('order_by field must be a non-empty string') if order_by not in _RESERVED_FILTERS: if order_by.startswith('/'): @@ -704,7 +703,7 @@ def _get_index_type(cls, index): return cls._type_bool_true if isinstance(index, (int, float)): return cls._type_numeric - if isinstance(index, six.string_types): + if isinstance(index, str): return cls._type_string return cls._type_object @@ -825,11 +824,11 @@ def _parse_db_url(cls, url, emulator_host=None): base URL will use emulator_host instead. emulator_host is ignored if url is already an emulator URL. """ - if not url or not isinstance(url, six.string_types): + if not url or not isinstance(url, str): raise ValueError( 'Invalid database URL: "{0}". Database URL must be a non-empty ' 'URL string.'.format(url)) - parsed_url = urllib.parse.urlparse(url) + parsed_url = parse.urlparse(url) if parsed_url.netloc.endswith('.firebaseio.com'): return cls._parse_production_url(parsed_url, emulator_host) @@ -857,7 +856,7 @@ def _parse_production_url(cls, parsed_url, emulator_host): @classmethod def _parse_emulator_url(cls, parsed_url): """Parses emulator URL like http://localhost:8080/?ns=foo-bar""" - query_ns = urllib.parse.parse_qs(parsed_url.query).get('ns') + query_ns = parse.parse_qs(parsed_url.query).get('ns') if parsed_url.scheme != 'http' or (not query_ns or len(query_ns) != 1 or not query_ns[0]): raise ValueError( 'Invalid database URL: "{0}". Database URL must be a valid URL to a ' diff --git a/firebase_admin/instance_id.py b/firebase_admin/instance_id.py index f90d058cc..604158d9c 100644 --- a/firebase_admin/instance_id.py +++ b/firebase_admin/instance_id.py @@ -18,7 +18,6 @@ """ import requests -import six from firebase_admin import _http_client from firebase_admin import _utils @@ -80,7 +79,7 @@ def __init__(self, app): credential=app.credential.get_credential(), base_url=_IID_SERVICE_URL) def delete_instance_id(self, instance_id): - if not isinstance(instance_id, six.string_types) or not instance_id: + if not isinstance(instance_id, str) or not instance_id: raise ValueError('Instance ID must be a non-empty string.') path = 'project/{0}/instanceId/{1}'.format(self._project_id, instance_id) try: diff --git a/firebase_admin/messaging.py b/firebase_admin/messaging.py index 71366e5c4..9262751a1 100644 --- a/firebase_admin/messaging.py +++ b/firebase_admin/messaging.py @@ -15,12 +15,11 @@ """Firebase Cloud Messaging module.""" import json -import requests -import six import googleapiclient from googleapiclient import http from googleapiclient import _auth +import requests import firebase_admin from firebase_admin import _http_client @@ -395,15 +394,15 @@ def batch_callback(_, response, error): def make_topic_management_request(self, tokens, topic, operation): """Invokes the IID service for topic management functionality.""" - if isinstance(tokens, six.string_types): + if isinstance(tokens, str): tokens = [tokens] if not isinstance(tokens, list) or not tokens: raise ValueError('Tokens must be a string or a non-empty list of strings.') - invalid_str = [t for t in tokens if not isinstance(t, six.string_types) or not t] + invalid_str = [t for t in tokens if not isinstance(t, str) or not t] if invalid_str: raise ValueError('Tokens must be non-empty strings.') - if not isinstance(topic, six.string_types) or not topic: + if not isinstance(topic, str) or not topic: raise ValueError('Topic must be a non-empty string.') if not topic.startswith('/topics/'): topic = '/topics/{0}'.format(topic) diff --git a/firebase_admin/project_management.py b/firebase_admin/project_management.py index 076542bda..91aa1eebb 100644 --- a/firebase_admin/project_management.py +++ b/firebase_admin/project_management.py @@ -22,7 +22,6 @@ import time import requests -import six import firebase_admin from firebase_admin import exceptions @@ -117,13 +116,13 @@ def create_ios_app(bundle_id, display_name=None, app=None): def _check_is_string_or_none(obj, field_name): - if obj is None or isinstance(obj, six.string_types): + if obj is None or isinstance(obj, str): return obj raise ValueError('{0} must be a string.'.format(field_name)) def _check_is_nonempty_string(obj, field_name): - if isinstance(obj, six.string_types) and obj: + if isinstance(obj, str) and obj: return obj raise ValueError('{0} must be a non-empty string.'.format(field_name)) diff --git a/firebase_admin/storage.py b/firebase_admin/storage.py index a080b31ef..16f48e273 100644 --- a/firebase_admin/storage.py +++ b/firebase_admin/storage.py @@ -25,8 +25,6 @@ raise ImportError('Failed to import the Cloud Storage library for Python. Make sure ' 'to install the "google-cloud-storage" module.') -import six - from firebase_admin import _utils @@ -77,7 +75,7 @@ def bucket(self, name=None): 'Storage bucket name not specified. Specify the bucket name via the ' '"storageBucket" option when initializing the App, or specify the bucket ' 'name explicitly when calling the storage.bucket() function.') - if not bucket_name or not isinstance(bucket_name, six.string_types): + if not bucket_name or not isinstance(bucket_name, str): raise ValueError( 'Invalid storage bucket name: "{0}". Bucket name must be a non-empty ' 'string.'.format(bucket_name)) diff --git a/integration/test_auth.py b/integration/test_auth.py index c3759ce12..5d26dd9f1 100644 --- a/integration/test_auth.py +++ b/integration/test_auth.py @@ -17,13 +17,13 @@ import datetime import random import time +from urllib import parse import uuid import google.oauth2.credentials from google.auth import transport import pytest import requests -import six import firebase_admin from firebase_admin import auth @@ -82,8 +82,8 @@ def _sign_in_with_email_link(email, oob_code, api_key): return resp.json().get('idToken') def _extract_link_params(link): - query = six.moves.urllib.parse.urlparse(link).query - query_dict = dict(six.moves.urllib.parse.parse_qsl(query)) + query = parse.urlparse(link).query + query_dict = dict(parse.parse_qsl(query)) return query_dict def test_custom_token(api_key): @@ -427,7 +427,7 @@ def test_import_users_with_password(api_key): def test_password_reset(new_user_email_unverified, api_key): link = auth.generate_password_reset_link(new_user_email_unverified.email) - assert isinstance(link, six.string_types) + assert isinstance(link, str) query_dict = _extract_link_params(link) user_email = _reset_password(query_dict['oobCode'], 'newPassword', api_key) assert new_user_email_unverified.email == user_email @@ -436,7 +436,7 @@ def test_password_reset(new_user_email_unverified, api_key): def test_email_verification(new_user_email_unverified, api_key): link = auth.generate_email_verification_link(new_user_email_unverified.email) - assert isinstance(link, six.string_types) + assert isinstance(link, str) query_dict = _extract_link_params(link) user_email = _verify_email(query_dict['oobCode'], api_key) assert new_user_email_unverified.email == user_email @@ -446,7 +446,7 @@ def test_password_reset_with_settings(new_user_email_unverified, api_key): action_code_settings = auth.ActionCodeSettings(ACTION_LINK_CONTINUE_URL) link = auth.generate_password_reset_link(new_user_email_unverified.email, action_code_settings=action_code_settings) - assert isinstance(link, six.string_types) + assert isinstance(link, str) query_dict = _extract_link_params(link) assert query_dict['continueUrl'] == ACTION_LINK_CONTINUE_URL user_email = _reset_password(query_dict['oobCode'], 'newPassword', api_key) @@ -458,7 +458,7 @@ def test_email_verification_with_settings(new_user_email_unverified, api_key): action_code_settings = auth.ActionCodeSettings(ACTION_LINK_CONTINUE_URL) link = auth.generate_email_verification_link(new_user_email_unverified.email, action_code_settings=action_code_settings) - assert isinstance(link, six.string_types) + assert isinstance(link, str) query_dict = _extract_link_params(link) assert query_dict['continueUrl'] == ACTION_LINK_CONTINUE_URL user_email = _verify_email(query_dict['oobCode'], api_key) @@ -469,7 +469,7 @@ def test_email_sign_in_with_settings(new_user_email_unverified, api_key): action_code_settings = auth.ActionCodeSettings(ACTION_LINK_CONTINUE_URL) link = auth.generate_sign_in_with_email_link(new_user_email_unverified.email, action_code_settings=action_code_settings) - assert isinstance(link, six.string_types) + assert isinstance(link, str) query_dict = _extract_link_params(link) assert query_dict['continueUrl'] == ACTION_LINK_CONTINUE_URL oob_code = query_dict['oobCode'] diff --git a/integration/test_db.py b/integration/test_db.py index abd02660f..7a73ea3ad 100644 --- a/integration/test_db.py +++ b/integration/test_db.py @@ -18,7 +18,6 @@ import os import pytest -import six import firebase_admin from firebase_admin import db @@ -113,7 +112,7 @@ def test_get_value_and_etag(self, testref, testdata): value, etag = testref.get(etag=True) assert isinstance(value, dict) assert testdata == value - assert isinstance(etag, six.string_types) + assert isinstance(etag, str) def test_get_shallow(self, testref): value = testref.get(shallow=True) @@ -124,7 +123,7 @@ def test_get_if_changed(self, testref, testdata): success, data, etag = testref.get_if_changed('wrong_etag') assert success is True assert data == testdata - assert isinstance(etag, six.string_types) + assert isinstance(etag, str) assert testref.get_if_changed(etag) == (False, None, None) def test_get_child_value(self, testref, testdata): @@ -211,7 +210,7 @@ def test_set_if_unchanged(self, testref): success, data, etag = edward.set_if_unchanged('invalid-etag', update_data) assert success is False assert data == push_data - assert isinstance(etag, six.string_types) + assert isinstance(etag, str) success, data, new_etag = edward.set_if_unchanged(etag, update_data) assert success is True diff --git a/requirements.txt b/requirements.txt index 6d28b38ac..d7fb6d736 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,4 +8,3 @@ google-api-core[grpc] >= 1.14.0, < 2.0.0dev; platform.python_implementation != ' google-api-python-client >= 1.7.8 google-cloud-firestore >= 1.4.0; platform.python_implementation != 'PyPy' google-cloud-storage >= 1.18.0 -six >= 1.6.1 diff --git a/setup.py b/setup.py index b492ec922..43da5eb85 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,6 @@ 'google-api-python-client >= 1.7.8', 'google-cloud-firestore>=1.4.0; platform.python_implementation != "PyPy"', 'google-cloud-storage>=1.18.0', - 'six>=1.6.1' ] setup( diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 3df7ec2e3..96072d91b 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import io import json import socket @@ -19,7 +20,6 @@ import pytest import requests from requests import models -import six from googleapiclient import errors from firebase_admin import exceptions @@ -174,7 +174,7 @@ def _create_response(self, status=500, payload=None): resp = models.Response() resp.status_code = status if payload: - resp.raw = six.BytesIO(payload.encode()) + resp.raw = io.BytesIO(payload.encode()) exc = requests.exceptions.RequestException('Test error', response=resp) return resp, exc diff --git a/tests/test_messaging.py b/tests/test_messaging.py index 36f5943be..33c99445b 100644 --- a/tests/test_messaging.py +++ b/tests/test_messaging.py @@ -17,10 +17,8 @@ import json import numbers -import pytest -import six - from googleapiclient.http import HttpMockSequence +import pytest import firebase_admin from firebase_admin import exceptions @@ -288,7 +286,7 @@ def test_invalid_priority(self, data): with pytest.raises(ValueError) as excinfo: check_encoding(messaging.Message( topic='topic', android=messaging.AndroidConfig(priority=data))) - if isinstance(data, six.string_types): + if isinstance(data, str): assert str(excinfo.value) == 'AndroidConfig.priority must be "high" or "normal".' else: assert str(excinfo.value) == 'AndroidConfig.priority must be a non-empty string.' @@ -405,7 +403,7 @@ def test_invalid_icon(self, data): def test_invalid_color(self, data): notification = messaging.AndroidNotification(color=data) excinfo = self._check_notification(notification) - if isinstance(data, six.string_types): + if isinstance(data, str): assert str(excinfo.value) == 'AndroidNotification.color must be in the form #RRGGBB.' else: assert str(excinfo.value) == 'AndroidNotification.color must be a non-empty string.' @@ -491,7 +489,7 @@ def test_invalid_event_timestamp(self, timestamp): def test_invalid_priority(self, priority): notification = messaging.AndroidNotification(priority=priority) excinfo = self._check_notification(notification) - if isinstance(priority, six.string_types): + if isinstance(priority, str): if not priority: expected = 'AndroidNotification.priority must be a non-empty string.' else: @@ -505,7 +503,7 @@ def test_invalid_priority(self, priority): def test_invalid_visibility(self, visibility): notification = messaging.AndroidNotification(visibility=visibility) excinfo = self._check_notification(notification) - if isinstance(visibility, six.string_types): + if isinstance(visibility, str): if not visibility: expected = 'AndroidNotification.visibility must be a non-empty string.' else: @@ -679,7 +677,7 @@ def test_invalid_color(self, data): notification = messaging.LightSettings(color=data, light_on_duration_millis=300, light_off_duration_millis=200) excinfo = self._check_light_settings(notification) - if isinstance(data, six.string_types): + if isinstance(data, str): assert str(excinfo.value) == ('LightSettings.color must be in the form #RRGGBB or ' '#RRGGBBAA.') else: @@ -853,7 +851,7 @@ def test_invalid_badge(self, data): def test_invalid_direction(self, data): notification = messaging.WebpushNotification(direction=data) excinfo = self._check_notification(notification) - if isinstance(data, six.string_types): + if isinstance(data, str): assert str(excinfo.value) == ('WebpushNotification.direction must be "auto", ' '"ltr" or "rtl".') else: @@ -2195,7 +2193,7 @@ def _get_url(self, path): @pytest.mark.parametrize('tokens', [None, '', list(), dict(), tuple()]) def test_invalid_tokens(self, tokens): expected = 'Tokens must be a string or a non-empty list of strings.' - if isinstance(tokens, six.string_types): + if isinstance(tokens, str): expected = 'Tokens must be non-empty strings.' with pytest.raises(ValueError) as excinfo: diff --git a/tests/test_sseclient.py b/tests/test_sseclient.py index 881ecc6b9..70edcf0d0 100644 --- a/tests/test_sseclient.py +++ b/tests/test_sseclient.py @@ -13,10 +13,10 @@ # limitations under the License. """Tests for firebase_admin._sseclient.""" +import io import json import requests -import six from firebase_admin import _sseclient from tests import testutils @@ -31,7 +31,7 @@ def send(self, request, **kwargs): resp = super(MockSSEClientAdapter, self).send(request, **kwargs) resp.url = request.url resp.status_code = self.status - resp.raw = six.BytesIO(self.data.encode()) + resp.raw = io.BytesIO(self.data.encode()) resp.encoding = "utf-8" return resp diff --git a/tests/test_token_gen.py b/tests/test_token_gen.py index e92fd0059..439c1ba6e 100644 --- a/tests/test_token_gen.py +++ b/tests/test_token_gen.py @@ -26,7 +26,6 @@ import google.oauth2.id_token import pytest from pytest_localserver import plugin -import six import firebase_admin from firebase_admin import auth @@ -68,7 +67,7 @@ def _merge_jwt_claims(defaults, overrides): return defaults def _verify_custom_token(custom_token, expected_claims): - assert isinstance(custom_token, six.binary_type) + assert isinstance(custom_token, bytes) token = google.oauth2.id_token.verify_token( custom_token, testutils.MockRequest(200, MOCK_PUBLIC_CERTS), diff --git a/tests/test_user_mgt.py b/tests/test_user_mgt.py index f1572baf2..9b0b4ce11 100644 --- a/tests/test_user_mgt.py +++ b/tests/test_user_mgt.py @@ -17,9 +17,9 @@ import base64 import json import time +from urllib import parse import pytest -from six.moves import urllib import firebase_admin from firebase_admin import auth @@ -772,7 +772,7 @@ def _check_rpc_calls(self, recorder, expected=None): if expected is None: expected = {'maxResults' : '1000'} assert len(recorder) == 1 - request = dict(urllib.parse.parse_qsl(urllib.parse.urlsplit(recorder[0].url).query)) + request = dict(parse.parse_qsl(parse.urlsplit(recorder[0].url).query)) assert request == expected diff --git a/tests/testutils.py b/tests/testutils.py index 9c69663a0..d0663ead1 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -13,13 +13,13 @@ # limitations under the License. """Common utility classes and functions for testing.""" +import io import os from google.auth import credentials from google.auth import transport from requests import adapters from requests import models -import six import firebase_admin @@ -145,7 +145,7 @@ def send(self, request, **kwargs): # pylint: disable=arguments-differ resp = models.Response() resp.url = request.url resp.status_code = self._statuses[self._current_response] - resp.raw = six.BytesIO(self._responses[self._current_response].encode()) + resp.raw = io.BytesIO(self._responses[self._current_response].encode()) self._current_response = min(self._current_response + 1, len(self._responses) - 1) return resp