cookiecutter / cookiecutter/cookiecutter

[Bug]: "NameError: name 'unicode' is not defined" when template includes certain file types

Open
#2,197 1 comment 5 reactions 0 assignees View on GitHub
bug
Dominant language
Python
Stars
25.1k
Forks
2.3k
PR merge metrics
No merged PRs in 30d

Description

### What happened?

Template creation is failing when certain files are included in the build. This appears to impact v2.7.1 only. Based on my CI history this wasn't happening until this version.

In my case it's font files (`.tff`) which are failing, but it could impact other extensions also. It appears related to a call to the `binaryornot` library to decide if the file is a binary and if it should be rendered or not. This is an older library and the incompatibility is probably deeper than cookiecutter itself.

I was able to work around this by including the impacted binary files in `_copy_without_render` within `cookiecutter.json`. Not attempting to render these files feels like the right approach anyway, but I'm sharing this in case anyone else falls foul to this and in case there's a fix available or if it needs documenting.

### Steps to reproduce

Steps to replicate:
* Use v2.7.1 of cookiecutter
* Include a valid `.tff` file in the build directories
* Generate the template

### Template

{
"project_name": "Sample App",
"app_name": "Sample App",
"_copy_without_render": []
}

### Output / traceback

```shell
Actual output

Traceback (most recent call last):
File "/Users/user/cookiecutter-test/.venv/lib/python3.12/site-packages/binaryornot/helpers.py", line 103, in is_binary_string
bytes_to_check.decode(encoding=detected_encoding['encoding'])
TypeError: decode() argument 'encoding' must be str, not None

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Users/user/cookiecutter-test/.venv/bin/cookiecutter", line 8, in
sys.exit(main())
^^^^^^
File "/Users/user/cookiecutter-test/.venv/lib/python3.12/site-packages/click/core.py", line 1485, in __call__
return self.main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/cookiecutter-test/.venv/lib/python3.12/site-packages/click/core.py", line 1406, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
File "/Users/user/cookiecutter-test/.venv/lib/python3.12/site-packages/click/core.py", line 1269, in invoke
return ctx.invoke(self.callback, **ctx.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/cookiecutter-test/.venv/lib/python3.12/site-packages/click/core.py", line 824, in invoke
return callback(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/cookiecutter-test/.venv/lib/python3.12/site-packages/cookiecutter/cli.py", line 219, in main
cookiecutter(
File "/Users/user/cookiecutter-test/.venv/lib/python3.12/site-packages/cookiecutter/main.py", line 185, in cookiecutter
result = generate_files(
^^^^^^^^^^^^^^^
File "/Users/user/cookiecutter-test/.venv/lib/python3.12/site-packages/cookiecutter/generate.py", line 448, in generate_files
generate_file(
File "/Users/user/cookiecutter-test/.venv/lib/python3.12/site-packages/cookiecutter/generate.py", line 221, in generate_file
if is_binary(infile):
^^^^^^^^^^^^^^^^^
File "/Users/user/cookiecutter-test/.venv/lib/python3.12/site-packages/binaryornot/check.py", line 33, in is_binary
return is_binary_string(chunk)
^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/cookiecutter-test/.venv/lib/python3.12/site-packages/binaryornot/helpers.py", line 106, in is_binary_string
unicode(bytes_to_check, encoding=detected_encoding['encoding']) # noqa
^^^^^^^
NameError: name 'unicode' is not defined
```

### Cookiecutter version

2.7.1

### Python version

3.12

### Operating system

macOS

### How did you install Cookiecutter?

pip

### Additional context

I asked an LLM to summarise, hopefully this helps:
```
binaryornot 0.4.4 (last released in 2017) declares its dependency as chardet >= 3.0.2 with no upper bound. It was written against chardet 3.x behavior where detect() always returned a string encoding. In chardet 7.x, detect() can return None for both encoding and confidence when fed unrecognizable binary data. binaryornot has no guards against None values, and its Python 2 fallback (unicode()) is dead code on Python 3.
```

Contributor guide

Open the contributing guide

Research direction

Start in cookiecutter/generate.py at generate_file, which calls binaryornot/check.py and binaryornot/helpers.py while processing the .tff file. Reproduce with Cookiecutter 2.7.1, Python 3.12, and the supplied template, then determine whether template generation can complete for binary files; done means the reported traceback no longer occurs.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.