Skip to content
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

1.0 version deprecations removal #484

Merged
merged 2 commits into from
Nov 7, 2021
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
3 changes: 0 additions & 3 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ Forms and Fields
.. module:: flask_wtf.file

.. autoclass:: FileField
:members: has_file

.. autoclass:: FileAllowed

Expand All @@ -34,8 +33,6 @@ CSRF Protection
.. autoclass:: CSRFProtect
:members:

.. autoclass:: CsrfProtect(...)

.. autoclass:: CSRFError
:members:

Expand Down
5 changes: 2 additions & 3 deletions docs/changes.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
Changes
=======

Version 0.16.0
Version 1.0.0
--------------

Unreleased

- Deprecated items removal :pr:`484`

Version 0.15.1
--------------
Expand Down
1 change: 0 additions & 1 deletion src/flask_wtf/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from .csrf import CSRFProtect
from .csrf import CsrfProtect
from .form import FlaskForm
from .form import Form
from .recaptcha import Recaptcha
Expand Down
14 changes: 0 additions & 14 deletions src/flask_wtf/_compat.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
import warnings


def to_bytes(text):
"""Transform string to bytes."""
if isinstance(text, str):
text = text.encode("utf-8")
return text


def to_unicode(input_bytes, encoding="utf-8"):
"""Decodes input_bytes to text if needed."""
if not isinstance(input_bytes, str):
input_bytes = input_bytes.decode(encoding)
return input_bytes


class FlaskWTFDeprecationWarning(DeprecationWarning):
pass

Expand Down
57 changes: 0 additions & 57 deletions src/flask_wtf/csrf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
import hmac
import logging
import os
import warnings
from functools import wraps
from urllib.parse import urlparse

from flask import Blueprint
Expand All @@ -18,8 +16,6 @@
from wtforms import ValidationError
from wtforms.csrf.core import CSRF

from ._compat import FlaskWTFDeprecationWarning

__all__ = ("generate_csrf", "validate_csrf", "CSRFProtect")
logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -310,59 +306,6 @@ def some_view():
def _error_response(self, reason):
raise CSRFError(reason)

def error_handler(self, view):
"""Register a function that will generate the response for CSRF errors.

.. deprecated:: 0.14
Use the standard Flask error system with
``@app.errorhandler(CSRFError)`` instead. This will be removed in
version 1.0.

The function will be passed one argument, ``reason``. By default it
will raise a :class:`~flask_wtf.csrf.CSRFError`. ::

@csrf.error_handler
def csrf_error(reason):
return render_template('error.html', reason=reason)

Due to historical reasons, the function may either return a response
or raise an exception with :func:`flask.abort`.
"""

warnings.warn(
FlaskWTFDeprecationWarning(
'"@csrf.error_handler" is deprecated. Use the standard Flask '
'error system with "@app.errorhandler(CSRFError)" instead. This '
"will be removed in 1.0."
),
stacklevel=2,
)

@wraps(view)
def handler(reason):
response = current_app.make_response(view(reason))
raise CSRFError(response=response)

self._error_response = handler
return view


class CsrfProtect(CSRFProtect):
"""
.. deprecated:: 0.14
Renamed to :class:`~flask_wtf.csrf.CSRFProtect`.
"""

def __init__(self, app=None):
warnings.warn(
FlaskWTFDeprecationWarning(
'"flask_wtf.CsrfProtect" has been renamed to "CSRFProtect" '
"and will be removed in 1.0."
),
stacklevel=2,
)
super().__init__(app=app)


class CSRFError(BadRequest):
"""Raise if the client sends invalid CSRF data with the request.
Expand Down
20 changes: 0 additions & 20 deletions src/flask_wtf/file.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import warnings
from collections import abc

from werkzeug.datastructures import FileStorage
Expand All @@ -7,8 +6,6 @@
from wtforms.validators import StopValidation
from wtforms.validators import ValidationError

from ._compat import FlaskWTFDeprecationWarning


class FileField(_FileField):
"""Werkzeug-aware subclass of :class:`wtforms.fields.FileField`."""
Expand All @@ -22,23 +19,6 @@ def process_formdata(self, valuelist):
else:
self.raw_data = ()

def has_file(self):
"""Return ``True`` if ``self.data`` is a
:class:`~werkzeug.datastructures.FileStorage` object.

.. deprecated:: 0.14.1
``data`` is no longer set if the input is not a non-empty
``FileStorage``. Check ``form.data is not None`` instead.
"""

warnings.warn(
FlaskWTFDeprecationWarning(
'"has_file" is deprecated and will be removed in 1.0. The data is '
"checked during processing instead."
)
)
return bool(self.data)
Copy link

Choose a reason for hiding this comment

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

@azmeuk / @davidism So how does a user check whether the file field has data? The deprecation is a triple negative and I find it hard to understand 'data' is no longer set if the input is not a non-empty". That triple negative is hard to understand.

The bit in the documentation I can find from the change log https://flask-wtf.readthedocs.io/en/1.0.x/changes/#version-0-14-1 says:

"has_file is deprecated; it’s now equivalent to bool(field.data)."

As that's the only mention in the change log I can see, I presume I can write bool(field.data) still? Which sort of makes me wonder why remove the has_file() method?



class FileRequired(DataRequired):
"""Validates that the data is a Werkzeug
Expand Down
33 changes: 0 additions & 33 deletions src/flask_wtf/form.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import warnings

from flask import current_app
from flask import request
from flask import session
Expand All @@ -11,7 +9,6 @@
from wtforms.meta import DefaultMeta
from wtforms.widgets import HiddenInput

from ._compat import FlaskWTFDeprecationWarning
from .csrf import _FlaskFormCSRF

try:
Expand Down Expand Up @@ -73,19 +70,6 @@ def get_translations(self, form):
return translations

def __init__(self, formdata=_Auto, **kwargs):
csrf_enabled = kwargs.pop("csrf_enabled", None)

if csrf_enabled is not None:
warnings.warn(
FlaskWTFDeprecationWarning(
'"csrf_enabled" is deprecated and will be removed in 1.0. '
"Pass meta={'csrf': False} instead."
),
stacklevel=3,
)
kwargs["meta"] = kwargs.get("meta") or {}
kwargs["meta"].setdefault("csrf", csrf_enabled)

super().__init__(formdata=formdata, **kwargs)

