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

Issue:
Bug: event_postprocessor 不能在 matcher 运行后正常执行
**描述问题：**

event_postprocessor 不能在 matcher 运行后正常执行

**如何复现？**

编写以下插件
```python
from nonebot import on_command, logger
from nonebot.message import event_postprocessor
from nonebot.typing import T_State
from nonebot.adapters.cqhttp.event import Event, MessageEvent
from nonebot.adapters.cqhttp.bot import Bot


test = on_command('test')


@test.handle()
async def handle_test(bot: Bot, event: MessageEvent, state: T_State):
    logger.opt(colors=True).info('<ly>matcher is running!</ly>')


@event_postprocessor
async def handle_event_postprocessor(bot: Bot, event: Event, state: T_State):
    logger.opt(colors=True).success('<ly>event_postprocessor is running!</ly>')
```

**期望的结果**

event_postprocessor 能在任意情况下正常执行

实际上当 matcher 运行后 event_postprocessor 会被跳过

![image](https://user-images.githubusercontent.com/41713304/134709135-4d0d52ec-2df1-48a8-94ee-196c9c4d3da6.png)

**其他信息**

第 250 行 `return result` 将直接导致 matcher 运行后 event_postprocessor 被跳过

https://github.com/nonebot/nonebot2/blob/0b35d5e724a2fc7fc1e7d90499aea8a9c27e821d/nonebot/message.py#L238-L262

**环境信息：**

 - OS: Windows 10 21H1
 - Python Version: 3.9.6
 - Nonebot Version: 2.0.0a15

**协议端信息：**

 - 协议端: 无
 - 协议端版本: 无

**截图或日志**

如上



Discussion:
这个确实会这样，如果某一个matcher是block的话，会触发StopPropagation这个异常，之后应该continue的但是却直接return了，所以return只应该面对非StopPropagation的Exception才行。
这个问题是由pr #322 导致

Resolving patch:
diff --git a/nonebot/message.py b/nonebot/message.py
--- a/nonebot/message.py
+++ b/nonebot/message.py
@@ -176,7 +176,7 @@ async def _run_matcher(Matcher: Type[Matcher], bot: "Bot", event: "Event",
     return
 
 
-async def handle_event(bot: "Bot", event: "Event") -> Optional[Exception]:
+async def handle_event(bot: "Bot", event: "Event") -> None:
     """
     :说明:
 
@@ -213,12 +213,12 @@ async def handle_event(bot: "Bot", event: "Event") -> Optional[Exception]:
         except IgnoredException as e:
             logger.opt(colors=True).info(
                 f"Event {escape_tag(event.get_event_name())} is <b>ignored</b>")
-            return e
+            return
         except Exception as e:
             logger.opt(colors=True, exception=e).error(
                 "<r><bg #f8bbd0>Error when running EventPreProcessors. "
                 "Event ignored!</bg #f8bbd0></r>")
-            return e
+            return
 
     # Trie Match
     _, _ = TrieRule.get_value(bot, event, state)
@@ -248,7 +248,6 @@ async def handle_event(bot: "Bot", event: "Event") -> Optional[Exception]:
                 logger.opt(colors=True, exception=result).error(
                     "<r><bg #f8bbd0>Error when checking Matcher.</bg #f8bbd0></r>"
                 )
-            return result
 
     coros = list(map(lambda x: x(bot, event, state), _event_postprocessors))
     if coros:
@@ -260,4 +259,3 @@ async def handle_event(bot: "Bot", event: "Event") -> Optional[Exception]:
             logger.opt(colors=True, exception=e).error(
                 "<r><bg #f8bbd0>Error when running EventPostProcessors</bg #f8bbd0></r>"
             )
-            return e


Test patch:
Repository: nonebot/nonebot2

Issue:
Bug: got 装饰器行为异常
**描述问题：**

如果手动在 state 设置一个 key 的值为 []，got 装饰器依旧会向用户发送 prompt 消息，并等待用户回复。

**如何复现？**

```python
@matcher.handle()
async def init_cat(state: T_State = State()):
        state["cats"] = []

@matcher.got("cats", Message.template("这个不会被跳过"))
async def init_tag(event: GroupMessageEvent, state: T_State = State()):
     ...
```

**期望的结果**

自动跳过获取用户输入。

**环境信息：**

 - OS: Windows 11
 - Python Version: 3.9
 - Nonebot Version: 2.0.0b1

**协议端信息：**

 - 协议端: nonebot-adapter-onebot
 - 协议端版本: 2.0.0b1

**截图或日志**



Discussion:

Resolving patch:
diff --git a/nonebot/matcher.py b/nonebot/matcher.py
--- a/nonebot/matcher.py
+++ b/nonebot/matcher.py
@@ -425,7 +425,7 @@ async def _receive(event: Event, matcher: "Matcher") -> Union[None, NoReturn]:
             if matcher.get_target() == RECEIVE_KEY.format(id=id):
                 matcher.set_receive(id, event)
                 return
-            if matcher.get_receive(id):
+            if matcher.get_receive(id, ...) is not ...:
                 return
             await matcher.reject()
 
@@ -469,7 +469,7 @@ async def _key_getter(event: Event, matcher: "Matcher"):
             if matcher.get_target() == ARG_KEY.format(key=key):
                 matcher.set_arg(key, event.get_message())
                 return
-            if matcher.get_arg(key):
+            if matcher.get_arg(key, ...) is not ...:
                 return
             await matcher.reject(prompt)
 


Test patch:
Repository: nonebot/nonebot2

Issue:
Bug: 部分情况下，加载失败的插件依然会出现在当前已导入的所有插件中
**描述问题：**

通过 nonebot.get_loaded_plugins() 获取当前已导入的所有插件，加载失败的插件也出现在其中

**如何复现？**

1. 复制 2.0.0 a16 版本文档的[注册事件响应器](https://61d3d9dbcadf413fd3238e89--nonebot2.netlify.app/guide/creating-a-matcher.html)一节的 weather.py 的代码作为插件，并在 2.0.0 beta1 版本导入它（很显然，这会发生错误）
2. 通过 nonebot.get_loaded_plugins() 获取已导入的插件，可以发现这个加载失败的插件出现在了已导入的插件中

**期望的结果**

加载失败的插件不出现在已导入的所有插件中

**环境信息：**

 - OS: [Windows]
 - Python Version: [3.10]
 - Nonebot Version: [2.0.0 b1]

**协议端信息：**

 - 协议端: [go-cqhttp]
 - 协议端版本: [1.0.0]

**截图或日志**

```
[ERROR] nonebot | Failed to import "kirami.plugins.weather"
ValueError: Unknown parameter state for function <function handle_first_receive at 0x000001924056AB90> with type typing.Dict[typing.Any, typing.Any]

{Plugin(name='weather', module=<module 'kirami.plugins.weather' from 'D:\\Users\\Documents\\gitee\\KiramiBot\\kirami\\plugins\\weather\\__init__.py'>, module_name='kirami.plugins.weather', manager=<nonebot.plugin.manager.PluginManager object at 0x000002140ECEF130>, export={}, matcher=set(), parent_plugin=None, sub_plugins=set())}
```


Discussion:

Resolving patch:
diff --git a/nonebot/plugin/manager.py b/nonebot/plugin/manager.py
--- a/nonebot/plugin/manager.py
+++ b/nonebot/plugin/manager.py
@@ -10,8 +10,8 @@
 
 from nonebot.log import logger
 from nonebot.utils import escape_tag
-from .plugin import Plugin, _new_plugin
 from . import _managers, _current_plugin
+from .plugin import Plugin, _new_plugin, _confirm_plugin
 
 
 class PluginManager:
@@ -180,6 +180,8 @@ def exec_module(self, module: ModuleType) -> None:
         #     ) from e
         super().exec_module(module)
 
+        _confirm_plugin(plugin)
+
         _current_plugin.reset(_plugin_token)
         return
 
diff --git a/nonebot/plugin/plugin.py b/nonebot/plugin/plugin.py
--- a/nonebot/plugin/plugin.py
+++ b/nonebot/plugin/plugin.py
@@ -96,5 +96,10 @@ def _new_plugin(fullname: str, module: ModuleType, manager: "PluginManager") ->
     if name in plugins:
         raise RuntimeError("Plugin already exists! Check your plugin name.")
     plugin = Plugin(name, module, fullname, manager)
-    plugins[name] = plugin
     return plugin
+
+
+def _confirm_plugin(plugin: Plugin) -> None:
+    if plugin.name in plugins:
+        raise RuntimeError("Plugin already exists! Check your plugin name.")
+    plugins[plugin.name] = plugin


Test patch:
diff --git a/tests/test_init.py b/tests/test_init.py
--- a/tests/test_init.py
+++ b/tests/test_init.py
@@ -94,3 +94,9 @@ async def test_load_plugin(load_plugin: Set["Plugin"]):
         assert False
     except RuntimeError:
         assert True
+
+    try:
+        nonebot.load_plugin("some_plugin_no_exist")
+        assert False
+    except Exception:
+        assert nonebot.get_plugin("some_plugin_no_exist") is None
Repository: nonebot/nonebot2

Issue:
Bug: MessageTemplate无法对数字字符等类型进行格式化
**描述问题：**

上游issue：https://github.com/mnixry/nonebot-plugin-gocqhttp/issues/281

**如何复现？**

在一个消息模板中格式化数字

**期望的结果**

不报错

**故障原因**

推测原因如下

在函数`Message.__iadd__`中，如果相加类型错误会抛出`ValueError`异常：
https://github.com/nonebot/nonebot2/blob/549a37b172ceeedac183fb48b58fe13a16eb56cd/nonebot/internal/adapter/message.py#L181-L190

在`MessageTemplate._add`中，只对一般类型相加出错的`TypeError`做了处理：
https://github.com/nonebot/nonebot2/blob/549a37b172ceeedac183fb48b58fe13a16eb56cd/nonebot/internal/adapter/template.py#L180-L184

因此导致了该错误


Discussion:

Resolving patch:
diff --git a/nonebot/internal/adapter/message.py b/nonebot/internal/adapter/message.py
--- a/nonebot/internal/adapter/message.py
+++ b/nonebot/internal/adapter/message.py
@@ -186,7 +186,7 @@ def __iadd__(self: TM, other: Union[str, TMS, Iterable[TMS]]) -> TM:
         elif isinstance(other, Iterable):
             self.extend(other)
         else:
-            raise ValueError(f"Unsupported type: {type(other)}")  # pragma: no cover
+            raise TypeError(f"Unsupported type {type(other)!r}")
         return self
 
     @overload


Test patch:
diff --git a/tests/test_adapters/test_template.py b/tests/test_adapters/test_template.py
--- a/tests/test_adapters/test_template.py
+++ b/tests/test_adapters/test_template.py
@@ -11,11 +11,11 @@ def test_template_basis():
 
 def test_template_message():
     Message = make_fake_message()
-    template = Message.template("{a:custom}{b:text}{c:image}")
+    template = Message.template("{a:custom}{b:text}{c:image}/{d}")
 
     @template.add_format_spec
     def custom(input: str) -> str:
-        return input + "-custom!"
+        return f"{input}-custom!"
 
     try:
         template.add_format_spec(custom)
@@ -24,12 +24,17 @@ def custom(input: str) -> str:
     else:
         raise AssertionError("Should raise ValueError")
 
-    format_args = {"a": "custom", "b": "text", "c": "https://example.com/test"}
+    format_args = {
+        "a": "custom",
+        "b": "text",
+        "c": "https://example.com/test",
+        "d": 114,
+    }
     formatted = template.format(**format_args)
 
     assert template.format_map(format_args) == formatted
-    assert formatted.extract_plain_text() == "custom-custom!text"
-    assert str(formatted) == "custom-custom!text[fake:image]"
+    assert formatted.extract_plain_text() == "custom-custom!text/114"
+    assert str(formatted) == "custom-custom!text[fake:image]/114"
 
 
 def test_rich_template_message():
Repository: nonebot/nonebot2

Issue:
Bug: 插件加载日志存在歧义
1. 先 success 再报错
2. 当插件模块名内含 `.` 时，实际插件名和模块名不一致

https://github.com/nonebot/nonebot2/blob/1dc02bfe8e9e481b7b22f71fa878463e798f4114/nonebot/plugin/manager.py#L151-L158

3. 这里使用了已经处理过的名字即插件名，日志显示名称会与实际用户提供名称不一致，产生迷惑

https://github.com/nonebot/nonebot2/blob/1dc02bfe8e9e481b7b22f71fa878463e798f4114/nonebot/plugin/manager.py#L165-L170


Discussion:

Resolving patch:
diff --git a/nonebot/plugin/manager.py b/nonebot/plugin/manager.py
--- a/nonebot/plugin/manager.py
+++ b/nonebot/plugin/manager.py
@@ -148,14 +148,21 @@ def load_plugin(self, name: str) -> Optional[Plugin]:
             else:
                 raise RuntimeError(f"Plugin not found: {name}! Check your plugin name")
 
-            logger.opt(colors=True).success(
-                f'Succeeded to import "<y>{escape_tag(name)}</y>"'
-            )
-            if (plugin := getattr(module, "__plugin__", None)) is None:
+            if (
+                plugin := getattr(module, "__plugin__", None)
+            ) is None or not isinstance(plugin, Plugin):
                 raise RuntimeError(
                     f"Module {module.__name__} is not loaded as a plugin! "
                     "Make sure not to import it before loading."
                 )
+            logger.opt(colors=True).success(
+                f'Succeeded to load plugin "<y>{escape_tag(plugin.name)}</y>"'
+                + (
+                    f' from "<m>{escape_tag(plugin.module_name)}</m>"'
+                    if plugin.module_name != plugin.name
+                    else ""
+                )
+            )
             return plugin
         except Exception as e:
             logger.opt(colors=True, exception=e).error(


Test patch:
Repository: nonebot/nonebot2

Issue:
Feature: 替换 toml 读取方式
在 python 3.11 中已经支持了读取 toml 配置。https://docs.python.org/3/library/tomllib.html


Discussion:

Resolving patch:
diff --git a/nonebot/plugin/load.py b/nonebot/plugin/load.py
--- a/nonebot/plugin/load.py
+++ b/nonebot/plugin/load.py
@@ -9,14 +9,17 @@
 from types import ModuleType
 from typing import Set, Union, Iterable, Optional
 
-import tomlkit
-
 from nonebot.utils import path_to_module_name
 
 from .plugin import Plugin
 from .manager import PluginManager
 from . import _managers, get_plugin, _module_name_to_plugin_name
 
+try:
+    import tomllib  # pyright: reportMissingImports=false
+except ModuleNotFoundError:
+    import tomli as tomllib
+
 
 def load_plugin(module_path: Union[str, Path]) -> Optional[Plugin]:
     """加载单个插件，可以是本地插件或是通过 `pip` 安装的插件。
@@ -108,7 +111,7 @@ def load_from_toml(file_path: str, encoding: str = "utf-8") -> Set[Plugin]:
         ```
     """
     with open(file_path, "r", encoding=encoding) as f:
-        data = tomlkit.parse(f.read())  # type: ignore
+        data = tomllib.loads(f.read())
 
     nonebot_data = data.get("tool", {}).get("nonebot")
     if nonebot_data is None:


Test patch:
Repository: nonebot/nonebot2

Issue:
Bug: `Adapter.bot_disconnect` 不应允许关闭其他适配器创建的 bot
**描述问题：**

当前的 `bot_disconnect` 只会根据 `bot.self_id` 关闭对应 bot。如果 `OneBot V12` 适配器调用 `bot_disconnect` 也能将 `OneBot V11` 适配器创建的 bot 移除。

**如何复现？**

<https://github.com/nonebot/adapter-onebot/pull/45>
<https://github.com/he0119/CoolQBot/issues/264>

**期望的结果**

如果关闭的 bot 不属于当前适配器，则跳过或者报错。



Discussion:

Resolving patch:
diff --git a/nonebot/internal/adapter/adapter.py b/nonebot/internal/adapter/adapter.py
--- a/nonebot/internal/adapter/adapter.py
+++ b/nonebot/internal/adapter/adapter.py
@@ -66,8 +66,9 @@ def bot_disconnect(self, bot: Bot) -> None:
         参数:
             bot: {ref}`nonebot.adapters.Bot` 实例
         """
+        if self.bots.pop(bot.self_id, None) is None:
+            raise RuntimeError(f"{bot} not found in adapter {self.get_name()}")
         self.driver._bot_disconnect(bot)
-        self.bots.pop(bot.self_id, None)
 
     def setup_http_server(self, setup: HTTPServerSetup):
         """设置一个 HTTP 服务器路由配置"""


Test patch:
Repository: nonebot/nonebot2

Issue:
Bug: run_sync忽略了上下文变量
### 操作系统

Windows

### Python 版本

3.11.0

### NoneBot 版本

2.0.0rc4

### 适配器

-

### 协议端

-

### 描述问题

[run_sync](https://github.com/nonebot/nonebot2/blob/e98d28f3b4fdda2504ecc07318563ce202464b96/nonebot/utils.py#L114)忽略了上下文变量，可能会导致异常，比如https://github.com/nonebot/nonebot2/issues/1966

### 复现步骤

-

### 期望的结果

使用```copy_context```然后```ctx.run```进executor

### 截图或日志

-


Discussion:
索性直接换anyio解决所有问题 一步到位（

Resolving patch:
diff --git a/nonebot/utils.py b/nonebot/utils.py
--- a/nonebot/utils.py
+++ b/nonebot/utils.py
@@ -12,6 +12,7 @@
 import importlib
 import dataclasses
 from pathlib import Path
+from contextvars import copy_context
 from functools import wraps, partial
 from contextlib import asynccontextmanager
 from typing_extensions import ParamSpec, get_args, get_origin
@@ -111,7 +112,9 @@ def run_sync(call: Callable[P, R]) -> Callable[P, Coroutine[None, None, R]]:
     async def _wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
         loop = asyncio.get_running_loop()
         pfunc = partial(call, *args, **kwargs)
-        result = await loop.run_in_executor(None, pfunc)
+        context = copy_context()
+        context_run = context.run
+        result = await loop.run_in_executor(None, context_run, pfunc)
         return result
 
     return _wrapper


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
Generating reminder cards fails
``````
Exception occurred while handling POST request to /teach/class/TY060/print_reminder_cards/
Traceback (most recent call last):
  File "/base/data/home/apps/e~decent-digit-629/snap-75.390448226767000709/lib/django/core/handlers/base.py", line 132, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/base/data/home/apps/e~decent-digit-629/snap-75.390448226767000709/lib/django/contrib/auth/decorators.py", line 22, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/base/data/home/apps/e~decent-digit-629/snap-75.390448226767000709/lib/django/contrib/auth/decorators.py", line 22, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/base/data/home/apps/e~decent-digit-629/snap-75.390448226767000709/lib/portal/views/teacher/teach.py", line 596, in teacher_print_reminder_cards
    character_image = ImageReader(finders.find(character_file))
  File "/base/data/home/apps/e~decent-digit-629/snap-75.390448226767000709/lib/reportlab/lib/utils.py", line 801, in __init__
    annotateException('\nfileName=%r identity=%s'%(fileName,self.identity()))
  File "/base/data/home/apps/e~decent-digit-629/snap-75.390448226767000709/lib/reportlab/lib/utils.py", line 1381, in annotateException
    rl_reraise(t,v,b)
  File "/base/data/home/apps/e~decent-digit-629/snap-75.390448226767000709/lib/reportlab/lib/utils.py", line 765, in __init__
    self.fp = open_for_read(fileName,'b')
  File "/base/data/home/apps/e~decent-digit-629/snap-75.390448226767000709/lib/reportlab/lib/utils.py", line 663, in open_for_read
    raise IOError('Cannot open resource "%s"' % name)
IOError: Cannot open resource "None"
fileName=None identity=[ImageReader@0xf8ec4750L]```
``````



Discussion:
This is happening because the static files in the app dirs are being stripped during deployment to get under the 10k files limit.

In prod they need to be accessed under STATIC_ROOT instead.

Check how the {% static %} tag works?


Resolving patch:
diff --git a/portal/views/teacher/teach.py b/portal/views/teacher/teach.py
--- a/portal/views/teacher/teach.py
+++ b/portal/views/teacher/teach.py
@@ -46,7 +46,7 @@
 from django.contrib import messages as messages
 from django.contrib.auth import logout, update_session_auth_hash
 from django.contrib.auth.decorators import login_required, user_passes_test
-from django.contrib.staticfiles import finders
+from django.contrib.staticfiles.storage import staticfiles_storage
 from django.forms.formsets import formset_factory
 from django.utils import timezone
 from reportlab.pdfgen import canvas
@@ -593,7 +593,7 @@ def teacher_print_reminder_cards(request, access_code):
     CHARACTERS = []
 
     for character_file in CHARACTER_FILES:
-        character_image = ImageReader(finders.find(character_file))
+        character_image = ImageReader(staticfiles_storage.path(character_file))
         character_height = CARD_INNER_HEIGHT
         character_width = CARD_IMAGE_WIDTH
         character_height = character_width * character_image.getSize()[1] / character_image.getSize()[0]


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
Password Reset Hidden while waiting for 2FA
https://github.com/ocadotechnology/rapid-router/issues/684

Original message: 
Steps to reproduce on a 2FA enabled account:
1. Got to /teach/, enter login details and click "Sign in".
2. When the token form appears, go back to teach and click "Forgotten Password?" link

You'll end up back at teach and the url will change to "/teach/?next=/teach/home/"

It seems that if 2FA login process is pending, the password reset screen gets redirected back to /teach/.

---

=> This is because after the sign in attempt, the teacher is no longer "not_logged_in" because a UserProfile has been found.



Discussion:

Resolving patch:
diff --git a/portal/permissions.py b/portal/permissions.py
--- a/portal/permissions.py
+++ b/portal/permissions.py
@@ -56,6 +56,10 @@ def not_logged_in(u):
     return not hasattr(u, 'userprofile')
 
 
+def not_fully_logged_in(u):
+    return not_logged_in(u) or (not logged_in_as_student(u) and not logged_in_as_teacher(u))
+
+
 def teacher_verified(view_func):
     @wraps(view_func)
     def wrapped(request, *args, **kwargs):
diff --git a/portal/views/registration.py b/portal/views/registration.py
--- a/portal/views/registration.py
+++ b/portal/views/registration.py
@@ -47,7 +47,7 @@
 from deploy.captcha import CAPTCHA_ENABLED
 
 from portal.forms.registration import PasswordResetSetPasswordForm, StudentPasswordResetForm, TeacherPasswordResetForm
-from portal.permissions import not_logged_in
+from portal.permissions import not_logged_in, not_fully_logged_in
 from portal.helpers.email import PASSWORD_RESET_EMAIL
 from portal import app_settings
 from ratelimit.decorators import ratelimit
@@ -64,7 +64,7 @@ def custom_2FA_login(request):
     return LoginView.as_view()(request)
 
 
-@user_passes_test(not_logged_in, login_url=reverse_lazy('current_user'))
+@user_passes_test(not_fully_logged_in, login_url=reverse_lazy('current_user'))
 def password_reset_check_and_confirm(request, uidb64=None, token=None, post_reset_redirect=None):
     # Customised standard django auth view with customised form to incorporate checking the password set is strong enough
     UserModel = get_user_model()
@@ -87,7 +87,7 @@ def student_password_reset(request, post_reset_redirect):
     return password_reset(request, from_email=PASSWORD_RESET_EMAIL, template_name='registration/student_password_reset_form.html', password_reset_form=form, post_reset_redirect=post_reset_redirect, is_admin_site=True)
 
 
-@user_passes_test(not_logged_in, login_url=reverse_lazy('current_user'))
+@user_passes_test(not_fully_logged_in, login_url=reverse_lazy('current_user'))
 def teacher_password_reset(request, post_reset_redirect):
     form = TeacherPasswordResetForm if not CAPTCHA_ENABLED else decorate_with_captcha(TeacherPasswordResetForm, request,
                                                                                    recaptcha_client)


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
Print Reminder Cards Not Generating Cards anymore
When a teacher tries to generate a reminder login card for a pupil, an error occurs.
Trace in local:
Traceback:

`File "/home/c/.virtualenvs/rapid-router/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response`
`132. response = wrapped_callback(request, *callback_args, **callback_kwargs)`
`File "/home/c/.virtualenvs/rapid-router/local/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view`
`22. return view_func(request, *args, **kwargs)
File "/home/c/.virtualenvs/rapid-router/local/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view`
`22. return view_func(request, *args, **kwargs)
File "/home/c/code-for-life/worktree/codeforlife-portal/portal/views/teacher/teach.py" in teacher_print_reminder_cards`
`629. klass = Class.objects.get_object_or_404(access_code=access_code)`
`Exception Type: AttributeError at /portal/teach/class/GQ653/print_reminder_cards/`
`Exception Value: 'Manager' object has no attribute 'get_object_or_404'`



Discussion:

Resolving patch:
diff --git a/portal/views/teacher/teach.py b/portal/views/teacher/teach.py
--- a/portal/views/teacher/teach.py
+++ b/portal/views/teacher/teach.py
@@ -626,9 +626,9 @@ def teacher_print_reminder_cards(request, access_code):
         character = {'image': character_image, 'height': character_height, 'width': character_width}
         CHARACTERS.append(character)
 
-    klass = Class.objects.get_object_or_404(access_code=access_code)
+    klass = get_object_or_404(Class, access_code=access_code)
     # Check auth
-    if klass.Teacher != request.user:
+    if klass.teacher.user.user != request.user:
         raise Http404
 
     COLUMN_WIDTH = (CARD_INNER_WIDTH - CARD_IMAGE_WIDTH) * 0.45


Test patch:
Repository: ocadotechnology/codeforlife-portal

Issue:
Update models search field values in admin



Discussion:

Resolving patch:
diff --git a/portal/models.py b/portal/models.py
--- a/portal/models.py
+++ b/portal/models.py
@@ -126,7 +126,7 @@ def class_(self):
         return None
 
     def __unicode__(self):
-        return '%s %s' % (self.user.first_name, self.user.last_name)
+        return '%s %s' % (self.new_user.first_name, self.new_user.last_name)
 
 
 class Class(models.Model):


Test patch: