internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: web2py/web2py

Issue:
SQLFORM.factory Shows Non for fields with writable=False in 2.17.1
After upgrade to 2.17.1 (from 2.14.06)
Fields with a default value and writable=False  shows Non instead of the default value

**To Reproduce**
Run the following function and change  writable from True to false to show the default values

function:
```

def form_test():
    form = SQLFORM.factory(
        Field('tag_product_name', label='', writable=False, default='Som great product'),
        Field('today', 'date', label='today', writable=False, default=request.now.date()),
        buttons=[   TAG.button(T('Roll back'), _type="submit", _class="btn btn-primary")
                ,   TAG.button(T('Cancel'), _type="button",_onClick="parent.location='%s' ;return false" % URL('default', 'form_test'))
                 ], table_name='refund',
    )
    title=T("Form test")

    if form.process(session=None, formname='test').accepted:
        print form.vars.today,type(form.vars.today)
        session.flash = T('Message that not flashing')
        redirect(URL('default', 'form_test'))
    elif form.errors:
        response.flash = 'form has errors'
    else:
        response.flash = T('Select items to refund')
    return locals()

```
The view (form_test.html):

```
{{left_sidebar_enabled=right_sidebar_enabled=True}}
{{extend 'layout.html'}}
{{block header}}
 {{end}}
{{block left_sidebar}}
 {{end}}
 {{block right_sidebar}}
 {{end}}
 <div class="alert alert-success" role="alert"><h3 align=center>
         {{=title}}
              </h3>
 </div>
    <div class="well">
	<div class="row">
        <div class="col-md-9">
        <h4>{{=T('Fields with writable=False shows None')}}</h4>
        {{=form.custom.begin}}
        <table id="mytable" class="table table-bordred table-striped">
                   <thead>
                   </thead>
        
    <tbody>
      <tr><td>{{=form.custom.widget.tag_product_name}}</td>
    </tr>
   <tr>
   <td align="right">{{=form.custom.widget.today}}</td>
    </tbody>
    </table> 
            {{=form.custom.submit}}
            {{=form.custom.end}}
</div>
</div>
</div>

```


**Expected behavior**
Shows the default values as readonly (as in web2py version 2.14.06)



Discussion:
One can argue that a read only value could just be printed in the template. However it worked in 2.14.06 this way.

Resolving patch:
diff --git a/gluon/sqlhtml.py b/gluon/sqlhtml.py
--- a/gluon/sqlhtml.py
+++ b/gluon/sqlhtml.py
@@ -1351,7 +1351,7 @@ def __init__(
             if not readonly:
                 if not record:
                     # create form should only show writable fields
-                    fields = [f.name for f in table if (ignore_rw or f.writable) and not f.compute]
+                    fields = [f.name for f in table if (ignore_rw or f.writable or (f.readable and f.default)) and not f.compute]
                 else:
                     # update form should also show readable fields and computed fields (but in reaodnly mode)
                     fields = [f.name for f in table if (ignore_rw or f.writable or f.readable)]


Test patch:
Repository: web2py/web2py

Issue:
[Py3] ASCII decode error when running app in shell with non-ascii characters
**Describe the bug**
When running a file from shell (`-S` and `-R` options), any code executed is treated as ASCII no matter the current locale. That causes errors when there's a non-ASCII character in file, as in Py3, Py2 built-in function `execfile` was removed and redefined by web2py with:
```Python
with open(filename) as f:
    code = compile(f.read(), filename, 'exec')
    exec(code, global_vars, local_vars)
```

`open(`) opens the file with ASCII encoding and `f.read()` crashes with following traceback:
```
Traceback (most recent call last):
  File "/home/devel/venvs/py3sys/web2py/gluon/shell.py",
line 277, in run
    execfile(startfile, _env)
  File "/home/devel/venvs/py3sys/web2py/gluon/shell.py",
line 41, in execfile
    file_input = f.read()
  File "/home/devel/venvs/py3sys/lib64/python3.6/encodings/ascii.py", line 26, in decode
    return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3
in position 3253: ordinal not in range(128)
```

