Skip to content

Commit

Permalink
rename Form to FlaskForm (#250)
Browse files Browse the repository at this point in the history
show deprecation warning when using Form
closes #249
  • Loading branch information
davidism authored Jun 30, 2016
1 parent 62bf5b4 commit 42cc475
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 48 deletions.
6 changes: 4 additions & 2 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ Forms and Fields

.. module:: flask_wtf

.. autoclass:: Form
:members:
.. autoclass:: FlaskForm
:members:

.. autoclass:: Form(...)

.. autoclass:: RecaptchaField

Expand Down
4 changes: 2 additions & 2 deletions examples/babel/app.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from flask import Flask, render_template, request
from wtforms import TextField
from wtforms.validators import DataRequired
from flask_wtf import Form
from flask_wtf import FlaskForm
from flask_babel import Babel
from flask_babel import lazy_gettext as _


class BabelForm(Form):
class BabelForm(FlaskForm):
name = TextField(_('Name'), validators=[DataRequired()])


Expand Down
6 changes: 3 additions & 3 deletions examples/flaskr/flaskr.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from __future__ import with_statement
from flask import (Flask, session, redirect, url_for, abort,
render_template, flash)
from flask_wtf import Form
from flask_wtf import FlaskForm
from wtforms import TextField, TextAreaField, PasswordField, SubmitField
from wtforms.validators import DataRequired, ValidationError
from flask_sqlalchemy import SQLAlchemy
Expand Down Expand Up @@ -46,14 +46,14 @@ class Entry(db.Model):
db.create_all()


class EntryForm(Form):
class EntryForm(FlaskForm):

title = TextField("Title", validators=[DataRequired()])
text = TextAreaField("Text")
submit = SubmitField("Share")


class LoginForm(Form):
class LoginForm(FlaskForm):

username = TextField("Username")
password = PasswordField("Password")
Expand Down
4 changes: 2 additions & 2 deletions examples/recaptcha/app.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from flask import Flask, render_template, flash, session, redirect, url_for
from wtforms import TextAreaField
from wtforms.validators import DataRequired
from flask_wtf import Form
from flask_wtf import FlaskForm
from flask_wtf.recaptcha import RecaptchaField


Expand All @@ -17,7 +17,7 @@
app.config.from_object(__name__)


class CommentForm(Form):
class CommentForm(FlaskForm):

comment = TextAreaField("Comment", validators=[DataRequired()])
recaptcha = RecaptchaField()
Expand Down
4 changes: 2 additions & 2 deletions examples/uploadr/app.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from flask import Flask, render_template
from flask_wtf import Form
from flask_wtf import FlaskForm
from flask_wtf.file import FileField
from wtforms import FieldList

class FileUploadForm(Form):
class FileUploadForm(FlaskForm):
uploads = FieldList(FileField())

DEBUG = True
Expand Down
2 changes: 1 addition & 1 deletion flask_wtf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# flake8: noqa
from __future__ import absolute_import

from .form import Form
from .form import FlaskForm, Form
from .csrf import CsrfProtect
from .recaptcha import *

Expand Down
10 changes: 10 additions & 0 deletions flask_wtf/_compat.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import sys
import warnings

if sys.version_info[0] == 3:
text_type = str
string_types = (str,)
Expand All @@ -19,3 +21,11 @@ def to_unicode(input_bytes, encoding='utf-8'):
if not isinstance(input_bytes, string_types):
input_bytes = input_bytes.decode(encoding)
return input_bytes


class FlaskWTFDeprecationWarning(DeprecationWarning):
pass


warnings.simplefilter('always', FlaskWTFDeprecationWarning)
warnings.filterwarnings('ignore', category=FlaskWTFDeprecationWarning, module='wtforms|flask_wtf')
66 changes: 42 additions & 24 deletions flask_wtf/form.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
# coding: utf-8
import warnings

import werkzeug.datastructures

from jinja2 import Markup, escape
from flask import request, session, current_app
from jinja2 import Markup, escape
from wtforms.compat import with_metaclass
from wtforms.ext.csrf.form import SecureForm
from wtforms.fields import HiddenField
from wtforms.widgets import HiddenInput
from wtforms.form import FormMeta
from wtforms.validators import ValidationError
from wtforms.ext.csrf.form import SecureForm
from ._compat import text_type, string_types
from wtforms.widgets import HiddenInput

from ._compat import text_type, string_types, FlaskWTFDeprecationWarning
from .csrf import generate_csrf, validate_csrf

try:
Expand All @@ -19,11 +22,11 @@
SUBMIT_METHODS = set(('POST', 'PUT', 'PATCH', 'DELETE'))


class _Auto():
'''Placeholder for unspecified variables that should be set to defaults.
class _Auto(object):
"""Placeholder for unspecified variables that should be set to defaults.
Used when None is a valid option and should not be replaced by a default.
'''
"""
pass


Expand All @@ -36,28 +39,27 @@ def _is_hidden(field):
return False


class Form(SecureForm):
"""
Flask-specific subclass of WTForms **SecureForm** class.
class FlaskForm(SecureForm):
"""Flask-specific subclass of WTForms :class:`~wtforms.ext.csrf.form.SecureForm` class.
If formdata is not specified, this will use flask.request.form.
Explicitly pass formdata = None to prevent this.
If ``formdata`` is not specified, this will use :attr:`flask.request.form` and
:attr:`flask.request.files`. Explicitly pass ``formdata=None`` to prevent this.
:param csrf_context: a session or dict-like object to use when making
CSRF tokens. Default: flask.session.
CSRF tokens. Default: :data:`flask.session`.
:param secret_key: a secret key for building CSRF tokens. If this isn't
specified, the form will take the first of these
that is defined:
specified, the form will take the first of these
that is defined:
* SECRET_KEY attribute on this class
* WTF_CSRF_SECRET_KEY config of flask app
* SECRET_KEY config of flask app
* session secret key
* SECRET_KEY attribute on this class
* WTF_CSRF_SECRET_KEY config of Flask app
* SECRET_KEY config of Flask app
* session secret key
:param csrf_enabled: whether to use CSRF protection. If False, all
csrf behavior is suppressed.
Default: WTF_CSRF_ENABLED config value
csrf behavior is suppressed.
Default: WTF_CSRF_ENABLED config value
"""

SECRET_KEY = None
Expand Down Expand Up @@ -93,7 +95,7 @@ def __init__(self, formdata=_Auto, obj=None, prefix='', csrf_context=None,
else:
csrf_context = {}
self.SECRET_KEY = ''
super(Form, self).__init__(
super(FlaskForm, self).__init__(
formdata, obj, prefix,
csrf_context=csrf_context,
**kwargs
Expand Down Expand Up @@ -169,7 +171,7 @@ def validate_on_submit(self):

@property
def data(self):
d = super(Form, self).data
d = super(FlaskForm, self).data
# https://github.com/lepture/flask-wtf/issues/208
if self.csrf_enabled:
d.pop('csrf_token', None)
Expand All @@ -179,3 +181,19 @@ def _get_translations(self):
if not current_app.config.get('WTF_I18N_ENABLED', True):
return None
return translations


class DeprecatedFormMeta(FormMeta):
def __init__(cls, name, bases, attrs):
warnings.warn(FlaskWTFDeprecationWarning(
'"flask_wtf.Form" has been renamed to "FlaskForm" '
'and will be removed in 1.0.'
), stacklevel=2)
type.__init__(cls, name, bases, attrs)


class Form(with_metaclass(DeprecatedFormMeta, FlaskForm)):
"""
.. deprecated:: 0.13
Renamed to :class:`~flask_wtf.FlaskForm`.
"""
8 changes: 4 additions & 4 deletions tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from flask import Flask, render_template, jsonify
from wtforms import StringField, HiddenField, SubmitField
from wtforms.validators import DataRequired
from flask_wtf import Form
from flask_wtf import FlaskForm
from flask_wtf._compat import text_type


Expand All @@ -13,13 +13,13 @@ def to_unicode(text):
return text


class MyForm(Form):
class MyForm(FlaskForm):
SECRET_KEY = "a poorly kept secret."
name = StringField("Name", validators=[DataRequired()])
submit = SubmitField("Submit")


class HiddenFieldsForm(Form):
class HiddenFieldsForm(FlaskForm):
SECRET_KEY = "a poorly kept secret."
name = HiddenField()
url = HiddenField()
Expand All @@ -32,7 +32,7 @@ def __init__(self, *args, **kwargs):
self.method.name = '_method'


class SimpleForm(Form):
class SimpleForm(FlaskForm):
SECRET_KEY = "a poorly kept secret."
pass

Expand Down
15 changes: 15 additions & 0 deletions tests/test_form.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import warnings
from unittest import TestCase
from flask_wtf import Form
from flask_wtf._compat import FlaskWTFDeprecationWarning


class TestForm(TestCase):
def test_deprecated_form(self):
def define_deprecated_form():
class F(Form):
pass

with warnings.catch_warnings():
warnings.simplefilter('error', FlaskWTFDeprecationWarning)
self.assertRaises(FlaskWTFDeprecationWarning, define_deprecated_form)
4 changes: 2 additions & 2 deletions tests/test_recaptcha.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
from .base import TestCase
from flask import json
from flask import Flask, render_template
from flask_wtf import Form
from flask_wtf import FlaskForm
from flask_wtf.recaptcha import RecaptchaField


RECAPTCHA_PUBLIC_KEY = '6LeYIbsSAAAAACRPIllxA7wvXjIE411PfdB2gt2J'
RECAPTCHA_PRIVATE_KEY = '6LeYIbsSAAAAAJezaIq3Ft_hSTo0YtyeFG-JgRtu'


class RecaptchaFrom(Form):
class RecaptchaFrom(FlaskForm):
SECRET_KEY = "a poorly kept secret."
recaptcha = RecaptchaField()

Expand Down
12 changes: 6 additions & 6 deletions tests/test_uploads.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from flask import render_template, request

from wtforms import StringField, FieldList
from flask_wtf import Form
from flask_wtf import FlaskForm
from flask_wtf.file import FileField
from flask_wtf.file import file_required, file_allowed

Expand All @@ -30,21 +30,21 @@ def file_allowed(self, storage, basename):
images = UploadSet('images', ['jpg', 'png'])


class FileUploadForm(Form):
class FileUploadForm(FlaskForm):
upload = FileField("Upload file")


class MultipleFileUploadForm(Form):
class MultipleFileUploadForm(FlaskForm):
uploads = FieldList(FileField("upload"), min_entries=3)


class ImageUploadForm(Form):
class ImageUploadForm(FlaskForm):
upload = FileField("Upload file",
validators=[file_required(),
file_allowed(images)])


class TextUploadForm(Form):
class TextUploadForm(FlaskForm):
upload = FileField("Upload file",
validators=[file_required(),
file_allowed(['txt'])])
Expand Down Expand Up @@ -152,7 +152,7 @@ def test_invalid_image_file(self):
assert b'invalid' in response.data


class BrokenForm(Form):
class BrokenForm(FlaskForm):
text_fields = FieldList(StringField())
file_fields = FieldList(FileField())

Expand Down

0 comments on commit 42cc475

Please sign in to comment.