def is_submitted(self):
Expand Down Expand Up @@ -141,20 +125,3 @@ def _is_submitted():
"""

return bool(request) and request.method in SUBMIT_METHODS


class Form(FlaskForm):
"""
.. deprecated:: 0.13
Renamed to :class:`~flask_wtf.FlaskForm`.
"""

def __init__(self, *args, **kwargs):
warnings.warn(
FlaskWTFDeprecationWarning(
'"flask_wtf.Form" has been renamed to "FlaskForm" '
"and will be removed in 1.0."
),
stacklevel=3,
)
super().__init__(*args, **kwargs)
15 changes: 0 additions & 15 deletions src/flask_wtf/html5.py

This file was deleted.

7 changes: 2 additions & 5 deletions src/flask_wtf/recaptcha/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
from werkzeug.urls import url_encode
from wtforms import ValidationError

from .._compat import to_bytes
from .._compat import to_unicode

RECAPTCHA_VERIFY_SERVER = "https://www.google.com/recaptcha/api/siteverify"
RECAPTCHA_ERROR_CODES = {
"missing-input-secret": "The secret parameter is missing.",
Expand Down Expand Up @@ -57,12 +54,12 @@ def _validate_recaptcha(self, response, remote_addr):
{"secret": private_key, "remoteip": remote_addr, "response": response}
)

http_response = http.urlopen(RECAPTCHA_VERIFY_SERVER, to_bytes(data))
http_response = http.urlopen(RECAPTCHA_VERIFY_SERVER, data.encode("utf-8"))

if http_response.code != 200:
return False

json_resp = json.loads(to_unicode(http_response.read()))
json_resp = json.loads(http_response.read())

if json_resp["success"]:
return True
Expand Down
29 changes: 0 additions & 29 deletions tests/test_csrf_extension.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import pytest
from flask import abort
from flask import Blueprint
from flask import g
from flask import render_template_string
from flask import request

from flask_wtf import FlaskForm
from flask_wtf._compat import FlaskWTFDeprecationWarning
from flask_wtf.csrf import CSRFError
from flask_wtf.csrf import CSRFProtect
from flask_wtf.csrf import CsrfProtect
from flask_wtf.csrf import generate_csrf


Expand Down Expand Up @@ -180,28 +176,3 @@ def assert_info(message):
client.post("/")
assert len(messages) == 1
assert messages[0] == "The CSRF token is missing."


def test_deprecated_csrfprotect(recwarn):
CsrfProtect()
w = recwarn.pop(FlaskWTFDeprecationWarning)
assert "CSRFProtect" in str(w.message)


def test_deprecated_error_handler(csrf, client, recwarn):
@csrf.error_handler
def handle_csrf_error(reason):
if "abort" in request.form:
abort(418)

return "return"

w = recwarn.pop(FlaskWTFDeprecationWarning)
assert "@app.errorhandler" in str(w.message)

response = client.post("/", data={"abort": "1"})
assert response.status_code == 418

response = client.post("/")
assert response.status_code == 200
assert "return" in response.get_data(as_text=True)
7 changes: 0 additions & 7 deletions tests/test_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from wtforms import FileField as BaseFileField

from flask_wtf import FlaskForm
from flask_wtf._compat import FlaskWTFDeprecationWarning
from flask_wtf.file import FileAllowed
from flask_wtf.file import FileField
from flask_wtf.file import FileRequired
Expand Down Expand Up @@ -127,9 +126,3 @@ class Meta:
assert not F().validate()
assert not F(f=FileStorage()).validate()
assert F(f=FileStorage(filename="real")).validate()


def test_deprecated_filefield(recwarn, form):
assert not form().file.has_file()
w = recwarn.pop(FlaskWTFDeprecationWarning)
assert "has_file" in str(w.message)
32 changes: 0 additions & 32 deletions tests/test_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@
from wtforms import HiddenField
from wtforms import IntegerField
from wtforms import StringField
from wtforms.form import FormMeta
from wtforms.validators import DataRequired
from wtforms.widgets import HiddenInput

from flask_wtf import FlaskForm
from flask_wtf import Form
from flask_wtf._compat import FlaskWTFDeprecationWarning


class BasicForm(FlaskForm):
Expand Down Expand Up @@ -105,35 +102,6 @@ class Meta:
assert "csrf_token" not in f.hidden_tag("count", "key")


def test_deprecated_form(req_ctx, recwarn):
class F(Form):
pass

F()
w = recwarn.pop(FlaskWTFDeprecationWarning)
assert "FlaskForm" in str(w.message)


def test_custom_meta_with_deprecated_form(req_ctx, recwarn):
class FMeta(FormMeta):
pass

class F(Form, metaclass=FMeta):
pass

F()
recwarn.pop(FlaskWTFDeprecationWarning)


def test_deprecated_csrf_enabled(req_ctx, recwarn):
class F(FlaskForm):
pass

F(csrf_enabled=False)
w = recwarn.pop(FlaskWTFDeprecationWarning)
assert "meta={'csrf': False}" in str(w.message)


def test_set_default_message_language(app, client):
@app.route("/default", methods=["POST"])
def default():
Expand Down
7 changes: 0 additions & 7 deletions tests/test_html5.py

This file was deleted.

Loading