As `exec()`, by Py3 Docs, takes either `string` or `bytearray` as first argument, quick fix would be to open file in `rb` mode

**Expected behavior**
Shell should be able to execute non-ASCII files naturally

**Desktop (please complete the following information):**
 - OS: Centos 7.5
 - Version 1.7.2



Discussion:

Resolving patch:
diff --git a/gluon/shell.py b/gluon/shell.py
--- a/gluon/shell.py
+++ b/gluon/shell.py
@@ -37,7 +37,7 @@
 
 if not PY2:
     def execfile(filename, global_vars=None, local_vars=None):
-        with open(filename) as f:
+        with open(filename, "rb") as f:
             code = compile(f.read(), filename, 'exec')
             exec(code, global_vars, local_vars)
     raw_input = input


Test patch:
Repository: web2py/web2py

Issue:
Invalid Login - Redirect Not Setting "vars" to "request.post_vars"
**Issue**
In the Auth class login function, if an invalid login occurs (passes SQLFORM field validation), i.e. valid email format and password is appropriate length, then there is a redirect to the same login function to generate another SQLFORM but it passes in request.get_vars instead of request.post_vars. Since the invalid submission is due to a POST request, get_vars will be empty and the post_vars which the user submitted will be lost and thus return a new login form which is blank (email and password field are blank).

Solution:
 Change the redirect call to use vars=request.post_vars so the user submitted values are pushed through with the redirect.
Before Fix:
                        session.flash = self.messages.invalid_login
                        callback(onfail, None)
                        redirect(
                            self.url(args=request.args, vars=request.get_vars),
                            client_side=settings.client_side)

After Fix:
                        session.flash = self.messages.invalid_login
                        callback(onfail, None)
                        redirect(
                            self.url(args=request.args, vars=request.post_vars),
                            client_side=settings.client_side)

**To Reproduce**
Steps to reproduce the behavior:
1. Go to login page of welcome app
2. Submit a valid email format and a valid password length.
3. Results: email and password are currently reset to blank instead of remaining.

**Expected Results**
- Email and password should remain the same as when the user submitted them.
 


Discussion:

Resolving patch:
diff --git a/gluon/tools.py b/gluon/tools.py
--- a/gluon/tools.py
+++ b/gluon/tools.py
@@ -2637,8 +2637,10 @@ def login(self,
                         # invalid login
                         session.flash = specific_error if self.settings.login_specify_error else self.messages.invalid_login
                         callback(onfail, None)
+                        if 'password' in request.post_vars:
+                            del request.post_vars['password']
                         redirect(
-                            self.url(args=request.args, vars=request.get_vars),
+                            self.url(args=request.args, get_vars=request.get_vars, post_vars=request.post_vars),
                             client_side=settings.client_side)
 
             else:  # use a central authentication server


Test patch:
Repository: web2py/web2py

Issue:
Error in gluon/tools.py file
Error in function "_get_login_settings()" line:

userfield = self.settings.login_userfield or 'username' if 'username' in table_user.fields else 'email'

does not return the value "self.settings.login_userfield"

correction:

userfield = self.settings.login_userfield or ('username' if 'username' in table_user.fields else 'email')
Error in gluon/tools.py file
Error in function "_get_login_settings()" line:

userfield = self.settings.login_userfield or 'username' if 'username' in table_user.fields else 'email'

does not return the value "self.settings.login_userfield"

correction:

userfield = self.settings.login_userfield or ('username' if 'username' in table_user.fields else 'email')


Discussion:

Resolving patch:
diff --git a/gluon/tools.py b/gluon/tools.py
--- a/gluon/tools.py
+++ b/gluon/tools.py
@@ -2260,9 +2260,9 @@ def basic(self, basic_auth_realm=False):
 
     def _get_login_settings(self):
         table_user = self.table_user()
-        userfield = self.settings.login_userfield or 'username' \
+        userfield = self.settings.login_userfield or ('username' \
             if self.settings.login_userfield or 'username' \
-            in table_user.fields else 'email'
+            in table_user.fields else 'email')
         passfield = self.settings.password_field
         return Storage({'table_user': table_user,
                         'userfield': userfield,


Test patch:
Repository: web2py/web2py

Issue:
Extend RConn to be able to connect to different Redis servers from within the same web2py application
Right now it's not possible to connect to different Redis servers from within the same web2py application. Taking a look at the [code of RConn class](https://github.com/web2py/web2py/blob/f06c60b963a373f661e3bb09d5af49d2098902ec/gluon/contrib/redis_utils.py#L39), you can see that the first stablished connection made to a Redis server is linked to the current web2py application. And subsequent calls to RConn from within that web2py application will return the first created connection, no matter what the connection parameters are.

This is a problem if you need to connect to different Redis servers from within the same web2py application. Notice this is also a problem if some of the connection arguments change (host, port, password, etc). 

I'm not shure what's the reason for returning always the first stablished connection, but I think a couple of fixes could be done in order to avoid this issues. I'll prepare a pull request with a proposal. 



Discussion:

Resolving patch:
diff --git a/gluon/contrib/redis_utils.py b/gluon/contrib/redis_utils.py
--- a/gluon/contrib/redis_utils.py
+++ b/gluon/contrib/redis_utils.py
@@ -29,14 +29,16 @@
 locker = Lock()
 
 
-def RConn(*args, **vars):
+def RConn(application=None, *args, **vars):
     """
     Istantiates a StrictRedis connection with parameters, at the first time
     only
     """
     locker.acquire()
     try:
-        instance_name = 'redis_conn_' + current.request.application
+        if application is None:
+            application = current.request.application
+        instance_name = 'redis_conn_' + application
         if not hasattr(RConn, instance_name):
             setattr(RConn, instance_name, redis.StrictRedis(*args, **vars))
         return getattr(RConn, instance_name)


Test patch:
Repository: web2py/web2py

Issue:
Error when using @cache.action with cache_model=None and time_expire=None
Recently, I've found that using @cache.action with time_expire=None would throw an error.

In my specific scenario, I use @cache.action with variable arguments, and in some situations I need to set all parameters to None, in order to tell @cache.action "hey, don't do anything, just do as if you weren't there". 

Here I explained my case:
[https://groups.google.com/forum/#!topic/web2py/5SuaspDnjoQ](url)

The problem can be solved with this simple modification to gluon/cache.py:
[https://github.com/gonguinguen/web2py/commit/93cd4b9fa18788dd3b6cb3087f87a71a967aaa85](url)

Could you review the change and accept it if it's ok?
I've done some tests, and it's working ok, but maybe it needs the look of a more experienced developer.

Anyway, no problem if the change isn't accepted.
Regards,
Lisandro.


Discussion:

Resolving patch:
diff --git a/gluon/cache.py b/gluon/cache.py
--- a/gluon/cache.py
+++ b/gluon/cache.py
@@ -600,15 +600,14 @@ def wrapped_f():
                     (session_, vars_, lang_, user_agent_, public_) = \
                         (session, vars, lang, user_agent, public)
 
+                expires = 'Fri, 01 Jan 1990 00:00:00 GMT'
                 if time_expire:
                     cache_control = 'max-age=%(time_expire)s, s-maxage=%(time_expire)s' % dict(time_expire=time_expire)
-                    if not session_ and public_:
-                        cache_control += ', public'
-                        expires = (current.request.utcnow + datetime.timedelta(seconds=time_expire)
-                                   ).strftime('%a, %d %b %Y %H:%M:%S GMT')
-                    else:
-                        cache_control += ', private'
-                        expires = 'Fri, 01 Jan 1990 00:00:00 GMT'
+                    expires = (current.request.utcnow + datetime.timedelta(seconds=time_expire)).strftime(
+                        '%a, %d %b %Y %H:%M:%S GMT')
+                else:
+                    cache_control = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
+                cache_control += ', public' if not session_ and public_ else ', private'
 
                 if cache_model:
                     # figure out the correct cache key


Test patch:
Repository: web2py/web2py

Issue:
Python 3 compatibility fix
https://github.com/web2py/web2py/blob/master/gluon/contrib/webclient.py#L124 should be `data['_formname'] = list(self.forms.keys())[0]` to avoid `TypeError: 'dict_keys' object does not support indexing` when this is executing under Python 3.


Discussion:

Resolving patch:
diff --git a/gluon/contrib/webclient.py b/gluon/contrib/webclient.py
--- a/gluon/contrib/webclient.py
+++ b/gluon/contrib/webclient.py
@@ -121,7 +121,7 @@ def post(self, url, data=None, cookies=None,
                 self.method = 'POST' if method=='auto' else method
                 # if there is only one form, set _formname automatically
                 if not '_formname' in data and len(self.forms) == 1:
-                    data['_formname'] = self.forms.keys()[0]
+                    data['_formname'] = next(iter(self.forms.keys())) # Use the first key
 
                 # if there is no formkey but it is known, set it
                 if '_formname' in data and not '_formkey' in data and \


Test patch:
Repository: web2py/web2py

Issue:
gluon.utils.unlocalised_http_header_date returns wrong time
**Describe the bug**
in function unlocalised_http_header_date, line 481:
`year_and_time = time.strftime("%Y %H:%M:%S GMT")`
should be:
`year_and_time = time.strftime("%Y %H:%M:%S GMT", data)`



Discussion:
Quite right!

Resolving patch:
diff --git a/gluon/utils.py b/gluon/utils.py
--- a/gluon/utils.py
+++ b/gluon/utils.py
@@ -411,7 +411,7 @@ def unlocalised_http_header_date(data):
         "12": "Dec",
     }.get(time.strftime("%m", data))
 
-    year_and_time = time.strftime("%Y %H:%M:%S GMT")
+    year_and_time = time.strftime("%Y %H:%M:%S GMT", data)
 
     return "{}, {} {} {}".format(
         short_weekday,


Test patch:
Repository: web2py/web2py

Issue:
Feature request: Add support to typing in function def return
web2py 2.18.3 returns and error when a function has typing in the def return.
Eg.
`def get_approval() -> Dict[str, SQLFORM]:`
or
`def get_approval() -> None:`

I suggest that support for it be added.


Discussion:

Resolving patch:
diff --git a/gluon/compileapp.py b/gluon/compileapp.py
--- a/gluon/compileapp.py
+++ b/gluon/compileapp.py
@@ -23,7 +23,6 @@
 from gluon.template import parse_template
 from gluon.restricted import restricted, compile2
 from gluon.fileutils import mktree, listdir, read_file, write_file
-from gluon.myregex import regex_expose, regex_longcomments
 from gluon.languages import TranslatorFactory
 from gluon.dal import DAL, Field
 from gluon.validators import Validator
@@ -45,6 +44,7 @@
 from gluon import rewrite
 from gluon.custom_import import custom_import_install
 import py_compile
+import ast
 
 logger = logging.getLogger("web2py")
 
@@ -517,8 +517,8 @@ def compile_models(folder):
 
 
 def find_exposed_functions(data):
-    data = regex_longcomments.sub('', data)
-    return regex_expose.findall(data)
+    parsed = ast.parse(data)
+    return [n.name for n in ast.walk(parsed) if type(n) == ast.FunctionDef and len(n.args.args) == 0 and n.args.kwarg is None]
 
 
 def compile_controllers(folder):
diff --git a/gluon/myregex.py b/gluon/myregex.py
--- a/gluon/myregex.py
+++ b/gluon/myregex.py
@@ -18,13 +18,7 @@
     """^[\w]+\.define_table\(\s*[\'\"](?P<name>\w+)[\'\"]""",
     flags=re.M)
 
-# pattern to find exposed functions in controller
-
-regex_expose = re.compile(
-    '^def\s+(?P<name>_?[a-zA-Z0-9]\w*)\( *\)\s*:',
-    flags=re.M)
-
-regex_longcomments = re.compile('(""".*?"""|'+"'''.*?''')", re.DOTALL)
+# patterns to find includes and extends in views
 
 regex_include = re.compile(
     '(?P<all>\{\{\s*include\s+[\'"](?P<name>[^\'"]*)[\'"]\s*\}\})')


Test patch:
Repository: web2py/web2py

Issue:
lazyT should implement a __lt__ method
In Python-2, it is possible to sort a list of ``lazyT`` resp. use ``lazyT`` as key with ``sorted()`` - because it implements a ``__cmp__``. 

But Python-3 uses ``__lt__`` for sorting, so for forward-compatibility, it would be good if ``lazyT`` would implement that.

Steps to reproduce the behavior (works in Py2, but fails in Py3):
```
>>> a = [T("quick"), T("lazy"), T("fox")]
>>> a.sort()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: '<' not supported between instances of 'lazyT' and 'lazyT'
```

**Expected behavior**
List of ``lazyT`` can be sorted in Python-3 as it could in Python-2.



Discussion:

Resolving patch:
diff --git a/gluon/languages.py b/gluon/languages.py
--- a/gluon/languages.py
+++ b/gluon/languages.py
@@ -392,6 +392,12 @@ def __str__(self):
     def __eq__(self, other):
         return str(self) == str(other)
 
+    def __lt__(self, other):
+        return str(self) < str(other)
+
+    def __gt__(self, other):
+        return str(self) > str(other)
+
     def __ne__(self, other):
         return str(self) != str(other)
 


Test patch:
Repository: web2py/web2py

Issue:
copystream_progress returns StringIO not BytesIO if Content-Length is missing.
**Describe the bug**

In this code:

```python
def copystream_progress(request, chunk_size=10 ** 5):
    """
    Copies request.env.wsgi_input into request.body
    and stores progress upload status in cache_ram
    X-Progress-ID:length and X-Progress-ID:uploaded
    """
    env = request.env
    if not env.get('CONTENT_LENGTH', None):
        return StringIO()
    source = env['wsgi.input']
    try:
        size = int(env['CONTENT_LENGTH'])
    except ValueError:
        raise HTTP(400, "Invalid Content-Length header")
    try:  # Android requires this
        dest = tempfile.NamedTemporaryFile()
    except NotImplementedError:  # and GAE this
        dest = tempfile.TemporaryFile()
    copystream(source, dest, size, chunk_size,
               lambda v : cache_ram.increment(cache_key + ':uploaded', v))
    # [snip]
    return dest
```

If there is no request body we get a `StringIO` instance returned. However, the default file mode for `tempfile.TemporaryFile` is `w+b`, which returns a bytes-oriented file object.

The consequence is that the return type is inconsistent, and requires a check before attempting to `.decode()` the stream.

**To Reproduce**
Steps to reproduce the behavior:

With a controller of e.g.:

```python
def index():
    return request.body.read().decode('utf-8')
```

make requests like:

```sh
$ curl http://localhost:8000/app/controller -XPOST  # fails with AttributeError('str' object has no attribute 'decode')
$ curl http://localhost:8000/app/controller -XPOST -d''  # returns a response body of ''
$ curl http://localhost:8000/app/controller -XPOST  -d'hello'  # returns a response body of 'hello'
```

**Expected behavior**

`copystream_progress` should always return a bytes-returning file-like-object . This can be achieved by using `BytesIO` in place of `StringIO`.



Discussion:

Resolving patch:
diff --git a/gluon/globals.py b/gluon/globals.py
--- a/gluon/globals.py
+++ b/gluon/globals.py
@@ -12,8 +12,8 @@
 - Session
 
 """
-from gluon._compat import pickle, StringIO, copyreg, Cookie, urlparse, PY2, iteritems, to_unicode, to_native, \
-    to_bytes, unicodeT, long, hashlib_md5, urllib_quote, to_native
+from gluon._compat import pickle, BytesIO, StringIO, copyreg, Cookie, urlparse, PY2, iteritems, to_unicode, \
+    to_native, to_bytes, unicodeT, long, hashlib_md5, urllib_quote, to_native
 from gluon.storage import Storage, List
 from gluon.streamer import streamer, stream_file_or_304_or_206, DEFAULT_CHUNK_SIZE
 from gluon.contenttype import contenttype
@@ -129,7 +129,7 @@ def copystream_progress(request, chunk_size=10 ** 5):
     """
     env = request.env
     if not env.get('CONTENT_LENGTH', None):
-        return StringIO()
+        return BytesIO()
     source = env['wsgi.input']
     try:
         size = int(env['CONTENT_LENGTH'])


Test patch:
Repository: web2py/web2py

Issue:
Returning iterable of string instead of bytes in HEAD response
**Describe the bug**
uWSGI is expecting an iterable of bytes instead of (empty) string which is returned in case of HEAD request. This results in logging `[ERROR] Unhandled object from iterator: ''` because  [_The iterator returned something that we were not able to handle._](https://github.com/unbit/uwsgi/blob/d58a832c81c2c96ae0f6e72614e1cc47f4b5d332/plugins/python/wsgi_subhandler.c#L355)

**To Reproduce**
1. Create HEAD request
2. Check uwsgi logs for mentioned error log


Discussion:

Resolving patch:
diff --git a/gluon/http.py b/gluon/http.py
--- a/gluon/http.py
+++ b/gluon/http.py
@@ -122,7 +122,7 @@ def to(self, responder, env=None):
                 rheaders.append((k, str(v)))
         responder(status, rheaders)
         if env.get('request_method', '') == 'HEAD':
-            return ['']
+            return [to_bytes('')]
         elif isinstance(body, (str, bytes, bytearray)):
             if isinstance(body, unicodeT):
                 body = to_bytes(body)


Test patch:
Repository: web2py/web2py

Issue:
Unable to login when using redis for storing sessions
Basically a new session is created on each page load so the login is never established.

Issue discussed at: https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/web2py/6Ig5YVgvIsI/HpueAUELBgAJ

Confirmed with web2py versions from 2.18.5 up to 2.20.4.  Python versions 3.6 and 3.8





Discussion:
I can confirm the issue with web2py v2.20.4 ant python 3.8. Can not login when redis is used for sessions storage.
Neither works on v2.21.1 with python 3.8. Is this bug going to get any attention?

Resolving patch:
diff --git a/gluon/contrib/redis_session.py b/gluon/contrib/redis_session.py
--- a/gluon/contrib/redis_session.py
+++ b/gluon/contrib/redis_session.py
@@ -13,7 +13,7 @@
 from gluon.storage import Storage
 from gluon.contrib.redis_utils import acquire_lock, release_lock
 from gluon.contrib.redis_utils import register_release_lock
-from gluon._compat import to_native
+from gluon._compat import to_native, to_bytes
 from datetime import datetime
 
 logger = logging.getLogger("web2py.session.redis")
@@ -131,7 +131,6 @@ def __call__(self, record_id, unique_key=None):
         q.op = 'eq'
         q.value = record_id
         q.unique_key = unique_key
-
         row = q.select()
         return row[0] if row else Storage()
 
@@ -208,7 +207,7 @@ def select(self):
             if rtn:
                 if self.unique_key:
                     # make sure the id and unique_key are correct
-                    if rtn['unique_key'] == to_native(self.unique_key):
+                    if rtn['unique_key'] == to_bytes(self.unique_key):
                         rtn['update_record'] = self.update  # update record support
                     else:
                         rtn = None


Test patch: